Pass traits around instead of individual associated types.

[SVN r852]
This commit is contained in:
Dave Abrahams
2003-01-13 16:50:48 +00:00
parent dd9e6c3f57
commit 05afa8467c
+163 -137
View File
@@ -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;