forked from boostorg/iterator
added new iterator category support to iterator adaptors
[SVN r609]
This commit is contained in:
@@ -3,25 +3,24 @@
|
||||
|
||||
#include <boost/utility.hpp> // for prior
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
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
|
||||
: iterator<C, V, D, P, R>
|
||||
: iterator<typename cvt_iterator_category<RC, TC>::type, V, D, P, R>
|
||||
|
||||
{
|
||||
typedef Final type;
|
||||
typedef V value_type;
|
||||
typedef R reference;
|
||||
typedef C iterator_category;
|
||||
typedef D difference_type;
|
||||
typedef Final final;
|
||||
typedef RC return_category;
|
||||
typedef TC traversal_category;
|
||||
};
|
||||
|
||||
template <class Base>
|
||||
struct downcastable : Base
|
||||
{
|
||||
typedef typename Base::type final_t;
|
||||
typedef typename Base::final final_t;
|
||||
public:
|
||||
final_t& downcast() { return static_cast<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>
|
||||
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>
|
||||
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>
|
||||
@@ -102,17 +105,17 @@ typename Base1::difference_type operator-(
|
||||
|
||||
|
||||
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<
|
||||
iterator_comparisons<
|
||||
downcastable<repository<Final, V, R, P, C, D> > > >
|
||||
iterator_comparisons<
|
||||
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 R reference;
|
||||
typedef P pointer;
|
||||
typedef C iterator_category;
|
||||
typedef typename B::iterator_category iterator_category;
|
||||
typedef D difference_type;
|
||||
|
||||
reference operator*() const
|
||||
@@ -135,14 +138,25 @@ struct iterator_adaptor : B
|
||||
Final operator-(difference_type x) const
|
||||
{ Final result(downcast()); return result -= x; }
|
||||
|
||||
template <class Final2, class V2, class R2, class P2>
|
||||
bool equal(iterator_adaptor<Final2,V2,R2,P2,C,D> const& x) const
|
||||
template <class Final2, class V2, class R2, class P2, class B2>
|
||||
bool equal(iterator_adaptor<Final2,V2,R2,P2,RC,TC,D,B2> const& x) const
|
||||
{
|
||||
return this->downcast().base() == x.downcast().base();
|
||||
}
|
||||
void advance(difference_type n)
|
||||
{
|
||||
this->downcast().base() += n;
|
||||
}
|
||||
|
||||
void increment() { ++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:
|
||||
using B::downcast;
|
||||
@@ -150,13 +164,13 @@ struct iterator_adaptor : B
|
||||
|
||||
|
||||
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
|
||||
: 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;
|
||||
// hmm, I don't like the next two lines
|
||||
@@ -171,7 +185,7 @@ struct reverse_iterator
|
||||
Base const& base() const { return m_base; }
|
||||
|
||||
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) { }
|
||||
|
||||
|
||||
@@ -186,7 +200,7 @@ struct reverse_iterator
|
||||
|
||||
template <class B2, class V2, class R2, class P2>
|
||||
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;
|
||||
}
|
||||
@@ -195,8 +209,6 @@ struct reverse_iterator
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
|
@@ -12,6 +12,8 @@
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
#include <boost/pending/ct_if.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <iterator>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -106,10 +108,10 @@ namespace boost {
|
||||
bidirectional_traversal_tag,
|
||||
typename ct_if<
|
||||
is_convertible<Category*, std::forward_iterator_tag*>::value,
|
||||
forward_traversal_tag,
|
||||
forward_traversal_tag,
|
||||
typename ct_if<
|
||||
is_convertible<Category*, std::input_iterator_tag*>::value,
|
||||
input_traversal_tag,
|
||||
input_traversal_tag,
|
||||
output_traversal_tag
|
||||
>::type
|
||||
>::type
|
||||
@@ -187,6 +189,27 @@ namespace boost {
|
||||
|
||||
#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
|
||||
|
||||
#endif // BOOST_ITERATOR_CATEGORIES_HPP
|
||||
|
Reference in New Issue
Block a user