Compare commits

..

11 Commits

Author SHA1 Message Date
c2d2f1c20f Create branch to keep WIP patch for modular build.
[SVN r85883]
2013-09-25 08:12:19 +00:00
db29a874f1 refs #6403
[SVN r80903]
2012-10-08 03:22:45 +00:00
8345293f94 refs #6404
[SVN r80902]
2012-10-08 02:17:55 +00:00
512298cb5c - BREAKING CHANGE: iterator_facade::pointer now corresponds to the actual result of iterator_facade::operator-> rather than Value*. This required an adjustment to a test.
- The logic for determining the result of iterator_facade::operator[] has been factored out into a separate detail header in preparation for its potential use in iterator_range to avoid iterator_range::operator[] from returning a reference to a temporary.

[SVN r80901]
2012-10-08 02:02:09 +00:00
7dbd0f5a89 Fixing typos in comments of iterator_facade.
[SVN r80817]
2012-10-02 13:27:34 +00:00
1ce1296320 Extending the usability of function_input_iterator after the changes addressing #5825: a dereference before each increment is no longer required.
[SVN r80790]
2012-09-30 18:58:56 +00:00
c6f3269f4a updating documentation to reflect new and more sensible behavior
[SVN r80468]
2012-09-09 15:51:22 +00:00
31c3971720 fix #5825; fix #7194
[SVN r80467]
2012-09-09 15:33:12 +00:00
2db78eec90 Replace all uses of boost/utility.hpp with more-granular includes. Solves modularization dependency nightmare.
[SVN r78502]
2012-05-18 04:44:04 +00:00
ad90dac61d refs #5127 applying Michael Morin's patch for transform_iterator to trunk
[SVN r78121]
2012-04-22 01:27:49 +00:00
964a29979c Applied patches from #5697; refs #5697
[SVN r77723]
2012-04-02 18:19:44 +00:00
14 changed files with 309 additions and 194 deletions

View File

@ -1,10 +1,13 @@
:Author: :Author:
`Dean Michael Berris <mailto:mikhailberis@gmail.com>`_ `Dean Michael Berris <mailto:me@deanberris.com>`_
:License: :License:
Distributed under the Boost Software License, Version 1.0 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) (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
:Copyright:
Copyright 2012 Google, Inc.
Function Input Iterator Function Input Iterator
======================= =======================
@ -15,11 +18,14 @@ the iterator has been incremented. A Function Input Iterator models the
.. _InputIterator: http://www.sgi.com/tech/stl/InputIterator.html .. _InputIterator: http://www.sgi.com/tech/stl/InputIterator.html
Like the Generator Iterator, the Function Input Iterator takes a function The Function Input Iterator takes a function that models the Generator_ concept
that models the Generator_ concept (which is basically a nullary or 0-arity (which is basically a nullary or 0-arity function object). The first dereference
function object). Each increment of the function Function Input Iterator of the iterator at a given position invokes the generator function and stores
invokes the generator function and stores the value in the iterator. When and returns the result; subsequent dereferences at the same position simply
the iterator is dereferenced the stored value is returned. return the same stored result. Incrementing the iterator places it at a new
position, hence a subsequent dereference will generate a new value via another
invokation of the generator function. This ensures the generator function is
invoked precisely when the iterator is requested to return a (new) value.
.. _Generator: http://www.sgi.com/tech/stl/Generator.html .. _Generator: http://www.sgi.com/tech/stl/Generator.html
@ -58,7 +64,7 @@ Synopsis
template <class Function, class State> template <class Function, class State>
typename function_input_iterator<Function, State> typename function_input_iterator<Function, State>
make_function_input_iterator(Function & f); make_function_input_iterator(Function & f, State s);
struct infinite; struct infinite;
} }
@ -112,7 +118,7 @@ it with the ``boost::infinite`` helper class.
copy( copy(
make_function_input_iterator(f,infinite()), make_function_input_iterator(f,infinite()),
make_function_input_iterator(f,infinite()), make_function_input_iterator(f,infinite()),
ostream_iterator<int>(count, " ") ostream_iterator<int>(cout, " ")
); );
Above, instead of creating a huge vector we rely on the STL copy algorithm Above, instead of creating a huge vector we rely on the STL copy algorithm

View File

