Boost logo

Boost :

From: Alex Chovanec (achovane_at_[hidden])
Date: 2004-08-22 13:42:06


"Thomas Witt" <witt_at_[hidden]> wrote in message
news:cgal5p$lb4$1_at_sea.gmane.org...

> How do you implement that?

Thomas,

I'm using the SFINAE principle. I have two member functions called 'test' in
'struct detail::is_iterator_impl', where one of them is a template:

    static char (& test(...))[2];

    template <typename T>
    static char test(
        T *,
        type_tag<typename T::value_type> * = 0,
        type_tag<typename T::reference> * = 0,
        type_tag<typename T::pointer> * = 0,
        type_tag<typename T::difference_type> * = 0,
        type_tag<typename T::iterator_category> * = 0,
        star_op_tag<T, &T::operator* > * = 0,
        arrow_op_tag<T, &T::operator-> > * = 0,
        prefix_op_tag<T, &T::operator++ > * = 0,
        postfix_op_tag<T, &T::operator++ > * = 0
    );

Then in 'is_iterator', I define 'value' as follows:

    BOOST_STATIC_CONSTANT(
        value_type,
        value = sizeof(detail::is_iterator_impl::test((T *) 0)) == 1
    );

Thus, if T meets the requirements for an iterator, argument deduction
succeeds and an instantiation of the 'test' function template is added to
the set of candidate functions. And since T * is a better match than ...,
this function is the one that gets chosen during overload resolution. Then
'value' evaluates to true.

Otherwise, argument deduction fails, and the first function gets chosen
instead because it's the only candidate. Then 'value' evaluates to false.

Of course, this implementation will not work for pointers, so I provide a
partial template specialization for this case. (Please see my response to
Jonathan for details.) As an alternative, I considered using Boost iterator
traits instead of constructs like 'typename T::value_type', since iterator
traits handle pointers correctly. But iterator traits don't include
operators, so a partial template specialization would still be required.

Lastly, Jonathan pointed out that these operators can be implemented as
non-member functions. I am working on a solution that will work when this is
the case.

Thanks,

Alex


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