//References: // [apply.html] // http://www.boost.org/doc/libs/1_38_0/libs/mpl/doc/refmanual/apply.html // [fold.html] // http://www.boost.org/doc/libs/1_38_0/libs/mpl/doc/refmanual/fold.html // //Purpose: // Demonstrate that either there's a bug in either [apply.hpp] or [fold.html] // #include #include #include #include #include #include #include #include #include using namespace boost::mpl; using namespace placeholders; namespace test_io {//input/outputs to test template < typename N1 , typename N2 > struct int_plus : int_<( N1::value + N2::value )> { }; typedef int_plus< _1, _2> op ; typedef range_c < int , 3 , 5 > seq ; typedef int_<1> state0 ; typedef int_<8> fold_expected ; }//exit test_io namespace namespace fold_good { using namespace test_io ; typedef fold < seq , state0 , op >::type fold_actual ; BOOST_MPL_ASSERT(( equal_to )); }//exit fold_good namespace //#define FOLD_BUG #ifdef FOLD_BUG namespace apply_iter_bad { using namespace test_io ; typedef iter_fold < seq , state0 , apply2 < op , _1 , deref<_2> > >::type iter_apply //This fails to compile despite being an almost exact copy //of the code shown in [fold.html]. ; //BOOST_MPL_ASSERT(( equal_to )); }//exit apply_iter_bad namespace #endif namespace wrap_iter_good { using namespace test_io ; typedef iter_fold < seq , state0 , apply_wrap2 < lambda::type , _1 , deref<_2> > >::type iter_wrap //This compiles OK & passes following test OK. // //What's puzzling about this is that, according to: // http://www.boost.org/doc/libs/1_38_0/libs/mpl/doc/refmanual/apply.html //the expresion: // apply //is supposed to be equivalent to: // apply_wrap2 //This equivalence is supported by looking at the -E compiler output //which contains: /* template < typename F , typename T1 , typename T2 > struct apply2 : apply_wrap2 < typename lambda < F >::type , T1 , T2 > { }; */ //CONCLUSION: // The compiler used to show the iter_apply failure // (gcc4.1) must be buggy. ; BOOST_MPL_ASSERT(( equal_to )); }//exit wrap_iter_good namespace namespace apply_apply_iter {//test apply,,> using namespace test_io ; typedef begin::type iter0 ; typedef apply < op , state0 , deref::type >::type apply_expected ; #if 0 typedef apply < apply < op , _1 , deref<_2> > , state0 , iter0 >::type apply_apply //This fails to compile. ; //BOOST_MPL_ASSERT(( equal_to )); #endif #if 1 typedef apply < apply_wrap2 < lambda::type , _1 , deref<_2> > , state0 , iter0 >::type apply_wrap_lambda //This compiles and passes following test. ; BOOST_MPL_ASSERT(( equal_to )); #endif }//exit apply_apply_iter