mirror of
https://github.com/boostorg/iterator.git
synced 2025-07-03 07:46:41 +02:00
Compare commits
8 Commits
svn-branch
...
boost-1.20
Author | SHA1 | Date | |
---|---|---|---|
2e89b8ae60 | |||
51616fa845 | |||
d7884b5613 | |||
15b5b66776 | |||
6f90982a45 | |||
bfda34e9e0 | |||
5bfc03ed4a | |||
490bee3a06 |
@ -28,6 +28,8 @@
|
||||
// Incrementable.
|
||||
//
|
||||
// Revision History
|
||||
// 09 Feb 2001 Factored out is_numeric computation. Borland still
|
||||
// unhappy :( (David Abrahams)
|
||||
// 08 Feb 2001 Beginning of a failed attempt to appease Borland
|
||||
// (David Abrahams)
|
||||
// 07 Feb 2001 rename counting_iterator() -> make_counting_iterator()
|
||||
@ -45,6 +47,7 @@
|
||||
# include <boost/iterator_adaptors.hpp>
|
||||
# include <boost/type_traits.hpp>
|
||||
# include <boost/detail/numeric_traits.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
# ifndef BOOST_NO_LIMITS
|
||||
# include <limits>
|
||||
# endif
|
||||
@ -117,20 +120,31 @@ 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 {
|
||||
// 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);
|
||||
enum { value =
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
std::numeric_limits<T>::is_specialized
|
||||
#elif defined(__BORLANDC__)
|
||||
::boost::is_integral<T>::value
|
||||
#else
|
||||
boost::is_convertible<int,T>::value && boost::is_convertible<T,int>::value
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
// Compute the distance over arbitrary numeric and/or iterator types
|
||||
template <class Distance, class Incrementable>
|
||||
Distance any_distance(Incrementable start, Incrementable finish, Distance* = 0)
|
||||
{
|
||||
return distance_policy_select<
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
std::numeric_limits<Incrementable>::is_specialized
|
||||
#else
|
||||
// Causes warnings with GCC, but how else can I detect numeric types
|
||||
// at compile-time?
|
||||
(boost::is_convertible<int,Incrementable>::value &&
|
||||
boost::is_convertible<Incrementable,int>::value)
|
||||
#endif
|
||||
>::template policy<Distance, Incrementable>::distance(start, finish);
|
||||
|
||||
return distance_policy_select<(
|
||||
is_numeric<Incrementable>::value)>::template
|
||||
policy<Distance, Incrementable>::distance(start, finish);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
@ -138,19 +152,10 @@ namespace detail {
|
||||
template <class Incrementable>
|
||||
struct counting_iterator_traits {
|
||||
private:
|
||||
enum {
|
||||
is_numeric =
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
std::numeric_limits<Incrementable>::is_specialized
|
||||
#else
|
||||
// Try to detect numeric types at compile time
|
||||
boost::is_convertible<int,Incrementable>::value
|
||||
&& boost::is_convertible<Incrementable,int>::value
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef typename detail::counting_iterator_traits_select<
|
||||
is_numeric>::template traits<Incrementable> traits;
|
||||
enum {numeric = detail::is_numeric<Incrementable>::value };
|
||||
typedef typename detail::counting_iterator_traits_select<(
|
||||
numeric
|
||||
)>::template traits<Incrementable> traits;
|
||||
public:
|
||||
typedef Incrementable value_type;
|
||||
typedef const Incrementable& reference;
|
||||
|
@ -13,6 +13,8 @@
|
||||
// Revision History:
|
||||
|
||||
// 09 Feb 2001 David Abrahams
|
||||
// Improved interface to indirect_ and reverse_ iterators
|
||||
//
|
||||
// Rolled back Jeremy's new constructor for now; it was causing
|
||||
// problems with counting_iterator_test
|
||||
//
|
||||
@ -658,39 +660,77 @@ struct indirect_iterator_policies : public default_iterator_policies
|
||||
{ return **x; }
|
||||
};
|
||||
|
||||
// This macro definition is only temporary in this file
|
||||
# if !defined(BOOST_MSVC)
|
||||
# define BOOST_ARG_DEPENDENT_TYPENAME typename
|
||||
# else
|
||||
# define BOOST_ARG_DEPENDENT_TYPENAME
|
||||
# endif
|
||||
|
||||
} template <class T> struct undefined; namespace boost {
|
||||
|
||||
namespace detail {
|
||||
# if !defined(BOOST_MSVC) // stragely instantiated even when unused! Maybe try a recursive template someday ;-)
|
||||
template <class T>
|
||||
struct value_type_of_value_type {
|
||||
typedef typename boost::detail::iterator_traits<T>::value_type outer_value;
|
||||
typedef typename boost::detail::iterator_traits<outer_value>::value_type type;
|
||||
};
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class OuterIterator, // Mutable or Immutable, does not matter
|
||||
// Mutable reference and pointer type in traits class -> mutable indirect iterator;
|
||||
// Immutable reference and pointer type in traits class -> immutable indirect iterator
|
||||
class InnerTraits = boost::detail::iterator_traits<typename boost::detail::iterator_traits<OuterIterator>::value_type>
|
||||
class Value
|
||||
#if !defined(BOOST_MSVC)
|
||||
= BOOST_ARG_DEPENDENT_TYPENAME detail::value_type_of_value_type<OuterIterator>::type
|
||||
#endif
|
||||
, class Pointer = Value*
|
||||
, class Reference = Value&
|
||||
>
|
||||
class indirect_iterator_generator
|
||||
{
|
||||
typedef boost::detail::iterator_traits<OuterIterator> OuterTraits;
|
||||
typedef typename OuterTraits::difference_type difference_type;
|
||||
typedef typename OuterTraits::iterator_category iterator_category;
|
||||
typedef boost::detail::iterator_traits<OuterIterator> outer_traits;
|
||||
typedef typename outer_traits::difference_type difference_type;
|
||||
typedef typename outer_traits::iterator_category iterator_category;
|
||||
|
||||
typedef typename InnerTraits::value_type value_type;
|
||||
typedef typename InnerTraits::pointer pointer;
|
||||
typedef typename InnerTraits::reference reference;
|
||||
typedef typename boost::remove_const<Value>::type value_type;
|
||||
typedef Pointer pointer;
|
||||
typedef Reference reference;
|
||||
public:
|
||||
typedef boost::iterator<iterator_category, value_type, difference_type, pointer, reference> indirect_traits;
|
||||
typedef iterator_adaptor<OuterIterator, indirect_iterator_policies, indirect_traits> type;
|
||||
};
|
||||
|
||||
template <class OuterIterator, // Mutable or Immutable, does not matter
|
||||
class ConstInnerIterator, // Immutable
|
||||
class ConstInnerTraits = boost::detail::iterator_traits<ConstInnerIterator>,
|
||||
class InnerTraits = boost::detail::iterator_traits<typename boost::detail::iterator_traits<OuterIterator>::value_type>
|
||||
class Value
|
||||
#if !defined(BOOST_MSVC)
|
||||
= BOOST_ARG_DEPENDENT_TYPENAME detail::value_type_of_value_type<OuterIterator>::type
|
||||
#endif
|
||||
, class Pointer = Value*
|
||||
, class Reference = Value&
|
||||
, class ConstPointer = const Value*
|
||||
, class ConstReference = const Value&
|
||||
>
|
||||
struct indirect_iterator_pair_generator
|
||||
{
|
||||
typedef typename indirect_iterator_generator<OuterIterator,
|
||||
InnerTraits>::type iterator;
|
||||
Value, Pointer, Reference>::type iterator;
|
||||
typedef typename indirect_iterator_generator<OuterIterator,
|
||||
ConstInnerTraits>::type const_iterator;
|
||||
Value, ConstPointer, ConstReference>::type const_iterator;
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
// Tried to allow InnerTraits to be provided by explicit template
|
||||
// argument to the function, but could not get it to work. -Jeremy Siek
|
||||
template <class Value, class OuterIterator>
|
||||
inline typename indirect_iterator_generator<OuterIterator,Value>::type
|
||||
make_indirect_iterator(OuterIterator base, Value* = 0)
|
||||
{
|
||||
typedef typename indirect_iterator_generator
|
||||
<OuterIterator, Value>::type result_t;
|
||||
return result_t(base);
|
||||
}
|
||||
|
||||
# if 0 // This just doesn't seem to work under any circumstances!
|
||||
template <class OuterIterator>
|
||||
inline typename indirect_iterator_generator<OuterIterator>::type
|
||||
make_indirect_iterator(OuterIterator base)
|
||||
@ -699,18 +739,7 @@ make_indirect_iterator(OuterIterator base)
|
||||
<OuterIterator>::type result_t;
|
||||
return result_t(base);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Tried to allow InnerTraits to be provided by explicit template
|
||||
// argument to the function, but could not get it to work. -Jeremy Siek
|
||||
template <class InnerTraits, class OuterIterator>
|
||||
inline typename indirect_iterator_generator<OuterIterator, InnerTraits>::type
|
||||
make_indirect_iterator(OuterIterator base, InnerTraits)
|
||||
{
|
||||
typedef typename indirect_iterator_generator
|
||||
<OuterIterator, InnerTraits>::type result_t;
|
||||
return result_t(base);
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@ -748,19 +777,62 @@ struct reverse_iterator_policies : public default_iterator_policies
|
||||
{ return y < x; }
|
||||
};
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace detail {
|
||||
template <bool is_pointer>
|
||||
struct iterator_defaults_select
|
||||
{
|
||||
template <class Iterator,class Value>
|
||||
struct traits
|
||||
{
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::pointer pointer;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_defaults_select<true>
|
||||
{
|
||||
template <class Iterator,class Value>
|
||||
struct traits
|
||||
{
|
||||
typedef Value value_type;
|
||||
typedef Value* pointer;
|
||||
typedef Value& reference;
|
||||
};
|
||||
};
|
||||
|
||||
template <class Iterator,class Value>
|
||||
struct iterator_defaults
|
||||
{
|
||||
enum { is_ptr = boost::is_pointer<Iterator>::value };
|
||||
typedef iterator_defaults_select<is_ptr>::template traits<Iterator,Value> traits;
|
||||
typedef typename traits::pointer pointer;
|
||||
typedef typename traits::reference reference;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class Iterator,
|
||||
class Traits = boost::detail::iterator_traits<Iterator>
|
||||
class Value = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_traits<Iterator>::value_type,
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
class Pointer = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_traits<Iterator>::pointer,
|
||||
class Reference = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_traits<Iterator>::reference,
|
||||
#else
|
||||
class Pointer = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_defaults<Iterator,Value>::pointer,
|
||||
class Reference = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_defaults<Iterator,Value>::reference,
|
||||
#endif
|
||||
class Category = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_traits<Iterator>::iterator_category,
|
||||
class Distance = BOOST_ARG_DEPENDENT_TYPENAME boost::detail::iterator_traits<Iterator>::difference_type
|
||||
>
|
||||
struct reverse_iterator_generator
|
||||
{
|
||||
typedef iterator_adaptor<Iterator, reverse_iterator_policies,
|
||||
Traits> type;
|
||||
typedef typename boost::remove_const<Value>::type value_type;
|
||||
typedef boost::iterator<Category,value_type,Distance,Pointer,Reference> traits;
|
||||
typedef iterator_adaptor<Iterator,reverse_iterator_policies,traits> type;
|
||||
};
|
||||
|
||||
// WARNING: Do not use the one template parameter version of
|
||||
// make_reverse_iterator() if the iterator is a builtin pointer type
|
||||
// and if your compiler does not support partial specialization.
|
||||
|
||||
template <class Iterator>
|
||||
inline typename reverse_iterator_generator<Iterator>::type
|
||||
make_reverse_iterator(Iterator base)
|
||||
@ -769,18 +841,6 @@ make_reverse_iterator(Iterator base)
|
||||
return result_t(base);
|
||||
}
|
||||
|
||||
// Specify Traits type with an explicit argument,
|
||||
// i.e., make_reverse_iterator<Traits>(base)
|
||||
|
||||
template <class Traits, class Iterator>
|
||||
inline typename reverse_iterator_generator<Iterator, Traits>::type
|
||||
make_reverse_iterator(Iterator base, Traits* = 0)
|
||||
{
|
||||
typedef typename reverse_iterator_generator<Iterator, Traits>::type result_t;
|
||||
return result_t(base);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Projection Iterators Adaptor
|
||||
|
||||
@ -929,6 +989,8 @@ make_filter_iterator(Iterator first, Iterator last, const Predicate& p = Predica
|
||||
|
||||
|
||||
} // namespace boost
|
||||
# undef BOOST_ARG_DEPENDENT_TYPENAME
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user