iterator_adaptor portability and fleshing-out

[SVN r600]
This commit is contained in:
Dave Abrahams
2002-10-22 22:10:49 +00:00
parent bc15598388
commit a17934adb5
3 changed files with 49 additions and 39 deletions

1
example/Jamfile Normal file
View File

@@ -0,0 +1 @@
unit-test ia1 : reverse_iterator.cpp : <sysinclude>../../.. <sysinclude>$(BOOST) ;

View File

@@ -1,8 +1,8 @@
#include <boost/iterator/iterator_adaptors.hpp>
#include <boost/cstdlib.hpp>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
#include "boost/iterator/iterator_adaptors.hpp" #include <algorithm>
#include "boost/cstdlib.hpp"
int main() int main()
{ {
@@ -11,4 +11,5 @@ int main()
first(x + 4), last(x); first(x + 4), last(x);
std::copy(first, last, std::ostream_iterator<int>(std::cout, " ")); std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl; std::cout << std::endl;
return 0;
} }

View File

@@ -1,61 +1,62 @@
#ifndef BOOST_ITERATOR_ADAPTORS_HPP #ifndef BOOST_ITERATOR_ADAPTORS_HPP
#define BOOST_ITERATOR_ADAPTORS_HPP #define BOOST_ITERATOR_ADAPTORS_HPP
#include "boost/utility.hpp" // for prior #include <boost/utility.hpp> // for prior
#include <boost/iterator.hpp>
namespace boost { namespace boost {
template <class Derived> template <class Derived, class Base>
struct iterator_comparisons { }; struct iterator_comparisons : Base { };
template <class D1, class D2> template <class D1, class D2, class B1, class B2>
inline bool operator==(const iterator_comparisons<D1>& xb, inline bool operator==(const iterator_comparisons<D1,B1>& xb,
const iterator_comparisons<D2>& yb) const iterator_comparisons<D2,B2>& yb)
{ {
const D1& x = static_cast<const D1&>(xb); const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb); const D2& y = static_cast<const D2&>(yb);
return x.equal(y); return x.equal(y);
} }
template <class D1, class D2> template <class D1, class D2, class B1, class B2>
inline bool operator!=(const iterator_comparisons<D1>& xb, inline bool operator!=(const iterator_comparisons<D1,B1>& xb,
const iterator_comparisons<D2>& yb) const iterator_comparisons<D2,B2>& yb)
{ {
const D1& x = static_cast<const D1&>(xb); const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb); const D2& y = static_cast<const D2&>(yb);
return !x.equal(y); return !x.equal(y);
} }
template <class D1, class D2> template <class D1, class D2, class B1, class B2>
inline bool operator<(const iterator_comparisons<D1>& xb, inline bool operator<(const iterator_comparisons<D1,B1>& xb,
const iterator_comparisons<D2>& yb) const iterator_comparisons<D2,B2>& yb)
{ {
const D1& x = static_cast<const D1&>(xb); const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb); const D2& y = static_cast<const D2&>(yb);
return y.distance(x) < 0; return y.distance(x) < 0;
} }
template <class D1, class D2> template <class D1, class D2, class B1, class B2>
inline bool operator>(const iterator_comparisons<D1>& xb, inline bool operator>(const iterator_comparisons<D1,B1>& xb,
const iterator_comparisons<D2>& yb) const iterator_comparisons<D2,B2>& yb)
{ {
const D1& x = static_cast<const D1&>(xb); const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb); const D2& y = static_cast<const D2&>(yb);
return y.distance(x) > 0; return y.distance(x) > 0;
} }
template <class D1, class D2> template <class D1, class D2, class B1, class B2>
inline bool operator>=(const iterator_comparisons<D1>& xb, inline bool operator>=(const iterator_comparisons<D1,B1>& xb,
const iterator_comparisons<D2>& yb) const iterator_comparisons<D2,B2>& yb)
{ {
const D1& x = static_cast<const D1&>(xb); const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb); const D2& y = static_cast<const D2&>(yb);
return y.distance(x) >= 0; return y.distance(x) >= 0;
} }
template <class D1, class D2> template <class D1, class D2, class B1, class B2>
inline bool operator<=(const iterator_comparisons<D1>& xb, inline bool operator<=(const iterator_comparisons<D1,B1>& xb,
const iterator_comparisons<D2>& yb) const iterator_comparisons<D2,B2>& yb)
{ {
const D1& x = static_cast<const D1&>(xb); const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb); const D2& y = static_cast<const D2&>(yb);
@@ -63,24 +64,24 @@ inline bool operator<=(const iterator_comparisons<D1>& xb,
} }
template <class Derived, class D> template <class Derived, class D, class Base>
struct iterator_arith : public iterator_comparisons<Derived> { }; struct iterator_arith : public iterator_comparisons<Derived,Base> { };
template <class Derived, class D> template <class Derived, class D, class Base>
D operator+(iterator_arith<Derived, D> i, D n) { return i += n; } D operator+(iterator_arith<Derived, D, Base> i, D n) { return i += n; }
template <class Derived, class D> template <class Derived, class D, class Base>
D operator+(D n, iterator_arith<Derived, D> i) { return i += n; } D operator+(D n, iterator_arith<Derived, D, Base> i) { return i += n; }
template <class Derived, class D> template <class Derived, class D, class Base>
D operator-(const iterator_arith<Derived, D>& i, D operator-(const iterator_arith<Derived, D, Base>& i,
const iterator_arith<Derived, D>& j) const iterator_arith<Derived, D, Base>& j)
{ return static_cast<const Derived&>(j).distance(static_cast<const Derived&>(i)); } { return static_cast<const Derived&>(j).distance(static_cast<const Derived&>(i)); }
template <class Derived, template <class Derived,
class V, class R, class P, class C, class D> class V, class R, class P, class C, class D>
class iterator_adaptor : public iterator_arith<Derived, D> class iterator_adaptor : public iterator_arith<Derived, D, iterator<C,V,D,P,R> >
{ {
public: public:
typedef V value_type; typedef V value_type;
@@ -108,6 +109,11 @@ public:
{ derived().advance(-n); return derived(); } { derived().advance(-n); return derived(); }
Derived operator-(difference_type x) const Derived operator-(difference_type x) const
{ Derived result(derived()); return result -= x; } { Derived result(derived()); return result -= x; }
template <class Derived2, class V2, class R2, class P2>
bool equal(iterator_adaptor<Derived2,V2,R2,P2,C,D> const& x) const
{ return this->derived().base() == x.derived().base(); }
private: private:
Derived& derived() { return static_cast<Derived&>(*this); } Derived& derived() { return static_cast<Derived&>(*this); }
const Derived& derived() const { return static_cast<const Derived&>(*this); } const Derived& derived() const { return static_cast<const Derived&>(*this); }
@@ -120,20 +126,22 @@ template <class Base,
class reverse_iterator : public iterator_adaptor<reverse_iterator<Base, V, R, P, C, D>, V, R, P, C, D> class reverse_iterator : public iterator_adaptor<reverse_iterator<Base, V, R, P, C, D>, V, R, P, C, 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, C, D>, V, R, P, C, 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
template <class Der> friend struct iterator_comparisons; // template <class Der> friend struct iterator_comparisons;
template <class Der, class Dist> friend struct iterator_arith; // template <class Der, class Dist> friend struct iterator_arith;
public: public:
reverse_iterator(const Base& x) : m_base(x) { } reverse_iterator(const Base& x) : m_base(x) { }
reverse_iterator() { } reverse_iterator() { }
Base const& base() const { return m_base; }
template <class B2, class V2, class R2, class P2, class C2, class D2> template <class B2, class V2, class R2, class P2, class C2, class D2>
reverse_iterator(const reverse_iterator<B2,V2,R2,P2,C2,D2>& y) reverse_iterator(const reverse_iterator<B2,V2,R2,P2,C2,D2>& y)
: m_base(y.m_base) { } : m_base(y.m_base) { }
//private: hmm, the above friend decls aren't doing the job. //private: hmm, the above friend decls aren't doing the job.
typename super::reference dereference() const { *boost::prior(m_base); } typename super::reference dereference() const { return *boost::prior(m_base); }
void increment() { --m_base; } void increment() { --m_base; }
void decrement() { ++m_base; } void decrement() { ++m_base; }
void advance(typename super::difference_type n) void advance(typename super::difference_type n)