pstade

PrevUpHomeNext

Ranges

any_range
any_indexed
array_range
directory_range
empty_range
file_range
as_array
as_c_str
as_literal
block
comprehension
counting
generation
hetero
initial_values
iteration
make_range
recursion
shared
single
shared_single
stream_lines
stream_read
streambuf_read
unfold

Oven provides many useful predefined ranges.

Description

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.

Header
  • <pstade/oven/any_range.hpp>
Model of
Valid expressions

Valid expression

Semantics

any_range<R, C>(_rng)

[_begin(_rng), _end(_rng)), whose boost::range_reference type is R.

any_range<R, C> any = _rng0;

any_range<R, C> any(_rng0);

Preconditions
  • 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.
Example
any_range<int, boost::single_pass_traversal_tag> factorials =
    counting(1, 500) |
        scanned(1, regular(lambda::_1 * lambda::_2));
See also
Description

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.

Header
  • <pstade/oven/any_indexed.hpp>
Model of
Valid expressions

Valid expression

Semantics

any_indexed<R>

any_range<R, boost::random_access_traversal_tag>

Preconditions
  • The corresponding semantics is a valid expression.
  • If R is a reference type, a range which initialize or is assigned to any_indexed<R> is a LvalueRange.
  • any_indexed<R> is not recursive.
Example
See also
Description

array_range is a noncopyable Random Access Range which delivers a range presentation of dynamically allocated arrays.

Header
  • <pstade/oven/array_range.hpp>
Model of
Valid expressions

Valid expression

Semantics

array_range<T>(sz)

[x, x + sz), where x = new T[sz].

Preconditions
  • new T[sz] is a valid expression.
Example
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) );
See also
Description

directory_range is a Single Pass Range which accesses the contents of a directory.

Header
  • <pstade/oven/directory_range.hpp>
Model of
Valid expressions

Valid expression

Semantics

basic_directory_range<P>(p)

[T(p), T())

directory_range(p)

basic_directory_range<boost::filesystem::path>(p)

wdirectory_range(p)

basic_directory_range<boost::filesystem::wpath>(p)

Preconditions
  • T is boost::filesystem::basic_directory_iterator<P> such that T(p) is a valid expression.
Example
BOOST_FOREACH (
    boost::filesystem::path const& pt,
    directory_range(boost::filesystem::current_path()))
{
    std::cout << pt.leaf() << std::endl;
}
See also
Description

empty_range is a Random Access Range which is always empty.

Header
  • <pstade/oven/empty_range.hpp>
Model of
Valid expressions

Valid expression

Semantics

empty_range<V>()

[(V *)0, (V *)0)

Example
BOOST_CHECK( boost::empty(empty_range<int>()) );
See also
Description

file_range is a Random Access Constant Range for files. If the file opening failed, the range is empty.

[Note] Note

file_range is "binary"; any automatic conversion isn't performed.

Header
  • <pstade/oven/file_range.hpp>
Model of
Notation
  • r is a file_range<X1,...,XN>.
Valid expressions

Valid expression

Semantics

file_range<X1,...,XN>(s)

[T(s), T())

r.is_open()

Returns true if and only if the file has successfully been opened.

Invariants
  • !r.is_open() ? boost::empty(r) : true
Preconditions
  • T is boost::spirit::file_iterator<X1,...,XN> such that T(s) is a valid expression.
[Note] Note

In the current implementation, an empty file is not opened. So is_open() can't tell whether a file exists or not.

Example
std::vector<char> vec;
file_range<char> frng("data.txt");
copy(frng, std::back_inserter(vec));
See also
Description

Some versions of Boost.Range regard char array as literal, which as_array works around.

Header
  • <pstade/oven/as_array.hpp>
Model of
Valid expressions

Valid expression

Semantics

as_array(a)

as_array proposal

Preconditions
  • a is an array.
Example
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.
See also
Description

as_c_str makes a Random Access Range from null-terminated c-style string.

Header
  • <pstade/oven/as_c_str.hpp>
Model of
Valid expressions

Valid expression

Semantics

as_c_str(s)

[s, s + strlen(s))

as_c_str(_rng)

[_begin(_rng), std::find(_begin(_rng), _end(_rng), 0))

Preconditions
  • _typeof(s) is convertible to char * or char const *.
  • _typeof(_rng) is neither convertible to char * nor char const *.
See also
Description

as_literal makes a Random Access Range from character array.

Header
  • <pstade/oven/as_literal.hpp>
Model of
Valid expressions

Valid expression

Semantics

as_literal(a)

