MPL iterator category
In C++ Template Metaprogramming book, there is the expression i::category in tables 5.1, 5.2 and 5.3 that says that the result is convertible to mpl::forward_iterator_tag, mpl::bidirectional_iterator_tag and mpl::random_access_iterator_tag respectively. Since a random access iterator is bidirectional iterator which is in turn a forward iterator, I was expecting that i::category for a bidirectional iterator would also be convertible to mpl::forward_tag which is not the case. So if an algorithm has to works differently for random-access iterator but it the same for forward and bidirectional iterator, it seems to me that I would need some extra logic to uses forward iterator algorithm if I have a bidirectional iterator as theree are no implicit conversion. In fact, in the implementation we derives from int_<n> where n is 0, 1 or 2 depending on the iterator type. Philippe
Philippe Mori writes:
In C++ Template Metaprogramming book, there is the expression i::category in tables 5.1, 5.2 and 5.3 that says that the result is convertible to mpl::forward_iterator_tag, mpl::bidirectional_iterator_tag and mpl::random_access_iterator_tag respectively.
Yep.
Since a random access iterator is bidirectional iterator which is in turn a forward iterator, I was expecting that i::category for a bidirectional iterator would also be convertible to mpl::forward_tag which is not the case.
Correct.
So if an algorithm has to works differently for random-access iterator but it the same for forward and bidirectional iterator, it seems to me that I would need some extra logic to uses forward iterator algorithm if I have a bidirectional iterator as theree are no implicit conversion.
Well, as a matter of fact this particular case can be easily handled by explicit specialization (see http://www.boost.org/libs/mpl/doc/refmanual/iterator-category.html#example). Writing an algorithm for _bidirectional_ iterators and making sure that it gets selected for random-access ones as well is somewhat more tricky: template< typename Iterator > struct algorithm : if_c< iterator_category<Iterator>::type::value >= bidirectional_iterator_tag::value , bidirectional_algorithm<Iterator> , forward_algorithm<Iterator> > { }; but try to write this up assuming that _there is_ an implicit conversion between 'random_access_iterator_tag' and 'bidirectional_iterator_tag', and you'll see that you'll end up with something at least as complex as the above. HTH, -- Aleksey Gurtovoy MetaCommunications Engineering
Aleksey Gurtovoy
Writing an algorithm for _bidirectional_ iterators and making sure that it gets selected for random-access ones as well is somewhat more tricky:
template< typename Iterator > struct algorithm : if_c< iterator_category<Iterator>::type::value >= bidirectional_iterator_tag::value , bidirectional_algorithm<Iterator> , forward_algorithm<Iterator> > { };
but try to write this up assuming that _there is_ an implicit conversion between 'random_access_iterator_tag' and 'bidirectional_iterator_tag', and you'll see that you'll end up with something at least as complex as the above.
If there was a _form_ relationship among MPL iterator tags just like
the _inheritance_ relationship among the STL ones, it would be easier
to do this with partial specialization. E.g.,
typedef tag<> forward_iterator_tag;
typedef tag
{
...
};
doesn't really communicate well. Maybe some built-in SFINAE
facilities would help?
template
participants (3)
-
Aleksey Gurtovoy
-
David Abrahams
-
Philippe Mori