1 // (C) Copyright Gennadiy Rozental 2012-2014.
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 /// Forward declares monomorphic datasets interfaces
10 // ***************************************************************************
11
12 #ifndef BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER
13 #define BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER
14
15 // Boost.Test
16 #include <boost/test/data/config.hpp>
17 #include <boost/test/data/size.hpp>
18
19 #include <boost/test/utils/is_forward_iterable.hpp>
20
21
22 // Boost
23 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
24 #include <boost/utility/enable_if.hpp>
25 #include <boost/type_traits/add_const.hpp>
26 #else
27 #include <boost/utility/declval.hpp>
28 #endif
29 #include <boost/type_traits/remove_const.hpp>
30 #include <boost/mpl/bool.hpp>
31 #include <boost/smart_ptr/make_shared.hpp>
32 #include <boost/shared_ptr.hpp>
33 #include <boost/type_traits/decay.hpp>
34
35 #include <boost/test/detail/suppress_warnings.hpp>
36
37 //____________________________________________________________________________//
38
39 namespace boost {
40 namespace unit_test {
41 namespace data {
42
43 namespace monomorphic {
44
45
46 #if !defined(BOOST_TEST_DOXYGEN_DOC__)
47 template<typename T>
48 struct traits;
49
50 template<typename T>
51 class dataset;
52
53 template<typename T>
54 class singleton;
55
56 template<typename C>
57 class collection;
58
59 template<typename T>
60 class array;
61 #endif
62
63 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
64 # define BOOST_TEST_ENABLE_IF std::enable_if
65 #else
66 # define BOOST_TEST_ENABLE_IF boost::enable_if_c
67 #endif
68
69 // ************************************************************************** //
70 // ************** monomorphic::is_dataset ************** //
71 // ************************************************************************** //
72
73 //! Helper metafunction indicating if the specified type is a dataset.
74 template<typename DataSet>
75 struct is_dataset : mpl::false_ {};
76
77 //! A reference to a dataset is a dataset
78 template<typename DataSet>
79 struct is_dataset<DataSet&> : is_dataset<DataSet> {};
80
81 //! A const dataset is a dataset
82 template<typename DataSet>
83 struct is_dataset<DataSet const> : is_dataset<DataSet> {};
84
85 //____________________________________________________________________________//
86
87 } // namespace monomorphic
88
89 // ************************************************************************** //
90 // ************** data::make ************** //
91 // ************************************************************************** //
92
93 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
94
95
96 //! @brief Creates a dataset from a value, a collection or an array
97 //!
98 //! This function has several overloads:
99 //! @code
100 //! // returns ds if ds is already a dataset
101 //! template <typename DataSet> DataSet make(DataSet&& ds);
102 //!
103 //! // creates a singleton dataset, for non forward iterable and non dataset type T
104 //! // (a C string is not considered as a sequence).
105 //! template <typename T> monomorphic::singleton<T> make(T&& v);
106 //! monomorphic::singleton<char*> make( char* str );
107 //! monomorphic::singleton<char const*> make( char const* str );
108 //!
109 //! // creates a collection dataset, for forward iterable and non dataset type C
110 //! template <typename C> monomorphic::collection<C> make(C && c);
111 //!
112 //! // creates an array dataset
113 //! template<typename T, std::size_t size> monomorphic::array<T> make( T (&a)[size] );
114 //! @endcode
115 template<typename DataSet>
116 inline typename BOOST_TEST_ENABLE_IF<monomorphic::is_dataset<DataSet>::value,DataSet>::type
make(DataSet && ds)117 make(DataSet&& ds)
118 {
119 return std::forward<DataSet>( ds );
120 }
121
122
123 // warning: doxygen is apparently unable to handle @overload from different files, so if the overloads
124 // below are not declared with @overload in THIS file, they do not appear in the documentation.
125
126 // fwrd declaration for singletons
127 //! @overload boost::unit_test::data::make()
128 template<typename T>
129 inline typename BOOST_TEST_ENABLE_IF<!is_forward_iterable<T>::value &&
130 !monomorphic::is_dataset<T>::value &&
131 !boost::is_array< typename boost::remove_reference<T>::type >::value,
132 monomorphic::singleton<T> >::type
133 make( T&& v );
134
135
136 //! @overload boost::unit_test::data::make()
137 template<typename C>
138 inline typename BOOST_TEST_ENABLE_IF<is_forward_iterable<C>::value,
139 monomorphic::collection<C> >::type
140 make( C&& c );
141
142
143 #else // !BOOST_NO_CXX11_RVALUE_REFERENCES
144
145 //! @overload boost::unit_test:data::make()
146 template<typename DataSet>
147 inline typename BOOST_TEST_ENABLE_IF<monomorphic::is_dataset<DataSet>::value,DataSet const&>::type
make(DataSet const & ds)148 make(DataSet const& ds)
149 {
150 return ds;
151 }
152
153
154 // fwrd declaration for singletons
155 #if !(defined(BOOST_MSVC) && (BOOST_MSVC < 1600))
156 //! @overload boost::unit_test::data::make()
157 template<typename T>
158 inline typename BOOST_TEST_ENABLE_IF<!is_forward_iterable<T>::value &&
159 !monomorphic::is_dataset<T>::value &&
160 !boost::is_array< typename boost::remove_reference<T>::type >::value,
161 monomorphic::singleton<T> >::type
162 make( T const& v );
163 #endif
164
165
166 // fwrd declaration for collections
167 //! @overload boost::unit_test::data::make()
168 template<typename C>
169 inline typename BOOST_TEST_ENABLE_IF<is_forward_iterable<C>::value,
170 monomorphic::collection<C> >::type
171 make( C const& c );
172
173 //____________________________________________________________________________//
174
175
176
177 #endif // !BOOST_NO_CXX11_RVALUE_REFERENCES
178
179
180
181
182 // fwrd declarations
183 //! @overload boost::unit_test::data::make()
184 template<typename T, std::size_t size>
185 inline monomorphic::array< typename boost::remove_const<T>::type >
186 make( T (&a)[size] );
187
188 // apparently some compilers (eg clang-3.4 on linux) have trouble understanding
189 // the previous line for T being const
190 //! @overload boost::unit_test::data::make()
191 template<typename T, std::size_t size>
192 inline monomorphic::array< typename boost::remove_const<T>::type >
193 make( T const (&)[size] );
194
195 template<typename T, std::size_t size>
196 inline monomorphic::array< typename boost::remove_const<T>::type >
197 make( T a[size] );
198
199
200
201 //! @overload boost::unit_test::data::make()
202 inline monomorphic::singleton<char*>
203 make( char* str );
204
205 //! @overload boost::unit_test::data::make()
206 inline monomorphic::singleton<char const*>
207 make( char const* str );
208
209
210
211 //____________________________________________________________________________//
212
213
214
215 namespace result_of {
216
217 #ifndef BOOST_NO_CXX11_DECLTYPE
218 //! Result of the make call.
219 template<typename DataSet>
220 struct make
221 {
222 typedef decltype(data::make(boost::declval<DataSet>())) type;
223 };
224 #else
225
226 // explicit specialisation, cumbersome
227
228 template <typename DataSet, typename Enable = void>
229 struct make;
230
231 template <typename DataSet>
232 struct make<
233 DataSet const&,
234 typename BOOST_TEST_ENABLE_IF<monomorphic::is_dataset<DataSet>::value>::type
235 >
236 {
237 typedef DataSet const& type;
238 };
239
240 template <typename T>
241 struct make<
242 T,
243 typename BOOST_TEST_ENABLE_IF< (!is_forward_iterable<T>::value &&
244 !monomorphic::is_dataset<T>::value &&
245 !boost::is_array< typename boost::remove_reference<T>::type >::value)
246 >::type
247 >
248 {
249 typedef monomorphic::singleton<T> type;
250 };
251
252 template <typename C>
253 struct make<
254 C,
255 typename BOOST_TEST_ENABLE_IF< is_forward_iterable<C>::value>::type
256 >
257 {
258 typedef monomorphic::collection<C> type;
259 };
260
261 #if 1
262 template <typename T, std::size_t size>
263 struct make<T [size]>
264 {
265 typedef monomorphic::array<typename boost::remove_const<T>::type> type;
266 };
267 #endif
268
269 template <typename T, std::size_t size>
270 struct make<T (&)[size]>
271 {
272 typedef monomorphic::array<typename boost::remove_const<T>::type> type;
273 };
274
275 template <typename T, std::size_t size>
276 struct make<T const (&)[size]>
277 {
278 typedef monomorphic::array<typename boost::remove_const<T>::type> type;
279 };
280
281 template <>
282 struct make<char*>
283 {
284 typedef monomorphic::singleton<char*> type;
285 };
286
287 template <>
288 struct make<char const*>
289 {
290 typedef monomorphic::singleton<char const*> type;
291 };
292
293 #endif // BOOST_NO_CXX11_DECLTYPE
294
295
296 } // namespace result_of
297
298
299
300
301 //____________________________________________________________________________//
302
303 } // namespace data
304 } // namespace unit_test
305 } // namespace boost
306
307
308
309
310
311 #include <boost/test/detail/enable_warnings.hpp>
312
313 #endif // BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER
314
315