added new iterator category support to iterator adaptors

[SVN r609]
This commit is contained in:
Jeremy Siek
2002-10-23 22:55:53 +00:00
parent 73e3961cd5
commit 26f5ac9a55
2 changed files with 63 additions and 28 deletions

View File

@@ -3,25 +3,24 @@
#include <boost/utility.hpp> // for prior #include <boost/utility.hpp> // for prior
#include <boost/iterator.hpp> #include <boost/iterator.hpp>
#include <boost/iterator/iterator_categories.hpp>
namespace boost { namespace boost {
template <class Final, class V, class R, class P, class C, class D> template <class Final, class V, class R, class P, class RC, class TC, class D>
struct repository struct repository
: iterator<C, V, D, P, R> : iterator<typename cvt_iterator_category<RC, TC>::type, V, D, P, R>
{ {
typedef Final type; typedef Final final;
typedef V value_type; typedef RC return_category;
typedef R reference; typedef TC traversal_category;
typedef C iterator_category;
typedef D difference_type;
}; };
template <class Base> template <class Base>
struct downcastable : Base struct downcastable : Base
{ {
typedef typename Base::type final_t; typedef typename Base::final final_t;
public: public:
final_t& downcast() { return static_cast<final_t&>(*this); } final_t& downcast() { return static_cast<final_t&>(*this); }
const final_t& downcast() const { return static_cast<const final_t&>(*this); } const final_t& downcast() const { return static_cast<const final_t&>(*this); }
@@ -80,16 +79,20 @@ struct iterator_arith : B { };
template <class Base> template <class Base>
typename Base::final operator+( typename Base::final operator+(
iterator_arith<Base> i, typename Base::distance n) const iterator_arith<Base>& i, // pass by ref, not value to avoid slicing -JGS
typename Base::difference_type n)
{ {
return i.downcast() += n; typename Base::final tmp(i.downcast());
return tmp += n;
} }
template <class Base> template <class Base>
typename Base::final operator+( typename Base::final operator+(
typename Base::distance n, iterator_arith<Base> i) typename Base::difference_type n,
const iterator_arith<Base>& i) // pass by ref, not value to avoid slicing -JGS
{ {
return i.downcast() += n; typename Base::final tmp(i.downcast());
return tmp += n;
} }
template <class Base1, class Base2> template <class Base1, class Base2>
@@ -102,17 +105,17 @@ typename Base1::difference_type operator-(
template <class Final template <class Final
, class V, class R, class P, class C, class D , class V, class R, class P, class RC, class TC, class D
, class B = iterator_arith< , class B = iterator_arith<
iterator_comparisons< iterator_comparisons<
downcastable<repository<Final, V, R, P, C, D> > > > downcastable<repository<Final, V, R, P, RC, TC, D> > > >
> >
struct iterator_adaptor : B struct iterator_adaptor : B, new_iterator_base
{ {
typedef V value_type; typedef V value_type;
typedef R reference; typedef R reference;
typedef P pointer; typedef P pointer;
typedef C iterator_category; typedef typename B::iterator_category iterator_category;
typedef D difference_type; typedef D difference_type;
reference operator*() const reference operator*() const
@@ -135,14 +138,25 @@ struct iterator_adaptor : B
Final operator-(difference_type x) const Final operator-(difference_type x) const
{ Final result(downcast()); return result -= x; } { Final result(downcast()); return result -= x; }
template <class Final2, class V2, class R2, class P2> template <class Final2, class V2, class R2, class P2, class B2>
bool equal(iterator_adaptor<Final2,V2,R2,P2,C,D> const& x) const bool equal(iterator_adaptor<Final2,V2,R2,P2,RC,TC,D,B2> const& x) const
{ {
return this->downcast().base() == x.downcast().base(); return this->downcast().base() == x.downcast().base();
} }
void advance(difference_type n)
{
this->downcast().base() += n;
}
void increment() { ++this->downcast().base(); } void increment() { ++this->downcast().base(); }
void decrement() { --this->downcast().base(); } void decrement() { --this->downcast().base(); }
template <class Final2, class B2, class V2, class R2, class P2>
difference_type
distance_from(const iterator_adaptor<Final2,V2,R2,P2,RC,TC,D,B2>& y) const
{
return y.downcast().base() - this->downcast().base();//?
}
private: private:
using B::downcast; using B::downcast;
@@ -150,13 +164,13 @@ struct iterator_adaptor : B
template <class Base, template <class Base,
class V, class R, class P, class C, class D> class V, class R, class P, class RC, class TC, class D>
struct reverse_iterator struct reverse_iterator
: iterator_adaptor< : iterator_adaptor<
reverse_iterator<Base, V, R, P, C, D>, V, R, P, C, D reverse_iterator<Base, V, R, P, RC, TC, D>, V, R, P, RC, TC, D
> >
{ {
typedef iterator_adaptor<reverse_iterator<Base, V, R, P, C, D>, V, R, P, C, D> super; typedef iterator_adaptor<reverse_iterator<Base, V, R, P, RC, TC, D>, V, R, P, RC, TC, D> super;
// friend class super; // friend class super;
// hmm, I don't like the next two lines // hmm, I don't like the next two lines
@@ -171,7 +185,7 @@ struct reverse_iterator
Base const& base() const { return m_base; } Base const& base() const { return m_base; }
template <class B2, class V2, class R2, class P2> template <class B2, class V2, class R2, class P2>
reverse_iterator(const reverse_iterator<B2,V2,R2,P2,C,D>& y) reverse_iterator(const reverse_iterator<B2,V2,R2,P2,RC,TC,D>& y)
: m_base(y.m_base) { } : m_base(y.m_base) { }
@@ -186,7 +200,7 @@ struct reverse_iterator
template <class B2, class V2, class R2, class P2> template <class B2, class V2, class R2, class P2>
typename super::difference_type typename super::difference_type
distance_from(const reverse_iterator<B2,V2,R2,P2,C,D>& y) const distance_from(const reverse_iterator<B2,V2,R2,P2,RC,TC,D>& y) const
{ {
return m_base - y.m_base; return m_base - y.m_base;
} }
@@ -195,8 +209,6 @@ struct reverse_iterator
}; };
} // namespace boost } // namespace boost

View File

@@ -12,6 +12,8 @@
#include <boost/type_traits/cv_traits.hpp> #include <boost/type_traits/cv_traits.hpp>
#include <boost/pending/ct_if.hpp> #include <boost/pending/ct_if.hpp>
#include <boost/detail/iterator.hpp> #include <boost/detail/iterator.hpp>
#include <boost/mpl/if.hpp>
#include <iterator>
namespace boost { namespace boost {
@@ -106,10 +108,10 @@ namespace boost {
bidirectional_traversal_tag, bidirectional_traversal_tag,
typename ct_if< typename ct_if<
is_convertible<Category*, std::forward_iterator_tag*>::value, is_convertible<Category*, std::forward_iterator_tag*>::value,
forward_traversal_tag, forward_traversal_tag,
typename ct_if< typename ct_if<
is_convertible<Category*, std::input_iterator_tag*>::value, is_convertible<Category*, std::input_iterator_tag*>::value,
input_traversal_tag, input_traversal_tag,
output_traversal_tag output_traversal_tag
>::type >::type
>::type >::type
@@ -187,6 +189,27 @@ namespace boost {
#endif #endif
template <class RC, class TC>
struct cvt_iterator_category {
typedef
typename mpl::if_c<(is_convertible<RC*, mutable_lvalue_iterator_tag*>::value
|| is_convertible<RC*, constant_lvalue_iterator_tag*>::value),
typename mpl::if_c<is_convertible<TC*, random_access_traversal_tag*>::value,
std::random_access_iterator_tag,
typename mpl::if_c<is_convertible<TC*, bidirectional_traversal_tag*>::value,
std::bidirectional_iterator_tag,
typename mpl::if_c<is_convertible<TC*, forward_traversal_tag*>::value,
std::forward_iterator_tag,
boost::error_iterator_tag>::type >::type >::type,
typename mpl::if_c<(is_convertible<RC*, readable_iterator_tag*>::value
&& is_convertible<TC*, input_traversal_tag*>::value),
std::input_iterator_tag,
typename mpl::if_c<(is_convertible<RC*, writable_iterator_tag*>::value
&& is_convertible<TC*, output_traversal_tag*>::value),
std::output_iterator_tag,
boost::error_iterator_tag>::type>::type >::type type;
};
} // namespace boost } // namespace boost
#endif // BOOST_ITERATOR_CATEGORIES_HPP #endif // BOOST_ITERATOR_CATEGORIES_HPP