Boost logo

Boost Users :

From: Angus Leeming (angus.leeming_at_[hidden])
Date: 2005-04-05 06:31:51


I see examples of enable_if used to specify a return type to a function:

template <class T>
typename enable_if_c<boost::is_arithmetic<T>::value, T>::type
foo(T t)
{
    return t;
}

Is it possible to use enable_if with a constructor? For example, I'd like
to define a constructor that allows only certain values of an enum:

#include <boost/utility/enable_if.hpp>

class foo {
public:
    enum state {
        state1,
        state2,
        state3
    };

    // This should compile only when passed (s == state2 or s == state3)
    template<int ID>
    foo(boost::enable_if_c<some_boolean_condition, state>::type s)
        : status_(s) {}

private:
    state status_;
};

Even if this turns out to be impossible, I'd like to go on and try to
define some_boolean_condition if I may. I see that Aleksey plans a
contains_c metafunction for 1.33,

http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?MPL_TODO_List
Equivalent URL: http://tinyurl.com/4toly

so my limited understanding leads me to
    some_boolean_condition is equivalent to:
    mpl::contains_c< mpl::vector_c< int, state2, state3 >, ID >::value

Does that look correct?

In the absence of contains_c, I've been trying to use mpl::find_if but my
predicate compiles for both "valid" and "invalid" values, so I must be
doing something wrong.

I'd be grateful if someone could put me back on track.

Regards,
Angus

#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/vector_c.hpp>

class foo {
public:
    enum state {
        state1,
        state2,
        state3
    };
};

int main()
{
// Should lead to a compile-time failure.
#define TESTED_VALUE foo::state1
// Should compile.
// #define TESTED_VALUE foo::state2

    namespace mpl = boost::mpl;
    typedef mpl::vector_c< int, foo::state2, foo::state3 >
        allowable_values;
        
    typedef
        mpl::find_if<
            allowable_values,
            mpl::equal_to<
                mpl::_1,
                mpl::integral_c<allowable_values::value_type, TESTED_VALUE>
>
>::type iter;

    BOOST_MPL_ASSERT((
        mpl::not_<
            boost::is_same<
                iter::type,
                mpl::end<allowable_values>::type
>
>
    ));

    return 0;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net