]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/test/include/boost/test/data/test_case.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / test / include / boost / test / data / test_case.hpp
1 // (C) Copyright Gennadiy Rozental 2001.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5
6 // See http://www.boost.org/libs/test for the library home page.
7 //
8 //!@file
9 //!@brief test case family based on data generator
10 // ***************************************************************************
11
12 #ifndef BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
13 #define BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
14
15 // Boost.Test
16 #include <boost/test/data/config.hpp>
17 #include <boost/test/data/dataset.hpp>
18 #include <boost/test/data/for_each_sample.hpp>
19
20 // Boost
21 #include <boost/preprocessor/repetition/enum_params.hpp>
22 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
23 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
24
25 #include <boost/preprocessor/variadic/to_seq.hpp>
26 #include <boost/preprocessor/variadic/size.hpp>
27 #include <boost/preprocessor/cat.hpp>
28 #include <boost/preprocessor/seq/for_each_i.hpp>
29 #include <boost/preprocessor/seq/for_each.hpp>
30 #include <boost/preprocessor/seq/enum.hpp>
31 #include <boost/preprocessor/control/iif.hpp>
32 #include <boost/preprocessor/comparison/equal.hpp>
33
34 #include <boost/bind.hpp>
35
36 #include <boost/type_traits/is_copy_constructible.hpp>
37
38 #include <boost/test/detail/suppress_warnings.hpp>
39 #include <boost/test/tools/detail/print_helper.hpp>
40 #include <boost/test/utils/string_cast.hpp>
41
42 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \
43 && !defined(BOOST_TEST_DATASET_MAX_ARITY)
44 # define BOOST_TEST_DATASET_MAX_ARITY 10
45 #endif
46
47 //____________________________________________________________________________//
48
49 namespace boost {
50 namespace unit_test {
51 namespace data {
52
53 namespace ds_detail {
54
55 // ************************************************************************** //
56 // ************** seed ************** //
57 // ************************************************************************** //
58
59 struct seed {
60 template<typename DataSet>
61 typename data::result_of::make<DataSet>::type
62 operator->*( DataSet&& ds ) const
63 {
64 return data::make( std::forward<DataSet>( ds ) );
65 }
66 };
67
68
69 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
70 !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
71 !defined(BOOST_NO_CXX11_DECLTYPE) && \
72 !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) && \
73 !defined(BOOST_NO_CXX11_SMART_PTR)
74
75 #define BOOST_TEST_DATASET_VARIADIC
76 template <class T>
77 struct parameter_holder {
78 std::shared_ptr<T> value;
79
80 parameter_holder(T && value_)
81 : value(std::make_shared<T>(std::move(value_)))
82 {}
83
84 operator T const&() const {
85 return *value;
86 }
87 };
88
89 template <class T>
90 parameter_holder<typename std::remove_reference<T>::type>
91 boost_bind_rvalue_holder_helper_impl(T&& value, boost::false_type /* is copy constructible */) {
92 return parameter_holder<typename std::remove_reference<T>::type>(std::forward<T>(value));
93 }
94
95 template <class T>
96 T&& boost_bind_rvalue_holder_helper_impl(T&& value, boost::true_type /* is copy constructible */) {
97 return std::forward<T>(value);
98 }
99
100 template <class T>
101 auto boost_bind_rvalue_holder_helper(T&& value)
102 -> decltype(boost_bind_rvalue_holder_helper_impl(
103 std::forward<T>(value),
104 typename boost::is_copy_constructible<typename std::remove_reference<T>::type>::type()))
105 {
106 // need to use boost::is_copy_constructible because std::is_copy_constructible is broken on MSVC12
107 return boost_bind_rvalue_holder_helper_impl(
108 std::forward<T>(value),
109 typename boost::is_copy_constructible<typename std::remove_reference<T>::type>::type());
110 }
111
112 #endif
113
114
115 // ************************************************************************** //
116 // ************** test_case_gen ************** //
117 // ************************************************************************** //
118
119 template<typename TestCase,typename DataSet>
120 class test_case_gen : public test_unit_generator {
121 public:
122 // Constructor
123 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
124 test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet&& ds )
125 : m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
126 , m_tc_file( tc_file )
127 , m_tc_line( tc_line )
128 , m_tc_index( 0 )
129 {
130 data::for_each_sample( std::forward<DataSet>( ds ), *this );
131 }
132 test_case_gen( test_case_gen&& gen )
133 : m_tc_name( gen.m_tc_name )
134 , m_tc_file( gen.m_tc_file )
135 , m_tc_line( gen.m_tc_line )
136 , m_tc_index( gen.m_tc_index )
137 , m_test_cases( std::move(gen.m_test_cases) )
138 {}
139 #else
140 test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet const& ds )
141 : m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
142 , m_tc_file( tc_file )
143 , m_tc_line( tc_line )
144 , m_tc_index( 0 )
145 {
146 data::for_each_sample( ds, *this );
147 }
148 #endif
149
150 virtual test_unit* next() const
151 {
152 if( m_test_cases.empty() )
153 return 0;
154
155 test_unit* res = m_test_cases.front();
156 m_test_cases.pop_front();
157
158 return res;
159 }
160
161 #if !defined(BOOST_TEST_DATASET_VARIADIC)
162 // see BOOST_TEST_DATASET_MAX_ARITY to increase the default supported arity
163 #define TC_MAKE(z,arity,_) \
164 template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
165 void operator()( BOOST_PP_ENUM_BINARY_PARAMS(arity, Arg, const& arg) ) const \
166 { \
167 m_test_cases.push_back( new test_case( genTestCaseName(), m_tc_file, m_tc_line, \
168 boost::bind( &TestCase::template test_method<BOOST_PP_ENUM_PARAMS(arity,Arg)>,\
169 BOOST_PP_ENUM_PARAMS(arity, arg) ) ) ); \
170 } \
171
172 BOOST_PP_REPEAT_FROM_TO(1, BOOST_TEST_DATASET_MAX_ARITY, TC_MAKE, _)
173 #else
174 template<typename ...Arg>
175 void operator()(Arg&& ... arg) const
176 {
177 m_test_cases.push_back(
178 new test_case( genTestCaseName(),
179 m_tc_file,
180 m_tc_line,
181 boost::bind( &TestCase::template test_method<Arg...>,
182 boost_bind_rvalue_holder_helper(std::forward<Arg>(arg))...)));
183 }
184 #endif
185
186 private:
187 std::string genTestCaseName() const
188 {
189 return "_" + utils::string_cast(m_tc_index++);
190 }
191
192 // Data members
193 std::string m_tc_name;
194 const_string m_tc_file;
195 std::size_t m_tc_line;
196 mutable std::size_t m_tc_index;
197 mutable std::list<test_unit*> m_test_cases;
198 };
199
200 //____________________________________________________________________________//
201
202 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
203 template<typename TestCase,typename DataSet>
204 test_case_gen<TestCase,DataSet>
205 make_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet&& ds )
206 {
207 return test_case_gen<TestCase,DataSet>( tc_name, tc_file, tc_line, std::forward<DataSet>(ds) );
208 }
209 #else
210 template<typename TestCase,typename DataSet>
211 test_case_gen<TestCase,DataSet>
212 make_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet const& ds )
213 {
214 return test_case_gen<TestCase,DataSet>( tc_name, tc_file, tc_line, ds );
215 }
216 #endif
217
218 //____________________________________________________________________________//
219
220 } // namespace ds_detail
221
222 // ************************************************************************** //
223 // ************** BOOST_DATA_TEST_CASE ************** //
224 // ************************************************************************** //
225
226 #define BOOST_DATA_TEST_CASE_PARAM(r, _, i, param) (BOOST_PP_CAT(Arg, i) const& param)
227 #define BOOST_DATA_TEST_CONTEXT(r, _, param) << BOOST_STRINGIZE(param) << " = " << boost::test_tools::tt_detail::print_helper(param) << "; "
228
229 #define BOOST_DATA_TEST_CASE_PARAMS( params ) \
230 BOOST_PP_SEQ_ENUM( \
231 BOOST_PP_SEQ_FOR_EACH_I(BOOST_DATA_TEST_CASE_PARAM, _, params)) \
232 /**/
233
234 #define BOOST_DATA_TEST_CASE_IMPL(arity, F, test_name, dataset, params) \
235 struct BOOST_PP_CAT(test_name, case) : public F { \
236 template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
237 static void test_method( BOOST_DATA_TEST_CASE_PARAMS( params ) ) \
238 { \
239 BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture entry.");\
240 BOOST_PP_CAT(test_name, case) t; \
241 BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \
242 BOOST_TEST_CONTEXT( "" \
243 BOOST_PP_SEQ_FOR_EACH(BOOST_DATA_TEST_CONTEXT, _, params)) \
244 t._impl(BOOST_PP_SEQ_ENUM(params)); \
245 BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \
246 } \
247 private: \
248 template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
249 void _impl(BOOST_DATA_TEST_CASE_PARAMS( params )); \
250 }; \
251 \
252 BOOST_AUTO_TEST_SUITE( test_name ) \
253 \
254 BOOST_AUTO_TU_REGISTRAR( BOOST_PP_CAT(test_name, case) )( \
255 boost::unit_test::data::ds_detail::make_test_case_gen< \
256 BOOST_PP_CAT(test_name, case)>( \
257 BOOST_STRINGIZE( test_name ), \
258 __FILE__, __LINE__, \
259 boost::unit_test::data::ds_detail::seed{} ->* dataset ), \
260 boost::unit_test::decorator::collector::instance() ); \
261 \
262 BOOST_AUTO_TEST_SUITE_END() \
263 \
264 template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
265 void BOOST_PP_CAT(test_name, case)::_impl( \
266 BOOST_DATA_TEST_CASE_PARAMS( params ) ) \
267 /**/
268
269 #define BOOST_DATA_TEST_CASE_WITH_PARAMS( F, test_name, dataset, ... ) \
270 BOOST_DATA_TEST_CASE_IMPL( BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
271 F, test_name, dataset, \
272 BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) \
273 /**/
274 #define BOOST_DATA_TEST_CASE_NO_PARAMS( F, test_name, dataset ) \
275 BOOST_DATA_TEST_CASE_WITH_PARAMS( F, test_name, dataset, sample ) \
276 /**/
277
278 #if BOOST_PP_VARIADICS_MSVC
279
280 #define BOOST_DATA_TEST_CASE( ... ) \
281 BOOST_PP_CAT( \
282 BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
283 BOOST_DATA_TEST_CASE_NO_PARAMS, \
284 BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
285 BOOST_AUTO_TEST_CASE_FIXTURE, __VA_ARGS__), ) \
286 /**/
287
288 #define BOOST_DATA_TEST_CASE_F( F, ... ) \
289 BOOST_PP_CAT( \
290 BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
291 BOOST_DATA_TEST_CASE_NO_PARAMS, \
292 BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
293 F, __VA_ARGS__), ) \
294 /**/
295
296 #else
297
298 #define BOOST_DATA_TEST_CASE( ... ) \
299 BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
300 BOOST_DATA_TEST_CASE_NO_PARAMS, \
301 BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
302 BOOST_AUTO_TEST_CASE_FIXTURE, __VA_ARGS__) \
303 /**/
304
305 #define BOOST_DATA_TEST_CASE_F( F, ... ) \
306 BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
307 BOOST_DATA_TEST_CASE_NO_PARAMS, \
308 BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
309 F, __VA_ARGS__) \
310 /**/
311 #endif
312
313 } // namespace data
314 } // namespace unit_test
315 } // namespace boost
316
317 #include <boost/test/detail/enable_warnings.hpp>
318
319 #endif // BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
320