libostd
Classes | Macros | Typedefs | Functions
range.hh File Reference

The range system implementation. More...

Go to the source code of this file.

Classes

struct  ostd::input_range_tag
 The input range tag. More...
 
struct  ostd::output_range_tag
 The output range tag. More...
 
struct  ostd::forward_range_tag
 The forward range tag. More...
 
struct  ostd::bidirectional_range_tag
 The bidirectional range tag. More...
 
struct  ostd::random_access_range_tag
 The infinite random access range tag. More...
 
struct  ostd::finite_random_access_range_tag
 The finite random access range tag. More...
 
struct  ostd::contiguous_range_tag
 The contiguous range tag. More...
 
struct  ostd::range_traits< R >
 The traits (properties) of a range type. More...
 
struct  ostd::input_range< B >
 A base type for all input-type ranges to derive from. More...
 
struct  ostd::output_range< B >
 The base type for all pure output ranges. More...
 
struct  ostd::ranged_traits< C >
 A structure to implement iterability of any object. More...
 
struct  ostd::iterator_range< T >
 A range type made up of two iterators. More...
 
struct  ostd::ranged_traits< std::initializer_list< T > >
 A specialization of ostd::ranged_traits for initializer list types. More...
 
struct  ostd::ranged_traits< T[N]>
 A specialization of ostd::ranged_traits for static arrays. More...
 

Macros

#define OSTD_TEST_MODULE   libostd_range
 

Typedefs

template<typename R >
using ostd::range_category_t = typename range_traits< R >::range_category
 The category tag of a range type. More...
 
template<typename R >
using ostd::range_size_t = typename range_traits< R >::size_type
 The size type of a range type. More...
 
template<typename R >
using ostd::range_value_t = typename range_traits< R >::value_type
 The value type of range elements. More...
 
template<typename R >
using ostd::range_reference_t = typename range_traits< R >::reference
 The type returned by range element accessors. More...
 
template<typename T >
using ostd::iterator_range_tag = typename detail::iterator_range_tag_base< T >::type
 Gets the best range category that can be created from the given iterator category. More...
 

Functions

template<typename IR >
range_size_t< IR > ostd::range_pop_front_n (IR &range, range_size_t< IR > n)
 Pops out at most n elements from the front of the given range. More...
 
template<typename IR >
range_size_t< IR > ostd::range_pop_back_n (IR &range, range_size_t< IR > n)
 Pops out at most n elements from the back of the given range. More...
 
template<typename OR , typename IR >
void ostd::range_put_all (OR &orange, IR range)
 Puts all of range's elements into orange. More...
 
template<typename T >
auto ostd::noop_sink ()
 Creates an output range that does nothing. More...
 
template<typename R >
auto ostd::counting_sink (R const &range)
 Creates an output range that counts items put into it. More...
 
auto ostd::reverse ()
 A pipeable version of ostd::input_range::reverse().
 
auto ostd::movable ()
 A pipeable version of ostd::input_range::movable().
 
auto ostd::enumerate ()
 A pipeable version of ostd::input_range::enumerate().
 
auto ostd::take (std::size_t n)
 A pipeable version of ostd::input_range::take().
 
auto ostd::chunks (std::size_t n)
 A pipeable version of ostd::input_range::chunks().
 
template<typename R >
auto ostd::join (R &&range)
 A pipeable version of ostd::input_range::join().
 
template<typename R1 , typename ... R>
auto ostd::join (R1 &&r1, R &&...rr)
 A pipeable version of ostd::input_range::join().
 
template<typename R >
auto ostd::zip (R &&range)
 A pipeable version of ostd::input_range::zip().
 
template<typename R1 , typename ... R>
auto ostd::zip (R1 &&r1, R &&...rr)
 A pipeable version of ostd::input_range::zip().
 
template<typename T >
auto ostd::iter (T &&r) -> decltype(ranged_traits< std::remove_reference_t< T >>::iter(r))
 A generic function to iterate any object. More...
 
template<typename T >
auto ostd::citer (T const &r) -> decltype(ranged_traits< T const >::iter(r))
 A generic function to iterate an immutable version of any object. More...
 
template<typename T >
auto ostd::range (T a, T b, std::make_signed_t< T > step=1)
 Creates an integer interval between a and b. More...
 
template<typename T >
auto ostd::range (T v)
 Creates an integer interval between 0 and v. More...
 
template<typename Container >
auto ostd::appender ()
 Creates am appender output range for a container. More...
 
template<typename Container >
auto ostd::appender (Container &&v)
 Creates an appender from an existing container. More...
 
template<typename T >
iterator_range< T const * > ostd::iter (std::initializer_list< T > init) noexcept
 An overload of ostd::iter() for initializer lists. More...
 
template<typename T >
iterator_range< T const * > ostd::citer (std::initializer_list< T > init) noexcept
 An overload of ostd::citer() for initializer lists. More...
 
template<typename T >
iterator_range< T * > ostd::iter (T *a, T *b)
 Creates an ostd::iterator_range from two pointers. More...
 
template<typename Container , typename InputRange , typename ... Args>
Container ostd::from_range (InputRange range, Args &&...args)
 Creates a Container from range. More...
 

Detailed Description

The range system implementation.

This file provides the actual range system implementation, some basic range types, iteration utilities and range traits.

Some examples:

