|
1 |
|
2 #ifndef BOOST_MPL_ASSERT_HPP_INCLUDED |
|
3 #define BOOST_MPL_ASSERT_HPP_INCLUDED |
|
4 |
|
5 // Copyright Aleksey Gurtovoy 2000-2006 |
|
6 // |
|
7 // Distributed under the Boost Software License, Version 1.0. |
|
8 // (See accompanying file LICENSE_1_0.txt or copy at |
|
9 // http://www.boost.org/LICENSE_1_0.txt) |
|
10 // |
|
11 // See http://www.boost.org/libs/mpl for documentation. |
|
12 |
|
13 // $Source: /cvsroot/boost/boost/boost/mpl/assert.hpp,v $ |
|
14 // $Date: 2006/11/10 21:31:19 $ |
|
15 // $Revision: 1.13.14.6 $ |
|
16 |
|
17 #include <boost/mpl/not.hpp> |
|
18 #include <boost/mpl/aux_/value_wknd.hpp> |
|
19 #include <boost/mpl/aux_/nested_type_wknd.hpp> |
|
20 #include <boost/mpl/aux_/yes_no.hpp> |
|
21 #include <boost/mpl/aux_/na.hpp> |
|
22 #include <boost/mpl/aux_/adl_barrier.hpp> |
|
23 |
|
24 #include <boost/mpl/aux_/config/nttp.hpp> |
|
25 #include <boost/mpl/aux_/config/dtp.hpp> |
|
26 #include <boost/mpl/aux_/config/gcc.hpp> |
|
27 #include <boost/mpl/aux_/config/msvc.hpp> |
|
28 #include <boost/mpl/aux_/config/static_constant.hpp> |
|
29 #include <boost/mpl/aux_/config/workaround.hpp> |
|
30 |
|
31 #include <boost/preprocessor/cat.hpp> |
|
32 |
|
33 #include <boost/config.hpp> // make sure 'size_t' is placed into 'std' |
|
34 #include <cstddef> |
|
35 |
|
36 |
|
37 #if BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, < 0x600) \ |
|
38 || (BOOST_MPL_CFG_GCC != 0) \ |
|
39 || BOOST_WORKAROUND(__IBMCPP__, <= 600) |
|
40 # define BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES |
|
41 #endif |
|
42 |
|
43 #if BOOST_WORKAROUND(__MWERKS__, < 0x3202) \ |
|
44 || BOOST_WORKAROUND(__EDG_VERSION__, <= 238) \ |
|
45 || BOOST_WORKAROUND(__BORLANDC__, < 0x600) \ |
|
46 || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) |
|
47 # define BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER |
|
48 #endif |
|
49 |
|
50 // agurt, 10/nov/06: use enums for Borland (which cannot cope with static constants) |
|
51 // and GCC (which issues "unused variable" warnings when static constants are used |
|
52 // at a function scope) |
|
53 #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) \ |
|
54 || (BOOST_MPL_CFG_GCC != 0) |
|
55 # define BOOST_MPL_AUX_ASSERT_CONSTANT(T, expr) enum { expr } |
|
56 #else |
|
57 # define BOOST_MPL_AUX_ASSERT_CONSTANT(T, expr) BOOST_STATIC_CONSTANT(T, expr) |
|
58 #endif |
|
59 |
|
60 |
|
61 BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN |
|
62 |
|
63 struct failed {}; |
|
64 |
|
65 // agurt, 24/aug/04: MSVC 7.1 workaround here and below: return/accept |
|
66 // 'assert<false>' by reference; can't apply it unconditionally -- apparently it |
|
67 // degrades the quality of GCC diagnostics |
|
68 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) |
|
69 # define AUX778076_ASSERT_ARG(x) x& |
|
70 #else |
|
71 # define AUX778076_ASSERT_ARG(x) x |
|
72 #endif |
|
73 |
|
74 template< bool C > struct assert { typedef void* type; }; |
|
75 template<> struct assert<false> { typedef AUX778076_ASSERT_ARG(assert) type; }; |
|
76 |
|
77 template< bool C > |
|
78 int assertion_failed( typename assert<C>::type ); |
|
79 |
|
80 template< bool C > |
|
81 struct assertion |
|
82 { |
|
83 static int failed( assert<false> ); |
|
84 }; |
|
85 |
|
86 template<> |
|
87 struct assertion<true> |
|
88 { |
|
89 static int failed( void* ); |
|
90 }; |
|
91 |
|
92 struct assert_ |
|
93 { |
|
94 #if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) |
|
95 template< typename T1, typename T2 = na, typename T3 = na, typename T4 = na > struct types {}; |
|
96 #endif |
|
97 static assert_ const arg; |
|
98 enum relations { equal = 1, not_equal, greater, greater_equal, less, less_equal }; |
|
99 }; |
|
100 |
|
101 |
|
102 #if !defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES) |
|
103 |
|
104 bool operator==( failed, failed ); |
|
105 bool operator!=( failed, failed ); |
|
106 bool operator>( failed, failed ); |
|
107 bool operator>=( failed, failed ); |
|
108 bool operator<( failed, failed ); |
|
109 bool operator<=( failed, failed ); |
|
110 |
|
111 #if defined(__EDG_VERSION__) |
|
112 template< bool (*)(failed, failed), long x, long y > struct assert_relation {}; |
|
113 # define BOOST_MPL_AUX_ASSERT_RELATION(x, y, r) assert_relation<r,x,y> |
|
114 #else |
|
115 template< BOOST_MPL_AUX_NTTP_DECL(long, x), BOOST_MPL_AUX_NTTP_DECL(long, y), bool (*)(failed, failed) > |
|
116 struct assert_relation {}; |
|
117 # define BOOST_MPL_AUX_ASSERT_RELATION(x, y, r) assert_relation<x,y,r> |
|
118 #endif |
|
119 |
|
120 #else // BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES |
|
121 |
|
122 boost::mpl::aux::weighted_tag<1>::type operator==( assert_, assert_ ); |
|
123 boost::mpl::aux::weighted_tag<2>::type operator!=( assert_, assert_ ); |
|
124 boost::mpl::aux::weighted_tag<3>::type operator>( assert_, assert_ ); |
|
125 boost::mpl::aux::weighted_tag<4>::type operator>=( assert_, assert_ ); |
|
126 boost::mpl::aux::weighted_tag<5>::type operator<( assert_, assert_ ); |
|
127 boost::mpl::aux::weighted_tag<6>::type operator<=( assert_, assert_ ); |
|
128 |
|
129 template< assert_::relations r, long x, long y > struct assert_relation {}; |
|
130 |
|
131 #endif |
|
132 |
|
133 |
|
134 #if !defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER) |
|
135 |
|
136 template< bool > struct assert_arg_pred_impl { typedef int type; }; |
|
137 template<> struct assert_arg_pred_impl<true> { typedef void* type; }; |
|
138 |
|
139 template< typename P > struct assert_arg_pred |
|
140 { |
|
141 typedef typename P::type p_type; |
|
142 typedef typename assert_arg_pred_impl< p_type::value >::type type; |
|
143 }; |
|
144 |
|
145 template< typename P > struct assert_arg_pred_not |
|
146 { |
|
147 typedef typename P::type p_type; |
|
148 BOOST_MPL_AUX_ASSERT_CONSTANT( bool, p = !p_type::value ); |
|
149 typedef typename assert_arg_pred_impl<p>::type type; |
|
150 }; |
|
151 |
|
152 template< typename Pred > |
|
153 failed ************ (Pred::************ |
|
154 assert_arg( void (*)(Pred), typename assert_arg_pred<Pred>::type ) |
|
155 ); |
|
156 |
|
157 template< typename Pred > |
|
158 failed ************ (boost::mpl::not_<Pred>::************ |
|
159 assert_not_arg( void (*)(Pred), typename assert_arg_pred_not<Pred>::type ) |
|
160 ); |
|
161 |
|
162 template< typename Pred > |
|
163 AUX778076_ASSERT_ARG(assert<false>) |
|
164 assert_arg( void (*)(Pred), typename assert_arg_pred_not<Pred>::type ); |
|
165 |
|
166 template< typename Pred > |
|
167 AUX778076_ASSERT_ARG(assert<false>) |
|
168 assert_not_arg( void (*)(Pred), typename assert_arg_pred<Pred>::type ); |
|
169 |
|
170 |
|
171 #else // BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER |
|
172 |
|
173 template< bool c, typename Pred > struct assert_arg_type_impl |
|
174 { |
|
175 typedef failed ************ Pred::* mwcw83_wknd; |
|
176 typedef mwcw83_wknd ************* type; |
|
177 }; |
|
178 |
|
179 template< typename Pred > struct assert_arg_type_impl<true,Pred> |
|
180 { |
|
181 typedef AUX778076_ASSERT_ARG(assert<false>) type; |
|
182 }; |
|
183 |
|
184 template< typename Pred > struct assert_arg_type |
|
185 : assert_arg_type_impl< BOOST_MPL_AUX_VALUE_WKND(BOOST_MPL_AUX_NESTED_TYPE_WKND(Pred))::value, Pred > |
|
186 { |
|
187 }; |
|
188 |
|
189 template< typename Pred > |
|
190 typename assert_arg_type<Pred>::type |
|
191 assert_arg(void (*)(Pred), int); |
|
192 |
|
193 template< typename Pred > |
|
194 typename assert_arg_type< boost::mpl::not_<Pred> >::type |
|
195 assert_not_arg(void (*)(Pred), int); |
|
196 |
|
197 # if !defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES) |
|
198 template< long x, long y, bool (*r)(failed, failed) > |
|
199 typename assert_arg_type_impl< false,BOOST_MPL_AUX_ASSERT_RELATION(x,y,r) >::type |
|
200 assert_rel_arg( BOOST_MPL_AUX_ASSERT_RELATION(x,y,r) ); |
|
201 # else |
|
202 template< assert_::relations r, long x, long y > |
|
203 typename assert_arg_type_impl< false,assert_relation<r,x,y> >::type |
|
204 assert_rel_arg( assert_relation<r,x,y> ); |
|
205 # endif |
|
206 |
|
207 #endif // BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER |
|
208 |
|
209 #undef AUX778076_ASSERT_ARG |
|
210 |
|
211 BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE |
|
212 |
|
213 |
|
214 // BOOST_MPL_ASSERT((pred<x,...>)) |
|
215 |
|
216 #define BOOST_MPL_ASSERT(pred) \ |
|
217 BOOST_MPL_AUX_ASSERT_CONSTANT( \ |
|
218 std::size_t \ |
|
219 , BOOST_PP_CAT(mpl_assertion_in_line_,__LINE__) = sizeof( \ |
|
220 boost::mpl::assertion_failed<false>( \ |
|
221 boost::mpl::assert_arg( (void (*) pred)0, 1 ) \ |
|
222 ) \ |
|
223 ) \ |
|
224 ) \ |
|
225 /**/ |
|
226 |
|
227 // BOOST_MPL_ASSERT_NOT((pred<x,...>)) |
|
228 |
|
229 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) |
|
230 # define BOOST_MPL_ASSERT_NOT(pred) \ |
|
231 enum { \ |
|
232 BOOST_PP_CAT(mpl_assertion_in_line_,__LINE__) = sizeof( \ |
|
233 boost::mpl::assertion<false>::failed( \ |
|
234 boost::mpl::assert_not_arg( (void (*) pred)0, 1 ) \ |
|
235 ) \ |
|
236 ) \ |
|
237 }\ |
|
238 /**/ |
|
239 #else |
|
240 # define BOOST_MPL_ASSERT_NOT(pred) \ |
|
241 BOOST_MPL_AUX_ASSERT_CONSTANT( \ |
|
242 std::size_t \ |
|
243 , BOOST_PP_CAT(mpl_assertion_in_line_,__LINE__) = sizeof( \ |
|
244 boost::mpl::assertion_failed<false>( \ |
|
245 boost::mpl::assert_not_arg( (void (*) pred)0, 1 ) \ |
|
246 ) \ |
|
247 ) \ |
|
248 ) \ |
|
249 /**/ |
|
250 #endif |
|
251 |
|
252 // BOOST_MPL_ASSERT_RELATION(x, ==|!=|<=|<|>=|>, y) |
|
253 |
|
254 #if defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES) |
|
255 |
|
256 # if !defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER) |
|
257 // agurt, 9/nov/06: 'enum' below is a workaround for gcc 4.0.4/4.1.1 bugs #29522 and #29518 |
|
258 # define BOOST_MPL_ASSERT_RELATION(x, rel, y) \ |
|
259 enum { BOOST_PP_CAT(mpl_assert_rel_value,__LINE__) = (x rel y) }; \ |
|
260 BOOST_MPL_AUX_ASSERT_CONSTANT( \ |
|
261 std::size_t \ |
|
262 , BOOST_PP_CAT(mpl_assertion_in_line_,__LINE__) = sizeof( \ |
|
263 boost::mpl::assertion_failed<BOOST_PP_CAT(mpl_assert_rel_value,__LINE__)>( \ |
|
264 (boost::mpl::failed ************ ( boost::mpl::assert_relation< \ |
|
265 boost::mpl::assert_::relations( sizeof( \ |
|
266 boost::mpl::assert_::arg rel boost::mpl::assert_::arg \ |
|
267 ) ) \ |
|
268 , x \ |
|
269 , y \ |
|
270 >::************)) 0 ) \ |
|
271 ) \ |
|
272 ) \ |
|
273 /**/ |
|
274 # else |
|
275 # define BOOST_MPL_ASSERT_RELATION(x, rel, y) \ |
|
276 BOOST_MPL_AUX_ASSERT_CONSTANT( \ |
|
277 std::size_t \ |
|
278 , BOOST_PP_CAT(mpl_assert_rel,__LINE__) = sizeof( \ |
|
279 boost::mpl::assert_::arg rel boost::mpl::assert_::arg \ |
|
280 ) \ |
|
281 ); \ |
|
282 BOOST_MPL_AUX_ASSERT_CONSTANT( bool, BOOST_PP_CAT(mpl_assert_rel_value,__LINE__) = (x rel y) ); \ |
|
283 BOOST_MPL_AUX_ASSERT_CONSTANT( \ |
|
284 std::size_t \ |
|
285 , BOOST_PP_CAT(mpl_assertion_in_line_,__LINE__) = sizeof( \ |
|
286 boost::mpl::assertion_failed<BOOST_PP_CAT(mpl_assert_rel_value,__LINE__)>( \ |
|
287 boost::mpl::assert_rel_arg( boost::mpl::assert_relation< \ |
|
288 boost::mpl::assert_::relations(BOOST_PP_CAT(mpl_assert_rel,__LINE__)) \ |
|
289 , x \ |
|
290 , y \ |
|
291 >() ) \ |
|
292 ) \ |
|
293 ) \ |
|
294 ) \ |
|
295 /**/ |
|
296 # endif |
|
297 |
|
298 #else // !BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES |
|
299 |
|
300 # if defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER) |
|
301 # define BOOST_MPL_ASSERT_RELATION(x, rel, y) \ |
|
302 BOOST_MPL_AUX_ASSERT_CONSTANT( \ |
|
303 std::size_t \ |
|
304 , BOOST_PP_CAT(mpl_assertion_in_line_,__LINE__) = sizeof( \ |
|
305 boost::mpl::assertion_failed<(x rel y)>( boost::mpl::assert_rel_arg( \ |
|
306 boost::mpl::BOOST_MPL_AUX_ASSERT_RELATION(x,y,(&boost::mpl::operator rel))() \ |
|
307 ) ) \ |
|
308 ) \ |
|
309 ) \ |
|
310 /**/ |
|
311 # else |
|
312 # define BOOST_MPL_ASSERT_RELATION(x, rel, y) \ |
|
313 BOOST_MPL_AUX_ASSERT_CONSTANT( \ |
|
314 std::size_t \ |
|
315 , BOOST_PP_CAT(mpl_assertion_in_line_,__LINE__) = sizeof( \ |
|
316 boost::mpl::assertion_failed<(x rel y)>( (boost::mpl::failed ************ ( \ |
|
317 boost::mpl::BOOST_MPL_AUX_ASSERT_RELATION(x,y,(&boost::mpl::operator rel))::************))0 ) \ |
|
318 ) \ |
|
319 ) \ |
|
320 /**/ |
|
321 # endif |
|
322 |
|
323 #endif |
|
324 |
|
325 |
|
326 // BOOST_MPL_ASSERT_MSG( (pred<x,...>::value), USER_PROVIDED_MESSAGE, (types<x,...>) ) |
|
327 |
|
328 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) |
|
329 # define BOOST_MPL_ASSERT_MSG( c, msg, types_ ) \ |
|
330 struct msg; \ |
|
331 typedef struct BOOST_PP_CAT(msg,__LINE__) : boost::mpl::assert_ \ |
|
332 { \ |
|
333 using boost::mpl::assert_::types; \ |
|
334 static boost::mpl::failed ************ (msg::************ assert_arg()) types_ \ |
|
335 { return 0; } \ |
|
336 } BOOST_PP_CAT(mpl_assert_arg,__LINE__); \ |
|
337 BOOST_MPL_AUX_ASSERT_CONSTANT( \ |
|
338 std::size_t \ |
|
339 , BOOST_PP_CAT(mpl_assertion_in_line_,__LINE__) = sizeof( \ |
|
340 boost::mpl::assertion<(c)>::failed( BOOST_PP_CAT(mpl_assert_arg,__LINE__)::assert_arg() ) \ |
|
341 ) \ |
|
342 ) \ |
|
343 /**/ |
|
344 #else |
|
345 # define BOOST_MPL_ASSERT_MSG( c, msg, types_ ) \ |
|
346 struct msg; \ |
|
347 typedef struct BOOST_PP_CAT(msg,__LINE__) : boost::mpl::assert_ \ |
|
348 { \ |
|
349 static boost::mpl::failed ************ (msg::************ assert_arg()) types_ \ |
|
350 { return 0; } \ |
|
351 } BOOST_PP_CAT(mpl_assert_arg,__LINE__); \ |
|
352 BOOST_MPL_AUX_ASSERT_CONSTANT( \ |
|
353 std::size_t \ |
|
354 , BOOST_PP_CAT(mpl_assertion_in_line_,__LINE__) = sizeof( \ |
|
355 boost::mpl::assertion_failed<(c)>( BOOST_PP_CAT(mpl_assert_arg,__LINE__)::assert_arg() ) \ |
|
356 ) \ |
|
357 ) \ |
|
358 /**/ |
|
359 #endif |
|
360 |
|
361 #endif // BOOST_MPL_ASSERT_HPP_INCLUDED |