rah
Namespaces | Classes | Functions
rah::view Namespace Reference

Namespaces

 details
 

Classes

struct  chunk_iterator
 
struct  concat_iterator
 
struct  counted_iterator
 
struct  cycle_iterator
 
struct  filter_iterator
 
struct  generate_iterator
 
struct  ints_iterator
 
struct  iota_iterator
 
struct  join_iterator
 
struct  repeat_iterator
 
struct  set_difference_iterator
 
struct  sliding_iterator
 
struct  stride_iterator
 
struct  take_iterator
 
struct  transform_iterator
 
struct  unbounded_iterator
 
struct  zip_iterator
 

Functions

template<typename R >
auto all (R &&range)
 Create a view on the whole range. More...
 
auto all ()
 Create a view on the whole range. More...
 
template<typename R >
auto take (R &&range, size_t count)
 Given a source range and an integral count, return a range consisting of the first count elements from the source range, or the complete range if it has fewer elements. More...
 
auto take (size_t count)
 Given a source range and an integral count, return a range consisting of the first count elements from the source range, or the complete range if it has fewer elements. More...
 
template<typename I >
auto counted (I &&it, size_t n, decltype(++it, 0)=0)
 Given an iterator it and a count n, create a range that starts at it and includes the next n elements. More...
 
template<typename I >
auto unbounded (I &&it)
 Given an iterator, return an infinite range that begins at that position. More...
 
template<typename T = size_t>
auto ints (T b=0, T e=std ::numeric_limits< T >::max())
 Generate a range of monotonically increasing ints. More...
 
template<typename T = size_t>
auto iota (T b, T e, T step=1)
 Generate a range of sequential integers, increasing by a defined step. More...
 
template<typename V >
auto repeat (V &&value)
 Generate an infinite range of the given value. More...
 
template<typename R >
auto join (R &&range_of_ranges)
 Given a range of ranges, join them into a flattened sequence of elements. More...
 
auto join ()
 Given a range of ranges, join them into a flattened sequence of elements. More...
 
template<typename R >
auto cycle (R &&range)
 Returns an infinite range that endlessly repeats the source range. More...
 
auto cycle ()
 Returns an infinite range that endlessly repeats the source range. More...
 
template<typename F >
auto generate (F &&func)
 Create an infinite range, repetitively calling func. More...
 
template<typename F >
auto generate_n (size_t count, F &&func)
 
template<typename R , typename F >
auto transform (R &&range, F &&func)
 Create a view applying a transformation to each element of the input range. More...
 
template<typename F >
auto transform (F &&func)
 Create a view applying a transformation to each element of the input range. More...
 
template<typename R , typename F >
auto for_each (R &&range, F &&func)
 Lazily applies an unary function to each element in the source range that returns another range (possibly empty), flattening the result. More...
 
template<typename F >
auto for_each (F &&func)
 Lazily applies an unary function to each element in the source range that returns another range (possibly empty), flattening the result. More...
 
template<typename R >
auto slice (R &&range, intptr_t begin_idx, intptr_t end_idx)
 Create a view that is a sub-range of a range. More...
 
auto slice (intptr_t begin, intptr_t end)
 Create a view that is a sub-range of a range. More...
 
template<typename R >
auto stride (R &&range, size_t step)
 Create a view consisting of every Nth element, starting with the first. More...
 
auto stride (size_t step)
 Create a view consisting of every Nth element, starting with the first. More...
 
template<typename R >
auto retro (R &&range)
 Create a view that traverses the source range in reverse order. More...
 
auto retro ()
 Create a view that traverses the source range in reverse order. More...
 
template<typename V >
auto single (V &&value)
 Given value, create a view containing one element. More...
 
template<typename ... R>
auto zip (R &&... _ranges)
 Given N ranges, return a new range where Mth element is the result of calling std::make_tuple on the Mth elements of all N ranges. More...
 
template<typename R >
auto chunk (R &&range, size_t step)
 Create a view where each element is a range of N elements of the input range. More...
 
auto chunk (size_t step)
 Create a view where each element is a range of N elements of the input range. More...
 
template<typename R , typename F >
auto filter (R &&range, F &&func)
 Create a view with only elements which are filtered. More...
 
template<typename F >
auto filter (F &&func)
 Create a view with only elements which are filtered. More...
 
template<typename R1 >
auto concat (R1 &&range1)
 return the same range More...
 
