
I'm not qualified to answer this one; Aleksey? on Wed Oct 10 2012, Steven Watanabe <watanabesj-AT-gmail.com> wrote:
AMDG
I just ran into the following bug:
template<class T> struct test : T { BOOST_MPL_ASSERT((T)); }; BOOST_MPL_ASSERT((test<T>));
I've reworked BOOST_MPL_ASSERT to avoid the problem in the attached patch. Okay to commit?
In Christ, Steven Watanabe
Index: boost/mpl/assert.hpp =================================================================== --- boost/mpl/assert.hpp (revision 80856) +++ boost/mpl/assert.hpp (working copy) @@ -34,6 +34,9 @@ #include <boost/config.hpp> // make sure 'size_t' is placed into 'std' #include <cstddef>
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1700) +#include <boost/mpl/if.hpp> +#endif
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ || (BOOST_MPL_CFG_GCC != 0) \ @@ -131,9 +134,39 @@
#endif
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1700)
-#if !defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER) +template<class Pred> +struct extract_assert_pred;
+template<class Pred> +struct extract_assert_pred<void(Pred)> { typedef Pred type; }; + +template<class Pred> +struct eval_assert { + typedef typename extract_assert_pred<Pred>::type P; + typedef typename P::type p_type; + typedef typename ::boost::mpl::if_c<p_type::value, + AUX778076_ASSERT_ARG(assert<false>), + failed ************ P::************ + >::type type; +}; + +template<class Pred> +struct eval_assert_not { + typedef typename extract_assert_pred<Pred>::type P; + typedef typename P::type p_type; + typedef typename ::boost::mpl::if_c<!p_type::value, + AUX778076_ASSERT_ARG(assert<false>), + failed ************ ::boost::mpl::not_<P>::************ + >::type type; +}; + +template< typename T > +T make_assert_arg(); + +#elif !defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER) + template< bool > struct assert_arg_pred_impl { typedef int type; }; template<> struct assert_arg_pred_impl<true> { typedef void* type; };
@@ -211,6 +244,7 @@
BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
// BOOST_MPL_ASSERT((pred<x,...>))
@@ -219,6 +253,38 @@ std::size_t \ , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \ boost::mpl::assertion_failed<false>( \ + boost::mpl::make_assert_arg< \ + typename boost::mpl::eval_assert<void pred>::type \ + >() \ + ) \ + ) \ + ) \ +/**/ + +// BOOST_MPL_ASSERT_NOT((pred<x,...>)) + +#define BOOST_MPL_ASSERT_NOT(pred) \ +BOOST_MPL_AUX_ASSERT_CONSTANT( \ + std::size_t \ + , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \ + boost::mpl::assertion_failed<false>( \ + boost::mpl::make_assert_arg< \ + typename boost::mpl::eval_assert_not<void pred>::type \ + >() \ + ) \ + ) \ + ) \ +/**/ + +#else + +// BOOST_MPL_ASSERT((pred<x,...>)) + +#define BOOST_MPL_ASSERT(pred) \ +BOOST_MPL_AUX_ASSERT_CONSTANT( \ + std::size_t \ + , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \ + boost::mpl::assertion_failed<false>( \ boost::mpl::assert_arg( (void (*) pred)0, 1 ) \ ) \ ) \ @@ -250,6 +316,8 @@ /**/ #endif
+#endif + // BOOST_MPL_ASSERT_RELATION(x, ==|!=|<=|<|>=|>, y)
#if defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES) Index: libs/mpl/test/assert.cpp =================================================================== --- libs/mpl/test/assert.cpp (revision 80856) +++ libs/mpl/test/assert.cpp (working copy) @@ -71,6 +71,17 @@ } };
+template<class T> +struct nested : boost::mpl::true_ { + BOOST_MPL_ASSERT(( boost::is_pointer<T*> )); + BOOST_MPL_ASSERT_NOT(( boost::is_same<void,T> )); + BOOST_MPL_ASSERT_RELATION( sizeof(T*), >, 1 ); + BOOST_MPL_ASSERT_MSG( true, GLOBAL_SCOPE_ERROR, (int,long) ); +}; + +BOOST_MPL_ASSERT(( nested<int> )); +BOOST_MPL_ASSERT_NOT(( boost::mpl::not_<nested<unsigned> > )); + int main() { her<void> h;
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Dave Abrahams BoostPro Computing Software Development Training http://www.boostpro.com Clang/LLVM/EDG Compilers C++ Boost