
FWIW Here is one way that The separate Concepts in mpl::IntegralConstant could be broken down. If algorithms are specified in those terms then a wider range of types can be used. Note that the RuntimeEvaluable is useful on its own, as is Iterable. Its somewhat unfair to include The Numerics and comparisons, but note the warnings emitted in VC7.1 warning level 3(but none if warnings are turned off!) when a bool_ is used for maths, which suggest *Strongly* to me that it should be a separate Concept. Also not that bool_ fails the Iterable check so that check is commented out. regards Andy Little -------------------- #include <boost/typeof/typeof.hpp> #include <boost/type_traits/is_same.hpp> #include <iostream> #include <boost/mpl/integral_c.hpp> #include <boost/mpl/logical.hpp> #include <boost/mpl/comparison.hpp> #include <boost/mpl/arithmetic.hpp> #include <boost/mpl/bool.hpp> #include <boost/concept_check.hpp> #include <boost/mpl/next_prior.hpp> // UnaryMetaFunction Concept template <typename T> void UnaryMetaFunction() { typedef typename T::type type; bool result = boost::is_same<typename T::type, T> ::value; if(result) std::cout << typeid(T).name() << ((result)?" passed":"failed") << " UnaryMetaFunction test\n"; } template <typename T, T v> struct static_value_check{}; template <typename T> void ConstantMetaFunction() { /*refinement of */ UnaryMetaFunction<T>(); static_value_check<BOOST_TYPEOF(T::value),T::value> tested; boost::ignore_unused_variable_warning(tested); std::cout << typeid(T).name() << " passed ConstantMetaFunction test\n"; } template <typename T> void BooleanMetaFunction() { /*refinement of */ ConstantMetaFunction<T>(); static const bool equal_to = boost::mpl::equal_to<T,T>::value; typedef typename boost::mpl::not_<T>::type notT; static const bool not_equal_to = boost::mpl::not_equal_to<notT,T>::value; static const bool and_ = boost::mpl::and_<T,T>::value; static const bool or_ = boost::mpl::or_<T,notT>::value; static const bool result = equal_to && not_equal_to && and_ && or_; // etc std::cout << typeid(T).name() << ((result)?" passed":"failed") << " BooleanMetaFunction test\n"; } template <typename T> void IterableMetaFunction() { /*refinement of */ ConstantMetaFunction<T>(); typedef typename boost::mpl::next<T>::type next; typedef typename boost::mpl::prior<T>::type prior; std::cout << typeid(T).name() << " passed IterableMetaFunction test\n"; } template <typename T> void NumericMetaFunction() { /*refinement of */ BooleanMetaFunction<T>(); typedef typename boost::mpl::plus<T,T>::type plus; typedef typename boost::mpl::minus<T,T>::type minus; typedef typename boost::mpl::times<T,T>::type times; typedef typename boost::mpl::divides<T,T>::type divides; typedef typename boost::mpl::negate<T>::type negate; typedef typename boost::mpl::modulus<T,T>::type modulus; // todo ... check results std::cout << typeid(T).name() << " passed NumericMetaFunction test\n"; } template <typename T> void RuntimeEvaluableMetaFunction() { BOOST_AUTO_TPL(value,T()); std::cout << typeid(T).name() << " passed RuntimeEvaluableMetaFunction test\n"; } int main() { typedef boost::mpl::integral_c<int,1> integral_c; BooleanMetaFunction<integral_c>(); IterableMetaFunction<integral_c>(); NumericMetaFunction<integral_c>(); RuntimeEvaluableMetaFunction<integral_c>(); typedef boost::mpl::true_ true_; BooleanMetaFunction<true_>(); //fail IterableMetaFunction<true_>(); // warns in VC7.1 output below ---> NumericMetaFunction<true_>(); RuntimeEvaluableMetaFunction<true_>(); // also works for other types RuntimeEvaluableMetaFunction<float>(); } /* c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\plus.hpp(136) : warning C4305: 'specialization' : truncation from 'int' to 'boost::mpl::if_c<C,T1,T2>::type' with [ C=true, T1=boost::mpl::bool_<true>::value_type, T2=boost::mpl::bool_<true>::value_type ] c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\plus.hpp(108) : see reference to class template instantiation 'boost::mpl::plus_impl<boost::mpl::integral_c_tag,boost::mpl::integral_c_tag>::apply<N1,N2>' being compiled with [ N1=true_, N2=true_ ] e:\Projects\Test\test.cpp(60) : see reference to class template instantiation 'boost::mpl::plus<N1,N2>' being compiled with [ N1=true_, N2=true_ ] e:\Projects\Test\test.cpp(81) : see reference to function template instantiation 'void NumericMetaFunction<true_>(void)' being compiled c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\divides.hpp(135) : warning C4804: '/' : unsafe use of type 'bool' in operation c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\divides.hpp(108) : see reference to class template instantiation 'boost::mpl::divides_impl<boost::mpl::integral_c_tag,boost::mpl::integral_c_tag>::apply<N1,N2>' being compiled with [ N1=true_, N2=true_ ] e:\Projects\Test\test.cpp(63) : see reference to class template instantiation 'boost::mpl::divides<N1,N2>' being compiled with [ N1=true_, N2=true_ ] c:\boost\include\boost-1_33_1\boost\mpl\negate.hpp(73) : warning C4804: '-' : unsafe use of type 'bool' in operation c:\boost\include\boost-1_33_1\boost\mpl\negate.hpp(41) : see reference to class template instantiation 'boost::mpl::negate_impl<boost::mpl::integral_c_tag>::apply<N>' being compiled with [ N=true_ ] e:\Projects\Test\test.cpp(64) : see reference to class template instantiation 'boost::mpl::negate<N>' being compiled with [ N=true_ ] c:\boost\include\boost-1_33_1\boost\mpl\negate.hpp(73) : warning C4305: 'specialization' : truncation from 'int' to 'boost::mpl::bool_<C_>::value_type' with [ C_=true ] c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\modulus.hpp(93) : warning C4804: '%' : unsafe use of type 'bool' in operation c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\modulus.hpp(72) : see reference to class template instantiation 'boost::mpl::modulus_impl<boost::mpl::integral_c_tag,boost::mpl::integral_c_tag>::apply<N1,N2>' being compiled with [ N1=true_, N2=true_ ] e:\Projects\Test\test.cpp(65) : see reference to class template instantiation 'boost::mpl::modulus<N1,N2>' being compiled with [ N1=true_, N2=true_ ] */