template<typename R1 , typename R2 >
auto concat (R1 &&range1, R2 &&range2)
 Create a view that is the concatenation of 2 ranges. More...
 
template<typename R1 , typename R2 , typename ... Ranges>
auto concat (R1 &&range1, R2 &&range2, Ranges &&... ranges)
 
template<typename R >
auto enumerate (R &&range)
 Pair each element of a range with its index. More...
 
auto enumerate ()
 Pair each element of a range with its index. More...
 
template<typename R >
auto map_value (R &&range)
 Given a range of std::pair-std::tuple, create a view consisting of just the first element of the pair. More...
 
auto map_value ()
 Given a range of std::pair-std::tuple, create a view consisting of just the first element of the pair. More...
 
template<typename R >
auto map_key (R &&range)
 Given a range of std::pair-std::tuple, create a view consisting of just the second element of the pair. More...
 
auto map_key ()
 Given a range of std::pair-std::tuple, create a view consisting of just the second element of the pair. More...
 
template<typename R , typename P = is_lesser, typename = std ::enable_if_t<is_range<R>::value>>
auto sort (R &&range, P &&pred={})
 Make a sorted view of a range. More...
 
template<typename P = is_lesser, typename = std ::enable_if_t<not is_range<P>::value>>
auto sort (P &&pred={})
 Make a sorted view of a range. More...
 
template<typename R >
auto sliding (R &&range, size_t n)
 Given a range and a count n, place a window over the first n elements of the underlying range. More...
 
auto sliding (size_t n)
 Given a range and a count n, place a window over the first n elements of the underlying range. More...
 
template<typename R >
auto drop_exactly (R &&range, size_t count)
 Given a source range and an integral count, return a range consisting of all but the first count elements from the source range. More...
 
auto drop_exactly (size_t count)
 Given a source range and an integral count, return a range consisting of all but the first count elements from the source range. More...
 
template<typename R >
auto drop (R &&range, size_t count)
 Given a source range and an integral count, return a range consisting of all but the first count elements from the source range, or an empty range if it has fewer elements. More...
 
auto drop (size_t count)
 Given a source range and an integral count, return a range consisting of all but the first count elements from the source range, or an empty range if it has fewer elements. More...
 
template<typename T = size_t>
auto closed_ints (T b=0, T e=std ::numeric_limits< T >::max() - 1)
 Generate a range of monotonically increasing ints. More...
 
template<typename R1 , typename R2 >
auto set_difference (R1 &&range1, R2 &&range2)
 
template<typename R2 >
auto set_difference (R2 &&range2)
 

Function Documentation

◆ all() [1/2]

template<typename R >
auto rah::view::all ( R &&  range)

Create a view on the whole range.

◆ all() [2/2]

auto rah::view::all ( )
inline

Create a view on the whole range.

Remarks
pipeable syntax

◆ chunk() [1/2]

template<typename R >
auto rah::view::chunk ( R &&  range,
size_t  step 
)

Create a view where each element is a range of N elements of the input range.

std::vector<int> vec_01234{ 0, 1, 2, 3, 4 };
std::vector<std::vector<int>> result;
for (auto elts : rah::view::chunk(vec_01234, 2))
result.emplace_back(begin(elts), end(elts));
assert(result == std::vector<std::vector<int>>({ {0, 1}, { 2, 3 }, { 4 } }));

◆ chunk() [2/2]

auto rah::view::chunk ( size_t  step)
inline

Create a view where each element is a range of N elements of the input range.

Remarks
pipeable syntax
std::vector<int> vec_01234{ 0, 1, 2, 3, 4 };
std::vector<std::vector<int>> result;
for (auto elts : vec_01234 | rah::view::chunk(2))
result.emplace_back(begin(elts), end(elts));
assert(result == std::vector<std::vector<int>>({ {0, 1}, { 2, 3 }, { 4 } }));

◆ closed_ints()

template<typename T = size_t>
rah::view::closed_ints ( b = 0,
e = std ::numeric_limits<T>::max() - 1 
)

Generate a range of monotonically increasing ints.

When used without arguments, it generates the quasi-infinite range [0,1,2,3...]. It can also be called with a lower bound, or with a lower and upper bound (inclusive). [lower, uppder]

std::vector<int> result;
for (int i : rah::view::closed_ints(10, 14))
result.push_back(i);
assert(result == std::vector<int>({ 10, 11, 12, 13, 14 }));