@ -106,7 +106,7 @@ The ``iterator_category`` member of ``iterator_facade`` is
.. parsed-literal:: .. parsed-literal::
*iterator-category*\ (CategoryOrTraversal, value_type, reference) *iterator-category*\ (CategoryOrTraversal, reference, value_type)
where *iterator-category* is defined as follows: where *iterator-category* is defined as follows:

View File

@ -99,7 +99,7 @@ private:
</pre> </pre>
<p>If <tt class="docutils literal"><span class="pre">Reference</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">reference</span></tt> member of <p>If <tt class="docutils literal"><span class="pre">Reference</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">reference</span></tt> member of
<tt class="docutils literal"><span class="pre">transform_iterator</span></tt> is <tt class="docutils literal"><span class="pre">transform_iterator</span></tt> is
<tt class="docutils literal"><span class="pre">result_of&lt;UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>. <tt class="docutils literal"><span class="pre">result_of&lt;const UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>.
Otherwise, <tt class="docutils literal"><span class="pre">reference</span></tt> is <tt class="docutils literal"><span class="pre">Reference</span></tt>.</p> Otherwise, <tt class="docutils literal"><span class="pre">reference</span></tt> is <tt class="docutils literal"><span class="pre">Reference</span></tt>.</p>
<p>If <tt class="docutils literal"><span class="pre">Value</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">value_type</span></tt> member is <p>If <tt class="docutils literal"><span class="pre">Value</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">value_type</span></tt> member is
<tt class="docutils literal"><span class="pre">remove_cv&lt;remove_reference&lt;reference&gt;</span> <span class="pre">&gt;::type</span></tt>. Otherwise, <tt class="docutils literal"><span class="pre">remove_cv&lt;remove_reference&lt;reference&gt;</span> <span class="pre">&gt;::type</span></tt>. Otherwise,
@ -117,10 +117,10 @@ convertible to <tt class="docutils literal"><span class="pre">input_iterator_tag
<div class="section" id="transform-iterator-requirements"> <div class="section" id="transform-iterator-requirements">
<h1><a class="toc-backref" href="#id3"><tt class="docutils literal"><span class="pre">transform_iterator</span></tt> requirements</a></h1> <h1><a class="toc-backref" href="#id3"><tt class="docutils literal"><span class="pre">transform_iterator</span></tt> requirements</a></h1>
<p>The type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible, and <p>The type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible, and
the expression <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be valid where <tt class="docutils literal"><span class="pre">f</span></tt> is an object of the expression <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be valid where <tt class="docutils literal"><span class="pre">f</span></tt> is a const object of
type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt>, <tt class="docutils literal"><span class="pre">i</span></tt> is an object of type <tt class="docutils literal"><span class="pre">Iterator</span></tt>, and type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt>, <tt class="docutils literal"><span class="pre">i</span></tt> is an object of type <tt class="docutils literal"><span class="pre">Iterator</span></tt>, and
where the type of <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be where the type of <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be
<tt class="docutils literal"><span class="pre">result_of&lt;UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>.</p> <tt class="docutils literal"><span class="pre">result_of&lt;const UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>.</p>
<p>The argument <tt class="docutils literal"><span class="pre">Iterator</span></tt> shall model Readable Iterator.</p> <p>The argument <tt class="docutils literal"><span class="pre">Iterator</span></tt> shall model Readable Iterator.</p>
</div> </div>
<div class="section" id="transform-iterator-models"> <div class="section" id="transform-iterator-models">

View File

@ -41,7 +41,7 @@
If ``Reference`` is ``use_default`` then the ``reference`` member of If ``Reference`` is ``use_default`` then the ``reference`` member of
``transform_iterator`` is ``transform_iterator`` is
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``. ``result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
Otherwise, ``reference`` is ``Reference``. Otherwise, ``reference`` is ``Reference``.
If ``Value`` is ``use_default`` then the ``value_type`` member is If ``Value`` is ``use_default`` then the ``value_type`` member is
@ -64,10 +64,10 @@ convertible to ``input_iterator_tag``.
................................... ...................................
The type ``UnaryFunction`` must be Assignable, Copy Constructible, and The type ``UnaryFunction`` must be Assignable, Copy Constructible, and
the expression ``f(*i)`` must be valid where ``f`` is an object of the expression ``f(*i)`` must be valid where ``f`` is a const object of
type ``UnaryFunction``, ``i`` is an object of type ``Iterator``, and type ``UnaryFunction``, ``i`` is an object of type ``Iterator``, and
where the type of ``f(*i)`` must be where the type of ``f(*i)`` must be
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``. ``result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
The argument ``Iterator`` shall model Readable Iterator. The argument ``Iterator`` shall model Readable Iterator.