#include <vector>
#include <ostd/range.hh>
#include <ostd/io.hh>
using namespace ostd;
int main() {
/* range iter - prints 0 to 9 each on new line */
writeln("range iter test");
for (int i: range(10)) {
writeln(i);
}
/* algorithm: map - prints 0.5 to 9.5 each on new line */
writeln("range map test");
for (float f: map(range(10), [](int v) { return v + 0.5f; })) {
writeln(f);
}
/* algorithm: filter - prints 10, 15, 8 each on new line */
writeln("range filter test");
auto il = { 5, 5, 5, 5, 5, 10, 15, 4, 8, 2 };
for (int i: filter(iter(il), [](int v) { return v > 5; })) {
writeln(i);
}
/* prints ABCDEF (ASCII 65, 66, 67, 68, 69, 70) */
writeln("string gen test");
auto mr = map(range(6), [](int v) { return char(v + 65); });
std::string s{mr.iter_begin(), mr.iter_end()};
writeln(s);
/* join a few ranges together - prints 11, 22, 33 ... 99 each on new line */
writeln("range join test");
auto x = { 11, 22, 33 };
auto y = { 44, 55, 66 };
auto z = { 77, 88, 99 };
for (auto i: iter(x).join(iter(y), iter(z))) {
writeln(i);
}
/* chunk a range into subranges - prints
* {11, 22, 33}
* {44, 55, 66}
* {77, 88, 99}
*/
writeln("range chunk test");
auto cr = { 11, 22, 33, 44, 55, 66, 77, 88, 99 };
for (auto r: iter(cr).chunks(3)) {
writeln(r);
}
/* take test, prints only first 4 */
writeln("range take test");
for (auto r: iter(cr).take(4)) {
writeln(r);
}
/* {11, 44, 77}, {22, 55, 88}, {33, 66, 99} */
writeln("range zip test");
for (auto v: iter(x).zip(iter(y), iter(z))) {
writeln(v);
}
/* 2-tuple zip uses std::pair */
writeln("2-tuple range zip");
for (auto v: iter({ 5, 10, 15, 20 }).zip(iter({ 6, 11, 16, 21 }))) {
writeln(v.first, ", ", v.second);
}
/* insertion into containers with full_iterator */
writeln("vector range insert");
std::vector<int> foo = { 5, 10, 35, 40 };
writeln("before insert: ", foo);
auto r = range(15, 35, 5);
foo.insert(foo.cbegin() + 2, r.iter_begin(), r.iter_end());
writeln("after insert: ", foo);
}

Pipe syntax examples:

#include <array>
#include <ctime>
#include <ostd/range.hh>
#include <ostd/io.hh>
using namespace ostd;
int main() {
/* algorithm: map - prints 0.5 to 9.5 each on new line */
writeln("range map test");
for (float f: range(10) | map([](int v) { return v + 0.5f; })) {
writeln(f);
}
/* algorithm: filter - prints 10, 15, 8 each on new line */
writeln("range filter test");
auto il = { 5, 5, 5, 5, 5, 10, 15, 4, 8, 2 };
for (int i: iter(il) | filter([](int v) { return v > 5; })) {
writeln(i);
}
/* prints ABCDEF (ASCII 65, 66, 67, 68, 69, 70) */
writeln("string gen test");
auto mr = range(6) | map([](int v) { return char(v + 65); });
std::string s{mr.iter_begin(), mr.iter_end()};
writeln(s);
/* join a few ranges together - prints 11, 22, 33 ... 99 each on new line */
writeln("range join test");
auto x = { 11, 22, 33 };
auto y = { 44, 55, 66 };
auto z = { 77, 88, 99 };
for (auto i: iter(x) | join(iter(y), iter(z))) {
writeln(i);
}
/* chunk a range into subranges - prints
* {11, 22, 33}
* {44, 55, 66}
* {77, 88, 99}
*/
writeln("range chunk test");
auto cr = { 11, 22, 33, 44, 55, 66, 77, 88, 99 };
for (auto r: iter(cr) | chunks(3)) {
writeln(r);
}
/* take test, prints only first 4 */
writeln("range take test");
for (auto r: iter(cr) | take(4)) {
writeln(r);
}
/* {11, 44, 77}, {22, 55, 88}, {33, 66, 99} */
writeln("range zip test");
for (auto v: iter(x) | zip(iter(y), iter(z))) {
writeln(v);
}
/* 2-tuple zip uses std::pair */
writeln("2-tuple range zip");
for (auto v: iter({ 5, 10, 15, 20 }) | zip(iter({ 6, 11, 16, 21 }))) {
writeln(v.first, ", ", v.second);
}
/* more complex pipe */
writeln("several piped algorithms");
srand(static_cast<unsigned int>(std::time(nullptr)));
std::array<int, 100> arr;
generate(iter(arr), []() { return rand() % 128; });
auto r = iter(arr)
| sort ()
| filter([](auto v) { return v >= 65 && v <= 90; })
| map ([](auto v) { return char(v); });
writeln(std::string{r.iter_begin(), r.iter_end()});
/* "list comprehensions" */
writeln("list initialization");
auto vr = range(20)
| filter([](int v) { return v % 2 == 0; })
| map ([](int v) { return v * 2; });
std::vector<int> test{vr.iter_begin(), vr.iter_end()};
writeln(test);
}