[&a[0], &a[0] + sz-1), where sz is the size of array a.

as_literal(x)

x

Preconditions
  • a is an array.
  • x is not an array.
[Important] Important

as_literal doesn't use strlen, while Proposal for new string algorithms in TR2 does.

See also
Description

block makes a Single Pass Range from an Iteration Block.

Header
  • <pstade/oven/block.hpp>
Model of
Notation
Valid expressions

Valid expression

Semantics

block(b)

A Single Pass Range whose values are the objects passed to yield.

Preconditions
Example
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 << ',';
}
See also
Description

Pending... comprehension emulates set-builder notation.

Header
  • <pstade/oven/comprehension.hpp>
Model of
Notation
  • d(I) = distance(_rngI)
  • a(1,j) ia a j-th element of makerng1().
  • If I >= 2, a(I,j) is a j-th element of makerngI(a(I-1, u)).
Valid expressions

Valid expression

Semantics

comprehension(_fun, _prd, makerng1,...,makerngN)

A Forward Lvalue Constant {_fun(a(1,1),a(2,1),...a(N,1)),_fun(a(1,1),a(2,1),...a(N,2)),...,_fun(a(1,1),a(2,1),...a(N,d(N))),...} but filtered using _prd.

always_return

A Static Function Object

always_return(b)

boost::lambda::constant(b)

always_return(_rng)

boost::lambda::constant([_begin(_rng), _end(_rng)))

[Note] Note

A result object of _fun(...) is copied, whereas range referents which makerngI returns must outlive comprehension(...).

Preconditions
Example
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)}");
}
See also
Description

counting makes a boost::counting_iterator range, which is not a Lvalue Range.

Header
  • <pstade/oven/counting.hpp>
Model of
Valid expressions

Valid expression

Semantics

X_counting<X1,...,XN>

A Major Function Object type

X_counting<X1,...,XN>()(i, j)

[T(i), T(j))

counting(i, j)

X_counting<>()(i, j)

counting(i, max_count)

X_counting<>()(i, std::numeric_limits<_typeof(i)>::max())

Preconditions
  • 0 <= N && N <= 2
  • T is boost::counting_iterator<_typeof(j), X1,...,XN> such that T(i) and T(j) is a valid expression.
Example
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);
}
See also
Description

generation makes a Single Pass Range from a Stoppable Generator.

Header
  • <pstade/oven/generation.hpp>
Model of
Valid expressions

Valid expression

Semantics

generation(g)

The longest Single Pass {*g(),*g(),*g(),...,*g()} such that g() is not uninitialized.

Preconditions
Example
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;
    }
}
See also
Description

hetero runs through a "tuple".

Header
  • <pstade/oven/hetero.hpp>
Model of
Notation
  • N is boost::fusion::result_of::size<_typeof(tup)>::type::value.
Valid expressions

Valid expression

Semantics

X_hetero<Ref>

A Major Function Object type

X_hetero<Ref>()(tup)

A Random Access {(Ref)boost::fusion::at_c<0>(tup),...,(Ref)boost::fusion::at_c<N-1>(tup)}

oven::hetero<Ref>

X_hetero<Ref>()

Preconditions
  • tup is a Fusion Forward Sequence or boost::tuple<...>.
  • 0 <= N && N < 20.
  • For all 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.
Example
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();
}
See also
Description

initial_values emulates initializer-lists.

Header
  • <pstade/oven/initial_values.hpp>
Model of
Valid expressions

Valid expression

Semantics

X_initial_values<T>

A Major Function Object type

X_initial_values<T>()(a1,...,aN)

A Random Access Readable Lvalue Constant {a1,...,aN}

Rng rng = X_initial_values<T>()(a1,...,aN);

Rng rng = X_initial_values<T>()(a1,...,aN)|copied;

Rng2 rng2(X_initial_values<T>()(a1,...,aN));

Rng2 rng2(X_initial_values<T>()(a1,...,aN)|copied);

initial_values

X_initial_values<t>(), where t is deduced from the first argument.

[Note] Note

Every aK is copied, meaning that they are not referenced from Oven later.

Preconditions
  • 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] Tip

initial_values trades unlimited arity for the lightweight initialization of boost::array. Also, it doesn't require the arguments to be Assignable.

Example
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) );
See also
Description

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] 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.

Header
  • <pstade/oven/iteration.hpp>
Model of
Notation
  • just is an imaginary function object such that y -> boost::optional<_typeof(x)>(y).
Valid expressions

Valid expression

Semantics

iteration(x, _fun)

