forked from boostorg/iterator
Compare commits
4 Commits
boost-1.51
...
boost-1.55
Author | SHA1 | Date | |
---|---|---|---|
b126e2b48d | |||
6d0b2d4f8a | |||
c9463e941f | |||
9025bbfc2a |
@ -1,10 +1,13 @@
|
||||
:Author:
|
||||
`Dean Michael Berris <mailto:mikhailberis@gmail.com>`_
|
||||
`Dean Michael Berris <mailto:me@deanberris.com>`_
|
||||
|
||||
:License:
|
||||
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)
|
||||
|
||||
:Copyright:
|
||||
Copyright 2012 Google, Inc.
|
||||
|
||||
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
|
||||
|
||||
Like the Generator Iterator, the Function Input Iterator takes a function
|
||||
that models the Generator_ concept (which is basically a nullary or 0-arity
|
||||
function object). Each increment of the function Function Input Iterator
|
||||
invokes the generator function and stores the value in the iterator. When
|
||||
the iterator is dereferenced the stored value is returned.
|
||||
The Function Input Iterator takes a function that models the Generator_ concept
|
||||
(which is basically a nullary or 0-arity function object). The first dereference
|
||||
of the iterator at a given position invokes the generator function and stores
|
||||
and returns the result; subsequent dereferences at the same position simply
|
||||
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
|
||||
|
||||
@ -58,7 +64,7 @@ Synopsis
|
||||
|
||||
template <class Function, class State>
|
||||
typename function_input_iterator<Function, State>
|
||||
make_function_input_iterator(Function & f);
|
||||
make_function_input_iterator(Function & f, State s);
|
||||
|
||||
struct infinite;
|
||||
}
|
||||
@ -112,7 +118,7 @@ it with the ``boost::infinite`` helper class.
|
||||
copy(
|
||||
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
|
||||
|
@ -1,4 +1,6 @@
|
||||
// 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
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -7,11 +9,14 @@
|
||||
#ifndef BOOST_FUNCTION_INPUT_ITERATOR
|
||||
#define BOOST_FUNCTION_INPUT_ITERATOR
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/function_types/is_function_pointer.hpp>
|
||||
#include <boost/function_types/is_function_reference.hpp>
|
||||
#include <boost/function_types/result_type.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/none.hpp>
|
||||
#include <boost/optional/optional.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@ -29,16 +34,19 @@ namespace boost {
|
||||
public:
|
||||
function_input_iterator() {}
|
||||
function_input_iterator(Function & f_, Input state_ = Input())
|
||||
: f(&f_), state(state_), value((*f)()) {}
|
||||
: f(&f_), state(state_) {}
|
||||
|
||||
void increment() {
|
||||
value = (*f)();
|
||||
if(value)
|
||||
value = none;
|
||||
else
|
||||
(*f)();
|
||||
++state;
|
||||
}
|
||||
|
||||
typename Function::result_type const &
|
||||
dereference() const {
|
||||
return value;
|
||||
return (value ? value : value = (*f)()).get();
|
||||
}
|
||||
|
||||
bool equal(function_input_iterator const & other) const {
|
||||
@ -48,7 +56,7 @@ namespace boost {
|
||||
private:
|
||||
Function * f;
|
||||
Input state;
|
||||
typename Function::result_type value;
|
||||
mutable optional<typename Function::result_type> value;
|
||||
};
|
||||
|
||||
template <class Function, class Input>
|
||||
@ -63,17 +71,19 @@ namespace boost {
|
||||
public:
|
||||
function_pointer_input_iterator() {}
|
||||
function_pointer_input_iterator(Function &f_, Input state_ = Input())
|
||||
: f(f_), state(state_), value((*f)())
|
||||
{}
|
||||
: f(f_), state(state_) {}
|
||||
|
||||
void increment() {
|
||||
value = (*f)();
|
||||
if(value)
|
||||
value = none;
|
||||
else
|
||||
(*f)();
|
||||
++state;
|
||||
}
|
||||
|
||||
typename function_types::result_type<Function>::type const &
|
||||
dereference() const {
|
||||
return value;
|
||||
return (value ? value : value = (*f)()).get();
|
||||
}
|
||||
|
||||
bool equal(function_pointer_input_iterator const & other) const {
|
||||
@ -83,7 +93,7 @@ namespace boost {
|
||||
private:
|
||||
Function f;
|
||||
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>
|
||||
|
@ -147,7 +147,7 @@ namespace boost
|
||||
|
||||
// Returning a mutable reference allows nonsense like
|
||||
// (*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.
|
||||
value_type&
|
||||
operator*() const
|
||||
@ -294,7 +294,7 @@ namespace boost
|
||||
|
||||
// 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 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 a proxy object containing an instance of the reference object.
|
||||
template <class Reference, class Pointer>
|
||||
struct operator_arrow_dispatch // proxy references
|
||||
|
@ -7,8 +7,8 @@
|
||||
#ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <boost/next_prior.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
|
||||
namespace boost
|
||||
|
@ -3,12 +3,17 @@
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/iterator/function_input_iterator.hpp>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/iterator/function_input_iterator.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
struct ones {
|
||||
typedef int result_type;
|
||||
@ -21,6 +26,17 @@ int ones_function () {
|
||||
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;
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
@ -65,6 +81,21 @@ int main(int argc, char * argv[])
|
||||
assert(equal(values.begin(), values.end(), generated.begin()));
|
||||
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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user