forked from boostorg/iterator
Compare commits
44 Commits
svn-branch
...
boost-1.55
Author | SHA1 | Date | |
---|---|---|---|
b126e2b48d | |||
6d0b2d4f8a | |||
c9463e941f | |||
9025bbfc2a | |||
c7fc3470d0 | |||
fbbdcf8c99 | |||
5d72ae48da | |||
1ca1caddff | |||
d45b57c33c | |||
5a88e6f958 | |||
36565eae63 | |||
de4ef14f9b | |||
f65f03afcc | |||
cfc04ce11e | |||
25d4d34ebe | |||
ea26e9f109 | |||
264c186eac | |||
2ece3ac5c2 | |||
78effefadb | |||
37c46f7da5 | |||
6d0f901b2e | |||
db0e0b7b91 | |||
23d53055f9 | |||
ff73538b5b | |||
30685528c7 | |||
c849f35965 | |||
aa483f4961 | |||
93c010eb51 | |||
0dc017b1a8 | |||
92c92bbbf8 | |||
f51591cb04 | |||
624131ce46 | |||
47da2546f9 | |||
8a53abc1e8 | |||
b258a435cc | |||
43e4f1a766 | |||
02d22c12ae | |||
70ef2f0e81 | |||
b7283c93c6 | |||
5184d64b80 | |||
f482354ffd | |||
7a2b9d66a9 | |||
d79112ee5a | |||
4a5e8f175a |
@ -106,7 +106,7 @@ The ``iterator_category`` member of ``iterator_facade`` is
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
*iterator-category*\ (CategoryOrTraversal, reference, value_type)
|
||||
*iterator-category*\ (CategoryOrTraversal, value_type, reference)
|
||||
|
||||
where *iterator-category* is defined as follows:
|
||||
|
||||
|
@ -73,8 +73,15 @@ struct iterator_writability_disabled
|
||||
// Convert an iterator_facade's traversal category, Value parameter,
|
||||
// and ::reference type to an appropriate old-style category.
|
||||
//
|
||||
// Due to changeset 21683, this now never results in a category convertible
|
||||
// to output_iterator_tag.
|
||||
// If writability has been disabled per the above metafunction, the
|
||||
// result will not be convertible to output_iterator_tag.
|
||||
//
|
||||
// Otherwise, if Traversal == single_pass_traversal_tag, the following
|
||||
// conditions will result in a tag that is convertible both to
|
||||
// input_iterator_tag and output_iterator_tag:
|
||||
//
|
||||
// 1. Reference is a reference to non-const
|
||||
// 2. Reference is not a reference and is convertible to Value
|
||||
//
|
||||
template <class Traversal, class ValueParam, class Reference>
|
||||
struct iterator_facade_default_category
|
||||
|
@ -1,88 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// (C) Copyright Jeffrey Lee Hellrung, Jr. 2012.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_OPERATOR_BRACKETS_DISPATCH_07102012JLH_HPP
|
||||
#define BOOST_OPERATOR_BRACKETS_DISPATCH_07102012JLH_HPP
|
||||
|
||||
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
||||
|
||||
#include <boost/type_traits/is_pod.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace boost { namespace detail {
|
||||
|
||||
// operator[] must return a proxy in case iterator destruction invalidates
|
||||
// referents.
|
||||
// To see why, consider the following implementation of operator[]:
|
||||
// reference operator[](difference_type n) const
|
||||
// { return *(*this + n); }
|
||||
// The problem here is that operator[] would return a reference created from
|
||||
// a temporary iterator.
|
||||
|
||||
template <class Value>
|
||||
struct operator_brackets_value
|
||||
{
|
||||
typedef Value result_type;
|
||||
template <class Iterator>
|
||||
static result_type apply(Iterator const & i)
|
||||
{ return *i; }
|
||||
};
|
||||
|
||||
template <class Iterator, class Reference>
|
||||
struct operator_brackets_const_proxy
|
||||
{
|
||||
class result_type
|
||||
{
|
||||
Iterator const m_i;
|
||||
explicit result_type(Iterator const & i) : m_i(i) { }
|
||||
friend struct operator_brackets_const_proxy;
|
||||
void operator=(result_type&);
|
||||
public:
|
||||
operator Reference() const { return *m_i; }
|
||||
};
|
||||
static result_type apply(Iterator const & i)
|
||||
{ return result_type(i); }
|
||||
};
|
||||
|
||||
template <class Iterator, class Reference>
|
||||
struct operator_brackets_proxy
|
||||
{
|
||||
class result_type
|
||||
{
|
||||
Iterator const m_i;
|
||||
explicit result_type(Iterator const & i) : m_i(i) { }
|
||||
friend struct operator_brackets_proxy;
|
||||
void operator=(result_type&);
|
||||
public:
|
||||
operator Reference() const { return *m_i; }
|
||||
operator_brackets_proxy const & operator=(
|
||||
typename Iterator::value_type const & x) const
|
||||
{ *m_i = x; return *this; }
|
||||
};
|
||||
static result_type apply(Iterator const & i)
|
||||
{ return result_type(i); }
|
||||
};
|
||||
|
||||
template <class Iterator, class ValueType, class Reference>
|
||||
struct operator_brackets_dispatch
|
||||
{
|
||||
typedef typename mpl::if_c<
|
||||
iterator_writability_disabled<ValueType,Reference>::value,
|
||||
typename mpl::if_c<
|
||||
boost::is_POD<ValueType>::value,
|
||||
operator_brackets_value<typename boost::remove_const<ValueType>::type>,
|
||||
operator_brackets_const_proxy<Iterator,Reference>
|
||||
>::type,
|
||||
operator_brackets_proxy<Iterator,Reference>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} } // namespace detail / namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_OPERATOR_BRACKETS_DISPATCH_07102012JLH_HPP
|
@ -1,7 +1,6 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// (C) copyright Jeffrey Lee Hellrung, Jr. 2012.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -14,7 +13,6 @@
|
||||
|
||||
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
||||
#include <boost/iterator/detail/enable_if.hpp>
|
||||
#include <boost/iterator/detail/operator_brackets_dispatch.hpp>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
@ -77,7 +75,7 @@ namespace boost
|
||||
, Return
|
||||
, int[3]
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
#else
|
||||
: ::boost::iterators::enable_if<
|
||||
mpl::or_<
|
||||
@ -87,7 +85,7 @@ namespace boost
|
||||
, Return
|
||||
>
|
||||
{};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Generates associated types for an iterator_facade with the
|
||||
@ -96,7 +94,7 @@ namespace boost
|
||||
template <
|
||||
class ValueParam
|
||||
, class CategoryOrTraversal
|
||||
, class Reference
|
||||
, class Reference
|
||||
, class Difference
|
||||
>
|
||||
struct iterator_facade_types
|
||||
@ -104,16 +102,16 @@ namespace boost
|
||||
typedef typename facade_iterator_category<
|
||||
CategoryOrTraversal, ValueParam, Reference
|
||||
>::type iterator_category;
|
||||
|
||||
|
||||
typedef typename remove_const<ValueParam>::type value_type;
|
||||
|
||||
|
||||
// Not the real associated pointer type
|
||||
typedef typename mpl::eval_if<
|
||||
boost::detail::iterator_writability_disabled<ValueParam,Reference>
|
||||
, add_pointer<const value_type>
|
||||
, add_pointer<value_type>
|
||||
>::type pointer;
|
||||
|
||||
|
||||
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
&& (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
|
||||
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
|
||||
@ -159,7 +157,7 @@ namespace boost
|
||||
private:
|
||||
mutable value_type stored_value;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// In general, we can't determine that such an iterator isn't
|
||||
// writable -- we also need to store a copy of the old iterator so
|
||||
@ -211,7 +209,7 @@ namespace boost
|
||||
{
|
||||
return stored_iterator;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
mutable value_type stored_value;
|
||||
Iterator stored_iterator;
|
||||
@ -223,7 +221,7 @@ namespace boost
|
||||
struct is_non_proxy_reference_impl
|
||||
{
|
||||
static Reference r;
|
||||
|
||||
|
||||
template <class R>
|
||||
static typename mpl::if_<
|
||||
is_convertible<
|
||||
@ -233,17 +231,17 @@ namespace boost
|
||||
, char[1]
|
||||
, char[2]
|
||||
>::type& helper(R const&);
|
||||
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
|
||||
};
|
||||
|
||||
|
||||
template <class Reference, class Value>
|
||||
struct is_non_proxy_reference
|
||||
: mpl::bool_<
|
||||
is_non_proxy_reference_impl<Reference, Value>::value
|
||||
>
|
||||
{};
|
||||
# else
|
||||
# else
|
||||
template <class Reference, class Value>
|
||||
struct is_non_proxy_reference
|
||||
: is_convertible<
|
||||
@ -252,8 +250,8 @@ namespace boost
|
||||
, Value const volatile*
|
||||
>
|
||||
{};
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
// A metafunction to choose the result type of postfix ++
|
||||
//
|
||||
// Because the C++98 input iterator requirements say that *r++ has
|
||||
@ -275,7 +273,7 @@ namespace boost
|
||||
mpl::and_<
|
||||
// A proxy is only needed for readable iterators
|
||||
is_convertible<Reference,Value const&>
|
||||
|
||||
|
||||
// No multipass iterator can have values that disappear
|
||||
// before positions can be re-visited
|
||||
, mpl::not_<
|
||||
@ -298,7 +296,7 @@ namespace boost
|
||||
// standard's requirements. If *i is not a reference type, we must still
|
||||
// produce an lvalue to which a pointer can be formed. We do that by
|
||||
// returning a proxy object containing an instance of the reference object.
|
||||
template <class Reference>
|
||||
template <class Reference, class Pointer>
|
||||
struct operator_arrow_dispatch // proxy references
|
||||
{
|
||||
struct proxy
|
||||
@ -317,10 +315,10 @@ namespace boost
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct operator_arrow_dispatch<T&> // "real" references
|
||||
template <class T, class Pointer>
|
||||
struct operator_arrow_dispatch<T&, Pointer> // "real" references
|
||||
{
|
||||
typedef T* result_type;
|
||||
typedef Pointer result_type;
|
||||
static result_type apply(T& x)
|
||||
{
|
||||
return boost::addressof(x);
|
||||
@ -330,12 +328,79 @@ namespace boost
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
// Deal with ETI
|
||||
template<>
|
||||
struct operator_arrow_dispatch<int>
|
||||
struct operator_arrow_dispatch<int, int>
|
||||
{
|
||||
typedef int result_type;
|
||||
};
|
||||
# endif
|
||||
|
||||
// A proxy return type for operator[], needed to deal with
|
||||
// iterators that may invalidate referents upon destruction.
|
||||
// Consider the temporary iterator in *(a + n)
|
||||
template <class Iterator>
|
||||
class operator_brackets_proxy
|
||||
{
|
||||
// Iterator is actually an iterator_facade, so we do not have to
|
||||
// go through iterator_traits to access the traits.
|
||||
typedef typename Iterator::reference reference;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
|
||||
public:
|
||||
operator_brackets_proxy(Iterator const& iter)
|
||||
: m_iter(iter)
|
||||
{}
|
||||
|
||||
operator reference() const
|
||||
{
|
||||
return *m_iter;
|
||||
}
|
||||
|
||||
operator_brackets_proxy& operator=(value_type const& val)
|
||||
{
|
||||
*m_iter = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator m_iter;
|
||||
};
|
||||
|
||||
// A metafunction that determines whether operator[] must return a
|
||||
// proxy, or whether it can simply return a copy of the value_type.
|
||||
template <class ValueType, class Reference>
|
||||
struct use_operator_brackets_proxy
|
||||
: mpl::not_<
|
||||
mpl::and_<
|
||||
// Really we want an is_copy_constructible trait here,
|
||||
// but is_POD will have to suffice in the meantime.
|
||||
boost::is_POD<ValueType>
|
||||
, iterator_writability_disabled<ValueType,Reference>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class Iterator, class Value, class Reference>
|
||||
struct operator_brackets_result
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
use_operator_brackets_proxy<Value,Reference>
|
||||
, operator_brackets_proxy<Iterator>
|
||||
, Value
|
||||
>::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;
|
||||
}
|
||||
|
||||
struct choose_difference_type
|
||||
{
|
||||
template <class I1, class I2>
|
||||
@ -349,13 +414,13 @@ namespace boost
|
||||
, typename I1::difference_type
|
||||
, typename I2::difference_type
|
||||
>
|
||||
# else
|
||||
# else
|
||||
mpl::eval_if<
|
||||
is_convertible<I2,I1>
|
||||
, iterator_difference<I1>
|
||||
, iterator_difference<I2>
|
||||
>
|
||||
# endif
|
||||
# endif
|
||||
{};
|
||||
|
||||
};
|
||||
@ -373,7 +438,7 @@ namespace boost
|
||||
operator op( \
|
||||
iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
|
||||
, iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
|
||||
# else
|
||||
# else
|
||||
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
|
||||
template < \
|
||||
class Derived1, class V1, class TC1, class Reference1, class Difference1 \
|
||||
@ -386,7 +451,7 @@ namespace boost
|
||||
operator op( \
|
||||
iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
|
||||
, iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
|
||||
template <class Derived, class V, class TC, class R, class D> \
|
||||
@ -403,12 +468,12 @@ namespace boost
|
||||
//
|
||||
class iterator_core_access
|
||||
{
|
||||
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
// 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 TC, class R, class D> friend class iterator_facade;
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_RELATION(op) \
|
||||
@ -551,15 +616,14 @@ namespace boost
|
||||
> associated_types;
|
||||
|
||||
typedef boost::detail::operator_arrow_dispatch<
|
||||
Reference> operator_arrow_dispatch_;
|
||||
|
||||
typedef typename boost::detail::operator_brackets_dispatch<
|
||||
Derived, Value, Reference>::type operator_brackets_dispatch_;
|
||||
Reference
|
||||
, typename associated_types::pointer
|
||||
> operator_arrow_dispatch_;
|
||||
|
||||
protected:
|
||||
// For use by derived classes
|
||||
typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef typename associated_types::value_type value_type;
|
||||
@ -579,11 +643,16 @@ namespace boost
|
||||
{
|
||||
return operator_arrow_dispatch_::apply(*this->derived());
|
||||
}
|
||||
|
||||
typename operator_brackets_dispatch_::result_type
|
||||
|
||||
typename boost::detail::operator_brackets_result<Derived,Value,reference>::type
|
||||
operator[](difference_type n) const
|
||||
{
|
||||
return operator_brackets_dispatch_::apply(this->derived() + n);
|
||||
typedef boost::detail::use_operator_brackets_proxy<Value,Reference> use_proxy;
|
||||
|
||||
return boost::detail::make_operator_brackets_result<Derived>(
|
||||
this->derived() + n
|
||||
, use_proxy()
|
||||
);
|
||||
}
|
||||
|
||||
Derived& operator++()
|
||||
@ -602,7 +671,7 @@ namespace boost
|
||||
return tmp;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
Derived& operator--()
|
||||
{
|
||||
iterator_core_access::decrement(this->derived());
|
||||
@ -657,14 +726,14 @@ namespace boost
|
||||
{
|
||||
typename boost::detail::postfix_increment_result<I,V,R,TC>::type
|
||||
tmp(*static_cast<I*>(&i));
|
||||
|
||||
|
||||
++i;
|
||||
|
||||
|
||||
return tmp;
|
||||
}
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
//
|
||||
// Comparison operator implementation. The library supplied operators
|
||||
// enables the user to provide fully interoperable constant/mutable
|
||||
|
@ -82,7 +82,7 @@ int main()
|
||||
typedef boost::indirect_iterator<char**, int, std::random_access_iterator_tag, long&, short> Iter;
|
||||
STATIC_ASSERT_SAME(Iter::value_type, int);
|
||||
STATIC_ASSERT_SAME(Iter::reference, long&);
|
||||
STATIC_ASSERT_SAME(Iter::pointer, long*);
|
||||
STATIC_ASSERT_SAME(Iter::pointer, int*);
|
||||
STATIC_ASSERT_SAME(Iter::difference_type, short);
|
||||
}
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user