![]() |
Oven provides many useful predefined ranges.
Though Oven supports Boost.ResultOf,
it is often cumbersome to get the type of the adapted range. any_range behaves as the type erasure of
ranges.
<pstade/oven/any_range.hpp>C.
|
Valid expression |
Semantics |
|---|---|
|
|
|
|
|
|
boost::range_reference<_typeof(_rng)>::type is convertible to R without binding reference
to rvalue.
C is convertible to boost::single_pass_traversal_tag.
boost::range_traversal<_typeof(_rng)>::type is convertible to C.
_rng0 is a range returned
from Oven Function
Object and meets the preconditions of _rng.
any_range<int, boost::single_pass_traversal_tag> factorials = counting(1, 500) | scanned(1, regular(lambda::_1 * lambda::_2));
Iterators of Random
Access any_range
may require heap allocation to copy, whereas any_indexed
offers lightweight-copyable iterators in return for some extra preconditions.
<pstade/oven/any_indexed.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
array_range is a noncopyable
Random
Access Range
which delivers a range presentation of dynamically allocated arrays.
<pstade/oven/array_range.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
new T[sz]
is a valid expression.
std::string str("hello, array_range!"); boost::array<char, 19> sarr; copy(str, sarr|begin); array_range<char> darr(19); copy(str, darr|begin); BOOST_CHECK( equals(sarr, darr) );
directory_range is a Single
Pass Range
which accesses the contents of a directory.
<pstade/oven/directory_range.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
|
|
|
|
|
|
T is boost::filesystem::basic_directory_iterator<P> such that T(p)
is a valid expression.
BOOST_FOREACH ( boost::filesystem::path const& pt, directory_range(boost::filesystem::current_path())) { std::cout << pt.leaf() << std::endl; }
empty_range is a Random
Access Range
which is always empty.
<pstade/oven/empty_range.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
BOOST_CHECK( boost::empty(empty_range<int>()) );
file_range is a Random
Access Constant
Range
for files. If the file opening failed, the range is empty.
![]() |
Note |
|---|---|
|
|
<pstade/oven/file_range.hpp>r is a file_range<X1,...,XN>.
|
Valid expression |
Semantics |
|---|---|
|
|
|
|
|
Returns |
!r.is_open() ? boost::empty(r)
: trueT is boost::spirit::file_iterator<X1,...,XN> such that T(s)
is a valid expression.
![]() |
Note |
|---|---|
|
In the current implementation, an empty file is not opened. So
|
std::vector<char> vec; file_range<char> frng("data.txt"); copy(frng, std::back_inserter(vec));
Some versions of Boost.Range
regard char array as literal,
which as_array works around.
<pstade/oven/as_array.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
a is an array.
BOOST_CHECK( distance(as_array("abc\0de")) == 7 ); // contains the trailing null. BOOST_CHECK( distance(as_c_str("abc\0de")) == 3 ); // null means the end. BOOST_CHECK( distance(as_literal("abc\0de")) == 6 ); // null doesn't affect.
as_c_str makes a Random
Access Range
from null-terminated c-style string.
<pstade/oven/as_c_str.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
|
|
|
_typeof(s) is
convertible to char *
or char const
*.
_typeof(_rng)
is neither convertible to char * nor char
const *.
as_literal makes a Random
Access Range
from character array.
<pstade/oven/as_literal.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
|
|
|
a is an array.
x is not an array.
![]() |
Important |
|---|---|
|
|
block makes a Single
Pass Range
from an Iteration Block.
<pstade/oven/block.hpp>yield is an unspecified
unary Function Object
passed to b.
|
Valid expression |
Semantics |
|---|---|
|
|
A Single
Pass Range
whose values are the objects passed to |
b is an Iteration
Block.
struct power { int m_number, m_exponent; power(int number, int exponent) : m_number(number), m_exponent(exponent) { } typedef int yield_type; template<typename Yield> void operator()(Yield yield) const { int counter = 0; int result = 1; while (counter++ < m_exponent) { result = result * m_number; yield(result); } } }; void test() { power(2, 8)(std::cout << boost::lambda::_1 << ','); BOOST_FOREACH (int x, block(power(2, 8))) std::cout << x << ','; }
Pending... comprehension
emulates set-builder notation.
<pstade/oven/comprehension.hpp>d(I) =
distance(_rngI)a(1,j) ia a j-th
element of makerng1().
I >=
2, a(I,j) is
a j-th element of makerngI(a(I-1,
u)).
|
Valid expression |
Semantics |
|---|---|
|
|
A Forward
Lvalue
Constant |
|
|
|
|
|
|
|
|
|
![]() |
Note |
|---|---|
|
A result object of
|
N <=
3_fun is a N-ary Polymorphic
Function Object or Boost.Lambda
functor.
_typeof(_fun(...))
is Copy Constructible.
I, makerngI is a I-1-ary Polymorphic
Function Object or Boost.Lambda
functor which returns a Range.
_prd is N-ary.
_typeof(b) is
bool.
namespace bll = boost::lambda; typedef boost::tuple<int, int, int> triple_t; struct make_triple { typedef triple_t result_type; result_type operator()(int x, int y, int z) const { return result_type(x, y, z); } }; typedef any_range<triple_t, boost::forward_traversal_tag> triples_t; triples_t triples(int n) { return comprehension( ::make_triple(), bll::_1 * bll::_1 + bll::_2 * bll::_2 == bll::_3 * bll::_3, // guard bll::bind(counting, 1, n + 1), // -> _1 bll::bind(counting, bll::_1, n + 1), // -> _2 bll::bind(counting, bll::_2, n + 1) // -> _3 ); } void test() { std::stringstream sout; sout << ::triples(20); BOOST_CHECK(sout.str() == "{(3 4 5),(5 12 13),(6 8 10),(8 15 17),(9 12 15),(12 16 20)}"); }
counting makes a boost::counting_iterator range, which is not a
Lvalue
Range.
<pstade/oven/counting.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
A Major Function Object type |
|
|
|
|
|
|
|
|
|
0 <=
N &&
N <=
2T is boost::counting_iterator<_typeof(j),
X1,...,XN>
such that T(i) and
T(j) is
a valid expression.
int ans[] = { 2, 3, 4, 5, 6 }; BOOST_CHECK( equal(counting(2, 7), ans) ); std::vector<int> vec; BOOST_FOREACH (int i, counting(0, 5)) { vec.push_back(i); }
generation makes a Single
Pass Range
from a Stoppable Generator.
<pstade/oven/generation.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
The longest Single
Pass |
g is a nullary Stoppable
Generator.
g is Assignable.
_typeof(*g())
is Copy Constructible
and Assignable.
struct rand_generator { typedef boost::optional<long> result_type; result_type operator()() { long result = std::rand(); if (result % 3 == 0) return result_type(); // stop generating. return result; } }; void test() { rand_generator X; BOOST_FOREACH (long x, generation(X)) { std::cout << x << std::endl; } }
hetero runs through a "tuple".
<pstade/oven/hetero.hpp>N is boost::fusion::result_of::size<_typeof(tup)>::type::value.
|
Valid expression |
Semantics |
|---|---|
|
|
A Major Function Object type |
|
|
A Random
Access |
|
|
|
tup is a Fusion
Forward Sequence or boost::tuple<...>.
0 <=
N &&
N <
20.
I such that 0 <= I &&
I <
N, Ref
is convertible to boost::fusion::result_of::at_c<_typeof(tup), I>::type
without binding a reference to rvalue.
rectangle r; triangle t; circle c; boost::tuple<rectangle*, triangle*, circle*> tup(&r, &t, &c); BOOST_FOREACH (shape *s, oven::hetero<shape *>(tup)) { s->draw(); }
initial_values emulates initializer-lists.
<pstade/oven/initial_values.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
A Major Function Object type |
|
|
A Random
Access Readable
Lvalue
Constant |
|
|
|
|
|
|
|
|
|
![]() |
Note |
|---|---|
|
Every
|
1 <=
N &&
N <=
20_typeof(aK) is
Copy Constructible
for all K such that 1 <= K &&
K <=
N.
_typeof(aK) is
convertible to _typeof(a1)
for all K such that 2 <= K &&
K <=
N.
Rng rng
= X_initial_values<T>()(a1,...,aN)|copied; is a valid expression.
Rng2 rng2(X_initial_values<T>()(a1,...,aN)|copied); is a valid expression.
![]() |
Tip |
|---|---|
|
|
int const ans[] = { 1,5,3,6,1,3,7,1,4,2,2 }; std::vector<int> vec = initial_values(1,5,3,6,1,3,7,1,4,2,2); BOOST_CHECK( equals(vec, ans) );
iteration makes an infinite
Forward
Range
where the first item is calculated by applying the function on the first
argument, the second item by applying the function on the previous result
and so on.
![]() |
Note |
|---|---|
|
Strictly speaking, the range concept doesn't allow an infinite range. So assume here the end iterator is reachable from the begin iterator in the googolplex number of increments.
|
<pstade/oven/iteration.hpp>just is an imaginary function
object such that y ->
boost::optional<_typeof(x)>(y).
|
Valid expression |
Semantics |
|---|---|
|
|
|
int answer[] = { 1,2,4,8,16 }; BOOST_CHECK( equals(answer, iteration(1, regular(boost::lambda::_1 * 2))|taken(5) ) );
Types defined in Oven is so hardhead that you can't copy-initialize
any_range by third-party
ranges. So, you sometimes have to call make_range,
which turns a range into Oven compatible iterator-range.
<pstade/oven/make_range.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
|
|
|
Pending... recursion, collaborating
with any_range, creates a recursive
range.
<pstade/oven/recursion.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
An up-to-Bidirectional
|
_fwdrng is an any_range.
memoized in the base
range takes its own memo_table
object.
typedef any_range<int const&, boost::forward_traversal_tag> range_t; range_t fibs; memo_table tb; int const start[] = { 1, 1 }; fibs = start | rvalues // for jointed precondition | jointed( boost::make_tuple(recursion(fibs), recursion(fibs)|dropped(1)) | zipped_with(regular(boost::lambda::_1 + boost::lambda::_2)) ) | memoized(tb) ; std::cout << (fibs|taken(howMany));
![]() |
Note |
|---|---|
|
In a recursive range,
|
shared makes a range from
a pointer to a heap allocated range, and the iterators manage the allocation.
<pstade/oven/shared.hpp>shared_range_iterator is
an imaginary iterator which works like boost::shared_container_iterator
but uses a range instead of a container.
|
Valid expression |
Semantics |
|---|---|
|
|
|
sp is a boost::shared_ptr<_typeof(*p)>(p) such
that sp(p) is
a valid expression.
T is a shared_range_iterator<_typeof(*p)>
such that T(_begin(*p), sp) is
a valid expression.
BOOST_FOREACH (char ch, std::string("dangling")|identities) { // will crash; 'std::string' object doesn't exist anymore. std::cout << ch; } BOOST_FOREACH (char ch, shared(new std::string("ok"))|identities) { // works fine. std::cout << ch; }
single makes a Random
Access Range
which delivers a range presentation of one object.
<pstade/oven/single.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
![]() |
Note |
|---|---|
|
As the semantics implies, the iterators are valid as long as
|
BOOST_CHECK( equals(single('a'), std::string("a")) );
shared_single, given a pointer
to a heap allocated object, delivers a range presentation of the pointee.
<pstade/oven/shared_single.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
boost::shared_ptr<_typeof(*p)>(p) is
a valid expression.
boost::result_of<T_shared_single(char *)>::type make_rng() { return shared_single(new char('a')); }
stream_lines makes a std::string
Single
Pass Range
from std::cout etc.
<pstade/oven/stream_lines.hpp>DefaultA is std::allocator<_typeof(s)::char_type>.
|
Valid expression |
Semantics |
|---|---|
|
|
A Major Function Object type |
|
|
|
|
|
|
T is hamigaki::istream_line_iterator<_typeof(s)::char_type,
_typeof(s)::traits_type,
A>
suct that T(s) is
a valid expression.
stream_read makes a Single
Pass Range
from std::cout etc.
<pstade/oven/stream_read.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
A Major Function Object type |
|
|
|
|
|
|
![]() |
Important |
|---|---|
|
Notice that
|
T is std::istream_iterator<V, _typeof(s)::char_type,
_typeof(s)::traits_type,
D>
suct that T(s) is
a valid expression.
std::string src("hello,stream_read!"); std::stringstream ss; ss << src; std::string result; copy(oven::stream_read<char>(ss), std::back_inserter(result)); BOOST_CHECK( equals(result, src) );
<pstade/oven/stream_read.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
|
|
|
|
T is std::istreambuf_iterator<_typeof(s)::char_type,
_typeof(s)::traits_type>
such that T(s) is
a valid expression.
U is std::istreambuf_iterator<_typeof(*p)::char_type,
_typeof(*p)::traits_type>
such that U(p) is
a valid expression.
unfold makes a range from
a seed.
<pstade/oven/unfold.hpp>|
Valid expression |
Semantics |
|---|---|
|
|
The longest Forward
|
![]() |
Note |
|---|---|
|
|
z, f(...) and g
is Assignable,
Copy Constructible
and Default
Constructible.
f is a unary Stoppable
Generator.
g is a Function
Object such that z1 = g(z1) is
well-formed, where _typeof(z)
z1 =
z.
f and g
is a mapping,
meaning that a ==
b implies f(a)
== f(b).
boost::optional<int> mod(int i) { if (i == 0) return boost::optional<int>(); return i % 10; } void test() { int const answer[] = { 1,5,4,1,9,2,3,6,1 }; BOOST_CHECK( equals(unfold(163291451, &mod, lambda::_1 / 10), answer) ); }
| Copyright © 2005 -2007 Shunsuke Sogame |