Boost logo

Boost :

Subject: Re: [boost] [mpl] Nested BOOST_MPL_ASSERT fails on VC11
From: Dave Abrahams (dave_at_[hidden])
Date: 2012-10-11 20:03:53


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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk