Compare commits

..

4 Commits

5 changed files with 70 additions and 23 deletions

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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;
}