unfold(x, just, _fun)

Preconditions
  • The corresponding semantics is a valid expression.
Example
int answer[] = { 1,2,4,8,16 };
BOOST_CHECK( equals(answer,
    iteration(1, regular(boost::lambda::_1 * 2))|taken(5)
) );
See also
Description

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.

Header
  • <pstade/oven/make_range.hpp>
Model of
Valid expressions

Valid expression

Semantics

make_range(_rng)

[_begin(_rng), _end(_rng))

make_range(i, j)

[i, j)

Preconditions
  • The corresponding semantics is a valid expression.
See also
Description

Pending... recursion, collaborating with any_range, creates a recursive range.

Header
  • <pstade/oven/recursion.hpp>
Model of
Valid expressions

Valid expression

Semantics

recursion(_fwdrng)

An up-to-Bidirectional [_begin(_fwdrng), _end(_fwdrng))

Preconditions
  • _fwdrng is an any_range.
  • Every memoized in the base range takes its own memo_table object.
Example
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] Note

In a recursive range, memoized must take a named memo_table object. A recursive range tends to be inefficient without memoization.

See also
Description

shared makes a range from a pointer to a heap allocated range, and the iterators manage the allocation.

Header
  • <pstade/oven/shared.hpp>
Model of
Notation
  • shared_range_iterator is an imaginary iterator which works like boost::shared_container_iterator but uses a range instead of a container.
Valid expressions

Valid expression

Semantics

shared(p)

[T(_begin(*p), sp), T(_end(*p), sp))

Preconditions
  • 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.
Example
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;
}
See also
Description

single makes a Random Access Range which delivers a range presentation of one object.

Header
  • <pstade/oven/single.hpp>
Model of
Valid expressions

Valid expression

Semantics

single(x)

[&x, &x + 1)

[Note] Note

As the semantics implies, the iterators are valid as long as x is not destructed. If you want the iterators to manage the base object lifetime, use shared_single.

Example
BOOST_CHECK( equals(single('a'), std::string("a")) );
See also
Description

shared_single, given a pointer to a heap allocated object, delivers a range presentation of the pointee.

Header
  • <pstade/oven/shared_single.hpp>
Model of
Valid expressions

Valid expression

Semantics

shared_single(p)

[&*p, &*p + 1)

Preconditions
  • boost::shared_ptr<_typeof(*p)>(p) is a valid expression.
Example
boost::result_of<T_shared_single(char *)>::type
make_rng()
{
    return shared_single(new char('a'));
}
See also
Description

stream_lines makes a std::string Single Pass Range from std::cout etc.

Header
  • <pstade/oven/stream_lines.hpp>
Model of
Notation
  • DefaultA is std::allocator<_typeof(s)::char_type>.
Valid expressions

Valid expression

Semantics

X_stream_lines<A = DefaultA>

A Major Function Object type

X_stream_lines<A>()(s)

[T(s), T())

stream_lines

X_stream_lines<>()

Preconditions
  • T is hamigaki::istream_line_iterator<_typeof(s)::char_type, _typeof(s)::traits_type, A> suct that T(s) is a valid expression.
Example
See also
Description

stream_read makes a Single Pass Range from std::cout etc.

Header
  • <pstade/oven/stream_read.hpp>
Valid expressions

Valid expression

Semantics

X_stream_read<V, D = std::ptrdiff_t>

A Major Function Object type

X_stream_read<V, D>()(s)

[T(s), T())

oven::stream_read<V>()(s)

X_stream_read<V>()(s)

[Important] Important

Notice that stream_read<V>(s) is qualified with oven:: to avoid unintentional ADL.

Preconditions
  • T is std::istream_iterator<V, _typeof(s)::char_type, _typeof(s)::traits_type, D> suct that T(s) is a valid expression.
Example
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) );
See also
Header
  • <pstade/oven/stream_read.hpp>
Model of
Valid expressions

Valid expression

Semantics

streambuf_read(s)

[T(s), T())

streambuf_read(p)

[U(p), U())

Preconditions
  • 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.
Description

unfold makes a range from a seed.

Header
  • <pstade/oven/unfold.hpp>
Model of
Valid expressions

Valid expression

Semantics

unfold(z, f, g)

The longest Forward {f(z),f(g(z)),f(g(g(z))),f(g(g(g(z)))),...} such that f(...) is not uninitialized.

[Note] Note

z is copied, meaning that it is not referenced from Oven later.

Preconditions
Example
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) );
}
See also
Copyright 2005 -2007 Shunsuke Sogame

PrevUpHomeNext