libostd
Files | Classes | Macros | Typedefs | Functions
Ranges

Ranges are the backbone of libostd iterable objects and algorithms. More...

Files

file  algorithm.hh
 Generic algorithms for working with ranges.
 
file  range.hh
 The range system implementation.
 

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_algorithm
 
#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 ForwardRange , typename Predicate >
ForwardRange ostd::partition (ForwardRange range, Predicate pred)
 Partitions a range. More...
 
template<typename Predicate >
auto ostd::partition (Predicate &&pred)
 A pipeable version of ostd::partition(). More...
 
template<typename InputRange , typename Predicate >
bool ostd::is_partitioned (InputRange range, Predicate pred)
 Checks if a range is partitioned as in ostd::partition(). More...
 
template<typename Predicate >
auto ostd::is_partitioned (Predicate &&pred)
 A pipeable version of ostd::is_partitioned(). More...
 
template<typename FiniteRandomRange , typename Compare >
FiniteRandomRange ostd::sort_cmp (FiniteRandomRange range, Compare compare)
 Sorts a range given a comparison function. More...
 
template<typename Compare >
auto ostd::sort_cmp (Compare &&compare)
 A pipeable version of ostd::sort_cmp(). More...
 
template<typename FiniteRandomRange >
FiniteRandomRange ostd::sort (FiniteRandomRange range)
 Like ostd::sort_cmp() using std::less<ostd::range_value_t<R>>{}.
 
auto ostd::sort ()
 A pipeable version of ostd::sort().
 
template<typename ForwardRange >
ForwardRange ostd::min_element (ForwardRange range)
 Finds the smallest element in the range. More...
 
template<typename ForwardRange , typename Compare >
ForwardRange ostd::min_element_cmp (ForwardRange range, Compare compare)
 Finds the smallest element in the range. More...
 
auto ostd::min_element ()
 A pipeable version of ostd::min_element().
 
template<typename Compare >
auto ostd::min_element_cmp (Compare &&compare)
 A pipeable version of ostd::min_element_cmp(). More...
 
template<typename ForwardRange >
ForwardRange ostd::max_element (ForwardRange range)
 Finds the largest element in the range. More...
 
template<typename ForwardRange , typename Compare >
ForwardRange ostd::max_element_cmp (ForwardRange range, Compare compare)
 Finds the largest element in the range. More...
 
auto ostd::max_element ()
 A pipeable version of ostd::max_element().
 
template<typename Compare >
auto ostd::max_element_cmp (Compare &&compare)
 A pipeable version of ostd::max_element_cmp(). More...
 
template<typename InputRange1 , typename InputRange2 >
bool ostd::lexicographical_compare (InputRange1 range1, InputRange2 range2)
 Like std::lexicographical_compare(), but for ranges. More...
 
template<typename InputRange >
auto ostd::lexicographical_compare (InputRange &&range)
 A pipeable version of ostd::lexicographical_compare(). More...
 
template<typename InputRange1 , typename InputRange2 , typename Compare >
bool ostd::lexicographical_compare_cmp (InputRange1 range1, InputRange2 range2, Compare compare)
 Like std::lexicographical_compare(), but for ranges. More...
 
template<typename InputRange , typename Compare >
auto ostd::lexicographical_compare_cmp (InputRange &&range, Compare &&compare)
 A pipeable version of ostd::lexicographical_compare_cmp(). More...
 
template<typename InputRange , typename UnaryFunction >
UnaryFunction ostd::for_each (InputRange range, UnaryFunction func)
 Executes func on each element of range. More...
 
template<typename UnaryFunction >
auto ostd::for_each (UnaryFunction &&func)
 A pipeable version of ostd::for_each(). More...
 
template<typename InputRange , typename Predicate >
bool ostd::all_of (InputRange range, Predicate pred)
 Checks if every element of range matches pred. More...
 
template<typename Predicate >
auto ostd::all_of (Predicate &&pred)
 A pipeable version of ostd::all_of(). More...
 
template<typename InputRange , typename Predicate >
bool ostd::any_of (InputRange range, Predicate pred)
 Checks if any element of range matches pred. More...
 
template<typename Predicate >
auto ostd::any_of (Predicate &&pred)
 A pipeable version of ostd::any_of(). More...
 
template<typename InputRange , typename Predicate >
bool ostd::none_of (InputRange range, Predicate pred)
 Checks if no element of range matches pred. More...
 
template<typename Predicate >
auto ostd::none_of (Predicate &&pred)
 A pipeable version of ostd::none_of(). More...
 
template<typename InputRange , typename Value >
InputRange ostd::find (InputRange range, Value const &v)
 Finds v in range. More...
 
template<typename Value >
auto ostd::find (Value &&v)
 A pipeable version of ostd::find(). More...
 
template<typename ForwardRange , typename Value >
ForwardRange ostd::find_last (ForwardRange range, Value const &v)
 Finds the last occurence of v in range. More...
 
template<typename Value >
auto ostd::find_last (Value &&v)
 A pipeable version of ostd::find_last(). More...
 
template<typename InputRange , typename Predicate >
InputRange ostd::find_if (InputRange range, Predicate pred)
 Finds an element matching pred in range. More...
 
template<typename Predicate >
auto ostd::find_if (Predicate &&pred)
 A pipeable version of ostd::find_if(). More...
 
template<typename InputRange , typename Predicate >
InputRange ostd::find_if_not (InputRange range, Predicate pred)
 Finds an element not matching pred in range. More...
 