View File

@ -73,15 +73,8 @@ struct iterator_writability_disabled
// Convert an iterator_facade's traversal category, Value parameter, // Convert an iterator_facade's traversal category, Value parameter,
// and ::reference type to an appropriate old-style category. // and ::reference type to an appropriate old-style category.
// //
// If writability has been disabled per the above metafunction, the // Due to changeset 21683, this now never results in a category convertible
// result will not be convertible to output_iterator_tag. // 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> template <class Traversal, class ValueParam, class Reference>
struct iterator_facade_default_category struct iterator_facade_default_category

View File

@ -0,0 +1,88 @@
// (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

View File

@ -1,4 +1,6 @@
// Copyright 2009 (C) Dean Michael Berris <me@deanberris.com> // Copyright 2009 (C) Dean Michael Berris <me@deanberris.com>
// Copyright 2012 (C) Google, Inc.
// Copyright 2012 (C) Jeffrey Lee Hellrung, Jr.
// Distributed under the Boost Software License, Version 1.0. (See // Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at // accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
@ -7,11 +9,14 @@
#ifndef BOOST_FUNCTION_INPUT_ITERATOR #ifndef BOOST_FUNCTION_INPUT_ITERATOR
#define BOOST_FUNCTION_INPUT_ITERATOR #define BOOST_FUNCTION_INPUT_ITERATOR
#include <boost/assert.hpp>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
#include <boost/function_types/is_function_pointer.hpp> #include <boost/function_types/is_function_pointer.hpp>
#include <boost/function_types/is_function_reference.hpp> #include <boost/function_types/is_function_reference.hpp>
#include <boost/function_types/result_type.hpp> #include <boost/function_types/result_type.hpp>
#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_facade.hpp>
#include <boost/none.hpp>
#include <boost/optional/optional.hpp>
namespace boost { namespace boost {
@ -29,16 +34,19 @@ namespace boost {
public: public:
function_input_iterator() {} function_input_iterator() {}
function_input_iterator(Function & f_, Input state_ = Input()) function_input_iterator(Function & f_, Input state_ = Input())
: f(&f_), state(state_), value((*f)()) {} : f(&f_), state(state_) {}
void increment() { void increment() {
value = (*f)(); if(value)
value = none;
else
(*f)();
++state; ++state;
} }
typename Function::result_type const & typename Function::result_type const &
dereference() const { dereference() const {
return value; return (value ? value : value = (*f)()).get();
} }
bool equal(function_input_iterator const & other) const { bool equal(function_input_iterator const & other) const {
@ -48,7 +56,7 @@ namespace boost {
private: private:
Function * f; Function * f;
Input state; Input state;
typename Function::result_type value; mutable optional<typename Function::result_type> value;
}; };
template <class Function, class Input> template <class Function, class Input>
@ -63,17 +71,19 @@ namespace boost {
public: public:
function_pointer_input_iterator() {} function_pointer_input_iterator() {}
function_pointer_input_iterator(Function &f_, Input state_ = Input()) function_pointer_input_iterator(Function &f_, Input state_ = Input())
: f(f_), state(state_), value((*f)()) : f(f_), state(state_) {}
{}
void increment() { void increment() {
value = (*f)(); if(value)
value = none;
else
(*f)();
++state; ++state;
} }
typename function_types::result_type<Function>::type const & typename function_types::result_type<Function>::type const &
dereference() const { dereference() const {
return value; return (value ? value : value = (*f)()).get();
} }
bool equal(function_pointer_input_iterator const & other) const { bool equal(function_pointer_input_iterator const & other) const {
@ -83,7 +93,7 @@ namespace boost {
private: private:
Function f; Function f;
Input state; Input state;
typename function_types::result_type<Function>::type value; mutable optional<typename function_types::result_type<Function>::type> value;
}; };
template <class Function, class Input> template <class Function, class Input>

View File

@ -1,6 +1,7 @@
// (C) Copyright David Abrahams 2002. // (C) Copyright David Abrahams 2002.
// (C) Copyright Jeremy Siek 2002. // (C) Copyright Jeremy Siek 2002.
// (C) Copyright Thomas Witt 2002. // (C) Copyright Thomas Witt 2002.
// (C) copyright Jeffrey Lee Hellrung, Jr. 2012.
// Distributed under the Boost Software License, Version 1.0. (See // Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at // accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
@ -13,9 +14,10 @@
#include <boost/iterator/detail/facade_iterator_category.hpp> #include <boost/iterator/detail/facade_iterator_category.hpp>
#include <boost/iterator/detail/enable_if.hpp> #include <boost/iterator/detail/enable_if.hpp>
#include <boost/iterator/detail/operator_brackets_dispatch.hpp>
#include <boost/implicit_cast.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_const.hpp> #include <boost/type_traits/add_const.hpp>
@ -147,7 +149,7 @@ namespace boost
// Returning a mutable reference allows nonsense like // Returning a mutable reference allows nonsense like
// (*r++).mutate(), but it imposes fewer assumptions about the // (*r++).mutate(), but it imposes fewer assumptions about the
// behavior of the value_type. In particular, recall taht // behavior of the value_type. In particular, recall that
// (*r).mutate() is legal if operator* returns by value. // (*r).mutate() is legal if operator* returns by value.
value_type& value_type&
operator*() const operator*() const
@ -294,116 +296,46 @@ namespace boost
// operator->() needs special support for input iterators to strictly meet the // operator->() needs special support for input iterators to strictly meet the
// standard's requirements. If *i is not a reference type, we must still // standard's requirements. If *i is not a reference type, we must still
// produce a lvalue to which a pointer can be formed. We do that by // produce an lvalue to which a pointer can be formed. We do that by
// returning an instantiation of this special proxy class template. // returning a proxy object containing an instance of the reference object.
template <class T> template <class Reference>
struct operator_arrow_proxy struct operator_arrow_dispatch // proxy references
{ {
operator_arrow_proxy(T const* px) : m_value(*px) {} struct proxy
T* operator->() const { return &m_value; } {
// This function is needed for MWCW and BCC, which won't call operator-> explicit proxy(Reference const & x) : m_ref(x) {}
// again automatically per 13.3.1.2 para 8 Reference* operator->() { return boost::addressof(m_ref); }
operator T*() const { return &m_value; } // This function is needed for MWCW and BCC, which won't call
mutable T m_value; // operator-> again automatically per 13.3.1.2 para 8
operator Reference*() { return boost::addressof(m_ref); }
Reference m_ref;
};
typedef proxy result_type;
static result_type apply(Reference const & x)
{
return result_type(x);
}
}; };
// A metafunction that gets the result type for operator->. Also template <class T>
// has a static function make() which builds the result from a struct operator_arrow_dispatch<T&> // "real" references
// Reference
template <class ValueType, class Reference, class Pointer>
struct operator_arrow_result
{ {
// CWPro8.3 won't accept "operator_arrow_result::type", and we typedef T* result_type;
// need that type below, so metafunction forwarding would be a static result_type apply(T& x)
// losing proposition here.
typedef typename mpl::if_<
is_reference<Reference>
, Pointer
, operator_arrow_proxy<ValueType>
>::type type;
static type make(Reference x)
{ {
return boost::implicit_cast<type>(&x); return boost::addressof(x);
} }
}; };
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) # if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
// Deal with ETI // Deal with ETI
template<> template<>
struct operator_arrow_result<int, int, int> struct operator_arrow_dispatch<int>
{ {
typedef int type; typedef int result_type;
}; };
# endif # 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 struct choose_difference_type
{ {
template <class I1, class I2> template <class I1, class I2>
@ -618,11 +550,11 @@ namespace boost
Value, CategoryOrTraversal, Reference, Difference Value, CategoryOrTraversal, Reference, Difference
> associated_types; > associated_types;
typedef boost::detail::operator_arrow_result< typedef boost::detail::operator_arrow_dispatch<
typename associated_types::value_type Reference> operator_arrow_dispatch_;
, Reference
, typename associated_types::pointer typedef typename boost::detail::operator_brackets_dispatch<
> pointer_; Derived, Value, Reference>::type operator_brackets_dispatch_;
protected: protected:
// For use by derived classes // For use by derived classes
@ -634,7 +566,7 @@ namespace boost
typedef Reference reference; typedef Reference reference;
typedef Difference difference_type; typedef Difference difference_type;
typedef typename pointer_::type pointer; typedef typename operator_arrow_dispatch_::result_type pointer;
typedef typename associated_types::iterator_category iterator_category; typedef typename associated_types::iterator_category iterator_category;
@ -645,18 +577,13 @@ namespace boost
pointer operator->() const pointer operator->() const
{ {
return pointer_::make(*this->derived()); return operator_arrow_dispatch_::apply(*this->derived());
} }
typename boost::detail::operator_brackets_result<Derived,Value,reference>::type typename operator_brackets_dispatch_::result_type
operator[](difference_type n) const operator[](difference_type n) const
{ {
typedef boost::detail::use_operator_brackets_proxy<Value,Reference> use_proxy; return operator_brackets_dispatch_::apply(this->derived() + n);
return boost::detail::make_operator_brackets_result<Derived>(
this->derived() + n
, use_proxy()
);
} }
Derived& operator++() Derived& operator++()

View File

@ -7,8 +7,8 @@
#ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP #ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP #define BOOST_REVERSE_ITERATOR_23022003THW_HPP
#include <boost/next_prior.hpp>
#include <boost/iterator.hpp> #include <boost/iterator.hpp>
#include <boost/utility.hpp>
#include <boost/iterator/iterator_adaptor.hpp> #include <boost/iterator/iterator_adaptor.hpp>
namespace boost namespace boost

View File

@ -46,7 +46,7 @@ namespace boost
// the function. // the function.
typedef typename ia_dflt_help< typedef typename ia_dflt_help<
Reference Reference
, result_of<UnaryFunc(typename std::iterator_traits<Iterator>::reference)> , result_of<const UnaryFunc(typename std::iterator_traits<Iterator>::reference)>
>::type reference; >::type reference;
// To get the default for Value: remove any reference on the // To get the default for Value: remove any reference on the

View File

@ -3,12 +3,17 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/function_input_iterator.hpp>
#include <vector>
#include <iterator>
#include <cassert> #include <cassert>
#include <cstddef>
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <iterator>
#include <vector>
#include <boost/iterator/function_input_iterator.hpp>
namespace {
struct ones { struct ones {
typedef int result_type; typedef int result_type;
@ -21,6 +26,17 @@ int ones_function () {
return 1; return 1;
} }
struct counter {
typedef int result_type;
int n;
explicit counter(int n_) : n(n_) { }
result_type operator() () {
return n++;
}
};
} // namespace
using namespace std; using namespace std;
int main(int argc, char * argv[]) int main(int argc, char * argv[])
@ -65,6 +81,21 @@ int main(int argc, char * argv[])
assert(equal(values.begin(), values.end(), generated.begin())); assert(equal(values.begin(), values.end(), generated.begin()));
cout << "function iterator test with reference to function successful." << endl; cout << "function iterator test with reference to function successful." << endl;
// test the iterator with a stateful function object
counter counter_generator(42);
vector<int>().swap(generated);
copy(
boost::make_function_input_iterator(counter_generator, 0),
boost::make_function_input_iterator(counter_generator, 10),
back_inserter(generated)
);
assert(generated.size() == 10);
assert(counter_generator.n == 42 + 10);
for(std::size_t i = 0; i != 10; ++i)
assert(generated[i] == 42 + i);
cout << "function iterator test with stateful function object successful." << endl;
return 0; return 0;
} }

View File

@ -82,7 +82,7 @@ int main()
typedef boost::indirect_iterator<char**, int, std::random_access_iterator_tag, long&, short> Iter; 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::value_type, int);
STATIC_ASSERT_SAME(Iter::reference, long&); STATIC_ASSERT_SAME(Iter::reference, long&);
STATIC_ASSERT_SAME(Iter::pointer, int*); STATIC_ASSERT_SAME(Iter::pointer, long*);
STATIC_ASSERT_SAME(Iter::difference_type, short); STATIC_ASSERT_SAME(Iter::difference_type, short);
} }
return 0; return 0;

View File

@ -7,6 +7,10 @@
#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/new_iterator_tests.hpp> #include <boost/iterator/new_iterator_tests.hpp>
#include <boost/call_traits.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
// This is a really, really limited test so far. All we're doing // This is a really, really limited test so far. All we're doing
// right now is checking that the postfix++ proxy for single-pass // right now is checking that the postfix++ proxy for single-pass
// iterators works properly. // iterators works properly.
@ -87,26 +91,76 @@ struct input_iter
} }
}; };
template <class T>
struct wrapper
{
T m_x;
explicit wrapper(typename boost::call_traits<T>::param_type x)
: m_x(x)
{ }
template <class U>
wrapper(const wrapper<U>& other,
typename boost::enable_if< boost::is_convertible<U,T> >::type* = 0)
: m_x(other.m_x)
{ }
};
struct iterator_with_proxy_reference
: boost::iterator_facade<
iterator_with_proxy_reference
, wrapper<int>
, boost::incrementable_traversal_tag
, wrapper<int&>
>
{
int& m_x;
explicit iterator_with_proxy_reference(int& x)
: m_x(x)
{ }
void increment()
{ }
wrapper<int&> dereference() const
{ return wrapper<int&>(m_x); }
};
template <class T, class U> template <class T, class U>
void same_type(U const&) void same_type(U const&)
{ BOOST_MPL_ASSERT((boost::is_same<T,U>)); } { BOOST_MPL_ASSERT((boost::is_same<T,U>)); }
int main() int main()
{ {
int state = 0; {
boost::readable_iterator_test(counter_iterator<int const&>(&state), 0); int state = 0;
state = 3; boost::readable_iterator_test(counter_iterator<int const&>(&state), 0);
boost::readable_iterator_test(counter_iterator<proxy>(&state), 3); state = 3;
boost::writable_iterator_test(counter_iterator<proxy>(&state), 9, 7); boost::readable_iterator_test(counter_iterator<proxy>(&state), 3);
BOOST_TEST(state == 8); boost::writable_iterator_test(counter_iterator<proxy>(&state), 9, 7);
BOOST_TEST(state == 8);
}
// test for a fix to http://tinyurl.com/zuohe {
// These two lines should be equivalent (and both compile) // test for a fix to http://tinyurl.com/zuohe
input_iter p; // These two lines should be equivalent (and both compile)
(*p).mutator(); input_iter p;
p->mutator(); (*p).mutator();
p->mutator();
same_type<input_iter::pointer>(p.operator->()); same_type<input_iter::pointer>(p.operator->());
}
{
int x = 0;
iterator_with_proxy_reference i(x);
BOOST_TEST(x == 0);
BOOST_TEST(i.m_x == 0);
++(*i).m_x;
BOOST_TEST(x == 1);
BOOST_TEST(i.m_x == 1);
++i->m_x;
BOOST_TEST(x == 2);
BOOST_TEST(i.m_x == 2);
}
return boost::report_errors(); return boost::report_errors();
} }

