]> git.donarmstrong.com Git - rsem.git/blob - boost/mpl/assert.hpp
Updated boost to v1.55.0
[rsem.git] / boost / mpl / assert.hpp
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 // $Id: assert.hpp 86514 2013-10-29 13:15:03Z bemandawes $
14 // $Date: 2013-10-29 06:15:03 -0700 (Tue, 29 Oct 2013) $
15 // $Revision: 86514 $
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/pp_counter.hpp>
30 #include <boost/mpl/aux_/config/workaround.hpp>
31
32 #include <boost/preprocessor/cat.hpp>
33
34 #include <boost/config.hpp> // make sure 'size_t' is placed into 'std'
35 #include <cstddef>
36
37 #if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
38 #include <boost/mpl/if.hpp>
39 #endif
40
41 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
42     || (BOOST_MPL_CFG_GCC != 0) \
43     || BOOST_WORKAROUND(__IBMCPP__, <= 600)
44 #   define BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES
45 #endif
46
47 #if BOOST_WORKAROUND(__MWERKS__, < 0x3202) \
48     || BOOST_WORKAROUND(__EDG_VERSION__, <= 238) \
49     || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
50     || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
51 #   define BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER
52 #endif
53
54 // agurt, 10/nov/06: use enums for Borland (which cannot cope with static constants) 
55 // and GCC (which issues "unused variable" warnings when static constants are used 
56 // at a function scope)
57 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
58     || (BOOST_MPL_CFG_GCC != 0)
59 #   define BOOST_MPL_AUX_ASSERT_CONSTANT(T, expr) enum { expr }
60 #else
61 #   define BOOST_MPL_AUX_ASSERT_CONSTANT(T, expr) BOOST_STATIC_CONSTANT(T, expr)
62 #endif
63
64
65 BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
66
67 struct failed {};
68
69 // agurt, 24/aug/04: MSVC 7.1 workaround here and below: return/accept 
70 // 'assert<false>' by reference; can't apply it unconditionally -- apparently it
71 // degrades the quality of GCC diagnostics
72 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
73 #   define AUX778076_ASSERT_ARG(x) x&
74 #else
75 #   define AUX778076_ASSERT_ARG(x) x
76 #endif
77
78 template< bool C >  struct assert        { typedef void* type; };
79 template<>          struct assert<false> { typedef AUX778076_ASSERT_ARG(assert) type; };
80
81 template< bool C >
82 int assertion_failed( typename assert<C>::type );
83
84 template< bool C >
85 struct assertion
86 {
87     static int failed( assert<false> );
88 };
89
90 template<>
91 struct assertion<true>
92 {
93     static int failed( void* );
94 };
95
96 struct assert_
97 {
98 #if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
99     template< typename T1, typename T2 = na, typename T3 = na, typename T4 = na > struct types {};
100 #endif
101     static assert_ const arg;
102     enum relations { equal = 1, not_equal, greater, greater_equal, less, less_equal };
103 };
104
105
106 #if !defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES)
107
108 bool operator==( failed, failed );
109 bool operator!=( failed, failed );
110 bool operator>( failed, failed );
111 bool operator>=( failed, failed );
112 bool operator<( failed, failed );
113 bool operator<=( failed, failed );
114
115 #if defined(__EDG_VERSION__)
116 template< bool (*)(failed, failed), long x, long y > struct assert_relation {};
117 #   define BOOST_MPL_AUX_ASSERT_RELATION(x, y, r) assert_relation<r,x,y>
118 #else
119 template< BOOST_MPL_AUX_NTTP_DECL(long, x), BOOST_MPL_AUX_NTTP_DECL(long, y), bool (*)(failed, failed) > 
120 struct assert_relation {};
121 #   define BOOST_MPL_AUX_ASSERT_RELATION(x, y, r) assert_relation<x,y,r>
122 #endif
123
124 #else // BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES
125
126 boost::mpl::aux::weighted_tag<1>::type operator==( assert_, assert_ );
127 boost::mpl::aux::weighted_tag<2>::type operator!=( assert_, assert_ );
128 boost::mpl::aux::weighted_tag<3>::type operator>(  assert_, assert_ );
129 boost::mpl::aux::weighted_tag<4>::type operator>=( assert_, assert_ );
130 boost::mpl::aux::weighted_tag<5>::type operator<( assert_, assert_ );
131 boost::mpl::aux::weighted_tag<6>::type operator<=( assert_, assert_ );
132
133 template< assert_::relations r, long x, long y > struct assert_relation {};
134
135 #endif 
136
137 #if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
138
139 template<class Pred>
140 struct extract_assert_pred;
141
142 template<class Pred>
143 struct extract_assert_pred<void(Pred)> { typedef Pred type; };
144
145 template<class Pred>
146 struct eval_assert {
147     typedef typename extract_assert_pred<Pred>::type P;
148     typedef typename P::type p_type;
149     typedef typename ::boost::mpl::if_c<p_type::value,
150         AUX778076_ASSERT_ARG(assert<false>),
151         failed ************ P::************
152     >::type type;
153 };
154
155 template<class Pred>
156 struct eval_assert_not {
157     typedef typename extract_assert_pred<Pred>::type P;
158     typedef typename P::type p_type;
159     typedef typename ::boost::mpl::if_c<!p_type::value,
160         AUX778076_ASSERT_ARG(assert<false>),
161         failed ************ ::boost::mpl::not_<P>::************
162     >::type type;
163 };
164
165 template< typename T >
166 T make_assert_arg();
167
168 #elif !defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER)
169
170 template< bool > struct assert_arg_pred_impl { typedef int type; };
171 template<> struct assert_arg_pred_impl<true> { typedef void* type; };
172
173 template< typename P > struct assert_arg_pred
174 {
175     typedef typename P::type p_type;
176     typedef typename assert_arg_pred_impl< p_type::value >::type type;
177 };
178
179 template< typename P > struct assert_arg_pred_not
180 {
181     typedef typename P::type p_type;
182     BOOST_MPL_AUX_ASSERT_CONSTANT( bool, p = !p_type::value );
183     typedef typename assert_arg_pred_impl<p>::type type;
184 };
185
186 template< typename Pred >
187 failed ************ (Pred::************ 
188       assert_arg( void (*)(Pred), typename assert_arg_pred<Pred>::type )
189     );
190
191 template< typename Pred >
192 failed ************ (boost::mpl::not_<Pred>::************ 
193       assert_not_arg( void (*)(Pred), typename assert_arg_pred_not<Pred>::type )
194     );
195
196 template< typename Pred >
197 AUX778076_ASSERT_ARG(assert<false>)
198 assert_arg( void (*)(Pred), typename assert_arg_pred_not<Pred>::type );
199
200 template< typename Pred >
201 AUX778076_ASSERT_ARG(assert<false>)
202 assert_not_arg( void (*)(Pred), typename assert_arg_pred<Pred>::type );
203
204
205 #else // BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER
206         
207 template< bool c, typename Pred > struct assert_arg_type_impl
208 {
209     typedef failed      ************ Pred::* mwcw83_wknd;
210     typedef mwcw83_wknd ************* type;
211 };
212
213 template< typename Pred > struct assert_arg_type_impl<true,Pred>
214 {
215     typedef AUX778076_ASSERT_ARG(assert<false>) type;
216 };
217
218 template< typename Pred > struct assert_arg_type
219     : assert_arg_type_impl< BOOST_MPL_AUX_VALUE_WKND(BOOST_MPL_AUX_NESTED_TYPE_WKND(Pred))::value, Pred >
220 {
221 };
222
223 template< typename Pred >
224 typename assert_arg_type<Pred>::type 
225 assert_arg(void (*)(Pred), int);
226
227 template< typename Pred >
228 typename assert_arg_type< boost::mpl::not_<Pred> >::type 
229 assert_not_arg(void (*)(Pred), int);
230
231 #   if !defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES)
232 template< long x, long y, bool (*r)(failed, failed) >
233 typename assert_arg_type_impl< false,BOOST_MPL_AUX_ASSERT_RELATION(x,y,r) >::type
234 assert_rel_arg( BOOST_MPL_AUX_ASSERT_RELATION(x,y,r) );
235 #   else
236 template< assert_::relations r, long x, long y >
237 typename assert_arg_type_impl< false,assert_relation<r,x,y> >::type
238 assert_rel_arg( assert_relation<r,x,y> );
239 #   endif
240
241 #endif // BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER
242
243 #undef AUX778076_ASSERT_ARG
244
245 BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
246
247 #if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
248
249 // BOOST_MPL_ASSERT((pred<x,...>))
250
251 #define BOOST_MPL_ASSERT(pred) \
252 BOOST_MPL_AUX_ASSERT_CONSTANT( \
253       std::size_t \
254     , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
255           boost::mpl::assertion_failed<false>( \
256               boost::mpl::make_assert_arg< \
257                   typename boost::mpl::eval_assert<void pred>::type \
258                 >() \
259             ) \
260         ) \
261     ) \
262 /**/
263
264 // BOOST_MPL_ASSERT_NOT((pred<x,...>))
265
266 #define BOOST_MPL_ASSERT_NOT(pred) \
267 BOOST_MPL_AUX_ASSERT_CONSTANT( \
268       std::size_t \
269     , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
270           boost::mpl::assertion_failed<false>( \
271               boost::mpl::make_assert_arg< \
272                   typename boost::mpl::eval_assert_not<void pred>::type \
273                 >() \
274             ) \
275         ) \
276     ) \
277 /**/
278
279 #else
280
281 // BOOST_MPL_ASSERT((pred<x,...>))
282
283 #define BOOST_MPL_ASSERT(pred) \
284 BOOST_MPL_AUX_ASSERT_CONSTANT( \
285       std::size_t \
286     , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
287           boost::mpl::assertion_failed<false>( \
288               boost::mpl::assert_arg( (void (*) pred)0, 1 ) \
289             ) \
290         ) \
291     ) \
292 /**/
293
294 // BOOST_MPL_ASSERT_NOT((pred<x,...>))
295
296 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
297 #   define BOOST_MPL_ASSERT_NOT(pred) \
298 enum { \
299       BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
300           boost::mpl::assertion<false>::failed( \
301               boost::mpl::assert_not_arg( (void (*) pred)0, 1 ) \
302             ) \
303         ) \
304 }\
305 /**/
306 #else
307 #   define BOOST_MPL_ASSERT_NOT(pred) \
308 BOOST_MPL_AUX_ASSERT_CONSTANT( \
309       std::size_t \
310     , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
311           boost::mpl::assertion_failed<false>( \
312               boost::mpl::assert_not_arg( (void (*) pred)0, 1 ) \
313             ) \
314         ) \
315    ) \
316 /**/
317 #endif
318
319 #endif
320
321 // BOOST_MPL_ASSERT_RELATION(x, ==|!=|<=|<|>=|>, y)
322
323 #if defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES)
324
325 #   if !defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER)
326 // agurt, 9/nov/06: 'enum' below is a workaround for gcc 4.0.4/4.1.1 bugs #29522 and #29518
327 #   define BOOST_MPL_ASSERT_RELATION_IMPL(counter, x, rel, y)      \
328 enum { BOOST_PP_CAT(mpl_assert_rel_value,counter) = (x rel y) }; \
329 BOOST_MPL_AUX_ASSERT_CONSTANT( \
330       std::size_t \
331     , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \
332         boost::mpl::assertion_failed<BOOST_PP_CAT(mpl_assert_rel_value,counter)>( \
333             (boost::mpl::failed ************ ( boost::mpl::assert_relation< \
334                   boost::mpl::assert_::relations( sizeof( \
335                       boost::mpl::assert_::arg rel boost::mpl::assert_::arg \
336                     ) ) \
337                 , x \
338                 , y \
339                 >::************)) 0 ) \
340         ) \
341     ) \
342 /**/
343 #   else
344 #   define BOOST_MPL_ASSERT_RELATION_IMPL(counter, x, rel, y)    \
345 BOOST_MPL_AUX_ASSERT_CONSTANT( \
346       std::size_t \
347     , BOOST_PP_CAT(mpl_assert_rel,counter) = sizeof( \
348           boost::mpl::assert_::arg rel boost::mpl::assert_::arg \
349         ) \
350     ); \
351 BOOST_MPL_AUX_ASSERT_CONSTANT( bool, BOOST_PP_CAT(mpl_assert_rel_value,counter) = (x rel y) ); \
352 BOOST_MPL_AUX_ASSERT_CONSTANT( \
353       std::size_t \
354     , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \
355         boost::mpl::assertion_failed<BOOST_PP_CAT(mpl_assert_rel_value,counter)>( \
356               boost::mpl::assert_rel_arg( boost::mpl::assert_relation< \
357                   boost::mpl::assert_::relations(BOOST_PP_CAT(mpl_assert_rel,counter)) \
358                 , x \
359                 , y \
360                 >() ) \
361             ) \
362         ) \
363     ) \
364 /**/
365 #   endif
366
367 #   define BOOST_MPL_ASSERT_RELATION(x, rel, y) \
368 BOOST_MPL_ASSERT_RELATION_IMPL(BOOST_MPL_AUX_PP_COUNTER(), x, rel, y) \
369 /**/
370
371 #else // !BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES
372
373 #   if defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER)
374 #   define BOOST_MPL_ASSERT_RELATION(x, rel, y) \
375 BOOST_MPL_AUX_ASSERT_CONSTANT( \
376       std::size_t \
377     , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
378         boost::mpl::assertion_failed<(x rel y)>( boost::mpl::assert_rel_arg( \
379               boost::mpl::BOOST_MPL_AUX_ASSERT_RELATION(x,y,(&boost::mpl::operator rel))() \
380             ) ) \
381         ) \
382     ) \
383 /**/
384 #   else
385 #   define BOOST_MPL_ASSERT_RELATION(x, rel, y) \
386 BOOST_MPL_AUX_ASSERT_CONSTANT( \
387       std::size_t \
388     , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
389         boost::mpl::assertion_failed<(x rel y)>( (boost::mpl::failed ************ ( \
390             boost::mpl::BOOST_MPL_AUX_ASSERT_RELATION(x,y,(&boost::mpl::operator rel))::************))0 ) \
391         ) \
392     ) \
393 /**/
394 #   endif
395
396 #endif
397
398
399 // BOOST_MPL_ASSERT_MSG( (pred<x,...>::value), USER_PROVIDED_MESSAGE, (types<x,...>) ) 
400
401 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202))
402 #   define BOOST_MPL_ASSERT_MSG_IMPL( counter, c, msg, types_ ) \
403 struct msg; \
404 typedef struct BOOST_PP_CAT(msg,counter) : boost::mpl::assert_ \
405 { \
406     using boost::mpl::assert_::types; \
407     static boost::mpl::failed ************ (msg::************ assert_arg()) types_ \
408     { return 0; } \
409 } BOOST_PP_CAT(mpl_assert_arg,counter); \
410 BOOST_MPL_AUX_ASSERT_CONSTANT( \
411       std::size_t \
412     , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \
413         boost::mpl::assertion<(c)>::failed( BOOST_PP_CAT(mpl_assert_arg,counter)::assert_arg() ) \
414         ) \
415     ) \
416 /**/
417 #else
418 #   define BOOST_MPL_ASSERT_MSG_IMPL( counter, c, msg, types_ )  \
419 struct msg; \
420 typedef struct BOOST_PP_CAT(msg,counter) : boost::mpl::assert_ \
421 { \
422     static boost::mpl::failed ************ (msg::************ assert_arg()) types_ \
423     { return 0; } \
424 } BOOST_PP_CAT(mpl_assert_arg,counter); \
425 BOOST_MPL_AUX_ASSERT_CONSTANT( \
426       std::size_t \
427     , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \
428         boost::mpl::assertion_failed<(c)>( BOOST_PP_CAT(mpl_assert_arg,counter)::assert_arg() ) \
429         ) \
430     ) \
431 /**/
432 #endif
433
434 #define BOOST_MPL_ASSERT_MSG( c, msg, types_ ) \
435 BOOST_MPL_ASSERT_MSG_IMPL( BOOST_MPL_AUX_PP_COUNTER(), c, msg, types_ ) \
436 /**/
437
438 #endif // BOOST_MPL_ASSERT_HPP_INCLUDED