template<typename Predicate >
auto ostd::find_if_not (Predicate &&pred)
 A pipeable version of ostd::find_if_not(). More...
 
template<typename InputRange , typename ForwardRange , typename Compare >
InputRange ostd::find_one_of_cmp (InputRange range, ForwardRange values, Compare compare)
 Finds the first element matching any element in values. More...
 
template<typename ForwardRange , typename Compare >
auto ostd::find_one_of_cmp (ForwardRange &&values, Compare &&compare)
 A pipeable version of ostd::find_one_of_cmp(). More...
 
template<typename InputRange , typename ForwardRange >
InputRange ostd::find_one_of (InputRange range, ForwardRange values)
 Finds the first element matching any element in values. More...
 
template<typename ForwardRange >
auto ostd::find_one_of (ForwardRange &&values)
 A pipeable version of ostd::find_one_of(). More...
 
template<typename InputRange , typename Value >
range_size_t< InputRange > ostd::count (InputRange range, Value const &v)
 Counts the number of occurences of v in range. More...
 
template<typename Value >
auto ostd::count (Value &&v)
 A pipeable version of ostd::count(). More...
 
template<typename InputRange , typename Predicate >
range_size_t< InputRange > ostd::count_if (InputRange range, Predicate pred)
 Counts the number of elements matching pred in `range. More...
 
template<typename Predicate >
auto ostd::count_if (Predicate &&pred)
 A pipeable version of ostd::count_if(). More...
 
template<typename InputRange , typename Predicate >
range_size_t< InputRange > ostd::count_if_not (InputRange range, Predicate pred)
 Counts the number of elements not matching pred in `range. More...
 
template<typename Predicate >
auto ostd::count_if_not (Predicate &&pred)
 A pipeable version of ostd::count_if_not(). More...
 
template<typename InputRange >
bool ostd::equal (InputRange range1, InputRange range2)
 Checks if two ranges have equal contents. More...
 
template<typename InputRange >
auto ostd::equal (InputRange &&range)
 A pipeable version of ostd::equal(). More...
 
template<typename InputRange , typename OutputRange >
OutputRange ostd::copy (InputRange irange, OutputRange orange)
 Copies all elements from irange to orange. More...
 
template<typename InputRange , typename OutputRange , typename Predicate >
OutputRange ostd::copy_if (InputRange irange, OutputRange orange, Predicate pred)
 Copies elements of irange matching pred into orange. More...
 
template<typename InputRange , typename OutputRange , typename Predicate >
OutputRange ostd::copy_if_not (InputRange irange, OutputRange orange, Predicate pred)
 Copies elements of irange not matching pred into orange. More...
 
template<typename BidirRange >
void ostd::reverse (BidirRange range)
 Reverses the order of the given range in-place. More...
 
template<typename BidirRange , typename OutputRange >
OutputRange ostd::reverse_copy (BidirRange irange, OutputRange orange)
 Reverses the order of the given range into orange. More...
 
template<typename InputRange , typename Value >
void ostd::fill (InputRange range, Value const &v)
 Fills the given input range with v. More...
 
template<typename InputRange , typename UnaryFunction >
void ostd::generate (InputRange range, UnaryFunction gen)
 Fills the given input range with calls to gen. More...
 
template<typename InputRange1 , typename InputRange2 >
std::pair< InputRange1, InputRange2 > ostd::swap_ranges (InputRange1 range1, InputRange2 range2)
 Swaps the contents of two input ranges. More...
 
template<typename InputRange , typename Value >
void ostd::iota (InputRange range, Value value)
 Fills the given input range with value++. More...
 
template<typename InputRange , typename Value >
Value ostd::foldl (InputRange range, Value init)
 Left-folds the range into init. More...
 
template<typename InputRange , typename Value , typename BinaryFunction >
Value ostd::foldl_f (InputRange range, Value init, BinaryFunction func)
 Left-folds the range into init. More...
 
template<typename Value >
auto ostd::foldl (Value &&init)
 A pipeable version of ostd::foldl(). More...
 
template<typename Value , typename BinaryFunction >
auto ostd::foldl_f (Value &&init, BinaryFunction &&func)
 A pipeable version of ostd::foldl_f(). More...
 
template<typename InputRange , typename Value >
Value ostd::foldr (InputRange range, Value init)
 Right-folds the range into init. More...
 
template<typename InputRange , typename Value , typename BinaryFunction >
Value ostd::foldr_f (InputRange range, Value init, BinaryFunction func)
 Right-folds the range into init. More...
 
template<typename Value >
auto ostd::foldr (Value &&init)
 A pipeable version of ostd::foldr(). More...
 
template<typename Value , typename BinaryFunction >
auto ostd::foldr_f (Value &&init, BinaryFunction &&func)
 A pipeable version of ostd::foldr_f(). More...
 
template<typename InputRange , typename UnaryFunction >
auto ostd::map (InputRange range, UnaryFunction func)
 Gets a wrapper range that maps each item by func. More...
 
template<typename UnaryFunction >
auto ostd::map (UnaryFunction &&func)
 A pipeable version of ostd::map(). More...
 
template<typename InputRange , typename Predicate >
auto ostd::filter (InputRange range, Predicate pred)
 Gets a wrapper range that filters items by pred. More...
 
template<typename Predicate >
auto ostd::filter (Predicate &&pred)
 A pipeable version of ostd::filter(). More...
 
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