View File

@ -12,6 +12,7 @@
// Moved test of transform iterator into its own file. It to // Moved test of transform iterator into its own file. It to
// to be in iterator_adaptor_test.cpp. // to be in iterator_adaptor_test.cpp.
#include <boost/assert.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <algorithm> #include <algorithm>
#include <boost/iterator/transform_iterator.hpp> #include <boost/iterator/transform_iterator.hpp>
@ -106,12 +107,17 @@ struct polymorphic_mult_functor
{ {
//Implement result_of protocol //Implement result_of protocol
template <class FArgs> struct result; template <class FArgs> struct result;
template <class F, class T> struct result<F(T )> {typedef T type;}; template <class F, class T> struct result<const F(T )> {typedef T type;};
template <class F, class T> struct result<F(T& )> {typedef T type;}; template <class F, class T> struct result<const F(T& )> {typedef T type;};
template <class F, class T> struct result<F(const T&)> {typedef T type;}; template <class F, class T> struct result<const F(const T&)> {typedef T type;};
template <class F, class T> struct result<F(T )> {typedef void type;};
template <class F, class T> struct result<F(T& )> {typedef void type;};
template <class F, class T> struct result<F(const T&)> {typedef void type;};
template <class T> template <class T>
T operator()(const T& _arg) const {return _arg*2;} T operator()(const T& _arg) const {return _arg*2;}
template <class T>
void operator()(const T& _arg) { BOOST_ASSERT(0); }
}; };
int int