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