Ranges are the backbone of libostd iterable objects and algorithms.

Ranges are simple objects that provide access to a sequence of data. They have a similar role to standard C++ iterators, but represent an entire bounded sequence, while iterators represent positions (you need two iterators to represent what a range is).

There are input-type and output-type ranges, the former being for reading from and the latter for writing into. There are also hybrid ranges called mutable ranges, which are input-type ranges that at the same time have an output range interface. Input-type ranges are further divided into several categories, each of which extends the former. These include the basic input range (access to front element), forward (access to front element plus state copy guarantee), bidirectional (access to front and back), infinite random access (access to random elements), finite random access (access to random elements plus size and slicing) and contiguous (access to random elements, size, slicing, contiguous memory guarantee).

There is a whole article dedicated to ranges here. You can also take a look at the many examples in the project tree.

Some more 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);
}

Typedef Documentation

◆ iterator_range_tag

template<typename T >
using ostd::iterator_range_tag = typedef typename detail::iterator_range_tag_base<T>::type

Gets the best range category that can be created from the given iterator category.

They match up to bidirectional. Random access iterators create finite random access ranges. Contiguous ranges can not be created from generic iterator types.

◆ range_category_t

template<typename R >
using ostd::range_category_t = typedef typename range_traits<R>::range_category

The category tag of a range type.

It's the same as doing

Works for all types of ranges.

See also
ostd::range_size_t, ostd::range_value_t, ostd::range_reference_t

◆ range_reference_t

template<typename R >
using ostd::range_reference_t = typedef typename range_traits<R>::reference

The type returned by range element accessors.

It's the same as doing

Works only for input-type ranges.

See also
ostd::range_category_t, ostd::range_size_t, ostd::range_value_t

◆ range_size_t

template<typename R >
using ostd::range_size_t = typedef typename range_traits<R>::size_type

The size type of a range type.

It's the same as doing

Works only for input-type ranges.

See also
ostd::range_category_t, ostd::range_value_t, ostd::range_reference_t

◆ range_value_t

template<typename R >
using ostd::range_value_t = typedef typename range_traits<R>::value_type

The value type of range elements.

It's the same as doing

Works for all types of ranges.

See also
ostd::range_category_t, ostd::range_size_t, ostd::range_reference_t

Function Documentation

◆ all_of() [1/2]

template<typename InputRange , typename Predicate >
bool ostd::all_of ( InputRange  range,
Predicate  pred 
)
inline

Checks if every element of range matches pred.

The pred has to return true when called like pred(range.front()). If it doesn't, false is returned.

The predicate is called at most N times, where N is the range length. The range is an ostd::input_range_tag or better.

See also
ostd::any_of(), ostd::none_of()

◆ all_of() [2/2]

template<typename Predicate >
auto ostd::all_of ( Predicate &&  pred)
inline

A pipeable version of ostd::all_of().

The function is forwarded.

◆ any_of() [1/2]

template<typename InputRange , typename Predicate >
bool ostd::any_of ( InputRange  range,
Predicate  pred 
)
inline

Checks if any element of range matches pred.

As soon as pred returns true when called like pred(range.front()), this returns true. Otherwise it returns false.

The predicate is called at most N times, where N is the range length. The range is an ostd::input_range_tag or better.

See also
ostd::all_of(), ostd::none_of()

◆ any_of() [2/2]

template<typename Predicate >
auto ostd::any_of ( Predicate &&  pred)
inline

A pipeable version of ostd::any_of().

The function is forwarded.

◆ appender() [1/2]

template<typename Container >
auto ostd::appender ( )
inline

Creates am appender output range for a container.

An appender is a kind of output range which wraps a standard container that supports push_back(v) and appends to it on every put(v). The value type of the range is the value type of the container.

It's posssible to assign a new container to it by copy or move, as long as the container is of the same type. It's also possible to create a new appender from an existing container by copy or move, using ostd::appender(Container &&).

Besides implementing a standard output range, appenders also implement an interface to the container, particularly the clear(), empty(), reserve(capacity), resize(length), size() and capacity() methods. These are available depending on if they're also available in the wrapped container and have identical signatures.

