Boost logo

Boost :

From: Andy Little (andy_at_[hidden])
Date: 2006-08-05 09:58:11


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_
        ]
*/


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