Metafunction to test whether object is compatible with boost range

240 views Asked by At

Is there, or how would you write, a metafunction class that tests whether a class is compatible with boost::range? I want to use the boost::enable idiom, something like

template <typename T>
Constructor::Constructor(const T& t, __attribute__((unused)) typename boost::enable_if<is_range_compatible<T> >::type* aux=NULL)

for an appropriate is_range_compatible metafunction. I know about is_container from pretty_print, which captures a lot of cases, but not everything that works with boost::range.

Edit This is using C++03, so I don't have access to C++11 features. I'm using an old, gcc 4.1, and boost 1.51.

2

There are 2 answers

0
Paul Michalik On

If you upgrade to Boost 1.54, there is a nice library called TTI. It allows you to compose type traits introspection meta functions at will, so that you can easily spin off you own meta predicates which can be used to enable or disable function templates. Though it is a nice meta programming exercise, I don't recommend to do that in production code. I found it hard to catch the "false negatives" which arise from implementation details of STL containers. For example, the associative containers coming with MSVC11 inherit their begin and end member functions from a base class which yields false negative with meta predicates generated via BOOST_TTI_HAS_MEMBER_FUNCTION. Despite of his nickname, Useless gave you a good advice: Use concepts coming with Boost.Range to reject or accept the type inside the body of the function template such as the constructor in your example... Of course, this will not solve the convertibility problem for your Constructor...

EDIT: example, taken from vex:

#include <boost/tti/has_member_function.hpp>
#include <vector>
#include <map>

namespace tti_test {
    BOOST_TTI_HAS_MEMBER_FUNCTION(begin);

    // .. begin test class for mstest

    // this succeeds in both variants
    TEST_METHOD(has_const_member_function_begin_is_true_for_vector)
    {
        Assert::IsTrue(has_member_function_begin<
            std::vector<int>::const_iterator (std::vector<int>::*)() const
        >::value);

        Assert::IsTrue(has_member_function_begin<
            const std::vector<int>, std::vector<int>::const_iterator
        >::value);
    }

    // this fails in both variants...
    TEST_METHOD(has_const_member_function_begin_is_true_for_map)
    {
        Assert::IsTrue(has_member_function_begin<
            std::map<int, int>::const_iterator (std::map<int, int>::*)() const
        >::value);

        Assert::IsTrue(has_member_function_begin<
            const std::map<int, int>, std::map<int, int>::const_iterator
        >::value);
    }

    // end test class for mstest
}
3
Useless On

Do you mean enable_if?

If you can persuade the Boost concept checks to work usefully with it (instead of the macro + compile error it uses now), checks like ForwardConceptRange are already provided.

Otherwise, is it a problem to use the existing BOOST_CONCEPT_ASSERT macro instead?