The get() method returns an lvalue or rvalue reference to the wrapped container, depending on the lvalue-ness or rvalue-ness of the appender itself (it's ref-qualified). If the appender is const, so will be the returned value.

The put(v) method is overloaded for both by-copy and by-move put.

See also
ostd::appender(Container &&)

◆ appender() [2/2]

template<typename Container >
auto ostd::appender ( Container &&  v)
inline

Creates an appender from an existing container.

Like ostd::appender(), except uses an existing container to create the range. The container is passed by universal reference, so it will work for lvalues and rvalues and appropriately copy or move the container.

See also
ostd::appender()

◆ citer() [1/2]

template<typename T >
auto ostd::citer ( T const &  r) -> decltype(ranged_traits<T const>::iter(r))
inline

A generic function to iterate an immutable version of any object.

This uses ostd::ranged_traits to create the range object, so it will work for anything ostd::ranged_traits is properly specialized for. It forces a range for an immutable object, unlike ostd::iter(), where it depends on the constness of the input.

See also
ostd::iter()

◆ citer() [2/2]

template<typename T >
iterator_range<T const *> ostd::citer ( std::initializer_list< T >  init)
noexcept

An overload of ostd::citer() for initializer lists.

This must be done to allow the type system to pick up on expressions such as ostd::iter({ a, b, c, d, ... }). It will not do so automatically because it looks for std::initializer_list in the prototype.

◆ copy()

template<typename InputRange , typename OutputRange >
OutputRange ostd::copy ( InputRange  irange,
OutputRange  orange 
)
inline

Copies all elements from irange to orange.

The irange is at least ostd::input_range_tag. The orange is an output range. The ostd::range_put_all() function is used to perform the copy. it respects ADL and therefore any per-type overloads of ostd::range_put_all.

See also
ostd::copy_if(), ostd::copy_if_not()
Examples:
stream1.cc, and stream2.cc.

◆ copy_if()

template<typename InputRange , typename OutputRange , typename Predicate >
OutputRange ostd::copy_if ( InputRange  irange,
OutputRange  orange,
Predicate  pred 
)
inline

Copies elements of irange matching pred into orange.

The irange (at least ostd::input_range_tag) is iterated and if the expression pred(irange.front()) is true, the element is inserted (like orange.put(irange.front())).

See also
ostd::copy(), ostd::copy_if_not()

◆ copy_if_not()

template<typename InputRange , typename OutputRange , typename Predicate >
OutputRange ostd::copy_if_not ( InputRange  irange,
OutputRange  orange,
Predicate  pred 
)
inline

Copies elements of irange not matching pred into orange.

The irange (at least ostd::input_range_tag) is iterated and if the expression !pred(irange.front()) is true, the element is inserted (like orange.put(irange.front())).

See also
ostd::copy(), ostd::copy_if()

◆ count() [1/2]

template<typename InputRange , typename Value >
range_size_t<InputRange> ostd::count ( InputRange  range,
Value const &  v 
)
inline

Counts the number of occurences of v in range.

Iterates the range and each time v is encountered (using the == operator) a counter is incremented. This counter is then returned.

The range is at least ostd::input_range_tag.

See also
ostd::count_if(), ostd::count_if_not()

◆ count() [2/2]

template<typename Value >
auto ostd::count ( Value &&  v)
inline

A pipeable version of ostd::count().

The v is forwarded.

◆ count_if() [1/2]

template<typename InputRange , typename Predicate >
range_size_t<InputRange> ostd::count_if ( InputRange  range,
Predicate  pred 
)
inline

Counts the number of elements matching pred in `range.

Iterates the range and each time pred(range.front()) returns true, a counter is incremented. This counter is then returned.

The range is at least ostd::input_range_tag.

See also
ostd::count(), ostd::count_if_not()

◆ count_if() [2/2]

template<typename Predicate >
auto ostd::count_if ( Predicate &&  pred)
inline

A pipeable version of ostd::count_if().

The pred is forwarded.

◆ count_if_not() [1/2]

template<typename InputRange , typename Predicate >
range_size_t<InputRange> ostd::count_if_not ( InputRange  range,
Predicate  pred 
)
inline

Counts the number of elements not matching pred in `range.

Iterates the range and each time !pred(range.front()) returns true, a counter is incremented. This counter is then returned.

The range is at least ostd::input_range_tag.

See also
ostd::count(), ostd::count_if()

◆ count_if_not() [2/2]

template<typename Predicate >
auto ostd::count_if_not ( Predicate &&  pred)
inline

A pipeable version of ostd::count_if_not().

The pred is forwarded.

◆ counting_sink()

template<typename R >
auto ostd::counting_sink ( R const &  range)
inline

Creates an output range that counts items put into it.

Takes an output range and creates a wrapper output range around it that counts each item put into it. A copy of the range is stored. The types are inherited from the wrapped range.

This method is provided to retrieve the number of values put into the range:

range_size_t<R> get_written() const;

These methods are provided to retrieve the range:

R &get_range();
R const &get_range() const;

◆ equal() [1/2]

template<typename InputRange >
bool ostd::equal ( InputRange  range1,
InputRange  range2 
)
inline

Checks if two ranges have equal contents.

Both ranges are at least ostd::input_range_tag. If one range becomes empty before the other does, false is returned. If the expression !(range1.front() == range2.front()) is true in any iteration, false is also returned. Otherwise true is returned.

◆ equal() [2/2]

template<typename InputRange >
auto ostd::equal ( InputRange &&  range)
inline

A pipeable version of ostd::equal().

The range is forwarded as the second range.

◆ fill()

template<typename InputRange , typename Value >
void ostd::fill ( InputRange  range,
Value const &  v 
)
inline

Fills the given input range with v.

Iterates over range and assigns v to each element. The elements must therefore be actual lvalue references so they can be assigned to.

See also
ostd::generate(), ostd::iota()

◆ filter() [1/2]

template<typename InputRange , typename Predicate >
auto ostd::filter ( InputRange  range,
Predicate  pred 
)
inline

Gets a wrapper range that filters items by pred.

The resulting range is ostd::forward_range_tag at most. The range will only contains items for which pred returns true. What this means is that upon creation, the given range is stored and all iterated until an item matching pred is reached. On pop_front(), this item is popped out and the same is done, i.e. again iterated until a new item matching pred is reached.

In other words, this is done:

void advance(R &range, P &pred) {
while (!range.empty() && !pred()) {
range.pop_front();
}
}
constructor(R range, P pred) {
store_range_and_pred(range, pred);
advance(stored_range, stored_pred);
}
void pop_front() {
stored_range.pop_front();
advance(stored_range, stored_pred);
}

The value, reference and size types are preserved, as are calls to front() and empty().

See also
ostd::map()
Examples:
range.cc, and range_pipe.cc.

◆ filter() [2/2]

template<typename Predicate >
auto ostd::filter ( Predicate &&  pred)
inline

A pipeable version of ostd::filter().

The pred is forwarded.

◆ find() [1/2]

template<typename InputRange , typename Value >
InputRange ostd::find ( InputRange  range,
Value const &  v 
)
inline

Finds v in range.

Iterates the range and as soon as range.front() is equal to v, returns range. The range is at least ostd::input_range_tag.

See also
ostd::find_last(), ostd::find_if(), ostd::find_if_not(), ostd::find_one_of()

◆ find() [2/2]

template<typename Value >
auto ostd::find ( Value &&  v)
inline

A pipeable version of ostd::find().

The v is forwarded.

◆ find_if() [1/2]

template<typename InputRange , typename Predicate >
InputRange ostd::find_if ( InputRange  range,
Predicate  pred 
)
inline

Finds an element matching pred in range.

Iterates the range and as soon as pred(range.front()) is true, returns range. The range is at least ostd::input_range_tag.

See also
ostd::find(), ostd::find_last(), ostd::find_if_not(), ostd::find_one_of()

◆ find_if() [2/2]

template<typename Predicate >
auto ostd::find_if ( Predicate &&  pred)
inline

A pipeable version of ostd::find_if().

The pred is forwarded.

◆ find_if_not() [1/2]

template<typename InputRange , typename Predicate >
InputRange ostd::find_if_not ( InputRange  range,
Predicate  pred 
)
inline

Finds an element not matching pred in range.

Iterates the range and as soon as !pred(range.front()) is true, returns range. The range is at least ostd::input_range_tag.

See also
ostd::find(), ostd::find_last(), ostd::find_if(), ostd::find_one_of()

◆ find_if_not() [2/2]

template<typename Predicate >
auto ostd::find_if_not ( Predicate &&  pred)
inline

A pipeable version of ostd::find_if_not().

The pred is forwarded.

◆ find_last() [1/2]

template<typename ForwardRange , typename Value >
ForwardRange ostd::find_last ( ForwardRange  range,
Value const &  v 
)
inline

Finds the last occurence of v in range.

Keeps attempting ostd::find() from the point of previous ostd::find() until no next matching element is found. As this algorithm has to save the previous result of ostd::find() in case nothing is found next, this algortihm requires range to be at least ostd::forward_range_tag.

See also
ostd::find(), ostd::find_if(), ostd::find_if_not(), ostd::find_one_of()

◆ find_last() [2/2]

template<typename Value >
auto ostd::find_last ( Value &&  v)
inline

A pipeable version of ostd::find_last().

The v is forwarded.

◆ find_one_of() [1/2]

template<typename InputRange , typename ForwardRange >
InputRange ostd::find_one_of ( InputRange  range,
ForwardRange  values 
)
inline

Finds the first element matching any element in values.

The == operator is used to compare the values. The range is iterated and each item is compared with each item in values and once a match is found, range is returned.

The range has to be at least ostd::input_range_tag as it's iterated only once, values has to be ostd::forward_range_tag or better.

The time complexity is up to N * M where N is the length of range and M is the length of values.

Use ostd::find_one_of_cmp() if you want to use a comparison function instead of the == operator.

See also
ostd::find(), ostd::find_last(), ostd::find_if(), ostd::find_if_not(), ostd::find_one_of_cmp()

◆ find_one_of() [2/2]

template<typename ForwardRange >
auto ostd::find_one_of ( ForwardRange &&  values)
inline

A pipeable version of ostd::find_one_of().

The values range is forwarded.

◆ find_one_of_cmp() [1/2]

template<typename InputRange , typename ForwardRange , typename Compare >
InputRange ostd::find_one_of_cmp ( InputRange  range,
ForwardRange  values,
Compare  compare 
)
inline

Finds the first element matching any element in values.

The compare function is used to compare the values. The range is iterated and each item is compared with each item in values and once a match is found, range is returned.

The range has to be at least ostd::input_range_tag as it's iterated only once, values has to be ostd::forward_range_tag or better.

The time complexity is up to N * M where N is the length of range and M is the length of values.

Use ostd::find_one_of() if you want to use the == operator instead of calling compare.

See also
ostd::find(), ostd::find_last(), ostd::find_if(), ostd::find_if_not(), ostd::find_one_of()

◆ find_one_of_cmp() [2/2]

template<typename ForwardRange , typename Compare >
auto ostd::find_one_of_cmp ( ForwardRange &&  values,
Compare &&  compare 
)
inline

A pipeable version of ostd::find_one_of_cmp().

The values and compare are forwarded.

◆ foldl() [1/2]

template<typename InputRange , typename Value >
Value ostd::foldl ( InputRange  range,
Value  init 
)
inline

Left-folds the range into init.

The init is an initial value. The range is iterated and each element is added to init using the + operator. Once that is done, init is returned.

The range must be at least ostd::input_range_tag.

A function-based version as well as right-folds are provided as well.

See also
ostd::foldl_f(), ostd::foldr()
Examples:
concurrency.cc.

◆ foldl() [2/2]

template<typename Value >
auto ostd::foldl ( Value &&  init)
inline

A pipeable version of ostd::foldl().

The init is forwarded.

◆ foldl_f() [1/2]

template<typename InputRange , typename Value , typename BinaryFunction >
Value ostd::foldl_f ( InputRange  range,
Value  init,
BinaryFunction  func 
)
inline

Left-folds the range into init.

The init is an initial value. The range is iterated and init is assigned as init = func(init, range.front()). Once that is done, init is returned.

The range must be at least ostd::input_range_tag.

A + operator-based version as well as right-folds are provided as well.

See also
ostd::foldl(), ostd::foldr_f()

◆ foldl_f() [2/2]

template<typename Value , typename BinaryFunction >
auto ostd::foldl_f ( Value &&  init,
BinaryFunction &&  func 
)
inline

A pipeable version of ostd::foldl_f().

The init and func are forwarded.

◆ foldr() [1/2]

template<typename InputRange , typename Value >
Value ostd::foldr ( InputRange  range,
Value  init 
)
inline

Right-folds the range into init.

The init is an initial value. The range is iterated backwards and each element is added to init using the + operator. Once that is done, init is returned.

The range must be at least ostd::bidirectional_range_tag.

A function-based version as well as left-folds are provided as well.

See also
ostd::foldr_f(), ostd::foldl()

◆ foldr() [2/2]

template<typename Value >
auto ostd::foldr ( Value &&  init)
inline

A pipeable version of ostd::foldr().

The init is forwarded.

◆ foldr_f() [1/2]

template<typename InputRange , typename Value , typename BinaryFunction >
Value ostd::foldr_f ( InputRange  range,
Value  init,
BinaryFunction  func 
)
inline

Right-folds the range into init.

The init is an initial value. The range is iterated backwards and init is assigned as init = func(init, range.back()). Once that is done, init is returned.

The range must be at least ostd::bidirectional_range_tag.

A + operator-based version as well as left-folds are provided as well.

See also
ostd::foldr(), ostd::foldl_f()

◆ foldr_f() [2/2]

template<typename Value , typename BinaryFunction >
auto ostd::foldr_f ( Value &&  init,
BinaryFunction &&  func 
)
inline

A pipeable version of ostd::foldr_f().

The init and func are forwarded.

◆ for_each() [1/2]

template<typename InputRange , typename UnaryFunction >
UnaryFunction ostd::for_each ( InputRange  range,
UnaryFunction  func 
)
inline

Executes func on each element of range.

The func is called like func(range.front()). The algorithm is not multi-pass, so an ostd::input_range_tag is perfectly fine.

Returns
The func by move.
Examples:
listdir.cc.

◆ for_each() [2/2]

template<typename UnaryFunction >
auto ostd::for_each ( UnaryFunction &&  func)
inline

A pipeable version of ostd::for_each().

The function is forwarded.

◆ from_range()

template<typename Container , typename InputRange , typename ... Args>
Container ostd::from_range ( InputRange  range,
Args &&...  args 
)
inline

Creates a Container from range.

Standard sequence containers usually support construction from an iterator pair. This is a utility function that will create a sequence container of the given type using an ostd::input_range's iter_begin() and iter_end() methods.

The remaining arguments are passed after the two iterators.

◆ generate()

template<typename InputRange , typename UnaryFunction >
void ostd::generate ( InputRange  range,
UnaryFunction  gen 
)
inline

Fills the given input range with calls to gen.

Iterates over range and assigns gen() to each element. The elements must therefore be actual lvalue references so they can be assigned to.

See also
ostd::fill(), ostd::iota()
Examples:
range_pipe.cc.

◆ iota()

template<typename InputRange , typename Value >
void ostd::iota ( InputRange  range,
Value  value 
)
inline

Fills the given input range with value++.

Iterates over range and assigns value++ to each element. The elements must therefore be actual lvalue references so they can be assigned to.

See also
ostd::fill(), ostd::generate()

◆ is_partitioned() [1/2]

template<typename InputRange , typename Predicate >
bool ostd::is_partitioned ( InputRange  range,
Predicate  pred 
)
inline

Checks if a range is partitioned as in ostd::partition().

First, all elements matching pred are skipped and then if any of the elements following that match pred, false is returned. Otherwise, true is returned.

The predicate is applied at most N times.

◆ is_partitioned() [2/2]

template<typename Predicate >
auto ostd::is_partitioned ( Predicate &&  pred)
inline

A pipeable version of ostd::is_partitioned().

The predicate is forwarded.

◆ iter() [1/3]

template<typename T >
auto ostd::iter ( T &&  r) -> decltype(ranged_traits<std::remove_reference_t<T>>::iter(r))
inline

A generic function to iterate any object.

This uses ostd::ranged_traits to create the range object, so it will work for anything ostd::ranged_traits is properly specialized for.

See also
ostd::citer()
Examples:
argparse.cc, concurrency.cc, range.cc, range_pipe.cc, stream1.cc, and stream2.cc.

◆ iter() [2/3]

template<typename T >
iterator_range<T const *> ostd::iter ( std::initializer_list< T >  init)
noexcept

An overload of ostd::iter() for initializer lists.

This must be done to allow the type system to pick up on expressions such as ostd::iter({ a, b, c, d, ... }). It will not do so automatically because it looks for std::initializer_list in the prototype.

◆ iter() [3/3]

template<typename T >
iterator_range<T *> ostd::iter ( T *  a,
T *  b 
)
inline

Creates an ostd::iterator_range from two pointers.

The resulting iterator range will be contiguous. The length of the resulting range will be b - a.

◆ lexicographical_compare() [1/2]

template<typename InputRange1 , typename InputRange2 >
bool ostd::lexicographical_compare ( InputRange1  range1,
InputRange2  range2 
)
inline

Like std::lexicographical_compare(), but for ranges.

This version uses the < operator for comparisons. This algorithm is not multi-pass, so an ostd::input_range_tag is perfectly fine here.

See also
ostd::lexicographical_compare_cmp()

◆ lexicographical_compare() [2/2]

template<typename InputRange >
auto ostd::lexicographical_compare ( InputRange &&  range)
inline

A pipeable version of ostd::lexicographical_compare().

The range is forwarded.

◆ lexicographical_compare_cmp() [1/2]

template<typename InputRange1 , typename InputRange2 , typename Compare >
bool ostd::lexicographical_compare_cmp ( InputRange1  range1,
InputRange2  range2,
Compare  compare 
)
inline

Like std::lexicographical_compare(), but for ranges.

This version uses the compare function for comparisons. This algorithm is not multi-pass, so an ostd::input_range_tag is perfectly fine here.

See also
ostd::lexicographical_compare()

◆ lexicographical_compare_cmp() [2/2]

template<typename InputRange , typename Compare >
auto ostd::lexicographical_compare_cmp ( InputRange &&  range,
Compare &&  compare 
)
inline

A pipeable version of ostd::lexicographical_compare_cmp().

The range and comparison function are forwarded.

◆ map() [1/2]

template<typename InputRange , typename UnaryFunction >
auto ostd::map ( InputRange  range,
UnaryFunction  func 
)
inline

Gets a wrapper range that maps each item by func.

The resulting range is at most ostd::finite_random_access_range_tag. There are no restrictions on the input range. The resulting range is not mutable, it's purely input-type.

The reference member type of the range is R where R is the return value of func. The value_type is std::remove_reference_t<R>. The size type is preserved.

On each access of a range item (front, back, indexing), the func is called with the actual wrapped range's item and the result is returned.

An example:

auto r = ostd::map(ostd::range(5), [](auto v) { return v + 5; });
for (auto i: r) {
ostd::writeln(i); // 5, 6, 7, 8, 9
}

Because the range is lazy, a new value is computed on each access, but the wrapper range also needs no memory of its own.

See also
ostd::filter()
Examples:
format.cc, range.cc, range_pipe.cc, and stream1.cc.

◆ map() [2/2]

template<typename UnaryFunction >
auto ostd::map ( UnaryFunction &&  func)
inline

A pipeable version of ostd::map().

The func is forwarded.

◆ max_element()

template<typename ForwardRange >
ForwardRange ostd::max_element ( ForwardRange  range)
inline

Finds the largest element in the range.

It works like std::max_element(). The range must be at least ostd::forward_range_tag. The < operator is used for comparisons.

See also
ostd::max_element_cmp(), ostd::min_element()

◆ max_element_cmp() [1/2]

template<typename ForwardRange , typename Compare >
ForwardRange ostd::max_element_cmp ( ForwardRange  range,
Compare  compare 
)
inline

Finds the largest element in the range.

It works like std::max_element. The range must be at least ostd::forward_range_tag. The compare function is used for comparisons.

See also
ostd::max_element(), ostd::min_element_cmp()

◆ max_element_cmp() [2/2]

template<typename Compare >
auto ostd::max_element_cmp ( Compare &&  compare)
inline

A pipeable version of ostd::max_element_cmp().

The comparison function is forwarded.

◆ min_element()

template<typename ForwardRange >
ForwardRange ostd::min_element ( ForwardRange  range)
inline

Finds the smallest element in the range.

It works like std::min_element(). The range must be at least ostd::forward_range_tag. The < operator is used for comparisons.

See also
ostd::min_element_cmp(), ostd::max_element()

◆ min_element_cmp() [1/2]

template<typename ForwardRange , typename Compare >
ForwardRange ostd::min_element_cmp ( ForwardRange  range,
Compare  compare 
)
inline

Finds the smallest element in the range.

It works like std::min_element. The range must be at least ostd::forward_range_tag. The compare function is used for comparisons.

See also
ostd::min_element(), ostd::max_element_cmp()

◆ min_element_cmp() [2/2]

template<typename Compare >
auto ostd::min_element_cmp ( Compare &&  compare)
inline

A pipeable version of ostd::min_element_cmp().

The comparison function is forwarded.

◆ none_of() [1/2]

template<typename InputRange , typename Predicate >
bool ostd::none_of ( InputRange  range,
Predicate  pred 
)
inline

Checks if no element of range matches pred.

As soon as pred returns true when called like pred(range.front()), this returns false. Otherwise it returns true.

The predicate is called at most N times, where N is the range length. The range is an ostd::input_range_tag or better.

See also
ostd::all_of(), ostd::any_of()

◆ none_of() [2/2]

template<typename Predicate >
auto ostd::none_of ( Predicate &&  pred)
inline

A pipeable version of ostd::none_of().

The function is forwarded.

◆ noop_sink()

template<typename T >
auto ostd::noop_sink ( )
inline

Creates an output range that does nothing.

This is a complete output range, but it doesn't actually store the given values, instead it simply does nothing. Useful in metaprogramming and when you need to go over a portion of something that uses sinks.

◆ partition() [1/2]

template<typename ForwardRange , typename Predicate >
ForwardRange ostd::partition ( ForwardRange  range,
Predicate  pred 
)
inline

Partitions a range.

Given a predicate pred, this rearranges the range so that items for which the predicate returns true are in the first part of the range.

The range must meet the conditions of ostd::is_range_element_swappable.

The predicate is applied N times and the swap is done at most N times.

Returns
The second part of the range.

◆ partition() [2/2]

template<typename Predicate >
auto ostd::partition ( Predicate &&  pred)
inline

A pipeable version of ostd::partition().

The predicate is forwarded.

◆ range() [1/2]

template<typename T >
auto ostd::range ( a,
b,
std::make_signed_t< T >  step = 1 
)
inline

Creates an integer interval between a and b.

The result is an ostd::forward_range_tag range with T for value and reference types. If T is unsigned, step is a signed version of it. If it's signed, step is the same type.

The range goes from a until b, incrementing by step with each pop. The b boudnary is not included in the range (it's half open). It's considered empty once (current * step) >= (b * step), with current being a at first, increased by step on each pop.

This allows writing nice code such as

for (int i: ostd::range(5, 10)) { // from 5 to 10, not including 10
...
}
Examples:
coroutine1.cc, coroutine2.cc, format.cc, listdir.cc, range.cc, and range_pipe.cc.

◆ range() [2/2]

template<typename T >
auto ostd::range ( v)
inline

Creates an integer interval between 0 and v.

Equivalent to ostd::range() with 0 and v for arguments. This allows writing nice code such as

for (int i: ostd::range(10)) { // from 0 to 10, not including 10
...
}

◆ range_pop_back_n()

template<typename IR >
range_size_t<IR> ostd::range_pop_back_n ( IR &  range,
range_size_t< IR >  n 
)
inline

Pops out at most n elements from the back of the given range.

For finite random access ranges (ostd::finite_random_access_range_tag) or better, slicing is used. Otherwise, each element is popped out separately. Therefore, the complexity either depends on the slciing operation (frequently O(1)) or is linear (O(n)).

If the range doesn't have the given number of elements, it will pop out at least what's there.

The range type must be a bidirectionalrange (ostd::bidirectional_range_tag) or better.

Returns
The number of elements popped out.
See also
ostd::range_pop_front_n()

◆ range_pop_front_n()

template<typename IR >
range_size_t<IR> ostd::range_pop_front_n ( IR &  range,
range_size_t< IR >  n 
)
inline

Pops out at most n elements from the front of the given range.

For finite random access ranges (ostd::finite_random_access_range_tag) or better, slicing is used. Otherwise, each element is popped out separately. Therefore, the complexity either depends on the slciing operation (frequently O(1)) or is linear (O(n)).

If the range doesn't have the given number of elements, it will pop out at least what's there.

The range type must be an input range (ostd::input_range_tag) or better.

Returns
The number of elements popped out.
See also
ostd::range_pop_back_n()

◆ range_put_all()

template<typename OR , typename IR >
void ostd::range_put_all ( OR &  orange,
IR  range 
)
inline

Puts all of range's elements into orange.

The default implementation is equivalent to iterating range and then calling orange.put(range.front()) on each, but it can be overloaded with more efficient implementations per type. Usages of this in generic algortihms follow ADL, so the right function will always be resolved.

◆ reverse()

template<typename BidirRange >
void ostd::reverse ( BidirRange  range)
inline

Reverses the order of the given range in-place.

The range must be at least ostd::bidirectional_range_tag. The range must also meet the conditions of ostd::is_range_element_swappable.

Equivalent to the following:

while (!range.empty()) {
using std::swap;
swap(range.front(), range.back());
range.pop_front();
range.pop_back();
}
See also
ostd::reverse_copy()

◆ reverse_copy()

template<typename BidirRange , typename OutputRange >
OutputRange ostd::reverse_copy ( BidirRange  irange,
OutputRange  orange 
)
inline

Reverses the order of the given range into orange.

Iterates irange backwards, putting each item into orange. The irange has to be at least ostd::bidirectional_range_tag.

Equivalent to the following:

while (!irange.empty()) {
orange.put(irange.back());
irange.pop_back();
}
return orange;
See also
ostd::reverse()

◆ sort_cmp() [1/2]

template<typename FiniteRandomRange , typename Compare >
FiniteRandomRange ostd::sort_cmp ( FiniteRandomRange  range,
Compare  compare 
)
inline

Sorts a range given a comparison function.

The range must be at least ostd::finite_random_access_range_tag. The comparison function takes two ostd::range_reference_t<R> and must return a boolean equivalent to a < b for ascending order.

The items are swapped in the range, which means the range must also meet the conditions of ostd::is_range_element_swappable.

The worst-case and average performance of this algorithm os O(n log n). The best-case performance is O(n). This happens when the range is small enough and already sorted (insertion sort is used for small ranges).

The actual algorithm used is a hybrid algorithm between quicksort and heapsort (intosort) with insertion sort for small ranges.

See also
ostd::sort()

◆ sort_cmp() [2/2]

template<typename Compare >
auto ostd::sort_cmp ( Compare &&  compare)
inline

A pipeable version of ostd::sort_cmp().

The comparison function is forwarded.

◆ swap_ranges()

template<typename InputRange1 , typename InputRange2 >
std::pair<InputRange1, InputRange2> ostd::swap_ranges ( InputRange1  range1,
InputRange2  range2 
)
inline

Swaps the contents of two input ranges.

Testing ostd::is_range_element_swappable_with must be true with the given ranges. The ranges must be at least ostd::input_range_tag. The swapping stops as soon as any of the ranges becomes empty.

Returns
The range1 and range2 in a pair after swapping is done.