mirror of
https://github.com/boostorg/iterator.git
synced 2025-07-20 08:02:10 +02:00
Move from boost-sanbox [ JDG ]
[SVN r18958]
This commit is contained in:
193
include/boost/iterator/counting_iterator.hpp
Normal file
193
include/boost/iterator/counting_iterator.hpp
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
// Copyright David Abrahams 2003. Permission to copy, use,
|
||||||
|
// modify, sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
#ifndef COUNTING_ITERATOR_DWA200348_HPP
|
||||||
|
# define COUNTING_ITERATOR_DWA200348_HPP
|
||||||
|
|
||||||
|
# include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
# include <boost/detail/numeric_traits.hpp>
|
||||||
|
# include <boost/mpl/bool.hpp>
|
||||||
|
# include <boost/mpl/if.hpp>
|
||||||
|
# include <boost/mpl/identity.hpp>
|
||||||
|
# include <boost/mpl/apply_if.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template <class Incrementable, class Category, class Difference> class counting_iterator;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
// Try to detect numeric types at compile time in ways compatible
|
||||||
|
// with the limitations of the compiler and library.
|
||||||
|
template <class T>
|
||||||
|
struct is_numeric_impl
|
||||||
|
{
|
||||||
|
// For a while, this wasn't true, but we rely on it below. This is a regression assert.
|
||||||
|
BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
|
||||||
|
|
||||||
|
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||||
|
|
||||||
|
# if defined(BOOST_HAS_LONG_LONG)
|
||||||
|
BOOST_STATIC_CONSTANT(
|
||||||
|
bool, value = (
|
||||||
|
std::numeric_limits<T>::is_specialized
|
||||||
|
| boost::is_same<T,long long>::value
|
||||||
|
| boost::is_same<T,unsigned long long>::value
|
||||||
|
));
|
||||||
|
# else
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
# if !defined(__BORLANDC__)
|
||||||
|
BOOST_STATIC_CONSTANT(
|
||||||
|
bool, value = (
|
||||||
|
boost::is_convertible<int,T>::value
|
||||||
|
&& boost::is_convertible<T,int>::value
|
||||||
|
));
|
||||||
|
# else
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct is_numeric
|
||||||
|
: mpl::bool_<(::boost::detail::is_numeric_impl<T>::value)>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct numeric_difference
|
||||||
|
{
|
||||||
|
typedef typename boost::detail::numeric_traits<T>::difference_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(is_numeric<int>::value);
|
||||||
|
template <class Incrementable, class Category, class Difference>
|
||||||
|
struct counting_iterator_base
|
||||||
|
{
|
||||||
|
typedef typename mpl::apply_if<
|
||||||
|
is_same<Category, use_default>
|
||||||
|
, mpl::apply_if<
|
||||||
|
is_numeric<Incrementable>
|
||||||
|
, mpl::identity<std::random_access_iterator_tag>
|
||||||
|
, BOOST_ITERATOR_CATEGORY<Incrementable>
|
||||||
|
>
|
||||||
|
, mpl::identity<Category>
|
||||||
|
>::type category;
|
||||||
|
|
||||||
|
typedef typename mpl::apply_if<
|
||||||
|
is_same<Difference, use_default>
|
||||||
|
, mpl::apply_if<
|
||||||
|
is_numeric<Incrementable>
|
||||||
|
, numeric_difference<Incrementable>
|
||||||
|
, iterator_difference<Incrementable>
|
||||||
|
>
|
||||||
|
, mpl::identity<Difference>
|
||||||
|
>::type difference;
|
||||||
|
|
||||||
|
typedef iterator_adaptor<
|
||||||
|
counting_iterator<Incrementable, Category, Difference> // self
|
||||||
|
, Incrementable // Base
|
||||||
|
, Incrementable // value_type
|
||||||
|
, category
|
||||||
|
, Incrementable const& // reference
|
||||||
|
, difference
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Template class distance_policy_select -- choose a policy for computing the
|
||||||
|
// distance between counting_iterators at compile-time based on whether or not
|
||||||
|
// the iterator wraps an integer or an iterator, using "poor man's partial
|
||||||
|
// specialization".
|
||||||
|
|
||||||
|
template <bool is_integer> struct distance_policy_select;
|
||||||
|
|
||||||
|
// A policy for wrapped iterators
|
||||||
|
template <class Difference, class Incrementable1, class Incrementable2>
|
||||||
|
struct iterator_distance
|
||||||
|
{
|
||||||
|
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||||
|
{
|
||||||
|
return boost::detail::distance(x, y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// A policy for wrapped numbers
|
||||||
|
template <class Difference, class Incrementable1, class Incrementable2>
|
||||||
|
struct number_distance
|
||||||
|
{
|
||||||
|
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||||
|
{
|
||||||
|
return numeric_distance(x, y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Incrementable, class Category = use_default, class Difference = use_default>
|
||||||
|
class counting_iterator
|
||||||
|
: public detail::counting_iterator_base<Incrementable, Category, Difference>::type
|
||||||
|
{
|
||||||
|
typedef typename detail::counting_iterator_base<Incrementable, Category, Difference>::type super_t;
|
||||||
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename super_t::difference_type difference_type;
|
||||||
|
|
||||||
|
counting_iterator() { }
|
||||||
|
|
||||||
|
counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {}
|
||||||
|
|
||||||
|
counting_iterator(Incrementable x)
|
||||||
|
: super_t(x)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
# if 0
|
||||||
|
template<class OtherIncrementable>
|
||||||
|
counting_iterator(
|
||||||
|
counting_iterator<OtherIncrementable> const& t
|
||||||
|
, typename enable_if_convertible<OtherIncrementable, Incrementable>::type* = 0
|
||||||
|
)
|
||||||
|
: super_t(t.base())
|
||||||
|
{}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
typename super_t::reference dereference() const
|
||||||
|
{
|
||||||
|
return this->base_reference();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OtherIncrementable>
|
||||||
|
difference_type
|
||||||
|
distance_to(counting_iterator<OtherIncrementable> const& y) const
|
||||||
|
{
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
detail::is_numeric<Incrementable>
|
||||||
|
, detail::number_distance<difference_type, Incrementable, OtherIncrementable>
|
||||||
|
, detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
|
||||||
|
>::type d;
|
||||||
|
|
||||||
|
return d::distance(this->base(), y.base());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Manufacture a counting iterator for an arbitrary incrementable type
|
||||||
|
template <class Incrementable>
|
||||||
|
inline counting_iterator<Incrementable>
|
||||||
|
make_counting_iterator(Incrementable x)
|
||||||
|
{
|
||||||
|
typedef counting_iterator<Incrementable> result_t;
|
||||||
|
return result_t(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace boost::iterator
|
||||||
|
|
||||||
|
#endif // COUNTING_ITERATOR_DWA200348_HPP
|
109
include/boost/iterator/filter_iterator.hpp
Normal file
109
include/boost/iterator/filter_iterator.hpp
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// (C) Copyright David Abrahams 2002.
|
||||||
|
// (C) Copyright Jeremy Siek 2002.
|
||||||
|
// (C) Copyright Thomas Witt 2002.
|
||||||
|
// Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
#ifndef BOOST_FILTER_ITERATOR_23022003THW_HPP
|
||||||
|
#define BOOST_FILTER_ITERATOR_23022003THW_HPP
|
||||||
|
|
||||||
|
#include <boost/iterator.hpp>
|
||||||
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <class Iterator>
|
||||||
|
struct filter_iterator_category
|
||||||
|
{
|
||||||
|
typedef iterator_tag<
|
||||||
|
typename access_category<Iterator>::type
|
||||||
|
, typename minimum_category<
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
, typename traversal_category<Iterator>::type
|
||||||
|
>::type
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <class Predicate, class Iterator>
|
||||||
|
class filter_iterator
|
||||||
|
: public iterator_adaptor<
|
||||||
|
filter_iterator<Predicate, Iterator>, Iterator
|
||||||
|
, use_default
|
||||||
|
, typename detail::filter_iterator_category<Iterator>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef iterator_adaptor<
|
||||||
|
filter_iterator<Predicate, Iterator>, Iterator
|
||||||
|
, use_default
|
||||||
|
, typename detail::filter_iterator_category<Iterator>::type
|
||||||
|
> super_t;
|
||||||
|
|
||||||
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
public:
|
||||||
|
filter_iterator() { }
|
||||||
|
|
||||||
|
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
|
||||||
|
: super_t(x), m_predicate(f), m_end(end)
|
||||||
|
{
|
||||||
|
satisfy_predicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
filter_iterator(Iterator x, Iterator end = Iterator())
|
||||||
|
: super_t(x), m_predicate(), m_end(end)
|
||||||
|
{
|
||||||
|
satisfy_predicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
filter_iterator(
|
||||||
|
filter_iterator<Predicate, OtherIterator> const& t
|
||||||
|
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||||
|
)
|
||||||
|
: super_t(t.base()), m_predicate(t.predicate()), m_end(t.end()) {}
|
||||||
|
|
||||||
|
Predicate predicate() const { return m_predicate; }
|
||||||
|
|
||||||
|
Iterator end() const { return m_end; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
++(this->base_reference());
|
||||||
|
satisfy_predicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void decrement()
|
||||||
|
{
|
||||||
|
while(!this->m_predicate(*--(this->base_reference()))){};
|
||||||
|
}
|
||||||
|
|
||||||
|
void satisfy_predicate()
|
||||||
|
{
|
||||||
|
while (this->base() != this->m_end && !this->m_predicate(*this->base()))
|
||||||
|
++(this->base_reference());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Probably should be the initial base class so it can be
|
||||||
|
// optimized away via EBO if it is an empty class.
|
||||||
|
Predicate m_predicate;
|
||||||
|
Iterator m_end;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Predicate, class Iterator>
|
||||||
|
filter_iterator<Predicate,Iterator>
|
||||||
|
make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
|
||||||
|
{
|
||||||
|
return filter_iterator<Predicate,Iterator>(f,x,end);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_FILTER_ITERATOR_23022003THW_HPP
|
220
include/boost/iterator/indirect_iterator.hpp
Normal file
220
include/boost/iterator/indirect_iterator.hpp
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
// (C) Copyright David Abrahams 2002.
|
||||||
|
// (C) Copyright Jeremy Siek 2002.
|
||||||
|
// (C) Copyright Thomas Witt 2002.
|
||||||
|
// Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
#ifndef BOOST_INDIRECT_ITERATOR_23022003THW_HPP
|
||||||
|
#define BOOST_INDIRECT_ITERATOR_23022003THW_HPP
|
||||||
|
|
||||||
|
#include <boost/iterator.hpp>
|
||||||
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
|
||||||
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
|
|
||||||
|
#include <boost/python/detail/indirect_traits.hpp>
|
||||||
|
#include <boost/mpl/not.hpp>
|
||||||
|
#include <boost/mpl/aux_/has_xxx.hpp>
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_MPL_AUX_HAS_XXX
|
||||||
|
# include <boost/shared_ptr.hpp>
|
||||||
|
# include <boost/scoped_ptr.hpp>
|
||||||
|
# include <boost/mpl/bool.hpp>
|
||||||
|
# include <memory>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_def.hpp> // must be last #include
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template <class Iter, class Value, class Category, class Reference, class Difference>
|
||||||
|
struct indirect_iterator;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct unspecified {};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detection for whether a type has a nested `element_type'
|
||||||
|
// typedef. Used to detect smart pointers. For compilers not
|
||||||
|
// supporting mpl's has_xxx, we supply specializations. 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.
|
||||||
|
//
|
||||||
|
# ifndef BOOST_NO_MPL_AUX_HAS_XXX
|
||||||
|
namespace aux
|
||||||
|
{
|
||||||
|
BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct has_element_type
|
||||||
|
: mpl::bool_<
|
||||||
|
mpl::if_<
|
||||||
|
is_class<T>
|
||||||
|
, ::boost::detail::aux::has_element_type<T>
|
||||||
|
, mpl::false_
|
||||||
|
>::type::value
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
# else
|
||||||
|
template <class T>
|
||||||
|
struct has_element_type
|
||||||
|
: mpl::false_ {};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct has_element_type<boost::shared_ptr<T> >
|
||||||
|
: mpl::true_ {};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct has_element_type<boost::scoped_ptr<T> >
|
||||||
|
: mpl::true_ {};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct has_element_type<std::auto_ptr<T> >
|
||||||
|
: mpl::true_ {};
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Metafunction returning the nested element_type typedef
|
||||||
|
template <class T>
|
||||||
|
struct smart_pointer_value : remove_const<typename T::element_type>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct iterator_is_mutable
|
||||||
|
: mpl::not_<
|
||||||
|
boost::python::detail::is_reference_to_const<
|
||||||
|
typename iterator_reference<T>::type
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct not_int_impl
|
||||||
|
{
|
||||||
|
template <class U>
|
||||||
|
struct apply {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct not_int_impl<int> {};
|
||||||
|
|
||||||
|
template <class T, class U>
|
||||||
|
struct not_int
|
||||||
|
: not_int_impl<T>::template apply<U> {};
|
||||||
|
|
||||||
|
// If the Value parameter is unspecified, we use this metafunction
|
||||||
|
// to deduce the default types
|
||||||
|
template <class Iter, class Value, class Category, class Reference, class Difference>
|
||||||
|
struct indirect_base
|
||||||
|
{
|
||||||
|
typedef typename iterator_value<Iter>::type dereferenceable;
|
||||||
|
|
||||||
|
typedef mpl::and_<
|
||||||
|
is_class<dereferenceable>
|
||||||
|
, has_element_type<dereferenceable>
|
||||||
|
> is_smart_ptr;
|
||||||
|
|
||||||
|
typedef typename mpl::apply_if<
|
||||||
|
is_smart_ptr
|
||||||
|
, smart_pointer_value<dereferenceable>
|
||||||
|
, iterator_value<dereferenceable>
|
||||||
|
>::type value_type;
|
||||||
|
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
mpl::or_<
|
||||||
|
is_smart_ptr
|
||||||
|
, iterator_is_mutable<dereferenceable>
|
||||||
|
>
|
||||||
|
, value_type
|
||||||
|
, value_type const
|
||||||
|
>::type cv_value_type;
|
||||||
|
|
||||||
|
typedef iterator_adaptor<
|
||||||
|
indirect_iterator<Iter, Value, Category, Reference, Difference>
|
||||||
|
, Iter
|
||||||
|
, cv_value_type
|
||||||
|
, Category
|
||||||
|
, Reference
|
||||||
|
, Difference
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct indirect_base<int, int, int, int, int> {};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Iterator
|
||||||
|
, class Value = use_default
|
||||||
|
, class Category = use_default
|
||||||
|
, class Reference = use_default
|
||||||
|
, class Difference = use_default
|
||||||
|
>
|
||||||
|
class indirect_iterator
|
||||||
|
: public detail::indirect_base<
|
||||||
|
Iterator, Value, Category, Reference, Difference
|
||||||
|
>::type
|
||||||
|
{
|
||||||
|
typedef typename detail::indirect_base<
|
||||||
|
Iterator, Value, Category, Reference, Difference
|
||||||
|
>::type super_t;
|
||||||
|
|
||||||
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
public:
|
||||||
|
indirect_iterator() {}
|
||||||
|
|
||||||
|
indirect_iterator(Iterator iter)
|
||||||
|
: super_t(iter) {}
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Iterator2, class Value2, class Category2
|
||||||
|
, class Reference2, class Difference2
|
||||||
|
>
|
||||||
|
indirect_iterator(
|
||||||
|
indirect_iterator<
|
||||||
|
Iterator2, Value2, Category2, Reference2, Difference2
|
||||||
|
> const& y
|
||||||
|
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0
|
||||||
|
)
|
||||||
|
: super_t(y.base())
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typename super_t::reference dereference() const
|
||||||
|
{
|
||||||
|
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
return const_cast<super_t::reference>(**this->base());
|
||||||
|
# else
|
||||||
|
return **this->base();
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Iter>
|
||||||
|
inline
|
||||||
|
indirect_iterator<Iter> make_indirect_iterator(Iter x)
|
||||||
|
{
|
||||||
|
return indirect_iterator<Iter>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Traits, class Iter>
|
||||||
|
inline
|
||||||
|
indirect_iterator<Iter,Traits> make_indirect_iterator(Iter x, Traits* = 0)
|
||||||
|
{
|
||||||
|
return indirect_iterator<Iter, Traits>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_INDIRECT_ITERATOR_23022003THW_HPP
|
52
include/boost/iterator/interoperable.hpp
Normal file
52
include/boost/iterator/interoperable.hpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// (C) Copyright David Abrahams 2002.
|
||||||
|
// (C) Copyright Jeremy Siek 2002.
|
||||||
|
// (C) Copyright Thomas Witt 2002.
|
||||||
|
// Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
#ifndef BOOST_INTEROPERABLE_23022003THW_HPP
|
||||||
|
# define BOOST_INTEROPERABLE_23022003THW_HPP
|
||||||
|
|
||||||
|
# include <boost/mpl/bool.hpp>
|
||||||
|
# include <boost/mpl/or.hpp>
|
||||||
|
|
||||||
|
# include <boost/type_traits/is_convertible.hpp>
|
||||||
|
|
||||||
|
# include <boost/iterator/detail/config_def.hpp> // must appear last
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
// Meta function that determines whether two
|
||||||
|
// iterator types are considered interoperable.
|
||||||
|
//
|
||||||
|
// Two iterator types A,B are considered interoperable if either
|
||||||
|
// A is convertible to B or vice versa.
|
||||||
|
// This interoperability definition is in sync with the
|
||||||
|
// standards requirements on constant/mutable container
|
||||||
|
// iterators (23.1 [lib.container.requirements]).
|
||||||
|
//
|
||||||
|
// For compilers that don't support is_convertible
|
||||||
|
// is_interoperable gives false positives. See comments
|
||||||
|
// on operator implementation for consequences.
|
||||||
|
//
|
||||||
|
template <typename A, typename B>
|
||||||
|
struct is_interoperable
|
||||||
|
# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||||
|
: mpl::true_
|
||||||
|
# else
|
||||||
|
: mpl::or_<
|
||||||
|
is_convertible< A, B >
|
||||||
|
, is_convertible< B, A > >
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
# include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_INTEROPERABLE_23022003THW_HPP
|
325
include/boost/iterator/iterator_adaptor.hpp
Normal file
325
include/boost/iterator/iterator_adaptor.hpp
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
// (C) Copyright David Abrahams 2002.
|
||||||
|
// (C) Copyright Jeremy Siek 2002.
|
||||||
|
// (C) Copyright Thomas Witt 2002.
|
||||||
|
// Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
#ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
|
||||||
|
#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
|
||||||
|
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/iterator.hpp>
|
||||||
|
#include <boost/detail/iterator.hpp>
|
||||||
|
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
|
#include <boost/iterator/detail/enable_if.hpp>
|
||||||
|
|
||||||
|
#include <boost/mpl/and.hpp>
|
||||||
|
#include <boost/mpl/not.hpp>
|
||||||
|
#include <boost/mpl/or.hpp>
|
||||||
|
|
||||||
|
#include <boost/python/detail/is_xxx.hpp>
|
||||||
|
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_def.hpp>
|
||||||
|
|
||||||
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
// Result type used in enable_if_convertible meta function.
|
||||||
|
// This can be an incomplete type, as only pointers to
|
||||||
|
// enable_if_convertible< ... >::type are used.
|
||||||
|
// We could have used void for this, but conversion to
|
||||||
|
// void* is just to easy.
|
||||||
|
//
|
||||||
|
struct enable_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// enable_if for use in adapted iterators constructors.
|
||||||
|
//
|
||||||
|
// In order to provide interoperability between adapted constant and
|
||||||
|
// mutable iterators, adapted iterators will usually provide templated
|
||||||
|
// conversion constructors of the following form
|
||||||
|
//
|
||||||
|
// template <class BaseIterator>
|
||||||
|
// class adapted_iterator :
|
||||||
|
// public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
//
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
// template <class OtherIterator>
|
||||||
|
// adapted_iterator(
|
||||||
|
// OtherIterator const& it
|
||||||
|
// , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
|
||||||
|
//
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// enable_if_convertible is used to remove those overloads from the overload
|
||||||
|
// set that cannot be instantiated. For all practical purposes only overloads
|
||||||
|
// for constant/mutable interaction will remain. This has the advantage that
|
||||||
|
// meta functions like boost::is_convertible do not return false positives,
|
||||||
|
// as they can only look at the signature of the conversion constructor
|
||||||
|
// and not at the actual instantiation.
|
||||||
|
//
|
||||||
|
// enable_if_interoperable can be safely used in user code. It falls back to
|
||||||
|
// always enabled for compilers that don't support enable_if or is_convertible.
|
||||||
|
// There is no need for compiler specific workarounds in user code.
|
||||||
|
//
|
||||||
|
// The operators implementation relies on boost::is_convertible not returning
|
||||||
|
// false positives for user/library defined iterator types. See comments
|
||||||
|
// on operator implementation for consequences.
|
||||||
|
//
|
||||||
|
# if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
|
||||||
|
|
||||||
|
template <class From, class To>
|
||||||
|
struct enable_if_convertible
|
||||||
|
{
|
||||||
|
typedef detail::enable_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
# elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
|
||||||
|
|
||||||
|
// For some reason vc7.1 needs us to "cut off" instantiation
|
||||||
|
// of is_convertible in a few cases.
|
||||||
|
template<typename From, typename To>
|
||||||
|
struct enable_if_convertible
|
||||||
|
: detail::enable_if<
|
||||||
|
mpl::or_<
|
||||||
|
is_same<From,To>
|
||||||
|
, is_convertible<From, To>
|
||||||
|
>
|
||||||
|
, detail::enable_type
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
template<typename From, typename To>
|
||||||
|
struct enable_if_convertible
|
||||||
|
: detail::enable_if<
|
||||||
|
is_convertible<From, To>
|
||||||
|
, detail::enable_type
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default template argument handling for iterator_adaptor
|
||||||
|
//
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
// If T is use_default, return the result of invoking
|
||||||
|
// DefaultNullaryFn, otherwise return T.
|
||||||
|
template <class T, class DefaultNullaryFn>
|
||||||
|
struct ia_dflt_help
|
||||||
|
: mpl::apply_if<
|
||||||
|
is_same<T, use_default>
|
||||||
|
, DefaultNullaryFn
|
||||||
|
, mpl::identity<T>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// A metafunction which computes an iterator_adaptor's base class,
|
||||||
|
// a specialization of iterator_facade.
|
||||||
|
template <
|
||||||
|
class Derived
|
||||||
|
, class Base
|
||||||
|
, class Value
|
||||||
|
, class Category
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
>
|
||||||
|
struct iterator_adaptor_base
|
||||||
|
{
|
||||||
|
private: // intermediate results
|
||||||
|
typedef typename detail::ia_dflt_help<
|
||||||
|
Category, BOOST_ITERATOR_CATEGORY<Base>
|
||||||
|
>::type category;
|
||||||
|
|
||||||
|
typedef typename detail::ia_dflt_help<
|
||||||
|
Reference
|
||||||
|
, mpl::apply_if<
|
||||||
|
is_same<Value, use_default>
|
||||||
|
, iterator_reference<Base>
|
||||||
|
, mpl::identity<Value&>
|
||||||
|
>
|
||||||
|
>::type reference;
|
||||||
|
|
||||||
|
public: // return type
|
||||||
|
typedef iterator_facade<
|
||||||
|
Derived
|
||||||
|
|
||||||
|
, typename detail::ia_dflt_help<
|
||||||
|
Value, iterator_value<Base>
|
||||||
|
>::type
|
||||||
|
|
||||||
|
, typename access_category_tag<category, reference>::type
|
||||||
|
|
||||||
|
, typename traversal_category_tag<category>::type
|
||||||
|
|
||||||
|
, reference
|
||||||
|
|
||||||
|
, typename detail::ia_dflt_help<
|
||||||
|
Difference, iterator_difference<Base>
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
type;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Iterator Adaptor
|
||||||
|
//
|
||||||
|
// The parameter ordering changed slightly with respect to former
|
||||||
|
// versions of iterator_adaptor The idea is that when the user needs
|
||||||
|
// to fiddle with the reference type it is highly likely that the
|
||||||
|
// iterator category has to be adjusted as well. Any of the
|
||||||
|
// following four template arguments may be ommitted or explicitly
|
||||||
|
// replaced by use_default.
|
||||||
|
//
|
||||||
|
// Value - if supplied, the value_type of the resulting iterator, unless
|
||||||
|
// const. If const, a conforming compiler strips constness for the
|
||||||
|
// value_type. If not supplied, iterator_traits<Base>::value_type is used
|
||||||
|
//
|
||||||
|
// Category - the iterator_category of the resulting iterator. If not
|
||||||
|
// supplied, iterator_traits<Base>::iterator_category is used.
|
||||||
|
//
|
||||||
|
// Reference - the reference type of the resulting iterator, and in
|
||||||
|
// particular, the result type of operator*(). If not supplied but
|
||||||
|
// Value is supplied, Value& is used. Otherwise
|
||||||
|
// iterator_traits<Base>::reference is used.
|
||||||
|
//
|
||||||
|
// Difference - the difference_type of the resulting iterator. If not
|
||||||
|
// supplied, iterator_traits<Base>::difference_type is used.
|
||||||
|
//
|
||||||
|
template <
|
||||||
|
class Derived
|
||||||
|
, class Base
|
||||||
|
, class Value = use_default
|
||||||
|
, class Category = use_default
|
||||||
|
, class Reference = use_default
|
||||||
|
, class Difference = use_default
|
||||||
|
>
|
||||||
|
class iterator_adaptor
|
||||||
|
: public detail::iterator_adaptor_base<
|
||||||
|
Derived, Base, Value, Category, Reference, Difference
|
||||||
|
>::type
|
||||||
|
{
|
||||||
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
typedef typename detail::iterator_adaptor_base<
|
||||||
|
Derived, Base, Value, Category, Reference, Difference
|
||||||
|
>::type super_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
iterator_adaptor() {}
|
||||||
|
|
||||||
|
explicit iterator_adaptor(Base iter)
|
||||||
|
: m_iterator(iter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Base base() const
|
||||||
|
{ return m_iterator; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
// lvalue access to the Base object for Derived
|
||||||
|
//
|
||||||
|
Base const& base_reference() const
|
||||||
|
{ return m_iterator; }
|
||||||
|
|
||||||
|
Base& base_reference()
|
||||||
|
{ return m_iterator; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Core iterator interface for iterator_facade. This is private
|
||||||
|
// to prevent temptation for Derived classes to use it, which
|
||||||
|
// will often result in an error. Derived classes should use
|
||||||
|
// base_reference(), above, to get direct access to m_iterator.
|
||||||
|
//
|
||||||
|
typename super_t::reference dereference() const
|
||||||
|
{ return *m_iterator; }
|
||||||
|
|
||||||
|
template <
|
||||||
|
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||||
|
>
|
||||||
|
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const
|
||||||
|
{
|
||||||
|
// Maybe readd with same_distance
|
||||||
|
// BOOST_STATIC_ASSERT(
|
||||||
|
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
|
||||||
|
// );
|
||||||
|
return m_iterator == x.base();
|
||||||
|
}
|
||||||
|
|
||||||
|
void advance(typename super_t::difference_type n)
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(detail::is_tag<
|
||||||
|
random_access_traversal_tag
|
||||||
|
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
|
||||||
|
>::value)
|
||||||
|
);
|
||||||
|
m_iterator += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment() { ++m_iterator; }
|
||||||
|
|
||||||
|
void decrement()
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(detail::is_tag<
|
||||||
|
bidirectional_traversal_tag
|
||||||
|
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
|
||||||
|
>::value)
|
||||||
|
);
|
||||||
|
--m_iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||||
|
>
|
||||||
|
typename super_t::difference_type distance_to(
|
||||||
|
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(detail::is_tag<
|
||||||
|
random_access_traversal_tag
|
||||||
|
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
|
||||||
|
>::value)
|
||||||
|
);
|
||||||
|
// Maybe readd with same_distance
|
||||||
|
// BOOST_STATIC_ASSERT(
|
||||||
|
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
|
||||||
|
// );
|
||||||
|
return y.base() - m_iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
private: // data members
|
||||||
|
Base m_iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
|
350
include/boost/iterator/iterator_archetypes.hpp
Normal file
350
include/boost/iterator/iterator_archetypes.hpp
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
|
||||||
|
#ifndef BOOST_ITERATOR_ARCHETYPES_HPP
|
||||||
|
#define BOOST_ITERATOR_ARCHETYPES_HPP
|
||||||
|
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
#include <boost/mpl/if.hpp>
|
||||||
|
#include <boost/mpl/and.hpp>
|
||||||
|
#include <boost/operators.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/type_traits/is_const.hpp>
|
||||||
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
|
|
||||||
|
#include <boost/mpl/aux_/msvc_eti_base.hpp>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class Value, class AccessCategory>
|
||||||
|
struct access_archetype;
|
||||||
|
|
||||||
|
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
||||||
|
struct traversal_archetype;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct assign_proxy
|
||||||
|
{
|
||||||
|
assign_proxy& operator=(T);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct read_write_proxy :
|
||||||
|
assign_proxy<T>
|
||||||
|
{
|
||||||
|
operator T();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct arrow_proxy
|
||||||
|
{
|
||||||
|
T const* operator->() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct no_operator_brackets {};
|
||||||
|
|
||||||
|
template <class ValueType>
|
||||||
|
struct readable_operator_brackets
|
||||||
|
{
|
||||||
|
ValueType operator[](std::ptrdiff_t n) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class ValueType>
|
||||||
|
struct writable_operator_brackets
|
||||||
|
{
|
||||||
|
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
|
struct operator_brackets :
|
||||||
|
mpl::if_< is_tag<random_access_traversal_tag, TraversalCategory>,
|
||||||
|
mpl::if_< is_tag<writable_iterator_tag, AccessCategory>,
|
||||||
|
writable_operator_brackets< Value >,
|
||||||
|
mpl::if_< is_tag<readable_iterator_tag, AccessCategory>,
|
||||||
|
readable_operator_brackets<Value>,
|
||||||
|
no_operator_brackets > >,
|
||||||
|
no_operator_brackets >::type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class TraversalCategory>
|
||||||
|
struct traversal_archetype_impl
|
||||||
|
{
|
||||||
|
template <class Derived,class Value> struct archetype;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Derived, class Value, class TraversalCategory>
|
||||||
|
struct traversal_archetype_
|
||||||
|
: mpl::aux::msvc_eti_base<
|
||||||
|
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
||||||
|
>::type
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct traversal_archetype_impl<incrementable_traversal_tag>
|
||||||
|
{
|
||||||
|
template<class Derived, class Value>
|
||||||
|
struct archetype
|
||||||
|
{
|
||||||
|
typedef void difference_type;
|
||||||
|
|
||||||
|
Derived& operator++();
|
||||||
|
Derived operator++(int) const;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct traversal_archetype_impl<single_pass_traversal_tag>
|
||||||
|
{
|
||||||
|
template<class Derived, class Value>
|
||||||
|
struct archetype
|
||||||
|
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
|
||||||
|
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||||
|
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||||
|
// doesn't seem to pick up != from equality_comparable
|
||||||
|
template <class Derived, class Value>
|
||||||
|
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||||
|
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
|
||||||
|
#endif
|
||||||
|
template <>
|
||||||
|
struct traversal_archetype_impl<forward_traversal_tag>
|
||||||
|
{
|
||||||
|
template<class Derived, class Value>
|
||||||
|
struct archetype
|
||||||
|
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
|
||||||
|
{
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct traversal_archetype_impl<bidirectional_traversal_tag>
|
||||||
|
{
|
||||||
|
template<class Derived, class Value>
|
||||||
|
struct archetype
|
||||||
|
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
|
||||||
|
{
|
||||||
|
Derived& operator--();
|
||||||
|
Derived operator--(int) const;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct traversal_archetype_impl<random_access_traversal_tag>
|
||||||
|
{
|
||||||
|
template<class Derived, class Value>
|
||||||
|
struct archetype
|
||||||
|
: public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >,
|
||||||
|
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
|
||||||
|
{
|
||||||
|
Derived& operator+=(std::ptrdiff_t);
|
||||||
|
Derived& operator-=(std::ptrdiff_t);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||||
|
std::ptrdiff_t);
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
Derived& operator+(std::ptrdiff_t,
|
||||||
|
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||||
|
std::ptrdiff_t);
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||||
|
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||||
|
|
||||||
|
template <class Derived, class Value>
|
||||||
|
bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||||
|
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||||
|
|
||||||
|
struct bogus_type;
|
||||||
|
|
||||||
|
template <class Value>
|
||||||
|
struct convertible_type
|
||||||
|
: mpl::if_< is_const<Value>,
|
||||||
|
typename remove_const<Value>::type,
|
||||||
|
bogus_type >
|
||||||
|
{};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
|
template <class> struct undefined;
|
||||||
|
|
||||||
|
template <class AccessCategory>
|
||||||
|
struct access_archetype_impl
|
||||||
|
{
|
||||||
|
template <class Value> struct archetype;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Value, class AccessCategory>
|
||||||
|
struct access_archetype
|
||||||
|
: mpl::aux::msvc_eti_base<
|
||||||
|
typename access_archetype_impl<AccessCategory>::template archetype<Value>
|
||||||
|
>::type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct access_archetype_impl<readable_iterator_tag>
|
||||||
|
{
|
||||||
|
template <class Value>
|
||||||
|
struct archetype
|
||||||
|
{
|
||||||
|
typedef typename remove_cv<Value>::type value_type;
|
||||||
|
typedef Value reference;
|
||||||
|
typedef Value* pointer;
|
||||||
|
|
||||||
|
value_type operator*() const;
|
||||||
|
|
||||||
|
detail::arrow_proxy<Value> operator->() const;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct access_archetype_impl<writable_iterator_tag>
|
||||||
|
{
|
||||||
|
template <class Value>
|
||||||
|
struct archetype
|
||||||
|
{
|
||||||
|
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||||
|
BOOST_STATIC_ASSERT(!is_const<Value>::value);
|
||||||
|
# endif
|
||||||
|
typedef void value_type;
|
||||||
|
typedef void reference;
|
||||||
|
typedef void pointer;
|
||||||
|
|
||||||
|
detail::assign_proxy<Value> operator*() const;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct access_archetype_impl<readable_writable_iterator_tag>
|
||||||
|
{
|
||||||
|
template <class Value>
|
||||||
|
struct archetype
|
||||||
|
: public virtual access_archetype<Value, readable_iterator_tag>
|
||||||
|
{
|
||||||
|
typedef detail::read_write_proxy<Value> reference;
|
||||||
|
|
||||||
|
detail::read_write_proxy<Value> operator*() const;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct access_archetype_impl<readable_lvalue_iterator_tag>
|
||||||
|
{
|
||||||
|
template <class Value>
|
||||||
|
struct archetype
|
||||||
|
: public virtual access_archetype<Value, readable_iterator_tag>
|
||||||
|
{
|
||||||
|
typedef Value& reference;
|
||||||
|
|
||||||
|
Value& operator*() const;
|
||||||
|
Value* operator->() const;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct access_archetype_impl<writable_lvalue_iterator_tag>
|
||||||
|
{
|
||||||
|
template <class Value>
|
||||||
|
struct archetype
|
||||||
|
: public virtual access_archetype<Value, readable_lvalue_iterator_tag>
|
||||||
|
{
|
||||||
|
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||||
|
BOOST_STATIC_ASSERT((!is_const<Value>::value));
|
||||||
|
# endif
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
|
struct iterator_archetype;
|
||||||
|
|
||||||
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
|
struct traversal_archetype_base
|
||||||
|
: detail::operator_brackets<
|
||||||
|
typename remove_cv<Value>::type
|
||||||
|
, AccessCategory
|
||||||
|
, TraversalCategory
|
||||||
|
>
|
||||||
|
, detail::traversal_archetype_<
|
||||||
|
iterator_archetype<Value, AccessCategory, TraversalCategory>
|
||||||
|
, Value
|
||||||
|
, TraversalCategory
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
|
struct iterator_archetype
|
||||||
|
: public traversal_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||||
|
, public access_archetype<Value, AccessCategory>
|
||||||
|
|
||||||
|
// These broken libraries require derivation from std::iterator
|
||||||
|
// (or related magic) in order to handle iter_swap and other
|
||||||
|
// iterator operations
|
||||||
|
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||||
|
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||||
|
, public std::iterator<
|
||||||
|
iterator_tag<AccessCategory,TraversalCategory>
|
||||||
|
, typename access_archetype<Value, AccessCategory>::value_type
|
||||||
|
, typename traversal_archetype_base<
|
||||||
|
Value, AccessCategory, TraversalCategory
|
||||||
|
>::difference_type
|
||||||
|
>
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
// Derivation from std::iterator above caused ambiguity, so now
|
||||||
|
// we have to declare all the types here.
|
||||||
|
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||||
|
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||||
|
typedef typename access_archetype<Value, AccessCategory>::value_type value_type;
|
||||||
|
|
||||||
|
typedef typename access_archetype<Value, AccessCategory>::pointer pointer;
|
||||||
|
|
||||||
|
typedef typename access_archetype<Value, AccessCategory>::reference reference;
|
||||||
|
|
||||||
|
typedef typename traversal_archetype_base<
|
||||||
|
Value, AccessCategory, TraversalCategory
|
||||||
|
>::difference_type difference_type;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
||||||
|
|
||||||
|
iterator_archetype();
|
||||||
|
iterator_archetype(iterator_archetype const&);
|
||||||
|
|
||||||
|
iterator_archetype& operator=(iterator_archetype const&);
|
||||||
|
|
||||||
|
// Optional conversion from mutable
|
||||||
|
// iterator_archetype(iterator_archetype<typename detail::convertible_type<Value>::type, AccessCategory, TraversalCategory> const&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BOOST_ITERATOR_ARCHETYPES_HPP
|
405
include/boost/iterator/iterator_categories.hpp
Normal file
405
include/boost/iterator/iterator_categories.hpp
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// Add separate category tag for operator[].
|
||||||
|
|
||||||
|
#ifndef BOOST_ITERATOR_CATEGORIES_HPP
|
||||||
|
#define BOOST_ITERATOR_CATEGORIES_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/iterator/detail/categories.hpp>
|
||||||
|
|
||||||
|
#include <boost/type_traits/conversion_traits.hpp>
|
||||||
|
#include <boost/type_traits/cv_traits.hpp>
|
||||||
|
|
||||||
|
#include <boost/python/detail/indirect_traits.hpp>
|
||||||
|
|
||||||
|
#include <boost/detail/iterator.hpp>
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#include <boost/mpl/apply_if.hpp>
|
||||||
|
#include <boost/mpl/if.hpp>
|
||||||
|
#include <boost/mpl/bool.hpp>
|
||||||
|
#include <boost/mpl/aux_/has_xxx.hpp>
|
||||||
|
#include <boost/mpl/not.hpp>
|
||||||
|
#include <boost/mpl/or.hpp>
|
||||||
|
#include <boost/mpl/apply.hpp>
|
||||||
|
#include <boost/mpl/aux_/msvc_eti_base.hpp>
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_def.hpp> // must be last #include
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
|
||||||
|
# define BOOST_NO_IS_CONVERTIBLE // "Convertible does not provide enough/is not working"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
// Helper metafunction for std_category below
|
||||||
|
template <class Cat, class Tag, class Next>
|
||||||
|
struct match_tag
|
||||||
|
: mpl::apply_if<is_tag<Tag, Cat>, mpl::identity<Tag>, Next>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// Converts a possibly user-defined category tag to the
|
||||||
|
// most-derived standard tag which is a base of that tag.
|
||||||
|
template <class Category>
|
||||||
|
struct std_category
|
||||||
|
: match_tag<
|
||||||
|
Category, std::random_access_iterator_tag
|
||||||
|
, match_tag<Category, std::bidirectional_iterator_tag
|
||||||
|
, match_tag<Category, std::forward_iterator_tag
|
||||||
|
, match_tag<Category, std::input_iterator_tag
|
||||||
|
, match_tag<Category, std::output_iterator_tag
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||||
|
, mpl::identity<void>
|
||||||
|
# else
|
||||||
|
, void
|
||||||
|
# endif
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// std_to_new_tags --
|
||||||
|
//
|
||||||
|
// A metafunction which converts any standard tag into its
|
||||||
|
// corresponding new-style traversal tag.
|
||||||
|
//
|
||||||
|
// Also, instantiations are metafunction classes which convert a
|
||||||
|
// reference type into a corresponding new-style access tag.
|
||||||
|
template <class Category> struct std_to_new_tags
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) // handle ETI
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
template <class T> struct apply { typedef void type; };
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
;
|
||||||
|
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // handle ETI
|
||||||
|
template <> struct std_to_new_tags<int> {};
|
||||||
|
# endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Specializations for specific standard tags
|
||||||
|
//
|
||||||
|
template <>
|
||||||
|
struct std_to_new_tags<std::input_iterator_tag>
|
||||||
|
{
|
||||||
|
typedef single_pass_traversal_tag type;
|
||||||
|
|
||||||
|
template <class Reference>
|
||||||
|
struct apply
|
||||||
|
: mpl::identity<readable_iterator_tag> {};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct std_to_new_tags<std::output_iterator_tag>
|
||||||
|
{
|
||||||
|
typedef incrementable_traversal_tag type;
|
||||||
|
|
||||||
|
template <class Reference>
|
||||||
|
struct apply
|
||||||
|
: mpl::identity<writable_iterator_tag> {};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct std_to_new_tags<std::forward_iterator_tag>
|
||||||
|
{
|
||||||
|
typedef forward_traversal_tag type;
|
||||||
|
|
||||||
|
template <class Reference>
|
||||||
|
struct apply
|
||||||
|
: mpl::if_<
|
||||||
|
python::detail::is_reference_to_const<Reference>
|
||||||
|
, boost::readable_lvalue_iterator_tag
|
||||||
|
, boost::writable_lvalue_iterator_tag
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct std_to_new_tags<std::bidirectional_iterator_tag>
|
||||||
|
: std_to_new_tags<std::forward_iterator_tag>
|
||||||
|
{
|
||||||
|
typedef bidirectional_traversal_tag type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct std_to_new_tags<std::random_access_iterator_tag>
|
||||||
|
: std_to_new_tags<std::bidirectional_iterator_tag>
|
||||||
|
{
|
||||||
|
typedef random_access_traversal_tag type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Category>
|
||||||
|
struct old_tag_converter
|
||||||
|
: std_to_new_tags<
|
||||||
|
typename std_category<Category>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Category>
|
||||||
|
struct iter_category_to_traversal
|
||||||
|
: std_to_new_tags<
|
||||||
|
typename std_category<Category>::type
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <typename Category, typename Reference>
|
||||||
|
struct iter_category_to_access
|
||||||
|
: mpl::apply1<
|
||||||
|
iter_category_to_traversal<Category>
|
||||||
|
, Reference
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||||
|
// Deal with ETI
|
||||||
|
template <> struct iter_category_to_access<int, int> {};
|
||||||
|
template <> struct iter_category_to_traversal<int> {};
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// A metafunction returning true iff T is boost::iterator_tag<R,U>
|
||||||
|
template <class T>
|
||||||
|
struct is_boost_iterator_tag;
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||||
|
//
|
||||||
|
// has_xxx fails, so we have to use
|
||||||
|
// something less sophisticated.
|
||||||
|
//
|
||||||
|
// The solution depends on the fact that only
|
||||||
|
// std iterator categories work with is_xxx_iterator
|
||||||
|
// meta functions, as BOOST_NO_IS_CONVERTIBLE is
|
||||||
|
// defined for cwpro7.
|
||||||
|
//
|
||||||
|
template <class Tag>
|
||||||
|
struct is_new_iterator_tag
|
||||||
|
: mpl::not_<
|
||||||
|
mpl::or_<
|
||||||
|
is_tag<std::input_iterator_tag, Tag>
|
||||||
|
, is_tag<std::output_iterator_tag, Tag>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
#elif BOOST_WORKAROUND(__GNUC__, == 2 && __GNUC_MINOR__ == 95) \
|
||||||
|
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
|
||||||
|
template <class Tag>
|
||||||
|
struct is_new_iterator_tag
|
||||||
|
: is_boost_iterator_tag<Tag>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
BOOST_MPL_HAS_XXX_TRAIT_DEF(traversal)
|
||||||
|
|
||||||
|
template <class Tag>
|
||||||
|
struct is_new_iterator_tag
|
||||||
|
: mpl::if_<
|
||||||
|
is_class<Tag>
|
||||||
|
, has_traversal<Tag>
|
||||||
|
, mpl::false_
|
||||||
|
>::type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <class NewCategoryTag>
|
||||||
|
struct get_traversal_category {
|
||||||
|
typedef typename NewCategoryTag::traversal type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Remove all writability from the given access tag. This
|
||||||
|
// functionality is part of new_category_to_access in order to
|
||||||
|
// support deduction of the proper default access category for
|
||||||
|
// iterator_adaptor; when the reference type is a reference to
|
||||||
|
// constant we must strip writability.
|
||||||
|
template <class AccessTag>
|
||||||
|
struct remove_access_writability
|
||||||
|
: mpl::apply_if<
|
||||||
|
is_tag<writable_lvalue_iterator_tag, AccessTag>
|
||||||
|
, mpl::identity<readable_lvalue_iterator_tag>
|
||||||
|
|
||||||
|
, mpl::apply_if<
|
||||||
|
is_tag<readable_writable_iterator_tag, AccessTag>
|
||||||
|
, mpl::identity<readable_iterator_tag>
|
||||||
|
|
||||||
|
, mpl::if_<
|
||||||
|
is_tag<writable_iterator_tag, AccessTag>
|
||||||
|
// Is this OK? I think it may correct be for all
|
||||||
|
// legitimate cases, because at this point the
|
||||||
|
// iterator is not readable, so it could not have
|
||||||
|
// been any more than writable + swappable.
|
||||||
|
, swappable_iterator_tag
|
||||||
|
, AccessTag
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <class NewCategoryTag, class Reference>
|
||||||
|
struct new_category_to_access
|
||||||
|
: mpl::apply_if<
|
||||||
|
python::detail::is_reference_to_const<Reference>
|
||||||
|
, remove_access_writability<typename NewCategoryTag::access>
|
||||||
|
, mpl::identity<typename NewCategoryTag::access>
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <class CategoryTag, class Reference>
|
||||||
|
struct access_category_tag
|
||||||
|
: mpl::apply_if<
|
||||||
|
is_new_iterator_tag<CategoryTag>
|
||||||
|
, new_category_to_access<CategoryTag, Reference>
|
||||||
|
, iter_category_to_access<CategoryTag, Reference>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class CategoryTag>
|
||||||
|
struct traversal_category_tag
|
||||||
|
: mpl::apply_if<
|
||||||
|
is_new_iterator_tag<CategoryTag>
|
||||||
|
, get_traversal_category<CategoryTag>
|
||||||
|
, iter_category_to_traversal<CategoryTag>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||||
|
// Deal with ETI
|
||||||
|
template <> struct access_category_tag<int, int> { typedef void type; };
|
||||||
|
template <> struct traversal_category_tag<int> { typedef void type; };
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// iterator_tag_base - a metafunction to compute the appropriate
|
||||||
|
// old-style tag (if any) to use as a base for a new-style tag.
|
||||||
|
template <class KnownAccessTag, class KnownTraversalTag>
|
||||||
|
struct iterator_tag_base
|
||||||
|
: minimum_category<
|
||||||
|
typename KnownAccessTag::max_category
|
||||||
|
, typename KnownTraversalTag::max_category
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC,<=1200)
|
||||||
|
template <>
|
||||||
|
struct iterator_tag_base<int,int>
|
||||||
|
: mpl::false_ {}; // just using false_ so that the result will be
|
||||||
|
// a legal base class
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// specialization for this special case. Otherwise we get
|
||||||
|
// input_output_iterator_tag, because the standard hierarchy has a
|
||||||
|
// sudden anomalous distinction between readability and
|
||||||
|
// writability at the level of input iterator/output iterator.
|
||||||
|
template <>
|
||||||
|
struct iterator_tag_base<
|
||||||
|
readable_lvalue_iterator_tag,single_pass_traversal_tag>
|
||||||
|
{
|
||||||
|
typedef std::input_iterator_tag type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
struct access_category
|
||||||
|
: detail::access_category_tag<
|
||||||
|
typename detail::iterator_traits<Iterator>::iterator_category
|
||||||
|
, typename detail::iterator_traits<Iterator>::reference>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
struct traversal_category
|
||||||
|
: detail::traversal_category_tag<
|
||||||
|
typename detail::iterator_traits<Iterator>::iterator_category
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct access_category<T*>
|
||||||
|
: mpl::if_<
|
||||||
|
is_const<T>
|
||||||
|
, readable_lvalue_iterator_tag
|
||||||
|
, writable_lvalue_iterator_tag>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct traversal_category<T*>
|
||||||
|
{
|
||||||
|
typedef random_access_traversal_tag type;
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
template <class AccessTag, class TraversalTag>
|
||||||
|
struct iterator_tag
|
||||||
|
: detail::iterator_tag_base<
|
||||||
|
typename detail::max_known_access_tag<AccessTag>::type
|
||||||
|
, typename detail::max_known_traversal_tag<TraversalTag>::type
|
||||||
|
>::type
|
||||||
|
{
|
||||||
|
typedef AccessTag access;
|
||||||
|
typedef TraversalTag traversal;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
template <class T>
|
||||||
|
struct is_boost_iterator_tag
|
||||||
|
: mpl::false_ {};
|
||||||
|
|
||||||
|
template <class R, class T>
|
||||||
|
struct is_boost_iterator_tag<iterator_tag<R,T> >
|
||||||
|
: mpl::true_ {};
|
||||||
|
# else
|
||||||
|
template <class T>
|
||||||
|
struct is_boost_iterator_tag
|
||||||
|
{
|
||||||
|
typedef char (&yes)[1];
|
||||||
|
typedef char (&no)[2];
|
||||||
|
|
||||||
|
template <class R, class U>
|
||||||
|
static yes test(mpl::identity<iterator_tag<R,U> >*);
|
||||||
|
static no test(...);
|
||||||
|
|
||||||
|
static mpl::identity<T>* inst;
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = sizeof(test(inst)) == sizeof(yes));
|
||||||
|
typedef mpl::bool_<value> type;
|
||||||
|
};
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_ITERATOR_CATEGORIES_HPP
|
358
include/boost/iterator/iterator_concepts.hpp
Normal file
358
include/boost/iterator/iterator_concepts.hpp
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
|
||||||
|
#ifndef BOOST_ITERATOR_CONCEPTS_HPP
|
||||||
|
#define BOOST_ITERATOR_CONCEPTS_HPP
|
||||||
|
|
||||||
|
// Revision History
|
||||||
|
// 26 Apr 2003 thw
|
||||||
|
// Adapted to new iterator concepts
|
||||||
|
// 22 Nov 2002 Thomas Witt
|
||||||
|
// Added interoperable concept.
|
||||||
|
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/type_traits/is_integral.hpp>
|
||||||
|
#include <boost/mpl/bool.hpp>
|
||||||
|
#include <boost/mpl/if.hpp>
|
||||||
|
#include <boost/mpl/and.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
|
// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems.
|
||||||
|
#include <boost/detail/iterator.hpp>
|
||||||
|
|
||||||
|
// Use boost/limits to work around missing limits headers on some compilers
|
||||||
|
#include <boost/limits.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace boost_concepts {
|
||||||
|
// Used a different namespace here (instead of "boost") so that the
|
||||||
|
// concept descriptions do not take for granted the names in
|
||||||
|
// namespace boost.
|
||||||
|
|
||||||
|
// We use this in place of STATIC_ASSERT((is_convertible<...>))
|
||||||
|
// because some compilers (CWPro7.x) can't detect convertibility.
|
||||||
|
//
|
||||||
|
// Of course, that just gets us a different error at the moment with
|
||||||
|
// some tests, since new iterator category deduction still depends
|
||||||
|
// on convertibility detection. We might need some specializations
|
||||||
|
// to support this compiler.
|
||||||
|
template <class Target, class Source>
|
||||||
|
struct static_assert_base_and_derived
|
||||||
|
{
|
||||||
|
static_assert_base_and_derived(Target* = (Source*)0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Iterator Access Concepts
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
class ReadableIteratorConcept {
|
||||||
|
public:
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits<Iterator>::reference reference;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME ::boost::access_category<Iterator>::type access_category;
|
||||||
|
|
||||||
|
void constraints() {
|
||||||
|
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||||
|
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
||||||
|
boost::function_requires<
|
||||||
|
boost::DefaultConstructibleConcept<Iterator> >();
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::readable_iterator_tag, access_category>::value));
|
||||||
|
|
||||||
|
reference r = *i; // or perhaps read(x)
|
||||||
|
value_type v(r);
|
||||||
|
boost::ignore_unused_variable_warning(v);
|
||||||
|
}
|
||||||
|
Iterator i;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator, typename ValueType>
|
||||||
|
class WritableIteratorConcept {
|
||||||
|
public:
|
||||||
|
typedef typename boost::access_category<Iterator>::type access_category;
|
||||||
|
|
||||||
|
void constraints() {
|
||||||
|
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||||
|
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
||||||
|
boost::function_requires<
|
||||||
|
boost::DefaultConstructibleConcept<Iterator> >();
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::writable_iterator_tag, access_category>::value));
|
||||||
|
|
||||||
|
*i = v; // a good alternative could be something like write(x, v)
|
||||||
|
}
|
||||||
|
ValueType v;
|
||||||
|
Iterator i;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
class SwappableIteratorConcept {
|
||||||
|
public:
|
||||||
|
typedef typename boost::access_category<Iterator>::type access_category;
|
||||||
|
|
||||||
|
void constraints() {
|
||||||
|
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::swappable_iterator_tag, access_category>::value));
|
||||||
|
|
||||||
|
std::iter_swap(i1, i2);
|
||||||
|
}
|
||||||
|
Iterator i1;
|
||||||
|
Iterator i2;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
class ReadableLvalueIteratorConcept {
|
||||||
|
public:
|
||||||
|
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||||
|
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
||||||
|
typedef typename boost::access_category<Iterator>::type access_category;
|
||||||
|
|
||||||
|
void constraints() {
|
||||||
|
boost::function_requires< ReadableIteratorConcept<Iterator> >();
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::readable_lvalue_iterator_tag, access_category>::value));
|
||||||
|
|
||||||
|
typedef boost::mpl::or_<
|
||||||
|
boost::is_same<reference, value_type&>,
|
||||||
|
boost::is_same<reference, value_type const&> > correct_reference;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(correct_reference::value);
|
||||||
|
|
||||||
|
reference v = *i;
|
||||||
|
boost::ignore_unused_variable_warning(v);
|
||||||
|
}
|
||||||
|
Iterator i;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
class WritableLvalueIteratorConcept {
|
||||||
|
public:
|
||||||
|
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||||
|
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
||||||
|
typedef typename boost::access_category<Iterator>::type access_category;
|
||||||
|
|
||||||
|
void constraints() {
|
||||||
|
boost::function_requires<
|
||||||
|
ReadableLvalueIteratorConcept<Iterator> >();
|
||||||
|
boost::function_requires<
|
||||||
|
WritableIteratorConcept<Iterator, value_type> >();
|
||||||
|
boost::function_requires<
|
||||||
|
SwappableIteratorConcept<Iterator> >();
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::writable_lvalue_iterator_tag, access_category>::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<reference, value_type&>::value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Iterator Traversal Concepts
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
class IncrementableIteratorConcept {
|
||||||
|
public:
|
||||||
|
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||||
|
|
||||||
|
void constraints() {
|
||||||
|
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||||
|
boost::function_requires<
|
||||||
|
boost::DefaultConstructibleConcept<Iterator> >();
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::incrementable_traversal_tag, traversal_category>::value));
|
||||||
|
|
||||||
|
++i;
|
||||||
|
(void)i++;
|
||||||
|
}
|
||||||
|
Iterator i;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
class SinglePassIteratorConcept {
|
||||||
|
public:
|
||||||
|
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||||
|
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
|
||||||
|
|
||||||
|
void constraints() {
|
||||||
|
boost::function_requires< IncrementableIteratorConcept<Iterator> >();
|
||||||
|
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::single_pass_traversal_tag, traversal_category>::value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
class ForwardTraversalConcept {
|
||||||
|
public:
|
||||||
|
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||||
|
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
|
||||||
|
|
||||||
|
void constraints() {
|
||||||
|
boost::function_requires< SinglePassIteratorConcept<Iterator> >();
|
||||||
|
|
||||||
|
typedef boost::mpl::and_<
|
||||||
|
boost::is_integral<difference_type>,
|
||||||
|
boost::mpl::bool_< std::numeric_limits<difference_type>::is_signed >
|
||||||
|
> difference_type_is_signed_integral;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(difference_type_is_signed_integral::value);
|
||||||
|
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::forward_traversal_tag, traversal_category>::value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
class BidirectionalTraversalConcept {
|
||||||
|
public:
|
||||||
|
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||||
|
|
||||||
|
void constraints() {
|
||||||
|
boost::function_requires< ForwardTraversalConcept<Iterator> >();
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::bidirectional_traversal_tag, traversal_category>::value));
|
||||||
|
|
||||||
|
--i;
|
||||||
|
(void)i--;
|
||||||
|
}
|
||||||
|
Iterator i;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
class RandomAccessTraversalConcept {
|
||||||
|
public:
|
||||||
|
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||||
|
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
|
||||||
|
difference_type;
|
||||||
|
|
||||||
|
void constraints() {
|
||||||
|
boost::function_requires< BidirectionalTraversalConcept<Iterator> >();
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::random_access_traversal_tag, traversal_category>::value));
|
||||||
|
|
||||||
|
i += n;
|
||||||
|
i = i + n;
|
||||||
|
i = n + i;
|
||||||
|
i -= n;
|
||||||
|
i = i - n;
|
||||||
|
n = i - j;
|
||||||
|
}
|
||||||
|
difference_type n;
|
||||||
|
Iterator i, j;
|
||||||
|
};
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Iterator Interoperability Concept
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename TraversalTag>
|
||||||
|
struct Operations;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Operations<boost::incrementable_traversal_tag>
|
||||||
|
{
|
||||||
|
template <typename Iterator1, typename Iterator2>
|
||||||
|
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
|
||||||
|
{
|
||||||
|
// no interoperability constraints
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Operations<boost::single_pass_traversal_tag>
|
||||||
|
{
|
||||||
|
template <typename Iterator1, typename Iterator2>
|
||||||
|
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
|
||||||
|
{
|
||||||
|
Operations<boost::incrementable_traversal_tag>(i1, i2);
|
||||||
|
i1 == i2;
|
||||||
|
i1 != i2;
|
||||||
|
|
||||||
|
i2 == i1;
|
||||||
|
i2 != i1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Operations<boost::forward_traversal_tag>
|
||||||
|
{
|
||||||
|
template <typename Iterator1, typename Iterator2>
|
||||||
|
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
|
||||||
|
{
|
||||||
|
Operations<boost::single_pass_traversal_tag>::constraints(i1, i2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Operations<boost::bidirectional_traversal_tag>
|
||||||
|
{
|
||||||
|
template <typename Iterator1, typename Iterator2>
|
||||||
|
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
|
||||||
|
{
|
||||||
|
Operations<boost::forward_traversal_tag>::constraints(i1, i2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Operations<boost::random_access_traversal_tag>
|
||||||
|
{
|
||||||
|
template <typename Iterator1, typename Iterator2>
|
||||||
|
static void constraints(Iterator1 const& i1, Iterator2 const& i2)
|
||||||
|
{
|
||||||
|
Operations<boost::bidirectional_traversal_tag>::constraints(i1, i2);
|
||||||
|
|
||||||
|
i1 < i2;
|
||||||
|
i1 <= i2;
|
||||||
|
i1 > i2;
|
||||||
|
i1 >= i2;
|
||||||
|
i1 - i2;
|
||||||
|
|
||||||
|
i2 < i1;
|
||||||
|
i2 <= i1;
|
||||||
|
i2 > i1;
|
||||||
|
i2 >= i1;
|
||||||
|
i2 - i1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename Iterator, typename ConstIterator>
|
||||||
|
class InteroperableConcept
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||||
|
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
|
||||||
|
difference_type;
|
||||||
|
|
||||||
|
typedef typename boost::traversal_category<ConstIterator>::type
|
||||||
|
const_traversal_category;
|
||||||
|
typedef typename boost::detail::iterator_traits<ConstIterator>::difference_type
|
||||||
|
const_difference_type;
|
||||||
|
|
||||||
|
void constraints() {
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same< difference_type,
|
||||||
|
const_difference_type>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same< traversal_category,
|
||||||
|
const_traversal_category>::value));
|
||||||
|
|
||||||
|
// ToDo check what the std really requires
|
||||||
|
|
||||||
|
// detail::Operations<traversal_category>::constraints(i, ci);
|
||||||
|
|
||||||
|
ci = i;
|
||||||
|
|
||||||
|
}
|
||||||
|
Iterator i;
|
||||||
|
ConstIterator ci;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost_concepts
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BOOST_ITERATOR_CONCEPTS_HPP
|
625
include/boost/iterator/iterator_facade.hpp
Normal file
625
include/boost/iterator/iterator_facade.hpp
Normal file
@ -0,0 +1,625 @@
|
|||||||
|
// (C) Copyright David Abrahams 2002.
|
||||||
|
// (C) Copyright Jeremy Siek 2002.
|
||||||
|
// (C) Copyright Thomas Witt 2002.
|
||||||
|
// Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
|
||||||
|
#define BOOST_ITERATOR_FACADE_23022003THW_HPP
|
||||||
|
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
|
#include <boost/iterator.hpp>
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
#include <boost/iterator/interoperable.hpp>
|
||||||
|
#include <boost/iterator/detail/enable_if.hpp>
|
||||||
|
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
|
||||||
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
|
|
||||||
|
#include <boost/mpl/apply_if.hpp>
|
||||||
|
#include <boost/mpl/or.hpp>
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_def.hpp> // this goes last
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
struct use_default;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
// enable if for use in operator implementation.
|
||||||
|
//
|
||||||
|
// enable_if_interoperable falls back to always enabled for compilers
|
||||||
|
// that don't support enable_if or is_convertible.
|
||||||
|
//
|
||||||
|
template <
|
||||||
|
class Facade1
|
||||||
|
, class Facade2
|
||||||
|
, class Return
|
||||||
|
>
|
||||||
|
struct enable_if_interoperable
|
||||||
|
#ifndef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||||
|
: ::boost::detail::enable_if<
|
||||||
|
mpl::or_<
|
||||||
|
is_convertible<Facade1, Facade2>
|
||||||
|
, is_convertible<Facade2, Facade1>
|
||||||
|
>
|
||||||
|
, Return
|
||||||
|
>
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||||
|
typedef Return type;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add const qualification for iterators which are not writable
|
||||||
|
//
|
||||||
|
template<class Value, class AccessCategory>
|
||||||
|
struct const_qualified_ref :
|
||||||
|
mpl::if_< is_tag< writable_iterator_tag, AccessCategory >,
|
||||||
|
Value&,
|
||||||
|
Value const& >
|
||||||
|
{};
|
||||||
|
|
||||||
|
// The apparent duplication here works around a Borland problem
|
||||||
|
template<class Value, class AccessCategory>
|
||||||
|
struct const_qualified_ptr :
|
||||||
|
mpl::if_< is_tag< writable_iterator_tag, AccessCategory >,
|
||||||
|
Value*,
|
||||||
|
Value const* >
|
||||||
|
{};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generates the associated types for an iterator_facade with the
|
||||||
|
// given parameters. Additionally generates a 'base' type for
|
||||||
|
// compiler/library combinations which require user-defined
|
||||||
|
// iterators to inherit from std::iterator.
|
||||||
|
//
|
||||||
|
template <
|
||||||
|
class Value
|
||||||
|
, class AccessCategory
|
||||||
|
, class TraversalCategory
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
>
|
||||||
|
struct iterator_facade_types
|
||||||
|
{
|
||||||
|
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
||||||
|
|
||||||
|
typedef typename remove_cv<Value>::type value_type;
|
||||||
|
|
||||||
|
typedef Difference difference_type;
|
||||||
|
|
||||||
|
typedef typename const_qualified_ptr<Value, AccessCategory>::type pointer;
|
||||||
|
|
||||||
|
// The use_default support is needed for iterator_adaptor.
|
||||||
|
// For practical reasons iterator_adaptor needs to specify
|
||||||
|
// a fixed number of template arguments of iterator_facade.
|
||||||
|
// So use_default is its way to say: "What I really mean
|
||||||
|
// is your default parameter".
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
is_same<Reference, use_default>
|
||||||
|
, typename const_qualified_ref<Value, AccessCategory>::type
|
||||||
|
, Reference
|
||||||
|
>::type reference;
|
||||||
|
|
||||||
|
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||||
|
&& (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
|
||||||
|
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
|
||||||
|
|| BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \
|
||||||
|
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
|
||||||
|
|
||||||
|
// To interoperate with some broken library/compiler
|
||||||
|
// combinations, user-defined iterators must be derived from
|
||||||
|
// std::iterator. It is possible to implement a standard
|
||||||
|
// library for broken compilers without this limitation.
|
||||||
|
# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
|
||||||
|
|
||||||
|
typedef
|
||||||
|
iterator<iterator_category, value_type, difference_type, pointer, reference>
|
||||||
|
base;
|
||||||
|
# endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// operator->() needs special support for input iterators to strictly meet the
|
||||||
|
// standard's requirements. If *i is not a reference type, we must still
|
||||||
|
// produce a (constant) lvalue to which a pointer can be formed. We do that by
|
||||||
|
// returning an instantiation of this special proxy class template.
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct operator_arrow_proxy
|
||||||
|
{
|
||||||
|
operator_arrow_proxy(T const* px) : m_value(*px) {}
|
||||||
|
const T* operator->() const { return &m_value; }
|
||||||
|
// This function is needed for MWCW and BCC, which won't call operator->
|
||||||
|
// again automatically per 13.3.1.2 para 8
|
||||||
|
operator const T*() const { return &m_value; }
|
||||||
|
T m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A metafunction that gets the result type for operator->. Also
|
||||||
|
// has a static function make() which builds the result from a
|
||||||
|
// Reference
|
||||||
|
template <class Value, class Category, class Reference, class Pointer>
|
||||||
|
struct operator_arrow_result
|
||||||
|
{
|
||||||
|
// CWPro8.3 won't accept "operator_arrow_result::type", and we
|
||||||
|
// need that type below, so metafunction forwarding would be a
|
||||||
|
// losing proposition here.
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
is_tag<
|
||||||
|
readable_lvalue_iterator_tag
|
||||||
|
, typename access_category_tag<Category,Reference>::type
|
||||||
|
>
|
||||||
|
, Pointer
|
||||||
|
, operator_arrow_proxy<Value>
|
||||||
|
>::type type;
|
||||||
|
|
||||||
|
static type make(Reference x)
|
||||||
|
{
|
||||||
|
return type(&x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||||
|
// Deal with ETI
|
||||||
|
template<>
|
||||||
|
struct operator_arrow_result<int, int, int, int>
|
||||||
|
{
|
||||||
|
typedef int type;
|
||||||
|
};
|
||||||
|
# endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Facade is actually an iterator. We require Facade here
|
||||||
|
// so that we do not have to go through iterator_traits
|
||||||
|
// to access the traits
|
||||||
|
//
|
||||||
|
template <class Iterator>
|
||||||
|
class operator_brackets_proxy
|
||||||
|
{
|
||||||
|
typedef typename Iterator::reference reference;
|
||||||
|
typedef typename Iterator::value_type value_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
operator_brackets_proxy(Iterator const& iter)
|
||||||
|
: m_iter(iter)
|
||||||
|
{}
|
||||||
|
|
||||||
|
operator reference()
|
||||||
|
{
|
||||||
|
return *m_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator_brackets_proxy& operator=(value_type const& val)
|
||||||
|
{
|
||||||
|
*m_iter = val;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Iterator m_iter;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Iterator, class ValueType, class Category, class Reference>
|
||||||
|
struct operator_brackets_result
|
||||||
|
{
|
||||||
|
typedef typename access_category_tag<Category,Reference>::type access_category;
|
||||||
|
|
||||||
|
typedef is_tag<writable_iterator_tag, access_category> use_proxy;
|
||||||
|
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
use_proxy
|
||||||
|
, operator_brackets_proxy<Iterator>
|
||||||
|
, ValueType
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
|
||||||
|
{
|
||||||
|
return operator_brackets_proxy<Iterator>(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
|
||||||
|
{
|
||||||
|
return *iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
|
// Macros which describe the declarations of binary operators
|
||||||
|
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
|
||||||
|
template < \
|
||||||
|
class Derived1, class V1, class AC1, class TC1, class R1, class D1 \
|
||||||
|
, class Derived2, class V2, class AC2, class TC2, class R2, class D2 \
|
||||||
|
> \
|
||||||
|
prefix typename detail::enable_if_interoperable< \
|
||||||
|
Derived1, Derived2, result_type \
|
||||||
|
>::type \
|
||||||
|
operator op( \
|
||||||
|
iterator_facade<Derived1, V1, AC1, TC1, R1, D1> const& lhs \
|
||||||
|
, iterator_facade<Derived2, V2, AC2, TC2, R2, D2> const& rhs)
|
||||||
|
|
||||||
|
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
|
||||||
|
template <class Derived, class V, class AC, class TC, class R, class D> \
|
||||||
|
prefix Derived operator+ args
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helper class for granting access to the iterator core interface.
|
||||||
|
//
|
||||||
|
// The simple core interface is used by iterator_facade. The core
|
||||||
|
// interface of a user/library defined iterator type should not be made public
|
||||||
|
// so that it does not clutter the public interface. Instead iterator_core_access
|
||||||
|
// should be made friend so that iterator_facade can access the core
|
||||||
|
// interface through iterator_core_access.
|
||||||
|
//
|
||||||
|
class iterator_core_access
|
||||||
|
{
|
||||||
|
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
|
||||||
|
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
// Tasteless as this may seem, making all members public allows member templates
|
||||||
|
// to work in the absence of member template friends.
|
||||||
|
public:
|
||||||
|
# else
|
||||||
|
|
||||||
|
template <class I, class V, class AC, class TC, class R, class D> friend class iterator_facade;
|
||||||
|
|
||||||
|
# define BOOST_ITERATOR_FACADE_RELATION(op) \
|
||||||
|
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, bool);
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(==)
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(!=)
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(<)
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(>)
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(<=)
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(>=)
|
||||||
|
# undef BOOST_ITERATOR_FACADE_RELATION
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_INTEROP_HEAD(
|
||||||
|
friend, -, typename Derived1::difference_type)
|
||||||
|
;
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
||||||
|
friend
|
||||||
|
, (iterator_facade<Derived, V, AC, TC, R, D> const&
|
||||||
|
, typename Derived::difference_type)
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
||||||
|
friend
|
||||||
|
, (typename Derived::difference_type
|
||||||
|
, iterator_facade<Derived, V, AC, TC, R, D> const&)
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
template <class Facade>
|
||||||
|
static typename Facade::reference dereference(Facade const& f)
|
||||||
|
{
|
||||||
|
return f.dereference();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Facade>
|
||||||
|
static void increment(Facade& f)
|
||||||
|
{
|
||||||
|
f.increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Facade>
|
||||||
|
static void decrement(Facade& f)
|
||||||
|
{
|
||||||
|
f.decrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Facade1, class Facade2>
|
||||||
|
static bool equal(Facade1 const& f1, Facade2 const& f2)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return f1.distance_to(f2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// objects of this class are useless
|
||||||
|
iterator_core_access(); //undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// iterator_facade - use as a public base class for defining new
|
||||||
|
// standard-conforming iterators.
|
||||||
|
//
|
||||||
|
template <
|
||||||
|
class Derived // The derived iterator type being constructed
|
||||||
|
, class Value
|
||||||
|
, class AccessCategory
|
||||||
|
, class TraversalCategory
|
||||||
|
, class Reference = typename detail::const_qualified_ref<Value, AccessCategory>::type
|
||||||
|
, class Difference = std::ptrdiff_t
|
||||||
|
>
|
||||||
|
class iterator_facade
|
||||||
|
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
|
||||||
|
: public detail::iterator_facade_types<
|
||||||
|
Value, AccessCategory, TraversalCategory, Reference, Difference
|
||||||
|
>::base
|
||||||
|
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef typename
|
||||||
|
detail::iterator_facade_types<Value, AccessCategory, TraversalCategory, Reference, Difference>
|
||||||
|
types;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Curiously Recursive Template interface.
|
||||||
|
//
|
||||||
|
typedef Derived derived_t;
|
||||||
|
|
||||||
|
Derived& derived()
|
||||||
|
{
|
||||||
|
return static_cast<Derived&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Derived const& derived() const
|
||||||
|
{
|
||||||
|
return static_cast<Derived const&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef typename types::value_type value_type;
|
||||||
|
typedef typename types::reference reference;
|
||||||
|
typedef typename types::difference_type difference_type;
|
||||||
|
typedef typename types::pointer pointer;
|
||||||
|
typedef typename types::iterator_category iterator_category;
|
||||||
|
|
||||||
|
reference operator*() const
|
||||||
|
{
|
||||||
|
return iterator_core_access::dereference(this->derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
typename detail::operator_arrow_result<
|
||||||
|
value_type
|
||||||
|
, iterator_category
|
||||||
|
, reference
|
||||||
|
, pointer
|
||||||
|
>::type
|
||||||
|
operator->() const
|
||||||
|
{
|
||||||
|
return detail::operator_arrow_result<
|
||||||
|
value_type
|
||||||
|
, iterator_category
|
||||||
|
, reference
|
||||||
|
, pointer
|
||||||
|
>::make(*this->derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
typename detail::operator_brackets_result<Derived,value_type,iterator_category,reference>::type
|
||||||
|
operator[](difference_type n) const
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
detail::operator_brackets_result<Derived,value_type,iterator_category,reference>::use_proxy
|
||||||
|
use_proxy;
|
||||||
|
|
||||||
|
return detail::make_operator_brackets_result<Derived>(this->derived() + n, use_proxy());
|
||||||
|
}
|
||||||
|
|
||||||
|
Derived& operator++()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||||
|
// There appears to be a bug which trashes the data of classes
|
||||||
|
// derived from iterator_facade when they are assigned unless we
|
||||||
|
// define this assignment operator. This bug is only revealed
|
||||||
|
// (so far) in STLPort debug mode, but it's clearly a codegen
|
||||||
|
// problem so we apply the workaround for all MSVC6.
|
||||||
|
iterator_facade& operator=(iterator_facade const&)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Operator implementation. The library supplied operators
|
||||||
|
// enables the user to provide fully interoperable constant/mutable
|
||||||
|
// iterator types. I.e. the library provides all operators
|
||||||
|
// for all mutable/constant iterator combinations.
|
||||||
|
//
|
||||||
|
// Note though that this kind of interoperability for constant/mutable
|
||||||
|
// iterators is not required by the standard for container iterators.
|
||||||
|
// All the standard asks for is a conversion mutable -> constant.
|
||||||
|
// Most standard library implementations nowadays provide fully interoperable
|
||||||
|
// iterator implementations, but there are still heavily used implementations
|
||||||
|
// that do not provide them. (Actually it's even worse, they do not provide
|
||||||
|
// them for only a few iterators.)
|
||||||
|
//
|
||||||
|
// ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
|
||||||
|
// enable the user to turn off mixed type operators
|
||||||
|
//
|
||||||
|
// The library takes care to provide only the right operator overloads.
|
||||||
|
// I.e.
|
||||||
|
//
|
||||||
|
// bool operator==(Iterator, Iterator);
|
||||||
|
// bool operator==(ConstIterator, Iterator);
|
||||||
|
// bool operator==(Iterator, ConstIterator);
|
||||||
|
// bool operator==(ConstIterator, ConstIterator);
|
||||||
|
//
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
// In order to do so it uses c++ idioms that are not yet widely supported
|
||||||
|
// by current compiler releases. The library is designed to degrade gracefully
|
||||||
|
// in the face of compiler deficiencies. In general compiler
|
||||||
|
// deficiencies result in less strict error checking and more obscure
|
||||||
|
// error messages, functionality is not affected.
|
||||||
|
//
|
||||||
|
// For full operation compiler support for "Substitution Failure Is Not An Error"
|
||||||
|
// (aka. enable_if) and boost::is_convertible is required.
|
||||||
|
//
|
||||||
|
// The following problems occur if support is lacking.
|
||||||
|
//
|
||||||
|
// Pseudo code
|
||||||
|
//
|
||||||
|
// ---------------
|
||||||
|
// AdaptorA<Iterator1> a1;
|
||||||
|
// AdaptorA<Iterator2> a2;
|
||||||
|
//
|
||||||
|
// // This will result in a no such overload error in full operation
|
||||||
|
// // If enable_if or is_convertible is not supported
|
||||||
|
// // The instantiation will fail with an error hopefully indicating that
|
||||||
|
// // there is no operator== for Iterator1, Iterator2
|
||||||
|
// // The same will happen if no enable_if is used to remove
|
||||||
|
// // false overloads from the templated conversion constructor
|
||||||
|
// // of AdaptorA.
|
||||||
|
//
|
||||||
|
// a1 == a2;
|
||||||
|
// ----------------
|
||||||
|
//
|
||||||
|
// AdaptorA<Iterator> a;
|
||||||
|
// AdaptorB<Iterator> b;
|
||||||
|
//
|
||||||
|
// // This will result in a no such overload error in full operation
|
||||||
|
// // If enable_if is not supported the static assert used
|
||||||
|
// // in the operator implementation will fail.
|
||||||
|
// // This will accidently work if is_convertible is not supported.
|
||||||
|
//
|
||||||
|
// a == b;
|
||||||
|
// ----------------
|
||||||
|
//
|
||||||
|
|
||||||
|
# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, condition, return_prefix, base_op) \
|
||||||
|
BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
|
||||||
|
{ \
|
||||||
|
/* For those compilers that do not support enable_if */ \
|
||||||
|
BOOST_STATIC_ASSERT(( \
|
||||||
|
is_interoperable< Derived1, Derived2 >::value \
|
||||||
|
&& condition \
|
||||||
|
)); \
|
||||||
|
return_prefix iterator_core_access::base_op( \
|
||||||
|
static_cast<Derived2 const&>(rhs), static_cast<Derived1 const&>(lhs)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
|
||||||
|
BOOST_ITERATOR_FACADE_INTEROP( \
|
||||||
|
op \
|
||||||
|
, bool \
|
||||||
|
, true \
|
||||||
|
, return_prefix \
|
||||||
|
, base_op \
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(<, return 0 >, distance_to)
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(>, return 0 <, distance_to)
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(<=, return 0 >=, distance_to)
|
||||||
|
BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_to)
|
||||||
|
# undef BOOST_ITERATOR_FACADE_RELATION
|
||||||
|
|
||||||
|
// operator- requires an additional part in the static assertion
|
||||||
|
BOOST_ITERATOR_FACADE_INTEROP(
|
||||||
|
-
|
||||||
|
, typename Derived1::difference_type
|
||||||
|
, (is_same<
|
||||||
|
BOOST_DEDUCED_TYPENAME Derived1::difference_type
|
||||||
|
, BOOST_DEDUCED_TYPENAME Derived2::difference_type
|
||||||
|
>::value)
|
||||||
|
, return
|
||||||
|
, distance_to )
|
||||||
|
# undef BOOST_ITERATOR_FACADE_INTEROP
|
||||||
|
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
|
||||||
|
|
||||||
|
# define BOOST_ITERATOR_FACADE_PLUS(args) \
|
||||||
|
BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
|
||||||
|
{ \
|
||||||
|
Derived tmp(static_cast<Derived const&>(i)); \
|
||||||
|
return tmp += n; \
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_PLUS((
|
||||||
|
iterator_facade<Derived, V, AC, TC, R, D> const& i
|
||||||
|
, typename Derived::difference_type n
|
||||||
|
))
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_PLUS((
|
||||||
|
typename Derived::difference_type n
|
||||||
|
, iterator_facade<Derived, V, AC, TC, R, D> const& i
|
||||||
|
))
|
||||||
|
# undef BOOST_ITERATOR_FACADE_PLUS
|
||||||
|
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP
|
93
include/boost/iterator/iterator_traits.hpp
Normal file
93
include/boost/iterator/iterator_traits.hpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// Copyright David Abrahams 2003. Permission to copy, use,
|
||||||
|
// modify, sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
#ifndef ITERATOR_TRAITS_DWA200347_HPP
|
||||||
|
# define ITERATOR_TRAITS_DWA200347_HPP
|
||||||
|
|
||||||
|
# include <boost/detail/iterator.hpp>
|
||||||
|
# include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
// Unfortunately, g++ 2.95.x chokes when we define a class template
|
||||||
|
// iterator_category which has the same name as its
|
||||||
|
// std::iterator_category() function, probably due in part to the
|
||||||
|
// "std:: is visible globally" hack it uses. Use
|
||||||
|
// BOOST_ITERATOR_CATEGORY to write code that's portable to older
|
||||||
|
// GCCs.
|
||||||
|
|
||||||
|
# if BOOST_WORKAROUND(__GNUC__, <= 2)
|
||||||
|
# define BOOST_ITERATOR_CATEGORY iterator_category_
|
||||||
|
# else
|
||||||
|
# define BOOST_ITERATOR_CATEGORY iterator_category
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
struct iterator_value
|
||||||
|
{
|
||||||
|
typedef typename detail::iterator_traits<Iterator>::value_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
struct iterator_reference
|
||||||
|
{
|
||||||
|
typedef typename detail::iterator_traits<Iterator>::reference type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
struct iterator_pointer
|
||||||
|
{
|
||||||
|
typedef typename detail::iterator_traits<Iterator>::pointer type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
struct iterator_difference
|
||||||
|
{
|
||||||
|
typedef typename detail::iterator_traits<Iterator>::difference_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
struct BOOST_ITERATOR_CATEGORY
|
||||||
|
{
|
||||||
|
typedef typename detail::iterator_traits<Iterator>::iterator_category type;
|
||||||
|
};
|
||||||
|
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||||
|
template <>
|
||||||
|
struct iterator_value<int>
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct iterator_reference<int>
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct iterator_pointer<int>
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct iterator_difference<int>
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct BOOST_ITERATOR_CATEGORY<int>
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
# endif
|
||||||
|
|
||||||
|
} // namespace boost::iterator
|
||||||
|
|
||||||
|
#endif // ITERATOR_TRAITS_DWA200347_HPP
|
204
include/boost/iterator/new_iterator_tests.hpp
Normal file
204
include/boost/iterator/new_iterator_tests.hpp
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
#ifndef BOOST_NEW_ITERATOR_TESTS_HPP
|
||||||
|
# define BOOST_NEW_ITERATOR_TESTS_HPP
|
||||||
|
|
||||||
|
// This is meant to be the beginnings of a comprehensive, generic
|
||||||
|
// test suite for STL concepts such as iterators and containers.
|
||||||
|
//
|
||||||
|
// Revision History:
|
||||||
|
// 28 Oct 2002 Started update for new iterator categories
|
||||||
|
// (Jeremy Siek)
|
||||||
|
// 28 Apr 2002 Fixed input iterator requirements.
|
||||||
|
// For a == b a++ == b++ is no longer required.
|
||||||
|
// See 24.1.1/3 for details.
|
||||||
|
// (Thomas Witt)
|
||||||
|
// 08 Feb 2001 Fixed bidirectional iterator test so that
|
||||||
|
// --i is no longer a precondition.
|
||||||
|
// (Jeremy Siek)
|
||||||
|
// 04 Feb 2001 Added lvalue test, corrected preconditions
|
||||||
|
// (David Abrahams)
|
||||||
|
|
||||||
|
# include <iterator>
|
||||||
|
# include <assert.h>
|
||||||
|
# include <boost/type_traits.hpp>
|
||||||
|
# include <boost/static_assert.hpp>
|
||||||
|
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
|
||||||
|
# include <boost/detail/iterator.hpp>
|
||||||
|
# include <boost/pending/iterator_tests.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
void is_readable(readable_iterator_tag) { }
|
||||||
|
void is_writable(writable_iterator_tag) { }
|
||||||
|
void is_swappable(swappable_iterator_tag) { }
|
||||||
|
void is_constant_lvalue(readable_lvalue_iterator_tag) { }
|
||||||
|
void is_mutable_lvalue(writable_lvalue_iterator_tag) { }
|
||||||
|
|
||||||
|
// Preconditions: *i == v
|
||||||
|
template <class Iterator, class T>
|
||||||
|
void readable_iterator_test(const Iterator i1, T v)
|
||||||
|
{
|
||||||
|
Iterator i2(i1); // Copy Constructible
|
||||||
|
typedef typename detail::iterator_traits<Iterator>::reference ref_t;
|
||||||
|
ref_t r1 = *i1;
|
||||||
|
ref_t r2 = *i2;
|
||||||
|
T v1 = r1;
|
||||||
|
T v2 = r2;
|
||||||
|
assert(v1 == v);
|
||||||
|
assert(v2 == v);
|
||||||
|
typedef typename access_category<Iterator>::type result_category;
|
||||||
|
is_readable(result_category());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator, class T>
|
||||||
|
void writable_iterator_test(Iterator i, T v)
|
||||||
|
{
|
||||||
|
Iterator i2(i); // Copy Constructible
|
||||||
|
*i2 = v;
|
||||||
|
is_writable(typename access_category<Iterator>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
void swappable_iterator_test(Iterator i, Iterator j)
|
||||||
|
{
|
||||||
|
Iterator i2(i), j2(j);
|
||||||
|
typename detail::iterator_traits<Iterator>::value_type bi = *i, bj = *j;
|
||||||
|
iter_swap(i2, j2);
|
||||||
|
typename detail::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
|
||||||
|
assert(bi == aj && bj == ai);
|
||||||
|
typedef typename access_category<Iterator>::type result_category;
|
||||||
|
is_swappable(result_category());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator, class T>
|
||||||
|
void constant_lvalue_iterator_test(Iterator i, T v1)
|
||||||
|
{
|
||||||
|
Iterator i2(i);
|
||||||
|
typedef typename detail::iterator_traits<Iterator>::value_type value_type;
|
||||||
|
typedef typename detail::iterator_traits<Iterator>::reference reference;
|
||||||
|
BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
|
||||||
|
const T& v2 = *i2;
|
||||||
|
assert(v1 == v2);
|
||||||
|
typedef typename access_category<Iterator>::type result_category;
|
||||||
|
is_constant_lvalue(result_category());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator, class T>
|
||||||
|
void mutable_lvalue_iterator_test(Iterator i, T v1, T v2)
|
||||||
|
{
|
||||||
|
Iterator i2(i);
|
||||||
|
typedef typename detail::iterator_traits<Iterator>::value_type value_type;
|
||||||
|
typedef typename detail::iterator_traits<Iterator>::reference reference;
|
||||||
|
BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
|
||||||
|
T& v3 = *i2;
|
||||||
|
assert(v1 == v3);
|
||||||
|
*i = v2;
|
||||||
|
T& v4 = *i2;
|
||||||
|
assert(v2 == v4);
|
||||||
|
typedef typename access_category<Iterator>::type result_category;
|
||||||
|
is_mutable_lvalue(result_category());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator, class T>
|
||||||
|
void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2)
|
||||||
|
{
|
||||||
|
Iterator i2;
|
||||||
|
Iterator i3(i);
|
||||||
|
i2 = i;
|
||||||
|
assert(i2 == i3);
|
||||||
|
assert(i != j);
|
||||||
|
assert(i2 != j);
|
||||||
|
readable_iterator_test(i, val1);
|
||||||
|
readable_iterator_test(i2, val1);
|
||||||
|
readable_iterator_test(i3, val1);
|
||||||
|
|
||||||
|
assert(i == i2++);
|
||||||
|
assert(i != ++i3);
|
||||||
|
|
||||||
|
readable_iterator_test(i2, val2);
|
||||||
|
readable_iterator_test(i3, val2);
|
||||||
|
|
||||||
|
readable_iterator_test(i, val1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator, class T>
|
||||||
|
void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2)
|
||||||
|
{
|
||||||
|
forward_readable_iterator_test(i, j, val1, val2);
|
||||||
|
Iterator i2 = i;
|
||||||
|
++i2;
|
||||||
|
swappable_iterator_test(i, i2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bidirectional
|
||||||
|
// Preconditions: *i == v1, *++i == v2
|
||||||
|
template <class Iterator, class T>
|
||||||
|
void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
|
||||||
|
{
|
||||||
|
Iterator j(i);
|
||||||
|
++j;
|
||||||
|
forward_readable_iterator_test(i, j, v1, v2);
|
||||||
|
++i;
|
||||||
|
|
||||||
|
Iterator i1 = i, i2 = i;
|
||||||
|
|
||||||
|
assert(i == i1--);
|
||||||
|
assert(i != --i2);
|
||||||
|
|
||||||
|
readable_iterator_test(i, v2);
|
||||||
|
readable_iterator_test(i1, v1);
|
||||||
|
readable_iterator_test(i2, v1);
|
||||||
|
|
||||||
|
--i;
|
||||||
|
assert(i == i1);
|
||||||
|
assert(i == i2);
|
||||||
|
++i1;
|
||||||
|
++i2;
|
||||||
|
|
||||||
|
readable_iterator_test(i, v1);
|
||||||
|
readable_iterator_test(i1, v2);
|
||||||
|
readable_iterator_test(i2, v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// random access
|
||||||
|
// Preconditions: [i,i+N) is a valid range
|
||||||
|
template <class Iterator, class TrueVals>
|
||||||
|
void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
||||||
|
{
|
||||||
|
bidirectional_readable_iterator_test(i, vals[0], vals[1]);
|
||||||
|
const Iterator j = i;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
for (c = 0; c < N-1; ++c) {
|
||||||
|
assert(i == j + c);
|
||||||
|
assert(*i == vals[c]);
|
||||||
|
assert(*i == j[c]);
|
||||||
|
assert(*i == *(j + c));
|
||||||
|
assert(*i == *(c + j));
|
||||||
|
++i;
|
||||||
|
assert(i > j);
|
||||||
|
assert(i >= j);
|
||||||
|
assert(j <= i);
|
||||||
|
assert(j < i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator k = j + N - 1;
|
||||||
|
for (c = 0; c < N-1; ++c) {
|
||||||
|
assert(i == k - c);
|
||||||
|
assert(*i == vals[N - 1 - c]);
|
||||||
|
assert(*i == j[N - 1 - c]);
|
||||||
|
Iterator q = k - c;
|
||||||
|
assert(*i == *q);
|
||||||
|
assert(i > j);
|
||||||
|
assert(i >= j);
|
||||||
|
assert(j <= i);
|
||||||
|
assert(j < i);
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #if 0'd code snipped; see CVS v 1.4 if you need it back
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_NEW_ITERATOR_TESTS_HPP
|
92
include/boost/iterator/permutation_iterator.hpp
Normal file
92
include/boost/iterator/permutation_iterator.hpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// (C) Copyright Toon Knapen 2001.
|
||||||
|
// (C) Copyright David Abrahams 2003.
|
||||||
|
// (C) Copyright Roland Richter 2003.
|
||||||
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
|
// is granted provided this copyright notice appears in all copies.
|
||||||
|
// This software is provided "as is" without express or implied
|
||||||
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
|
|
||||||
|
#ifndef BOOST_PERMUTATION_ITERATOR_HPP
|
||||||
|
#define BOOST_PERMUTATION_ITERATOR_HPP
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
template< class ElementIterator
|
||||||
|
, class IndexIterator
|
||||||
|
, class ValueT = use_default
|
||||||
|
, class CategoryT = use_default
|
||||||
|
, class ReferenceT = use_default
|
||||||
|
, class DifferenceT = use_default >
|
||||||
|
class permutation_iterator
|
||||||
|
: public iterator_adaptor<
|
||||||
|
permutation_iterator<ElementIterator, IndexIterator, ValueT, CategoryT, ReferenceT, DifferenceT>
|
||||||
|
, ElementIterator, ValueT, CategoryT, ReferenceT, DifferenceT >
|
||||||
|
{
|
||||||
|
typedef iterator_adaptor<
|
||||||
|
permutation_iterator<ElementIterator, IndexIterator, ValueT, CategoryT, ReferenceT, DifferenceT>
|
||||||
|
, ElementIterator, ValueT, CategoryT, ReferenceT, DifferenceT > super_t;
|
||||||
|
|
||||||
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
public:
|
||||||
|
permutation_iterator() : order_it_() {}
|
||||||
|
|
||||||
|
explicit permutation_iterator(ElementIterator x, IndexIterator y)
|
||||||
|
: super_t(x), order_it_(y) {}
|
||||||
|
|
||||||
|
template<class OtherElementIterator, class OtherIndexIterator, class V, class C, class R, class D >
|
||||||
|
permutation_iterator(
|
||||||
|
permutation_iterator<OtherElementIterator, OtherIndexIterator, V, C, R, D> const& r
|
||||||
|
, typename enable_if_convertible<OtherElementIterator, ElementIterator>::type* = 0
|
||||||
|
, typename enable_if_convertible<OtherIndexIterator, IndexIterator>::type* = 0
|
||||||
|
)
|
||||||
|
: super_t(r.base())
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typename super_t::reference dereference() const
|
||||||
|
{ return *(this->base() + *this->order_it_); }
|
||||||
|
|
||||||
|
void increment() { ++this->order_it_; }
|
||||||
|
void decrement() { --this->order_it_; }
|
||||||
|
|
||||||
|
void advance(typename super_t::difference_type n)
|
||||||
|
{
|
||||||
|
std::advance( order_it_, n );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherElementIterator, class OtherIndexIterator, class V, class C, class R, class D >
|
||||||
|
typename super_t::difference_type
|
||||||
|
distance_to( permutation_iterator<OtherElementIterator, OtherIndexIterator, V, C, R, D> const& y ) const
|
||||||
|
{
|
||||||
|
return std::distance( this->order_it_, y.order_it_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class OtherElementIterator, class OtherIndexIterator, class V, class C, class R, class D >
|
||||||
|
bool
|
||||||
|
equal( permutation_iterator<OtherElementIterator, OtherIndexIterator, V, C, R, D> const& y ) const
|
||||||
|
{
|
||||||
|
return( y.order_it_ == this->order_it_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexIterator order_it_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class ElementIterator, class IndexIterator>
|
||||||
|
permutation_iterator<ElementIterator, IndexIterator>
|
||||||
|
make_permutation_iterator( ElementIterator e, IndexIterator i )
|
||||||
|
{
|
||||||
|
return permutation_iterator<ElementIterator, IndexIterator>( e, i );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
71
include/boost/iterator/reverse_iterator.hpp
Normal file
71
include/boost/iterator/reverse_iterator.hpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// (C) Copyright David Abrahams 2002.
|
||||||
|
// (C) Copyright Jeremy Siek 2002.
|
||||||
|
// (C) Copyright Thomas Witt 2002.
|
||||||
|
// Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
#ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
||||||
|
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
||||||
|
|
||||||
|
#include <boost/iterator.hpp>
|
||||||
|
#include <boost/utility.hpp>
|
||||||
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
template <class Iterator>
|
||||||
|
class reverse_iterator
|
||||||
|
: public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
|
||||||
|
{
|
||||||
|
typedef iterator_adaptor< reverse_iterator<Iterator>, Iterator > super_t;
|
||||||
|
|
||||||
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
public:
|
||||||
|
reverse_iterator() {}
|
||||||
|
|
||||||
|
explicit reverse_iterator(Iterator x)
|
||||||
|
: super_t(x) {}
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
reverse_iterator(
|
||||||
|
reverse_iterator<OtherIterator> const& r
|
||||||
|
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||||
|
)
|
||||||
|
: super_t(r.base())
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typename super_t::reference dereference() const { return *boost::prior(this->base()); }
|
||||||
|
|
||||||
|
void increment() { --this->base_reference(); }
|
||||||
|
void decrement() { ++this->base_reference(); }
|
||||||
|
|
||||||
|
void advance(typename super_t::difference_type n)
|
||||||
|
{
|
||||||
|
this->base_reference() += -n;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OtherIterator>
|
||||||
|
typename super_t::difference_type
|
||||||
|
distance_to(reverse_iterator<OtherIterator> const& y) const
|
||||||
|
{
|
||||||
|
return this->base_reference() - y.base();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class BidirectionalIterator>
|
||||||
|
reverse_iterator<BidirectionalIterator> make_reverse_iterator(BidirectionalIterator x)
|
||||||
|
{
|
||||||
|
return reverse_iterator<BidirectionalIterator>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
154
include/boost/iterator/transform_iterator.hpp
Normal file
154
include/boost/iterator/transform_iterator.hpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
// (C) Copyright David Abrahams 2002.
|
||||||
|
// (C) Copyright Jeremy Siek 2002.
|
||||||
|
// (C) Copyright Thomas Witt 2002.
|
||||||
|
// Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||||
|
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||||
|
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
#include <boost/iterator.hpp>
|
||||||
|
#include <boost/iterator/detail/enable_if.hpp>
|
||||||
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
#include <boost/mpl/and.hpp>
|
||||||
|
#include <boost/mpl/bool.hpp>
|
||||||
|
#include <boost/type_traits/function_traits.hpp>
|
||||||
|
#include <boost/type_traits/is_const.hpp>
|
||||||
|
#include <boost/type_traits/is_function.hpp>
|
||||||
|
#include <boost/type_traits/is_reference.hpp>
|
||||||
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
|
||||||
|
class transform_iterator;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class UnaryFunction>
|
||||||
|
struct function_object_result
|
||||||
|
{
|
||||||
|
typedef typename UnaryFunction::result_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
template <class Return, class Argument>
|
||||||
|
struct function_object_result<Return(*)(Argument)>
|
||||||
|
{
|
||||||
|
typedef Return type;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Given the transform iterator's transformation and iterator, this
|
||||||
|
// is the type used as its traits.
|
||||||
|
template <class UnaryFunction, class Iterator, class Reference, class Value>
|
||||||
|
struct transform_iterator_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// transform_iterator does not support writable/swappable iterators
|
||||||
|
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||||
|
BOOST_STATIC_ASSERT((is_tag< readable_iterator_tag, typename access_category<Iterator>::type >::value));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef typename mpl::apply_if<
|
||||||
|
is_same< Reference, use_default >
|
||||||
|
, function_object_result<UnaryFunction>
|
||||||
|
, mpl::identity<Reference>
|
||||||
|
>::type result_type;
|
||||||
|
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
is_same< Value, use_default >
|
||||||
|
, typename remove_reference< result_type >::type
|
||||||
|
, Value
|
||||||
|
>::type cv_value_type;
|
||||||
|
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
is_reference< result_type >
|
||||||
|
, typename mpl::if_<
|
||||||
|
is_const< cv_value_type >
|
||||||
|
, readable_lvalue_iterator_tag
|
||||||
|
, writable_lvalue_iterator_tag
|
||||||
|
>::type
|
||||||
|
, readable_iterator_tag
|
||||||
|
>::type maximum_access_tag;
|
||||||
|
|
||||||
|
typedef typename minimum_category<
|
||||||
|
maximum_access_tag
|
||||||
|
, typename access_category<Iterator>::type
|
||||||
|
>::type access_category;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef iterator_adaptor<
|
||||||
|
transform_iterator<UnaryFunction, Iterator, Reference, Value>
|
||||||
|
, Iterator
|
||||||
|
, cv_value_type
|
||||||
|
, iterator_tag<
|
||||||
|
access_category
|
||||||
|
, typename traversal_category<Iterator>::type
|
||||||
|
>
|
||||||
|
, result_type
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class UnaryFunction, class Iterator, class Reference, class Value>
|
||||||
|
class transform_iterator
|
||||||
|
: public detail::transform_iterator_base<UnaryFunction, Iterator, Reference, Value>::type
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
detail::transform_iterator_base<UnaryFunction, Iterator, Reference, Value>::type
|
||||||
|
super_t;
|
||||||
|
|
||||||
|
friend class iterator_core_access;
|
||||||
|
|
||||||
|
public:
|
||||||
|
transform_iterator() { }
|
||||||
|
|
||||||
|
transform_iterator(Iterator const& x, UnaryFunction f)
|
||||||
|
: super_t(x), m_f(f) { }
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
transform_iterator(
|
||||||
|
transform_iterator<UnaryFunction, OtherIterator, Reference, Value> const& t
|
||||||
|
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||||
|
)
|
||||||
|
: super_t(t.base()), m_f(t.functor()) {}
|
||||||
|
|
||||||
|
UnaryFunction functor() const
|
||||||
|
{ return m_f; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
typename super_t::reference dereference() const
|
||||||
|
{ return m_f(*this->base()); }
|
||||||
|
|
||||||
|
// Probably should be the initial base class so it can be
|
||||||
|
// optimized away via EBO if it is an empty class.
|
||||||
|
UnaryFunction m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class UnaryFunction, class Iterator>
|
||||||
|
transform_iterator<UnaryFunction, Iterator> make_transform_iterator(Iterator it, UnaryFunction fun)
|
||||||
|
{
|
||||||
|
return transform_iterator<UnaryFunction, Iterator>(it, fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||||
|
template <class Return, class Argument, class Iterator>
|
||||||
|
transform_iterator< Return (*)(Argument), Iterator, Return>
|
||||||
|
make_transform_iterator(Iterator it, Return (*fun)(Argument))
|
||||||
|
{
|
||||||
|
return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
Reference in New Issue
Block a user