forked from boostorg/iterator
New minimal friend interface.
[SVN r703]
This commit is contained in:
@@ -1,400 +1,660 @@
|
|||||||
#ifndef BOOST_ITERATOR_ADAPTORS_HPP
|
#ifndef BOOST_ITERATOR_ADAPTORS_HPP
|
||||||
#define BOOST_ITERATOR_ADAPTORS_HPP
|
#define BOOST_ITERATOR_ADAPTORS_HPP
|
||||||
|
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
#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>
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
#include <boost/mpl/aux_/has_xxx.hpp>
|
#include <boost/mpl/aux_/has_xxx.hpp>
|
||||||
|
#include <boost/mpl/logical/or.hpp>
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
|
||||||
#include "boost/type_traits/detail/bool_trait_def.hpp"
|
#include "boost/type_traits/detail/bool_trait_def.hpp"
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template <class Final, class V, class R, class P, class C, class D>
|
namespace detail {
|
||||||
struct repository : iterator<C, V, D, P, R>
|
|
||||||
|
|
||||||
{
|
template<bool>
|
||||||
typedef Final final;
|
struct enabled
|
||||||
};
|
{
|
||||||
|
template<typename T>
|
||||||
|
struct base
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
template <class Base>
|
template<>
|
||||||
struct downcastable : Base
|
struct enabled<false>
|
||||||
{
|
{
|
||||||
typedef typename Base::final final_t;
|
template<typename T>
|
||||||
public:
|
struct base
|
||||||
final_t& self() { return static_cast<final_t&>(*this); }
|
{
|
||||||
const final_t& self() const { return static_cast<const final_t&>(*this); }
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Base>
|
struct enable_type {};
|
||||||
struct iterator_comparisons : Base
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Base1, class Base2>
|
template <typename A, typename B>
|
||||||
inline bool operator==(const iterator_comparisons<Base1>& xb,
|
struct is_interoperable :
|
||||||
const iterator_comparisons<Base2>& yb)
|
mpl::logical_or< is_convertible< A, B >,
|
||||||
{
|
is_convertible< B, A > >
|
||||||
return xb.self().equal(yb.self());
|
{
|
||||||
}
|
};
|
||||||
|
|
||||||
template <class Base1, class Base2>
|
template <class Facade1,
|
||||||
inline bool operator!=(const iterator_comparisons<Base1>& xb,
|
class Facade2,
|
||||||
const iterator_comparisons<Base2>& yb)
|
class Return>
|
||||||
{
|
struct enable_if_interoperable :
|
||||||
return !xb.self().equal(yb.self());
|
enabled<(is_interoperable<Facade1, Facade2>::value)>::template base<Return>
|
||||||
}
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template <class Base1, class Base2>
|
} // namespace detail
|
||||||
inline bool operator<(const iterator_comparisons<Base1>& xb,
|
|
||||||
const iterator_comparisons<Base2>& yb)
|
|
||||||
{
|
|
||||||
return xb.self().distance_to(yb.self()) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Base1, class Base2>
|
|
||||||
inline bool operator>(const iterator_comparisons<Base1>& xb,
|
|
||||||
const iterator_comparisons<Base2>& yb)
|
|
||||||
{
|
|
||||||
return xb.self().distance_to(yb.self()) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Base1, class Base2>
|
|
||||||
inline bool operator>=(const iterator_comparisons<Base1>& xb,
|
|
||||||
const iterator_comparisons<Base2>& yb)
|
|
||||||
{
|
|
||||||
return xb.self().distance_to(yb.self()) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Base1, class Base2>
|
|
||||||
inline bool operator<=(const iterator_comparisons<Base1>& xb,
|
|
||||||
const iterator_comparisons<Base2>& yb)
|
|
||||||
{
|
|
||||||
return xb.self().distance_to(yb.self()) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class B>
|
template<typename From,
|
||||||
struct iterator_arith : B { };
|
typename To>
|
||||||
|
struct enable_if_convertible :
|
||||||
|
detail::enabled<(is_convertible<From, To>::value)>::template base<detail::enable_type>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template <class Base>
|
//
|
||||||
typename Base::final operator+(
|
// Helper class for granting access to the iterator core interface.
|
||||||
const iterator_arith<Base>& i, // pass by ref, not value to avoid slicing -JGS
|
//
|
||||||
typename Base::difference_type n)
|
// The simple core interface is used by iterator_facade. The core
|
||||||
{
|
// interface should not be made public so that it does not clutter
|
||||||
typename Base::final tmp(i.self());
|
// the public interface of user defined iterators. Instead iterator_core_access
|
||||||
return tmp += n;
|
// should be made friend so that iterator_facade can access the core
|
||||||
}
|
// interface through iterator_core_access.
|
||||||
|
//
|
||||||
|
struct iterator_core_access
|
||||||
|
{
|
||||||
|
template <class Facade>
|
||||||
|
static typename Facade::reference dereference(Facade const& f)
|
||||||
|
{
|
||||||
|
return f.dereference();
|
||||||
|
}
|
||||||
|
|
||||||
template <class Base>
|
template <class Facade>
|
||||||
typename Base::final operator+(
|
static void increment(Facade& f)
|
||||||
typename Base::difference_type n,
|
{
|
||||||
const iterator_arith<Base>& i) // pass by ref, not value to avoid slicing -JGS
|
f.increment();
|
||||||
{
|
}
|
||||||
typename Base::final tmp(i.self());
|
|
||||||
return tmp += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Base1, class Base2>
|
template <class Facade>
|
||||||
typename Base1::difference_type operator-(
|
static void decrement(Facade& f)
|
||||||
const iterator_arith<Base1>& i,
|
{
|
||||||
const iterator_arith<Base2>& j)
|
f.decrement();
|
||||||
{
|
}
|
||||||
return j.self().distance_to(i.self());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used for a default template argument, when we can't afford to
|
template <class Facade1, class Facade2>
|
||||||
// instantiate the default calculation if unused.
|
static bool equal(Facade1 const& f1, Facade2 const& f2, Facade1* = 0, Facade2* = 0)
|
||||||
struct unspecified {};
|
{
|
||||||
|
return f1.equal(f2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Facade>
|
||||||
|
static void advance(Facade& f, typename Facade::difference_type n)
|
||||||
|
{
|
||||||
|
f.advance(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Facade1, class Facade2>
|
||||||
|
static typename Facade1::difference_type distance_to(Facade1 const& f1,
|
||||||
|
Facade2 const& f2,
|
||||||
|
Facade1* = 0,
|
||||||
|
Facade2* = 0)
|
||||||
|
{
|
||||||
|
return f1.distance_to(f2);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Derived,
|
||||||
|
class V,
|
||||||
|
class R,
|
||||||
|
class P,
|
||||||
|
class C,
|
||||||
|
class D>
|
||||||
|
class repository :
|
||||||
|
public iterator<C, V, D, P, R>
|
||||||
|
{
|
||||||
|
typedef Derived derived_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Base>
|
||||||
|
class downcastable :
|
||||||
|
public Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typename Base::derived_t& derived()
|
||||||
|
{
|
||||||
|
return static_cast<typename Base::derived_t&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
typename Base::derived_t const& derived() const
|
||||||
|
{
|
||||||
|
return static_cast<typename Base::derived_t const&>(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Beginnings of a failed attempt to conditionally provide base()
|
namespace detail {
|
||||||
// functions in iterator_adaptor. It may be that a public m_base
|
|
||||||
// member is the only way to avoid boilerplate!
|
|
||||||
|
|
||||||
template <class Base>
|
template <class Final1,
|
||||||
struct base_wrapper_impl
|
class Final2>
|
||||||
{
|
struct compare_traits :
|
||||||
template <class Super>
|
mpl::if_< is_convertible<Final2, Final1>,
|
||||||
struct apply : Super
|
Final1,
|
||||||
{
|
Final2 >
|
||||||
apply() {}
|
|
||||||
apply(Base b) : m_base(b) {}
|
|
||||||
|
|
||||||
Base base() const { return m_base; }
|
|
||||||
Base& base() { return m_base; }
|
|
||||||
private:
|
|
||||||
Base m_base;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct base_wrapper_impl<unspecified>
|
|
||||||
{
|
|
||||||
template <class Super>
|
|
||||||
struct apply : Super
|
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
} // namespace detail
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <class Final
|
template <class Base>
|
||||||
, class V, class R, class P, class C, class D
|
class iterator_comparisons :
|
||||||
, class B = iterator_arith<
|
public Base
|
||||||
iterator_comparisons<
|
{
|
||||||
downcastable<repository<Final, V, R, P, C, D> > > >
|
};
|
||||||
>
|
|
||||||
struct iterator_adaptor : B
|
template <class Base1,
|
||||||
{
|
class Base2>
|
||||||
typedef V value_type;
|
inline
|
||||||
typedef R reference;
|
typename detail::enable_if_interoperable<typename Base1::derived_t,
|
||||||
typedef P pointer;
|
typename Base2::derived_t,
|
||||||
typedef C iterator_category;
|
bool>::type
|
||||||
typedef D difference_type;
|
operator==(iterator_comparisons<Base1> const& lhs,
|
||||||
|
iterator_comparisons<Base2> const& rhs)
|
||||||
|
{
|
||||||
|
// For those compilers that do not support enable_if
|
||||||
|
BOOST_STATIC_ASSERT((detail::is_interoperable<
|
||||||
|
typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t >::value));
|
||||||
|
|
||||||
|
return iterator_core_access::equal(lhs.derived(),
|
||||||
|
rhs.derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Base1,
|
||||||
|
class Base2>
|
||||||
|
inline
|
||||||
|
typename detail::enable_if_interoperable<typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t,
|
||||||
|
bool>::type
|
||||||
|
operator!=(iterator_comparisons<Base1> const& lhs,
|
||||||
|
iterator_comparisons<Base2> const& rhs)
|
||||||
|
{
|
||||||
|
// For those compilers that do not support enable_if
|
||||||
|
BOOST_STATIC_ASSERT((detail::is_interoperable<
|
||||||
|
typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t >::value));
|
||||||
|
|
||||||
|
return !iterator_core_access::equal(lhs.derived(),
|
||||||
|
rhs.derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Base1,
|
||||||
|
class Base2>
|
||||||
|
inline
|
||||||
|
typename detail::enable_if_interoperable<typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t,
|
||||||
|
bool>::type
|
||||||
|
operator<(iterator_comparisons<Base1> const& lhs,
|
||||||
|
iterator_comparisons<Base2> const& rhs)
|
||||||
|
{
|
||||||
|
// For those compilers that do not support enable_if
|
||||||
|
BOOST_STATIC_ASSERT((detail::is_interoperable<
|
||||||
|
typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t >::value));
|
||||||
|
|
||||||
|
return iterator_core_access::distance_to(lhs.derived(),
|
||||||
|
rhs.derived()) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Base1,
|
||||||
|
class Base2>
|
||||||
|
inline
|
||||||
|
typename detail::enable_if_interoperable<typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t,
|
||||||
|
bool>::type
|
||||||
|
operator>(iterator_comparisons<Base1> const& lhs,
|
||||||
|
iterator_comparisons<Base2> const& rhs)
|
||||||
|
{
|
||||||
|
// For those compilers that do not support enable_if
|
||||||
|
BOOST_STATIC_ASSERT((detail::is_interoperable<
|
||||||
|
typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t >::value));
|
||||||
|
|
||||||
|
return iterator_core_access::distance_to(lhs.derived(),
|
||||||
|
rhs.derived()) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Base1,
|
||||||
|
class Base2>
|
||||||
|
inline
|
||||||
|
typename detail::enable_if_interoperable<typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t,
|
||||||
|
bool>::type
|
||||||
|
operator<=(iterator_comparisons<Base1> const& lhs,
|
||||||
|
iterator_comparisons<Base2> const& rhs)
|
||||||
|
{
|
||||||
|
// For those compilers that do not support enable_if
|
||||||
|
BOOST_STATIC_ASSERT((detail::is_interoperable<
|
||||||
|
typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t >::value));
|
||||||
|
|
||||||
|
return iterator_core_access::distance_to(lhs.derived(),
|
||||||
|
rhs.derived()) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Base1,
|
||||||
|
class Base2>
|
||||||
|
inline
|
||||||
|
typename detail::enable_if_interoperable<typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t,
|
||||||
|
bool>::type
|
||||||
|
operator>=(iterator_comparisons<Base1> const& lhs,
|
||||||
|
iterator_comparisons<Base2> const& rhs)
|
||||||
|
{
|
||||||
|
// For those compilers that do not support enable_if
|
||||||
|
BOOST_STATIC_ASSERT((detail::is_interoperable<
|
||||||
|
typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t >::value));
|
||||||
|
|
||||||
|
return iterator_core_access::distance_to(lhs.derived(),
|
||||||
|
rhs.derived()) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class Base>
|
||||||
|
class iterator_arith :
|
||||||
|
public Base
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Base>
|
||||||
|
inline
|
||||||
|
typename Base::derived_t operator+(iterator_arith<Base> const& i,
|
||||||
|
typename Base::difference_type n)
|
||||||
|
{
|
||||||
|
typename Base::derived_t tmp(i.derived());
|
||||||
|
return tmp += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Base>
|
||||||
|
inline
|
||||||
|
typename Base::derived_t operator+(typename Base::difference_type n,
|
||||||
|
iterator_arith<Base> const& i)
|
||||||
|
{
|
||||||
|
typename Base::derived_t tmp(i.derived());
|
||||||
|
return tmp += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Base1,
|
||||||
|
class Base2>
|
||||||
|
inline
|
||||||
|
typename detail::enable_if_interoperable<typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t,
|
||||||
|
typename Base1::difference_type>::type
|
||||||
|
operator-(iterator_arith<Base1> const& lhs,
|
||||||
|
iterator_arith<Base2> const& rhs)
|
||||||
|
{
|
||||||
|
// For those compilers that do not support enable_if
|
||||||
|
BOOST_STATIC_ASSERT((detail::is_interoperable<
|
||||||
|
typename Base1::derived_t,
|
||||||
|
typename Base2::derived_t >::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((is_same<typename Base1::difference_type,
|
||||||
|
typename Base2::difference_type>::value));
|
||||||
|
|
||||||
|
return iterator_core_access::distance_to(lhs.derived(),
|
||||||
|
rhs.derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Derived,
|
||||||
|
class V,
|
||||||
|
class R,
|
||||||
|
class P,
|
||||||
|
class C,
|
||||||
|
class D,
|
||||||
|
// We do not use the name base here, as base is used in
|
||||||
|
// reverse iterator.
|
||||||
|
class Super = iterator_arith<
|
||||||
|
iterator_comparisons<
|
||||||
|
downcastable<
|
||||||
|
repository< Derived, V, R, P, C, D > > > >
|
||||||
|
>
|
||||||
|
class iterator_facade :
|
||||||
|
public Super
|
||||||
|
{
|
||||||
|
typedef Super super_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename super_t::reference reference;
|
||||||
|
typedef typename super_t::difference_type difference_type;
|
||||||
|
|
||||||
reference operator*() const
|
reference operator*() const
|
||||||
{ return self().dereference(); }
|
{ return iterator_core_access::dereference(this->derived()); }
|
||||||
|
|
||||||
// Needs eventual help for input iterators
|
// Needs eventual help for input iterators
|
||||||
P operator->() const { return &self().dereference(); }
|
P operator->() const { return &iterator_core_access::dereference(this->derived()); }
|
||||||
|
|
||||||
//operator->() const { return detail::operator_arrow(*this, iterator_category()); }
|
|
||||||
|
|
||||||
reference operator[](difference_type n) const
|
reference operator[](difference_type n) const
|
||||||
{ return *(*this + n); }
|
{ return *(*this + n); }
|
||||||
Final& operator++()
|
|
||||||
{ self().increment(); return self(); }
|
|
||||||
Final operator++(int)
|
|
||||||
{ Final tmp(self()); ++*this; return tmp; }
|
|
||||||
Final& operator--()
|
|
||||||
{ self().decrement(); return self(); }
|
|
||||||
Final operator--(int)
|
|
||||||
{ Final tmp(self()); --*this; return tmp; }
|
|
||||||
Final& operator+=(difference_type n)
|
|
||||||
{ self().advance(n); return self(); }
|
|
||||||
Final& operator-=(difference_type n)
|
|
||||||
{ self().advance(-n); return self(); }
|
|
||||||
Final operator-(difference_type x) const
|
|
||||||
{ Final result(self()); return result -= x; }
|
|
||||||
|
|
||||||
template <class Final2, class V2, class R2, class P2, class B2>
|
Derived& operator++()
|
||||||
bool equal(iterator_adaptor<Final2,V2,R2,P2,C,D,B2> const& x) const
|
{ iterator_core_access::increment(this->derived()); return this->derived(); }
|
||||||
|
|
||||||
|
Derived operator++(int)
|
||||||
|
{ Derived tmp(this->derived()); ++*this; return tmp; }
|
||||||
|
|
||||||
|
Derived& operator--()
|
||||||
|
{ iterator_core_access::decrement(this->derived()); return this->derived(); }
|
||||||
|
|
||||||
|
Derived operator--(int)
|
||||||
|
{ Derived tmp(this->derived()); --*this; return tmp; }
|
||||||
|
|
||||||
|
Derived& operator+=(difference_type n)
|
||||||
|
{ iterator_core_access::advance(this->derived(), n); return this->derived(); }
|
||||||
|
|
||||||
|
Derived& operator-=(difference_type n)
|
||||||
|
{ iterator_core_access::advance(this->derived(), -n); return this->derived(); }
|
||||||
|
|
||||||
|
Derived operator-(difference_type x) const
|
||||||
|
{ Derived result(this->derived()); return result -= x; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// We should provide NTP here
|
||||||
|
//
|
||||||
|
// TODO Handle default arguments the same way as
|
||||||
|
// in former ia lib
|
||||||
|
//
|
||||||
|
template <class Derived,
|
||||||
|
class Iterator,
|
||||||
|
class Value = typename std::iterator_traits<Iterator>::value_type,
|
||||||
|
class Reference = typename std::iterator_traits<Iterator>::reference,
|
||||||
|
class Pointer = typename std::iterator_traits<Iterator>::pointer,
|
||||||
|
class Category = typename std::iterator_traits<Iterator>::iterator_category,
|
||||||
|
class Distance = typename std::iterator_traits<Iterator>::difference_type>
|
||||||
|
class iterator_adaptor :
|
||||||
|
public iterator_facade<Derived,
|
||||||
|
Value,
|
||||||
|
Reference,
|
||||||
|
Pointer,
|
||||||
|
Category,
|
||||||
|
Distance>
|
||||||
|
{
|
||||||
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
public:
|
||||||
|
iterator_adaptor() {}
|
||||||
|
|
||||||
|
explicit iterator_adaptor(Iterator iter)
|
||||||
|
: m_iterator(iter)
|
||||||
{
|
{
|
||||||
return self().base() == x.self().base();
|
|
||||||
}
|
|
||||||
void advance(difference_type n)
|
|
||||||
{
|
|
||||||
self().base() += n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reference dereference() const { return *self().base(); }
|
Iterator base() const { return m_iterator; }
|
||||||
|
|
||||||
void increment() { ++self().base(); }
|
protected:
|
||||||
void decrement() { --self().base(); }
|
// Core iterator interface for iterator_facade
|
||||||
|
//
|
||||||
|
Reference dereference() const { return *m_iterator; }
|
||||||
|
|
||||||
template <class Final2, class B2, class V2, class R2, class P2>
|
template <class OtherDerived,
|
||||||
difference_type
|
class OtherIterator,
|
||||||
distance_to(const iterator_adaptor<Final2,V2,R2,P2,C,D,B2>& y) const
|
class OtherValue,
|
||||||
|
class OtherReference,
|
||||||
|
class OtherPointer >
|
||||||
|
bool equal(iterator_adaptor<OtherDerived,
|
||||||
|
OtherIterator,
|
||||||
|
OtherValue,
|
||||||
|
OtherReference,
|
||||||
|
OtherPointer,
|
||||||
|
Category,
|
||||||
|
Distance> const& x) const
|
||||||
{
|
{
|
||||||
return y.self().base() - self().base();//?
|
return m_iterator == x.base();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't be private, or const/non-const interactions don't work
|
void advance(Distance n)
|
||||||
using B::self;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <class Base,
|
|
||||||
class V, class R, class P, class C, class D>
|
|
||||||
struct reverse_iterator
|
|
||||||
: 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;
|
|
||||||
|
|
||||||
// friend class super;
|
|
||||||
// hmm, I don't like the next two lines
|
|
||||||
// template <class Der> friend struct iterator_comparisons;
|
|
||||||
// template <class Der, class Dist> friend struct iterator_arith;
|
|
||||||
|
|
||||||
public:
|
|
||||||
reverse_iterator(const Base& x) : m_base(x) { }
|
|
||||||
|
|
||||||
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)
|
|
||||||
: m_base(y.m_base) { }
|
|
||||||
|
|
||||||
|
|
||||||
typename super::reference dereference() const { return *boost::prior(m_base); }
|
|
||||||
|
|
||||||
void increment() { --m_base; }
|
|
||||||
void decrement() { ++m_base; }
|
|
||||||
void advance(typename super::difference_type n)
|
|
||||||
{
|
{
|
||||||
m_base -= n;
|
m_iterator += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class B2, class V2, class R2, class P2>
|
void increment() { ++m_iterator; }
|
||||||
typename super::difference_type
|
void decrement() { --m_iterator; }
|
||||||
distance_to(const reverse_iterator<B2,V2,R2,P2,C,D>& y) const
|
|
||||||
|
template <class OtherDerived,
|
||||||
|
class OtherIterator,
|
||||||
|
class OtherValue,
|
||||||
|
class OtherReference,
|
||||||
|
class OtherPointer >
|
||||||
|
Distance distance_to(iterator_adaptor<OtherDerived,
|
||||||
|
OtherIterator,
|
||||||
|
OtherValue,
|
||||||
|
OtherReference,
|
||||||
|
OtherPointer,
|
||||||
|
Category,
|
||||||
|
Distance> const& y) const
|
||||||
{
|
{
|
||||||
return y.m_base - m_base;
|
return y.base() - m_iterator;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
Base m_base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class AdaptableUnaryFunction, class Base>
|
private:
|
||||||
struct transform_iterator
|
Iterator m_iterator;
|
||||||
: iterator_adaptor<
|
|
||||||
transform_iterator<AdaptableUnaryFunction, Base>,
|
|
||||||
typename AdaptableUnaryFunction::result_type,
|
|
||||||
typename AdaptableUnaryFunction::result_type,
|
|
||||||
typename AdaptableUnaryFunction::result_type*,
|
|
||||||
iterator_tag<readable_iterator_tag,
|
|
||||||
typename traversal_category<Base>::type>,
|
|
||||||
typename detail::iterator_traits<Base>::difference_type
|
|
||||||
>
|
|
||||||
{
|
|
||||||
public: // types
|
|
||||||
typedef typename AdaptableUnaryFunction::result_type value_type;
|
|
||||||
|
|
||||||
public: // member functions
|
};
|
||||||
transform_iterator() { }
|
|
||||||
|
|
||||||
transform_iterator(const Base& x, AdaptableUnaryFunction f)
|
//
|
||||||
: m_base(x), m_f(f) { }
|
//
|
||||||
|
//
|
||||||
|
template <class Iterator>
|
||||||
|
class reverse_iterator :
|
||||||
|
public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
|
||||||
|
{
|
||||||
|
typedef iterator_adaptor< reverse_iterator<Iterator>, Iterator > super_t;
|
||||||
|
|
||||||
value_type dereference() const { return m_f(*m_base); }
|
friend class iterator_core_access;
|
||||||
|
|
||||||
template <class F2, class B2>
|
public:
|
||||||
transform_iterator(const transform_iterator<F2,B2>& y)
|
reverse_iterator() {}
|
||||||
: m_base(y.m_base), m_f(y.m_f) { }
|
|
||||||
|
|
||||||
Base& base() { return m_base; }
|
explicit reverse_iterator(Iterator x)
|
||||||
Base const& base() const { return m_base; }
|
: super_t(x) {}
|
||||||
|
|
||||||
private:
|
template<class OtherIterator>
|
||||||
Base m_base;
|
reverse_iterator(reverse_iterator<OtherIterator> const& r,
|
||||||
AdaptableUnaryFunction m_f;
|
typename enable_if_convertible<OtherIterator, Iterator>::type* = 0)
|
||||||
};
|
: super_t(r.base()) {}
|
||||||
|
|
||||||
// This macro definition is only temporary in this file
|
private:
|
||||||
|
typename super_t::reference dereference() const { return *boost::prior(this->base()); }
|
||||||
|
|
||||||
|
void increment() { super_t::decrement(); }
|
||||||
|
void decrement() { super_t::increment(); }
|
||||||
|
|
||||||
|
void advance(typename super_t::difference_type n)
|
||||||
|
{
|
||||||
|
super_t::advance(-n);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OtherIterator>
|
||||||
|
typename super_t::difference_type
|
||||||
|
distance_to(reverse_iterator<OtherIterator> const& y) const
|
||||||
|
{
|
||||||
|
return -super_t::distance_to(y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO fix category
|
||||||
|
//
|
||||||
|
template <class AdaptableUnaryFunction, class Iterator>
|
||||||
|
class transform_iterator :
|
||||||
|
public iterator_adaptor< transform_iterator<AdaptableUnaryFunction, Iterator>,
|
||||||
|
Iterator,
|
||||||
|
typename AdaptableUnaryFunction::result_type,
|
||||||
|
typename AdaptableUnaryFunction::result_type,
|
||||||
|
typename AdaptableUnaryFunction::result_type*
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef iterator_adaptor< transform_iterator<AdaptableUnaryFunction, Iterator>,
|
||||||
|
Iterator,
|
||||||
|
typename AdaptableUnaryFunction::result_type,
|
||||||
|
typename AdaptableUnaryFunction::result_type,
|
||||||
|
typename AdaptableUnaryFunction::result_type* > super_t;
|
||||||
|
|
||||||
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
public:
|
||||||
|
transform_iterator() { }
|
||||||
|
|
||||||
|
transform_iterator(Iterator const& x,
|
||||||
|
AdaptableUnaryFunction f)
|
||||||
|
: super_t(x), m_f(f) { }
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
transform_iterator(transform_iterator<AdaptableUnaryFunction, OtherIterator> const& t,
|
||||||
|
typename enable_if_convertible<OtherIterator, Iterator>::type* = 0)
|
||||||
|
: super_t(t.base()), m_f(t.functor()) {}
|
||||||
|
|
||||||
|
AdaptableUnaryFunction functor() const { return m_f; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
typename super_t::value_type dereference() const { return m_f(super_t::dereference()); }
|
||||||
|
|
||||||
|
AdaptableUnaryFunction m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This macro definition is only temporary in this file
|
||||||
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
||||||
# define BOOST_ARG_DEPENDENT_TYPENAME typename
|
# define BOOST_ARG_DEPENDENT_TYPENAME typename
|
||||||
# else
|
# else
|
||||||
# define BOOST_ARG_DEPENDENT_TYPENAME
|
# define BOOST_ARG_DEPENDENT_TYPENAME
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
namespace detail
|
struct unspecified {};
|
||||||
{
|
|
||||||
//
|
|
||||||
// Detection for whether a type has a nested `element_type'
|
|
||||||
// typedef. Used to detect smart pointers. We're having trouble
|
|
||||||
// auto-detecting smart pointers with gcc-2.95 via the nested
|
|
||||||
// element_type member. However, we really ought to have a
|
|
||||||
// specializable is_pointer template which can be used instead with
|
|
||||||
// something like boost/python/pointee.hpp to find the value_type.
|
|
||||||
//
|
|
||||||
namespace aux
|
|
||||||
{
|
|
||||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
namespace detail
|
||||||
struct has_element_type
|
{
|
||||||
|
//
|
||||||
|
// Detection for whether a type has a nested `element_type'
|
||||||
|
// typedef. Used to detect smart pointers. We're having trouble
|
||||||
|
// auto-detecting smart pointers with gcc-2.95 via the nested
|
||||||
|
// element_type member. However, we really ought to have a
|
||||||
|
// specializable is_pointer template which can be used instead with
|
||||||
|
// something like boost/python/pointee.hpp to find the value_type.
|
||||||
|
//
|
||||||
|
namespace aux
|
||||||
|
{
|
||||||
|
BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct has_element_type
|
||||||
: mpl::if_<
|
: mpl::if_<
|
||||||
is_class<T>
|
is_class<T>
|
||||||
# if __GNUC__ == 2 // gcc 2.95 doesn't seem to be able to detect element_type without barfing
|
# if __GNUC__ == 2 // gcc 2.95 doesn't seem to be able to detect element_type without barfing
|
||||||
, mpl::bool_c<false>
|
, mpl::bool_c<false>
|
||||||
# else
|
# else
|
||||||
, aux::has_element_type<T>
|
, aux::has_element_type<T>
|
||||||
# endif
|
# endif
|
||||||
, mpl::bool_c<false>
|
, mpl::bool_c<false>
|
||||||
>::type
|
>::type
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
// Metafunction returning the nested element_type typedef
|
// Metafunction returning the nested element_type typedef
|
||||||
template <class T>
|
template <class T>
|
||||||
struct smart_pointer_traits
|
struct smart_pointer_traits
|
||||||
{
|
{
|
||||||
typedef typename remove_const<
|
typedef typename remove_const<
|
||||||
typename T::element_type
|
typename T::element_type
|
||||||
>::type value_type;
|
>::type value_type;
|
||||||
|
|
||||||
typedef typename T::element_type& reference;
|
typedef typename T::element_type& reference;
|
||||||
typedef typename T::element_type* pointer;
|
typedef typename T::element_type* pointer;
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the Value parameter is unspecified, we use this metafunction
|
// If the Value parameter is unspecified, we use this metafunction
|
||||||
// to deduce the default types
|
// to deduce the default types
|
||||||
template <class Iter>
|
template <class Iter>
|
||||||
struct indirect_defaults
|
struct indirect_defaults
|
||||||
: mpl::if_c<
|
: mpl::if_c<
|
||||||
has_element_type<typename iterator_traits<Iter>::value_type>::value
|
has_element_type<typename iterator_traits<Iter>::value_type>::value
|
||||||
, smart_pointer_traits<typename iterator_traits<Iter>::value_type>
|
, smart_pointer_traits<typename iterator_traits<Iter>::value_type>
|
||||||
, iterator_traits<typename iterator_traits<Iter>::value_type>
|
, iterator_traits<typename iterator_traits<Iter>::value_type>
|
||||||
>::type
|
>::type
|
||||||
{
|
{
|
||||||
typedef typename iterator_traits<Iter>::iterator_category iterator_category;
|
typedef typename iterator_traits<Iter>::iterator_category iterator_category;
|
||||||
typedef typename iterator_traits<Iter>::difference_type difference_type;
|
typedef typename iterator_traits<Iter>::difference_type difference_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Base, class Traits>
|
template <class Base, class Traits>
|
||||||
struct indirect_traits
|
struct indirect_traits
|
||||||
: mpl::if_<is_same<Traits,unspecified>, indirect_defaults<Base>, Traits>::type
|
: mpl::if_<is_same<Traits,unspecified>, indirect_defaults<Base>, Traits>::type
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <class Base, class Traits = unspecified>
|
template <class Iterator, class Traits = unspecified>
|
||||||
struct indirect_iterator
|
class indirect_iterator :
|
||||||
: iterator_adaptor<
|
public iterator_adaptor< indirect_iterator<Iterator, Traits>,
|
||||||
indirect_iterator<Base,Traits>
|
Iterator,
|
||||||
, typename detail::indirect_traits<Base,Traits>::value_type
|
typename detail::indirect_traits<Iterator, Traits>::value_type,
|
||||||
, typename detail::indirect_traits<Base,Traits>::reference
|
typename detail::indirect_traits<Iterator, Traits>::reference,
|
||||||
, typename detail::indirect_traits<Base,Traits>::pointer
|
typename detail::indirect_traits<Iterator, Traits>::pointer,
|
||||||
, typename detail::indirect_traits<Base,Traits>::iterator_category
|
typename detail::indirect_traits<Iterator, Traits>::iterator_category,
|
||||||
, typename detail::indirect_traits<Base,Traits>::difference_type
|
typename detail::indirect_traits<Iterator, Traits>::difference_type >
|
||||||
>
|
{
|
||||||
{
|
typedef iterator_adaptor< indirect_iterator<Iterator, Traits>,
|
||||||
|
Iterator,
|
||||||
|
typename detail::indirect_traits<Iterator, Traits>::value_type,
|
||||||
|
typename detail::indirect_traits<Iterator, Traits>::reference,
|
||||||
|
typename detail::indirect_traits<Iterator, Traits>::pointer,
|
||||||
|
typename detail::indirect_traits<Iterator, Traits>::iterator_category,
|
||||||
|
typename detail::indirect_traits<Iterator, Traits>::difference_type > super_t;
|
||||||
|
|
||||||
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
public:
|
||||||
indirect_iterator() {}
|
indirect_iterator() {}
|
||||||
|
|
||||||
typename detail::indirect_traits<Base,Traits>::reference
|
indirect_iterator(Iterator iter)
|
||||||
dereference() const { return **this->m_base; }
|
: super_t(iter) {}
|
||||||
|
|
||||||
indirect_iterator(Base iter)
|
template <class OtherIterator,
|
||||||
: m_base(iter) {}
|
class OtherTraits>
|
||||||
|
indirect_iterator(indirect_iterator<OtherIterator, OtherTraits> const& y,
|
||||||
|
typename enable_if_convertible<OtherIterator, Iterator>::type* = 0)
|
||||||
|
: super_t(y.base()) {}
|
||||||
|
|
||||||
template <class Base2, class Traits2>
|
private:
|
||||||
indirect_iterator(const indirect_iterator<Base2,Traits2>& y)
|
typename super_t::reference dereference() const { return **this->base(); }
|
||||||
: m_base(y.base())
|
|
||||||
{}
|
|
||||||
|
|
||||||
Base& base() { return m_base; }
|
};
|
||||||
Base const& base() const { return m_base; }
|
|
||||||
private:
|
|
||||||
Base m_base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Iter>
|
template <class Iter>
|
||||||
indirect_iterator<Iter> make_indirect_iterator(Iter x)
|
inline
|
||||||
{
|
indirect_iterator<Iter> make_indirect_iterator(Iter x)
|
||||||
|
{
|
||||||
return indirect_iterator<Iter>(x);
|
return indirect_iterator<Iter>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Traits, class Iter>
|
template <class Traits, class Iter>
|
||||||
indirect_iterator<Iter,Traits> make_indirect_iterator(Iter x, Traits* = 0)
|
inline
|
||||||
{
|
indirect_iterator<Iter,Traits> make_indirect_iterator(Iter x, Traits* = 0)
|
||||||
return indirect_iterator<Iter,Traits>(x);
|
{
|
||||||
}
|
return indirect_iterator<Iter, Traits>(x);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user