mirror of
https://github.com/boostorg/iterator.git
synced 2026-05-05 12:24:09 +02:00
Pass traits around instead of individual associated types.
[SVN r852]
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <boost/mpl/aux_/has_xxx.hpp>
|
#include <boost/mpl/aux_/has_xxx.hpp>
|
||||||
#include <boost/mpl/logical/or.hpp>
|
#include <boost/mpl/logical/or.hpp>
|
||||||
|
#include <boost/mpl/logical/and.hpp>
|
||||||
#include <boost/mpl/identity.hpp>
|
#include <boost/mpl/identity.hpp>
|
||||||
|
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/is_same.hpp>
|
||||||
@@ -52,10 +53,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost
|
||||||
|
{
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
//
|
//
|
||||||
// Base machinery for all kinds of enable if
|
// Base machinery for all kinds of enable if
|
||||||
//
|
//
|
||||||
@@ -152,6 +154,30 @@ namespace boost {
|
|||||||
//
|
//
|
||||||
struct enable_type;
|
struct enable_type;
|
||||||
|
|
||||||
|
// traits_iterator<It> has two important properties:
|
||||||
|
//
|
||||||
|
// 1. It is derived from boost::iterator<...>, which is
|
||||||
|
// important for standard library interoperability of
|
||||||
|
// iterator types on some (broken) implementations.
|
||||||
|
//
|
||||||
|
// 2. The associated types are taken from iterator_traits<It>.
|
||||||
|
//
|
||||||
|
// It might arguably be better to arrange for
|
||||||
|
// boost::detail::iterator_traits<It> to be derived from
|
||||||
|
// boost::iterator<...>, then we could use
|
||||||
|
// boost::detail::iterator_traits directly.
|
||||||
|
template <class Iterator>
|
||||||
|
struct traits_iterator
|
||||||
|
: iterator<
|
||||||
|
typename iterator_traits<Iterator>::iterator_category
|
||||||
|
, typename iterator_traits<Iterator>::value_type
|
||||||
|
, typename iterator_traits<Iterator>::difference_type
|
||||||
|
, typename iterator_traits<Iterator>::pointer
|
||||||
|
, typename iterator_traits<Iterator>::reference
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -256,41 +282,37 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
return f1.distance_to(f2);
|
return f1.distance_to(f2);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Derived,
|
namespace detail
|
||||||
class V,
|
|
||||||
class R,
|
|
||||||
class P,
|
|
||||||
class C,
|
|
||||||
class D>
|
|
||||||
class repository :
|
|
||||||
public iterator<C, V, D, P, R>
|
|
||||||
{
|
{
|
||||||
public:
|
struct empty_base {};
|
||||||
typedef Derived derived_t;
|
}
|
||||||
|
|
||||||
|
// Encapsulates the "Curiously Recursive Template" pattern.
|
||||||
|
// Derived should be a class derived from this instantiation, and
|
||||||
|
// Base will be inserted as a base class.
|
||||||
|
template <class Derived, class Base = detail::empty_base>
|
||||||
|
class downcastable
|
||||||
|
: public Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Derived derived_t;
|
||||||
|
|
||||||
|
Derived& derived()
|
||||||
|
{
|
||||||
|
return static_cast<Derived&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Derived const& derived() const
|
||||||
|
{
|
||||||
|
return static_cast<Derived const&>(*this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Base>
|
template <class Base>
|
||||||
class downcastable :
|
class iterator_comparisons
|
||||||
public Base
|
: 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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Base>
|
|
||||||
class iterator_comparisons :
|
|
||||||
public Base
|
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -496,9 +518,11 @@ namespace boost {
|
|||||||
template <class Base1,
|
template <class Base1,
|
||||||
class Base2>
|
class Base2>
|
||||||
inline
|
inline
|
||||||
typename detail::enable_if_interoperable<typename Base1::derived_t,
|
typename detail::enable_if_interoperable<
|
||||||
typename Base2::derived_t,
|
typename Base1::derived_t
|
||||||
typename Base1::difference_type>::type
|
, typename Base2::derived_t
|
||||||
|
, typename Base1::difference_type
|
||||||
|
>::type
|
||||||
operator-(iterator_arith<Base1> const& lhs,
|
operator-(iterator_arith<Base1> const& lhs,
|
||||||
iterator_arith<Base2> const& rhs)
|
iterator_arith<Base2> const& rhs)
|
||||||
{
|
{
|
||||||
@@ -514,33 +538,27 @@ namespace boost {
|
|||||||
lhs.derived());
|
lhs.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Derived,
|
template <
|
||||||
class V,
|
class Derived
|
||||||
class R,
|
, class Traits
|
||||||
class P,
|
, class Super = iterator_arith<
|
||||||
class C,
|
iterator_comparisons<
|
||||||
class D,
|
downcastable<Derived, Traits> > >
|
||||||
// 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 :
|
class iterator_facade
|
||||||
public Super
|
: public Super
|
||||||
{
|
{
|
||||||
typedef Super super_t;
|
typedef Super super_t;
|
||||||
|
public:
|
||||||
public:
|
|
||||||
typedef typename super_t::reference reference;
|
typedef typename super_t::reference reference;
|
||||||
typedef typename super_t::difference_type difference_type;
|
typedef typename super_t::difference_type difference_type;
|
||||||
|
typedef typename super_t::pointer pointer;
|
||||||
|
|
||||||
reference operator*() const
|
reference operator*() const
|
||||||
{ return iterator_core_access::dereference(this->derived()); }
|
{ return iterator_core_access::dereference(this->derived()); }
|
||||||
|
|
||||||
// Needs eventual help for input iterators
|
// Needs eventual help for input iterators
|
||||||
P operator->() const { return &iterator_core_access::dereference(this->derived()); }
|
pointer operator->() const { return &iterator_core_access::dereference(this->derived()); }
|
||||||
|
|
||||||
reference operator[](difference_type n) const
|
reference operator[](difference_type n) const
|
||||||
{ return *(*this + n); }
|
{ return *(*this + n); }
|
||||||
@@ -567,24 +585,34 @@ namespace boost {
|
|||||||
{ Derived result(this->derived()); return result -= x; }
|
{ Derived result(this->derived()); return result -= x; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <class Traits, class Other>
|
||||||
|
struct same_category_and_difference
|
||||||
|
: mpl::logical_and<
|
||||||
|
is_same<
|
||||||
|
typename Traits::iterator_category
|
||||||
|
, typename Other::iterator_category
|
||||||
|
>
|
||||||
|
, is_same<
|
||||||
|
typename Traits::iterator_category
|
||||||
|
, typename Other::iterator_category
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// TODO Handle default arguments the same way as
|
// TODO Handle default arguments the same way as
|
||||||
// in former ia lib
|
// in former ia lib
|
||||||
//
|
//
|
||||||
template <class Derived,
|
template <
|
||||||
class Iterator,
|
class Derived
|
||||||
class Value = typename detail::iterator_traits<Iterator>::value_type,
|
, class Iterator
|
||||||
class Reference = typename detail::iterator_traits<Iterator>::reference,
|
, class Traits = detail::traits_iterator<Iterator>
|
||||||
class Pointer = typename detail::iterator_traits<Iterator>::pointer,
|
>
|
||||||
class Category = typename detail::iterator_traits<Iterator>::iterator_category,
|
class iterator_adaptor
|
||||||
class Distance = typename detail::iterator_traits<Iterator>::difference_type>
|
: public iterator_facade<Derived,Traits>
|
||||||
class iterator_adaptor :
|
|
||||||
public iterator_facade<Derived,
|
|
||||||
Value,
|
|
||||||
Reference,
|
|
||||||
Pointer,
|
|
||||||
Category,
|
|
||||||
Distance>
|
|
||||||
{
|
{
|
||||||
friend class iterator_core_access;
|
friend class iterator_core_access;
|
||||||
|
|
||||||
@@ -601,50 +629,39 @@ namespace boost {
|
|||||||
protected:
|
protected:
|
||||||
// Core iterator interface for iterator_facade
|
// Core iterator interface for iterator_facade
|
||||||
//
|
//
|
||||||
Reference dereference() const { return *m_iterator; }
|
typename Traits::reference dereference() const { return *m_iterator; }
|
||||||
|
|
||||||
template <class OtherDerived,
|
template <
|
||||||
class OtherIterator,
|
class OtherDerived, class OtherIterator, class OtherTraits
|
||||||
class OtherValue,
|
>
|
||||||
class OtherReference,
|
bool equal(iterator_adaptor<OtherDerived,OtherIterator,OtherTraits> const& x) const
|
||||||
class OtherPointer >
|
|
||||||
bool equal(iterator_adaptor<OtherDerived,
|
|
||||||
OtherIterator,
|
|
||||||
OtherValue,
|
|
||||||
OtherReference,
|
|
||||||
OtherPointer,
|
|
||||||
Category,
|
|
||||||
Distance> const& x) const
|
|
||||||
{
|
{
|
||||||
return m_iterator == x.base();
|
BOOST_STATIC_ASSERT(
|
||||||
|
(detail::same_category_and_difference<Traits,OtherTraits>::value)
|
||||||
|
);
|
||||||
|
return m_iterator == x.base();
|
||||||
}
|
}
|
||||||
|
|
||||||
void advance(Distance n)
|
void advance(typename Traits::difference_type n)
|
||||||
{
|
{
|
||||||
m_iterator += n;
|
m_iterator += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void increment() { ++m_iterator; }
|
void increment() { ++m_iterator; }
|
||||||
void decrement() { --m_iterator; }
|
void decrement() { --m_iterator; }
|
||||||
|
|
||||||
template <class OtherDerived,
|
template <class OtherDerived, class OtherIterator, class OtherTraits>
|
||||||
class OtherIterator,
|
typename Traits::difference_type distance_to(
|
||||||
class OtherValue,
|
iterator_adaptor<OtherDerived, OtherIterator, OtherTraits> const& y) const
|
||||||
class OtherReference,
|
|
||||||
class OtherPointer >
|
|
||||||
Distance distance_to(iterator_adaptor<OtherDerived,
|
|
||||||
OtherIterator,
|
|
||||||
OtherValue,
|
|
||||||
OtherReference,
|
|
||||||
OtherPointer,
|
|
||||||
Category,
|
|
||||||
Distance> const& y) const
|
|
||||||
{
|
{
|
||||||
return y.base() - m_iterator;
|
BOOST_STATIC_ASSERT(
|
||||||
|
(detail::same_category_and_difference<Traits,OtherTraits>::value)
|
||||||
|
);
|
||||||
|
return y.base() - m_iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private: // data members
|
||||||
Iterator m_iterator;
|
Iterator m_iterator;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -699,23 +716,35 @@ namespace boost {
|
|||||||
return reverse_iterator<BidirectionalIterator>(x);
|
return reverse_iterator<BidirectionalIterator>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Given the transform iterator's transformation and iterator, this
|
||||||
|
// is the type used as its traits.
|
||||||
|
template <class AdaptableUnaryFunction, class Iterator>
|
||||||
|
struct transform_iterator_traits
|
||||||
|
: iterator<
|
||||||
|
typename detail::iterator_traits<Iterator>::iterator_category
|
||||||
|
, typename AdaptableUnaryFunction::result_type
|
||||||
|
, typename detail::iterator_traits<Iterator>::difference_type
|
||||||
|
, typename AdaptableUnaryFunction::result_type*
|
||||||
|
, typename AdaptableUnaryFunction::result_type
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
//
|
//
|
||||||
// TODO fix category
|
// TODO fix category
|
||||||
//
|
//
|
||||||
template <class AdaptableUnaryFunction, class Iterator>
|
template <class AdaptableUnaryFunction, class Iterator>
|
||||||
class transform_iterator :
|
class transform_iterator
|
||||||
public iterator_adaptor< transform_iterator<AdaptableUnaryFunction, Iterator>,
|
: public iterator_adaptor<
|
||||||
Iterator,
|
transform_iterator<AdaptableUnaryFunction, Iterator>
|
||||||
typename AdaptableUnaryFunction::result_type,
|
, Iterator
|
||||||
typename AdaptableUnaryFunction::result_type,
|
, transform_iterator_traits<AdaptableUnaryFunction,Iterator>
|
||||||
typename AdaptableUnaryFunction::result_type*
|
>
|
||||||
>
|
|
||||||
{
|
{
|
||||||
typedef iterator_adaptor< transform_iterator<AdaptableUnaryFunction, Iterator>,
|
typedef iterator_adaptor<
|
||||||
Iterator,
|
transform_iterator<AdaptableUnaryFunction, Iterator>
|
||||||
typename AdaptableUnaryFunction::result_type,
|
, Iterator
|
||||||
typename AdaptableUnaryFunction::result_type,
|
, transform_iterator_traits<AdaptableUnaryFunction,Iterator>
|
||||||
typename AdaptableUnaryFunction::result_type* > super_t;
|
> super_t;
|
||||||
|
|
||||||
friend class iterator_core_access;
|
friend class iterator_core_access;
|
||||||
|
|
||||||
@@ -816,30 +845,34 @@ namespace boost {
|
|||||||
typedef typename iterator_traits<Iter>::difference_type difference_type;
|
typedef typename iterator_traits<Iter>::difference_type difference_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The traits to use for indirect iterator, by default. Whatever
|
||||||
|
// is supplied gets passed through traits_iterator<...> so that it
|
||||||
|
// is ultimately derived from boost::iterator<...>
|
||||||
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
|
: traits_iterator<
|
||||||
|
typename mpl::if_<
|
||||||
|
is_same<Traits,unspecified>
|
||||||
|
, indirect_defaults<Base>
|
||||||
|
, Traits
|
||||||
|
>::type
|
||||||
|
>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <class Iterator, class Traits = unspecified>
|
template <class Iterator, class Traits = unspecified>
|
||||||
class indirect_iterator :
|
class indirect_iterator :
|
||||||
public iterator_adaptor< indirect_iterator<Iterator, Traits>,
|
public iterator_adaptor<
|
||||||
Iterator,
|
indirect_iterator<Iterator, Traits>
|
||||||
typename detail::indirect_traits<Iterator, Traits>::value_type,
|
, Iterator
|
||||||
typename detail::indirect_traits<Iterator, Traits>::reference,
|
, detail::indirect_traits<Iterator,Traits> >
|
||||||
typename detail::indirect_traits<Iterator, Traits>::pointer,
|
|
||||||
typename detail::indirect_traits<Iterator, Traits>::iterator_category,
|
|
||||||
typename detail::indirect_traits<Iterator, Traits>::difference_type >
|
|
||||||
{
|
{
|
||||||
typedef iterator_adaptor< indirect_iterator<Iterator, Traits>,
|
typedef iterator_adaptor<
|
||||||
Iterator,
|
indirect_iterator<Iterator, Traits>
|
||||||
typename detail::indirect_traits<Iterator, Traits>::value_type,
|
, Iterator
|
||||||
typename detail::indirect_traits<Iterator, Traits>::reference,
|
, detail::indirect_traits<Iterator,Traits>
|
||||||
typename detail::indirect_traits<Iterator, Traits>::pointer,
|
> super_t;
|
||||||
typename detail::indirect_traits<Iterator, Traits>::iterator_category,
|
|
||||||
typename detail::indirect_traits<Iterator, Traits>::difference_type > super_t;
|
|
||||||
|
|
||||||
friend class iterator_core_access;
|
friend class iterator_core_access;
|
||||||
|
|
||||||
@@ -892,21 +925,14 @@ namespace boost {
|
|||||||
template <class Predicate, class Iterator>
|
template <class Predicate, class Iterator>
|
||||||
class filter_iterator
|
class filter_iterator
|
||||||
: public iterator_adaptor<
|
: public iterator_adaptor<
|
||||||
filter_iterator<Predicate, Iterator>, Iterator,
|
filter_iterator<Predicate, Iterator>, Iterator
|
||||||
typename filter_iterator_traits<Iterator>::value_type,
|
, detail::traits_iterator<filter_iterator_traits<Iterator> >
|
||||||
typename filter_iterator_traits<Iterator>::reference,
|
|
||||||
typename filter_iterator_traits<Iterator>::pointer,
|
|
||||||
typename filter_iterator_traits<Iterator>::iterator_category,
|
|
||||||
typename filter_iterator_traits<Iterator>::difference_type
|
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
typedef iterator_adaptor<
|
typedef iterator_adaptor<
|
||||||
filter_iterator<Predicate, Iterator>, Iterator,
|
filter_iterator<Predicate, Iterator>, Iterator
|
||||||
typename filter_iterator_traits<Iterator>::value_type,
|
, detail::traits_iterator<filter_iterator_traits<Iterator> >
|
||||||
typename filter_iterator_traits<Iterator>::reference,
|
> super_t;
|
||||||
typename filter_iterator_traits<Iterator>::pointer,
|
|
||||||
typename filter_iterator_traits<Iterator>::iterator_category,
|
|
||||||
typename filter_iterator_traits<Iterator>::difference_type > super_t;
|
|
||||||
|
|
||||||
friend class iterator_core_access;
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user