◆ concat() [1/3]

template<typename R1 >
auto rah::view::concat ( R1 &&  range1)

return the same range

◆ concat() [2/3]

template<typename R1 , typename R2 >
auto rah::view::concat ( R1 &&  range1,
R2 &&  range2 
)

Create a view that is the concatenation of 2 ranges.

std::vector<int> inputA{ 0, 1, 2, 3 };
std::vector<int> inputB{ 4, 5, 6 };
std::vector<int> inputC{ 7, 8, 9, 10, 11 };
{
std::vector<int> result;
for (int i : rah::view::concat(inputA))
result.push_back(i);
assert(result == std::vector<int>({ 0, 1, 2, 3 }));
}
{
std::vector<int> result;
for (int i : rah::view::concat(inputA, inputB))
result.push_back(i);
assert(result == std::vector<int>({ 0, 1, 2, 3, 4, 5, 6 }));
}
{
std::vector<int> result;
for (int i : rah::view::concat(inputA, inputB, inputC))
result.push_back(i);
assert(result == std::vector<int>({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }));
}

◆ concat() [3/3]

template<typename R1 , typename R2 , typename ... Ranges>
auto rah::view::concat ( R1 &&  range1,
R2 &&  range2,
Ranges &&...  ranges 
)

◆ counted()

template<typename I >
auto rah::view::counted ( I &&  it,
size_t  n,
decltype(++it, 0)  = 0 
)

Given an iterator it and a count n, create a range that starts at it and includes the next n elements.

