[SVN r80467]
This commit is contained in:
Jeffrey Lee Hellrung, Jr.
2012-09-09 15:33:12 +00:00
parent 2db78eec90
commit 31c3971720
3 changed files with 55 additions and 15 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
======================= =======================
@ -58,7 +61,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 +115,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

@ -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,17 @@ 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)(); BOOST_ASSERT(value);
value = none;
++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 +54,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 +69,17 @@ 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)(); BOOST_ASSERT(value);
value = none;
++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 +89,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

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