New minimal friend interface.

[SVN r703]
This commit is contained in:
Thomas Witt
2002-11-22 08:05:44 +00:00
parent b412e85c2c
commit 8f98c66857

View File

@@ -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