std::vector<int> in{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto range = rah::view::counted(in.begin(), 5);
std::vector<int> out;
std::copy(begin(range), end(range), std::back_inserter(out));
assert(out == std::vector<int>({ 0, 1, 2, 3, 4 }));

◆ cycle() [1/2]

template<typename R >
auto rah::view::cycle ( R &&  range)

Returns an infinite range that endlessly repeats the source range.

std::vector<int> in{ 0, 1, 2 };
auto cy = rah::view::cycle(in);
std::vector<int> out;
std::copy_n(begin(cy), 8, std::back_inserter(out));
assert(out == std::vector<int>({ 0, 1, 2, 0, 1, 2, 0, 1 }));

◆ cycle() [2/2]

auto rah::view::cycle ( )
inline

Returns an infinite range that endlessly repeats the source range.

Remarks
pipeable syntax
std::vector<int> in{ 0, 1, 2 };
auto cy = in | rah::view::cycle();
std::vector<int> out;
std::copy_n(begin(cy), 8, std::back_inserter(out));
assert(out == std::vector<int>({ 0, 1, 2, 0, 1, 2, 0, 1 }));

◆ drop() [1/2]

template<typename R >
rah::view::drop ( R &&  range,
size_t  count 
)

Given a source range and an integral count, return a range consisting of all but the first count elements from the source range, or an empty range if it has fewer elements.

std::vector<int> in{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto range = rah::view::drop(in, 6);
std::vector<int> out;
std::copy(begin(range), end(range), std::back_inserter(out));
assert(out == std::vector<int>({ 6, 7, 8, 9 }));

◆ drop() [2/2]

rah::view::drop ( size_t  count)
inline

Given a source range and an integral count, return a range consisting of all but the first count elements from the source range, or an empty range if it has fewer elements.

Remarks
pipeable syntax
std::vector<int> in{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto range = in | rah::view::drop(6);
std::vector<int> out;
std::copy(begin(range), end(range), std::back_inserter(out));
assert(out == std::vector<int>({ 6, 7, 8, 9 }));

◆ drop_exactly() [1/2]

template<typename R >
rah::view::drop_exactly ( R &&  range,
size_t  count 
)

Given a source range and an integral count, return a range consisting of all but the first count elements from the source range.

The source range must have at least that many elements.

std::vector<int> in{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto range = rah::view::drop_exactly(in, 6);
std::vector<int> out;
std::copy(begin(range), end(range), std::back_inserter(out));
assert(out == std::vector<int>({ 6, 7, 8, 9 }));

◆ drop_exactly() [2/2]

rah::view::drop_exactly ( size_t  count)
inline

Given a source range and an integral count, return a range consisting of all but the first count elements from the source range.

The source range must have at least that many elements.

Remarks
pipeable syntax
std::vector<int> in{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto range = in | rah::view::drop_exactly(6);
std::vector<int> out;
std::copy(begin(range), end(range), std::back_inserter(out));
assert(out == std::vector<int>({ 6, 7, 8, 9 }));

◆ enumerate() [1/2]

template<typename R >
auto rah::view::enumerate ( R &&  range)

Pair each element of a range with its index.

std::vector<int> input{ 4, 5, 6, 7 };
std::vector<std::tuple<size_t, int>> result;
for (auto i_value : rah::view::enumerate(input))
result.emplace_back(i_value);
assert(result == (std::vector<std::tuple<size_t, int>>{ { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } }));

◆ enumerate() [2/2]

auto rah::view::enumerate ( )
inline

Pair each element of a range with its index.

Remarks
pipeable syntax
std::vector<int> input{ 4, 5, 6, 7 };
std::vector<std::tuple<size_t, int>> result;
for (auto i_value : input | rah::view::enumerate())
result.emplace_back(i_value);
assert(result == (std::vector<std::tuple<size_t, int>>{ { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } }));

◆ filter() [1/2]

template<typename R , typename F >
auto rah::view::filter ( R &&  range,
F &&  func 
)

Create a view with only elements which are filtered.

std::vector<int> vec_01234{ 0, 1, 2, 3, 4 };
std::vector<int> result;
for (int i : rah::view::filter(vec_01234, [](auto a) {return a % 2 == 0; }))
result.push_back(i);
assert(result == std::vector<int>({ 0, 2, 4 }));

◆ filter() [2/2]

template<typename F >
auto rah::view::filter ( F &&  func)

Create a view with only elements which are filtered.

Remarks
pipeable syntax
std::vector<int> vec_01234{ 0, 1, 2, 3, 4 };
std::vector<int> result;
for (int i : vec_01234 | rah::view::filter([](auto a) {return a % 2 == 0; }))
result.push_back(i);
assert(result == std::vector<int>({ 0, 2, 4 }));

◆ for_each() [1/2]

template<typename R , typename F >
auto rah::view::for_each ( R &&  range,
F &&  func 
)

Lazily applies an unary function to each element in the source range that returns another range (possibly empty), flattening the result.

auto createRange = [](int i)
{
return rah::view::repeat(char('a' + i)) | rah::view::counted(i);
};
auto range = rah::view::for_each(rah::view::iota(0, 5), createRange);
std::string result;
std::copy(begin(range), end(range), std::back_inserter(result));
assert(result == "bccdddeeee");

◆ for_each() [2/2]

template<typename F >
auto rah::view::for_each ( F &&  func)
inline

Lazily applies an unary function to each element in the source range that returns another range (possibly empty), flattening the result.

Remarks
pipeable syntax
auto range = rah::view::ints(0, 3) | rah::view::for_each([&](int z)
{
return rah::view::ints(3, 6) | rah::view::for_each([&, z](int y)
{
return rah::view::ints(6, 9) | rah::view::for_each([&, y, z](int x)
{
return rah::view::single(x + y * 3 + z * 9);
});
});
});
assert(equal(range, rah::view::ints(15, 42)));

◆ generate()

template<typename F >
auto rah::view::generate ( F &&  func)

Create an infinite range, repetitively calling func.

int y = 1;
auto gen = rah::view::generate([&y]() mutable { auto prev = y; y *= 2; return prev; });
std::vector<int> gen_copy;
std::copy_n(begin(gen), 4, std::back_inserter(gen_copy));
assert(gen_copy == std::vector<int>({ 1, 2, 4, 8 }));

◆ generate_n()

template<typename F >
auto rah::view::generate_n ( size_t  count,
F &&  func 
)

◆ ints()

template<typename T = size_t>
auto rah::view::ints ( b = 0,
e = std ::numeric_limits<T>::max() 
)

Generate a range of monotonically increasing ints.

When used without arguments, it generates the quasi-infinite range [0,1,2,3...]. It can also be called with a lower bound, or with a lower and upper bound (exclusive). [lower, uppder[

std::vector<int> result;
for (int i : rah::view::ints(10, 15))
result.push_back(i);
assert(result == std::vector<int>({ 10, 11, 12, 13, 14 }));

◆ iota()

template<typename T = size_t>
auto rah::view::iota ( b,
e,
step = 1 
)

Generate a range of sequential integers, increasing by a defined step.

std::vector<int> result;
for (int i : rah::view::iota(10, 19, 2))
result.push_back(i);
assert(result == std::vector<int>({ 10, 12, 14, 16, 18 }));

◆ join() [1/2]

template<typename R >
auto rah::view::join ( R &&  range_of_ranges)

Given a range of ranges, join them into a flattened sequence of elements.

std::vector<std::vector<int>> in = {
{ },
{0, 1},
{ },
{2, 3, 4},
{ 5},
{},
};
auto range = rah::view::join(in);
std::vector<int> result;
std::copy(begin(range), end(range), std::back_inserter(result));
assert(result == std::vector<int>({ 0, 1, 2, 3, 4, 5 }));

◆ join() [2/2]

auto rah::view::join ( )
inline

Given a range of ranges, join them into a flattened sequence of elements.

Remarks
pipeable syntax
std::vector<std::vector<int>> in = {
{0, 1},
{ },
{2, 3, 4},
{ 5},
{},
};
auto range = in | rah::view::join();
std::vector<int> result;
std::copy(begin(range), end(range), std::back_inserter(result));
assert(result == std::vector<int>({ 0, 1, 2, 3, 4, 5 }));

◆ map_key() [1/2]

template<typename R >
auto rah::view::map_key ( R &&  range)

Given a range of std::pair-std::tuple, create a view consisting of just the second element of the pair.

std::map<int, double> input{ {1, 1.5}, { 2, 2.5 }, { 3, 3.5 }, { 4, 4.5 } };
std::vector<int> result;
for (int key : rah::view::map_key(input))
result.push_back(key);
assert(result == (std::vector<int>{ 1, 2, 3, 4 }));

◆ map_key() [2/2]

auto rah::view::map_key ( )
inline

Given a range of std::pair-std::tuple, create a view consisting of just the second element of the pair.

Remarks
pipeable syntax
std::map<int, double> input{ {1, 1.5}, { 2, 2.5 }, { 3, 3.5 }, { 4, 4.5 } };
std::vector<int> result;
for (int key : input | rah::view::map_key())
result.push_back(key);
assert(result == (std::vector<int>{ 1, 2, 3, 4 }));

◆ map_value() [1/2]

template<typename R >
auto rah::view::map_value ( R &&  range)

Given a range of std::pair-std::tuple, create a view consisting of just the first element of the pair.

std::map<int, double> input{ {1, 1.5}, { 2, 2.5 }, { 3, 3.5 }, { 4, 4.5 } };
std::vector<double> result;
for (double value : rah::view::map_value(input))
result.push_back(value);
assert(result == (std::vector<double>{ 1.5, 2.5, 3.5, 4.5 }));

◆ map_value() [2/2]

auto rah::view::map_value ( )
inline

Given a range of std::pair-std::tuple, create a view consisting of just the first element of the pair.

Remarks
pipeable syntax
std::map<int, double> input{ {1, 1.5}, { 2, 2.5 }, { 3, 3.5 }, { 4, 4.5 } };
std::vector<double> result;
for (double value : input | rah::view::map_value())
result.push_back(value);
assert(result == (std::vector<double>{ 1.5, 2.5, 3.5, 4.5 }));

◆ repeat()

template<typename V >
auto rah::view::repeat ( V &&  value)

Generate an infinite range of the given value.

std::vector<int> out;
auto range = rah::view::repeat(42);
std::copy_n(begin(range), 5, std::back_inserter(out));
assert(out == std::vector<int>({ 42, 42, 42, 42, 42 }));

◆ retro() [1/2]

template<typename R >
auto rah::view::retro ( R &&  range)

Create a view that traverses the source range in reverse order.

std::vector<int> vec{ 0, 1, 2, 3 };
std::vector<int> result;
for (int i : rah::view::retro(vec))
result.push_back(i);
assert(result == std::vector<int>({ 3, 2, 1, 0 }));

◆ retro() [2/2]

auto rah::view::retro ( )
inline

Create a view that traverses the source range in reverse order.

Remarks
pipeable syntax
std::vector<int> vec{ 0, 1, 2, 3 };
std::vector<int> result;
for (int i : vec | rah::view::retro())
result.push_back(i);
assert(result == std::vector<int>({ 3, 2, 1, 0 }));

◆ set_difference() [1/2]

template<typename R1 , typename R2 >
auto rah::view::set_difference ( R1 &&  range1,
R2 &&  range2 
)

◆ set_difference() [2/2]

template<typename R2 >
auto rah::view::set_difference ( R2 &&  range2)

◆ single()

template<typename V >
auto rah::view::single ( V &&  value)

Given value, create a view containing one element.

std::vector<int> result;
for (int i : rah::view::single(20))
result.push_back(i);
assert(result == std::vector<int>({ 20 }));

◆ slice() [1/2]

template<typename R >
auto rah::view::slice ( R &&  range,
intptr_t  begin,
intptr_t  end 
)

Create a view that is a sub-range of a range.

std::vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7 };
std::vector<int> result;
for (int i : rah::view::slice(vec, 2, 6))
result.push_back(i);
assert(result == std::vector<int>({ 2, 3, 4, 5 }));
std::vector<int> result2;
for (int i : rah::view::slice(vec, rah::End - 6, rah::End - 2))
result2.push_back(i);
assert(result2 == std::vector<int>({ 2, 3, 4, 5 }));

◆ slice() [2/2]

auto rah::view::slice ( intptr_t  begin,
intptr_t  end 
)
inline

Create a view that is a sub-range of a range.

Remarks
pipeable syntax
std::vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7 };
std::vector<int> result;
for (int i : vec | rah::view::slice(2, 6))
result.push_back(i);
assert(result == std::vector<int>({ 2, 3, 4, 5 }));

◆ sliding() [1/2]

template<typename R >
rah::view::sliding ( R &&  range,
size_t  n 
)

Given a range and a count n, place a window over the first n elements of the underlying range.

Return the contents of that window as the first element of the adapted range, then slide the window forward one element at a time until hitting the end of the underlying range.

std::vector<int> in{ 0, 1, 2, 3, 4, 5 };
std::vector<std::vector<int>> out;
for (auto subRange : rah::view::sliding(in, 3))
{
out.emplace_back();
std::copy(begin(subRange), end(subRange), std::back_inserter(out.back()));
}
assert(out == (std::vector<std::vector<int>>{
{ 0, 1, 2 },
{ 1, 2, 3 },
{ 2, 3, 4 },
{ 3, 4, 5 } }));

◆ sliding() [2/2]

rah::view::sliding ( size_t  n)
inline

Given a range and a count n, place a window over the first n elements of the underlying range.

Return the contents of that window as the first element of the adapted range, then slide the window forward one element at a time until hitting the end of the underlying range.

Remarks
pipeable syntax
std::vector<int> in{ 0, 1, 2, 3, 4, 5 };
std::vector<std::vector<int>> out;
for (auto subRange : in | rah::view::sliding(3))
{
out.emplace_back();
std::copy(begin(subRange), end(subRange), std::back_inserter(out.back()));
}
assert(out == (std::vector<std::vector<int>>{
{ 0, 1, 2 },
{ 1, 2, 3 },
{ 2, 3, 4 },
{ 3, 4, 5 } }));

◆ sort() [1/2]

template<typename R , typename P = is_lesser, typename = std ::enable_if_t<is_range<R>::value>>
auto rah::view::sort ( R &&  range,
P &&  pred = {} 
)

Make a sorted view of a range.

Returns
A view that is sorted
Remarks
This view is not lasy. The sorting is computed immediately.
std::vector<int> in{ 2, 1, 5, 3, 4 };
auto&& result = rah::view::sort(in);
assert(in == std::vector<int>({ 2, 1, 5, 3, 4 }));
assert(result == std::vector<int>({ 1, 2, 3, 4, 5 }));
std::vector<int> in{ 2, 1, 5, 3, 4 };
auto&& result = rah::view::sort(in, [](auto a, auto b) {return a < b; });
assert(in == std::vector<int>({ 2, 1, 5, 3, 4 }));
assert(result == std::vector<int>({ 1, 2, 3, 4, 5 }));

◆ sort() [2/2]

template<typename P = is_lesser, typename = std ::enable_if_t<not is_range<P>::value>>
auto rah::view::sort ( P &&  pred = {})

Make a sorted view of a range.

Returns
A view that is sorted
Remarks
This view is not lasy. The sorting is computed immediately.
pipeable syntax
std::vector<int> in{ 2, 1, 5, 3, 4 };
auto&& result = in | rah::view::sort();
assert(in == std::vector<int>({ 2, 1, 5, 3, 4 }));
assert(result == std::vector<int>({ 1, 2, 3, 4, 5 }));
std::vector<int> in{ 2, 1, 5, 3, 4 };
auto&& result = in | rah::view::sort([](auto a, auto b) {return a < b; });
assert(in == std::vector<int>({ 2, 1, 5, 3, 4 }));
assert(result == std::vector<int>({ 1, 2, 3, 4, 5 }));

◆ stride() [1/2]

template<typename R >
auto rah::view::stride ( R &&  range,
size_t  step 
)

Create a view consisting of every Nth element, starting with the first.

std::vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7 };
std::vector<int> result;
for (int i : rah::view::stride(vec, 2))
result.push_back(i);
assert(result == std::vector<int>({ 0, 2, 4, 6 }));

◆ stride() [2/2]

auto rah::view::stride ( size_t  step)
inline

Create a view consisting of every Nth element, starting with the first.

Remarks
pipeable syntax
std::vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7 };
std::vector<int> result;
for (int i : vec | rah::view::stride(2))
result.push_back(i);
assert(result == std::vector<int>({ 0, 2, 4, 6 }));

◆ take() [1/2]

template<typename R >
auto rah::view::take ( R &&  range,
size_t  count 
)

Given a source range and an integral count, return a range consisting of the first count elements from the source range, or the complete range if it has fewer elements.

std::vector<int> in{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto range = rah::view::take(in, 5);
std::vector<int> out;
std::copy(begin(range), end(range), std::back_inserter(out));
assert(out == std::vector<int>({ 0, 1, 2, 3, 4 }));
auto range2 = rah::view::take(in, 1000);
std::vector<int> out2;
std::copy(begin(range2), end(range2), std::back_inserter(out2));
assert(out2 == std::vector<int>({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }));

◆ take() [2/2]

auto rah::view::take ( size_t  count)
inline

Given a source range and an integral count, return a range consisting of the first count elements from the source range, or the complete range if it has fewer elements.

Remarks
pipeable syntax
std::vector<int> in{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto range = in | rah::view::take(5);
std::vector<int> out;
std::copy(begin(range), end(range), std::back_inserter(out));
assert(out == std::vector<int>({ 0, 1, 2, 3, 4 }));
auto range2 = in | rah::view::take(1000);
std::vector<int> out2;
std::copy(begin(range2), end(range2), std::back_inserter(out2));
assert(out2 == std::vector<int>({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }));

◆ transform() [1/2]

template<typename R , typename F >
auto rah::view::transform ( R &&  range,
F &&  func 
)

Create a view applying a transformation to each element of the input range.

std::vector<int> vec{ 0, 1, 2, 3 };
std::vector<int> result;
for (int i : rah::view::transform(vec, [](auto a) {return a * 2; }))
result.push_back(i);
assert(result == std::vector<int>({ 0, 2, 4, 6 }));

◆ transform() [2/2]

template<typename F >
auto rah::view::transform ( F &&  func)

Create a view applying a transformation to each element of the input range.

Remarks
pipeable syntax
std::vector<int> vec{ 0, 1, 2, 3 };
std::vector<int> result;
for (int i : vec | rah::view::transform([](auto a) {return a * 2; }))
result.push_back(i);
assert(result == std::vector<int>({ 0, 2, 4, 6 }));

◆ unbounded()

template<typename I >
auto rah::view::unbounded ( I &&  it)

Given an iterator, return an infinite range that begins at that position.

std::vector<int> in{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto range = rah::view::unbounded(in.begin());
std::vector<int> out;
std::copy_n(begin(range), 5, std::back_inserter(out));
assert(out == std::vector<int>({ 0, 1, 2, 3, 4 }));

◆ zip()

template<typename ... R>
auto rah::view::zip ( R &&...  _ranges)

Given N ranges, return a new range where Mth element is the result of calling std::make_tuple on the Mth elements of all N ranges.

The resulting range has the size of the smaller of the sub-ranges

std::vector<int> inputA{ 1, 2, 3, 4 };
std::vector<double> inputB{ 2.5, 4.5, 6.5, 8.5 };
std::vector<char> inputC{ 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
std::vector<std::tuple<int, double, char>> result;
for (auto a_b_c : rah::view::zip(inputA, inputB, inputC))
result.emplace_back(a_b_c);
assert(result == (std::vector<std::tuple<int, double, char>>{
{ 1, 2.5, 'a' },
{ 2, 4.5, 'b' },
{ 3, 6.5, 'c' },
{ 4, 8.5, 'd' }
}));