rah
Namespaces | Classes | Typedefs | Functions | Variables
rah Namespace Reference

Namespaces

 action
 
 details
 
 view
 

Classes

struct  back_insert_iterator
 
struct  is_equal
 Apply the '==' operator on two values of any type. More...
 
struct  is_lesser
 Apply the '<' operator on two values of any type. More...
 
struct  is_range
 
struct  is_range< R, decltype(begin(fake< R >()), end(fake< R >()), 0)>
 
struct  iterator_facade
 Inerit to make an iterator. More...
 
struct  iterator_facade< I, R, std ::bidirectional_iterator_tag >
 
struct  iterator_facade< I, R, std ::forward_iterator_tag >
 
struct  iterator_facade< I, R, std ::output_iterator_tag >
 
struct  iterator_facade< I, R, std ::random_access_iterator_tag >
 
struct  iterator_facade< I, R, std::bidirectional_iterator_tag >
 Inerit to make a bidirectional iterator. More...
 
struct  iterator_facade< I, R, std::forward_iterator_tag >
 Inerit to make a forward_iterator. More...
 
struct  iterator_facade< I, R, std::output_iterator_tag >
 Inerit to make an appendable range. More...
 
struct  iterator_facade< I, R, std::random_access_iterator_tag >
 Inerit to make a random access iterator. More...
 
struct  iterator_range
 
struct  pipeable
 Allow to call a custom function when called whith the 'pipe' syntax on a range. More...
 
struct  stream_inserter_iterator
 

Typedefs

template<typename T >
using range_begin_type_t = decltype(begin(fake< T >()))
 
template<typename T >
using range_end_type_t = decltype(end(fake< T >()))
 
template<typename T >
using range_ref_type_t = decltype(*begin(fake< T >()))
 
template<typename T >
using range_value_type_t = std ::remove_reference_t< range_ref_type_t< T > >
 
template<typename R >
using range_iter_categ_t = typename std ::iterator_traits< range_begin_type_t< R > >::iterator_category
 

Functions

template<class T , size_t N>
T * begin (T(&array)[N])
 
template<class T , size_t N>
T * end (T(&array)[N]) noexcept
 
template<typename T >
T & fake ()
 Used in decltype to get an instance of a type. More...
 
template<typename I >
auto make_iterator_range (I b, I e)
 Create a rah::iterator_range with two given iterators. More...
 
template<typename I >
begin (iterator_range< I > &r)
 Get the begin iterator of the range. More...
 
template<typename I >
end (iterator_range< I > &r)
 Get the "past the" end iterator of the range. More...
 
template<typename I >
begin (iterator_range< I > const &r)
 Get the begin iterator of the range. More...
 
template<typename I >
end (iterator_range< I > const &r)
 Get the "past the" end iterator of the range. More...
 
template<typename MakeRange >
auto make_pipeable (MakeRange &&make_range)
 Call to create a "pipeable" function (UFCS style in c++) More...
 
template<typename R , typename MakeRange >
auto operator| (R &&range, pipeable< MakeRange > const &adapter) -> decltype(adapter.func(std ::forward< R >(range)))
 
template<typename C >
auto back_inserter (C &&container)
 Make a range which insert into the back of the a container. More...
 
template<typename R >
bool empty (R &&range)
 Check if the range if empty. More...
 
auto empty ()
 Check if the range if empty. More...
 
template<typename R , typename V >
auto equal_range (R &&range, V &&value, std ::enable_if_t< is_range< R >::value, int >=0)
 Returns a range containing all elements equivalent to value in the range. More...
 
template<typename V >
auto equal_range (V &&value)
 Returns a range containing all elements equivalent to value in the range. More...
 
template<typename R , typename V , typename P >
auto equal_range (R &&range, V &&value, P &&pred)
 Returns a range containing all elements equivalent to value in the range. More...
 
template<typename V , typename P >
auto equal_range (V &&value, P &&pred, std ::enable_if_t<!is_range< V >::value, int >=0)
 Returns a range containing all elements equivalent to value in the range. More...
 
template<typename R , typename V >
auto binary_search (R &&range, V &&value)
 Checks if an element equivalent to value appears within the range. More...
 
template<typename V >
auto binary_search (V &&value)
 Checks if an element equivalent to value appears within the range. More...
 
template<typename RI , typename RO , typename F >
auto transform (RI &&rangeIn, RO &&rangeOut, F &&unary_op)
 Applies the given function unary_op to the range rangeIn and stores the result in the range rangeOut. More...
 
template<typename RI1 , typename RI2 , typename RO , typename F >
auto transform (RI1 &&rangeIn1, RI2 &&rangeIn2, RO &&rangeOut, F &&binary_op)
 The binary operation binary_op is applied to pairs of elements from two ranges. More...
 
template<typename R , typename I , typename F >
auto reduce (R &&range, I &&init, F &&reducer)
 Executes a reducer function on each element of the range, resulting in a single output value. More...
 
template<typename I , typename F >
auto reduce (I &&init, F &&reducer)
 Executes a reducer function on each element of the range, resulting in a single output value. More...
 
template<typename R , typename F >
bool any_of (R &&range, F &&pred)
 Checks if unary predicate pred returns true for at least one element in the range. More...
 
template<typename P >
auto any_of (P &&pred)
 Checks if unary predicate pred returns true for at least one element in the range. More...
 
template<typename R , typename P >
bool all_of (R &&range, P &&pred)
 Checks if unary predicate pred returns true for all elements in the range. More...
 
template<typename P >
auto all_of (P &&pred)
 Checks if unary predicate pred returns true for all elements in the range. More...
 
template<typename R , typename P >
bool none_of (R &&range, P &&pred)
 Checks if unary predicate pred returns true for no elements in the range. More...
 
template<typename P >
auto none_of (P &&pred)
 Checks if unary predicate pred returns true for no elements in the range. More...
 
template<typename R , typename V >
auto count (R &&range, V &&value)
 Counts the elements that are equal to value. More...
 
template<typename V >
auto count (V &&value)
 Counts the elements that are equal to value. More...
 
template<typename R , typename P >
auto count_if (R &&range, P &&pred)
 Counts elements for which predicate pred returns true. More...
 
template<typename P >
auto count_if (P &&pred)
 Counts elements for which predicate pred returns true. More...
 
template<typename R , typename F >
auto for_each (R &&range, F &&func)
 Applies the given function func to each element of the range. More...
 
template<typename F >
auto for_each (F &&func)
 Applies the given function func to each element of the range. More...
 
template<typename C , typename R >
auto to_container (R &&range)
 Return a container of type C, filled with the content of range. More...
 
template<typename C >
auto to_container ()
 Return a container of type C, filled with the content of range. More...
 
template<typename R1 , typename R2 >
auto mismatch (R1 &&range1, R2 &&range2)
 Finds the first position where two ranges differ. More...
 
template<typename R , typename V >
auto find (R &&range, V &&value)
 Finds the first element equal to value. More...
 
template<typename V >
auto find (V &&value)
 Finds the first element equal to value. More...
 
template<typename R , typename P >
auto find_if (R &&range, P &&pred)
 Finds the first element satisfying specific criteria. More...
 
template<typename P >
auto find_if (P &&pred)
 Finds the first element satisfying specific criteria. More...
 
template<typename R , typename P >
auto find_if_not (R &&range, P &&pred)
 Finds the first element not satisfying specific criteria. More...
 
template<typename P >
auto find_if_not (P &&pred)
 Finds the first element not satisfying specific criteria. More...
 
template<typename R1 , typename R2 >
auto copy (R1 &&in, R2 &&out)
 Copy in range into an other. More...
 
template<typename R2 >
auto copy (R2 &&out)
 Copy in range into an other. More...
 
template<typename R1 , typename V >
auto fill (R1 &&in, V &&value)
 Assigns the given value to the elements in the range [first, last) More...
 
template<typename V >
auto fill (V &&value)
 Assigns the given value to the elements in the range [first, last) More...
 
template<typename R1 , typename R2 >
auto back_insert (R1 &&in, R2 &&out)
 Insert in in back of front More...
 
template<typename R2 >
auto back_insert (R2 &&out)
 Insert in in back of front More...
 
template<typename R1 , typename R2 , typename P >
auto copy_if (R1 &&in, R2 &&out, P &&pred)
 Copies the elements for which the predicate pred returns true. More...
 
template<typename R2 , typename P >
auto copy_if (R2 &&out, P &&pred)
 Copies the elements for which the predicate pred returns true. More...
 
template<typename R >
auto size (R &&range)
 Get the size of range. More...
 
auto size ()
 Get the size of range. More...
 
template<typename R1 , typename R2 >
auto equal (R1 &&range1, R2 &&range2)
 Determines if two sets of elements are the same. More...
 
template<typename R1 >
auto equal (R1 &&range2)
 Determines if two sets of elements are the same. More...
 
template<typename S >
auto stream_inserter (S &&stream)
 Make a range which output to a stream. More...
 
template<typename R , typename P >
auto remove_if (R &&range, P &&pred)
 Keep at the begining of the range only elements for which pred(elt) is false
. More...
 
template<typename P >
auto remove_if (P &&pred)
 Keep at the begining of the range only elements for which pred(elt) is false
. More...
 
template<typename R , typename P >
auto partition (R &&range, P &&pred)
 Reorders the elements in the range in such a way that all elements for which the predicate pred returns true precede the elements for which predicate pred returns false. More...
 
template<typename P >
auto partition (P &&pred)
 
template<typename R , typename P >
auto stable_partition (R &&range, P &&pred)
 Reorders the elements in the range in such a way that all elements for which the predicate pred returns true precede the elements for which predicate pred returns false. More...
 
template<typename P >
auto stable_partition (P &&pred)
 
template<typename C , typename R >
auto erase (C &&container, R &&subrange)
 Erase a sub-range of a given container. More...
 
template<typename R >
auto erase (R &&range)
 Erase a sub-range of a given container. More...
 
template<typename R , typename P = is_lesser, typename = std ::enable_if_t<is_range<R>::value>>
void sort (R &range, P &&pred={})
 Sort a range in place, using the given predicate. More...
 
template<typename P = is_lesser, typename = std ::enable_if_t<not is_range<P>::value>>
auto sort (P &&pred={})
 Sort a range in place, using the given predicate. More...
 
template<typename R , typename P = is_lesser, typename = std ::enable_if_t<is_range<R>::value>>
void stable_sort (R &range, P &&pred={})
 Sorts the elements in the range in ascending order. More...
 
template<typename P = is_lesser, typename = std ::enable_if_t<not is_range<P>::value>>
auto stable_sort (P &&pred={})
 Sorts the elements in the range in ascending order. More...
 
template<typename R , typename URBG >
void shuffle (R &range, URBG &&g)
 Reorders the elements in the given range such that each possible permutation of those elements has equal probability of appearance. More...
 
template<typename URBG >
auto shuffle (URBG &&g)
 Reorders the elements in the given range such that each possible permutation of those elements has equal probability of appearance. More...
 
template<typename R , typename P = is_equal, typename = std ::enable_if_t<is_range<R>::value>>
auto unique (R &&range, P &&pred={})
 Remove all but first successuve values which are equals. More...
 
template<typename P = is_equal, typename = std ::enable_if_t<not is_range<P>::value>>
auto unique (P &&pred={})
 Remove all but first successuve values which are equals. More...
 
template<typename IN1 , typename IN2 , typename OUT >
void set_difference (IN1 &&in1, IN2 &&in2, OUT &&out)
 Copies the elements from the sorted range in1 which are not found in the sorted range in2 to the range out The resulting range is also sorted. More...
 
template<typename IN1 , typename IN2 , typename OUT >
void set_intersection (IN1 &&in1, IN2 &&in2, OUT &&out)
 Copies the elements from the sorted range in1 which are also found in the sorted range in2 to the range out The resulting range is also sorted. More...
 
template<typename R , std ::enable_if_t< is_range< R >::value, int > = 0>
auto max_element (R &&range)
 Finds the greatest element in the range. More...
 
auto max_element ()
 Finds the greatest element in the range. More...
 
template<typename R , typename P >
auto max_element (R &&range, P &&pred)
 Finds the greatest element in the range. More...
 
template<typename P , std ::enable_if_t<!is_range< P >::value, int > = 0>
auto max_element (P &&pred)
 Finds the greatest element in the range. More...
 
template<typename R , std ::enable_if_t< is_range< R >::value, int > = 0>
auto min_element (R &&range)
 Finds the smallest element in the range. More...
 
auto min_element ()
 Finds the smallest element in the range. More...
 
template<typename R , typename P >
auto min_element (R &&range, P &&pred)
 Finds the smallest element in the range. More...
 
template<typename P , std ::enable_if_t<!is_range< P >::value, int > = 0>
auto min_element (P &&pred)
 Finds the smallest element in the range. More...
 
template<typename R , typename V >
auto remove (R &&range, V &&value)
 Keep at the begining of the range only elements not equal to value
. More...
 
template<typename V >
auto remove (V &&value)
 Keep at the begining of the range only elements not equal to value
. More...
 
template<typename IN1 , typename IN2 , typename OUT_ >
void set_difference (IN1 &&in1, IN2 &&in2, OUT_ &&out)
 Copies the elements from the sorted range in1 which are not found in the sorted range in2 to the range out The resulting range is also sorted. More...
 
template<typename IN1 , typename IN2 , typename OUT_ >
void set_intersection (IN1 &&in1, IN2 &&in2, OUT_ &&out)
 Copies the elements from the sorted range in1 which are also found in the sorted range in2 to the range out The resulting range is also sorted. More...
 

Variables

constexpr intptr_t End = -1
 Used with rah::view::slice to point to the end. More...
 

Typedef Documentation

◆ range_begin_type_t

template<typename T >
using rah::range_begin_type_t = typedef decltype(begin(fake<T>()))

◆ range_end_type_t

template<typename T >
using rah::range_end_type_t = typedef decltype(end(fake<T>()))

◆ range_iter_categ_t

template<typename R >
using rah::range_iter_categ_t = typedef typename std ::iterator_traits<range_begin_type_t<R> >::iterator_category

◆ range_ref_type_t

template<typename T >
using rah::range_ref_type_t = typedef decltype(*begin(fake<T>()))

◆ range_value_type_t

template<typename T >
using rah::range_value_type_t = typedef std ::remove_reference_t<range_ref_type_t<T> >

Function Documentation

◆ all_of() [1/2]

template<typename R , typename P >
bool rah::all_of ( R &&  range,
P &&  pred 
)

Checks if unary predicate pred returns true for all elements in the range.

std::initializer_list<int>{ 4, 4, 4, 4 },
[](auto a) {return a == 4; })
);

◆ all_of() [2/2]

template<typename P >
auto rah::all_of ( P &&  pred)

Checks if unary predicate pred returns true for all elements in the range.

Remarks
pipeable syntax
std::initializer_list<int>{ 4, 4, 3, 4 }
| rah::all_of([](auto a) {return a == 4; })
) == false);

◆ any_of() [1/2]

template<typename R , typename F >
bool rah::any_of ( R &&  range,
F &&  pred 
)

Checks if unary predicate pred returns true for at least one element in the range.

std::initializer_list<int>{ 3, 0, 1, 3, 4, 6 },
[](auto a) {return a == 3; })
);

◆ any_of() [2/2]

template<typename P >
auto rah::any_of ( P &&  pred)

Checks if unary predicate pred returns true for at least one element in the range.

Remarks
pipeable syntax
std::initializer_list<int>{0, 1, 2, 3, 4, 6}
| rah::any_of([](auto a) {return a == 3; })
));

◆ back_insert() [1/2]

template<typename R1 , typename R2 >
auto rah::back_insert ( R1 &&  in,
R2 &&  out 
)

Insert in in back of front

std::vector<int> in{ 1, 2, 3 };
std::vector<int> out{ 10 };
rah::back_insert(in, out);
assert(out == (std::vector<int>{ 10, 1, 2, 3 }));

◆ back_insert() [2/2]

template<typename R2 >
auto rah::back_insert ( R2 &&  out)

Insert in in back of front

Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 3 };
std::vector<int> out{ 10 };
in | rah::back_insert(out);
assert(out == (std::vector<int>{ 10, 1, 2, 3 }));

◆ back_inserter()

template<typename C >
auto rah::back_inserter ( C &&  container)

Make a range which insert into the back of the a container.

std::vector<int> in{ 1, 2, 3 };
std::vector<int> out;
assert(out == std::vector<int>({ 1, 2, 3 }));

◆ begin() [1/3]

template<class T , size_t N>
T * rah::begin ( T(&)  array[N])

◆ begin() [2/3]

template<typename I >
I rah::begin ( iterator_range< I > &  r)

Get the begin iterator of the range.

◆ begin() [3/3]

template<typename I >
I rah::begin ( iterator_range< I > const &  r)

Get the begin iterator of the range.

◆ binary_search() [1/2]

template<typename R , typename V >
auto rah::binary_search ( R &&  range,
V &&  value 
)

Checks if an element equivalent to value appears within the range.

std::vector<int> vecIn1{ 1, 2, 2, 3, 4 };
assert(not rah::binary_search(vecIn1, 0));

◆ binary_search() [2/2]

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

Checks if an element equivalent to value appears within the range.

Remarks
pipeable syntax
std::vector<int> vecIn1{ 1, 2, 2, 3, 4 };
assert(not (vecIn1 | rah::binary_search(0)));
assert(vecIn1 | rah::binary_search(1));
assert(vecIn1 | rah::binary_search(2));

◆ copy() [1/2]

template<typename R1 , typename R2 >
auto rah::copy ( R1 &&  in,
R2 &&  out 
)

Copy in range into an other.

Returns
The part of out after the copied part
std::vector<int> in{ 1, 2, 3 };
std::vector<int> out{ 0, 0, 0, 4, 5 };
// std::vector<int> out{ 0, 0 }; // Trigger an assert
assert(rah::make_iterator_range(rah::copy(in, out), end(out)) | rah::equal(std::initializer_list<int>({ 4, 5 })));
assert(out == (std::vector<int>{ 1, 2, 3, 4, 5 }));

◆ copy() [2/2]

template<typename R2 >
auto rah::copy ( R2 &&  out)

Copy in range into an other.

Returns
The part of out after the copied part
Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 3 };
std::vector<int> out{ 0, 0, 0, 4, 5 };
auto iter = in | rah::copy(out);
assert((rah::make_iterator_range(iter, end(out)) | rah::equal(std::initializer_list<int>{ 4, 5 })));
assert(out == (std::vector<int>{ 1, 2, 3, 4, 5 }));

◆ copy_if() [1/2]

template<typename R1 , typename R2 , typename P >
auto rah::copy_if ( R1 &&  in,
R2 &&  out,
P &&  pred 
)

Copies the elements for which the predicate pred returns true.

Returns
The part of out after the copied part
std::vector<int> in{ 1, 2, 3, 4 };
std::vector<int> out{ 0, 0, 5, 6 };
assert(rah::make_iterator_range(rah::copy_if(in, out, [](int i) {return i % 2 == 0; }), end(out)) | rah::equal(std::initializer_list<int>({ 5, 6 })));
assert(out == (std::vector<int>{ 2, 4, 5, 6 }));

◆ copy_if() [2/2]

template<typename R2 , typename P >
auto rah::copy_if ( R2 &&  out,
P &&  pred 
)

Copies the elements for which the predicate pred returns true.

Returns
The part of out after the copied part
Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 3, 4 };
std::vector<int> out{ 0, 0, 5, 6 };
assert(rah::make_iterator_range(in | rah::copy_if(out, [](int i) {return i % 2 == 0; }), end(out)) | rah::equal(std::initializer_list<int>({ 5, 6 })));
assert(out == (std::vector<int>{ 2, 4, 5, 6 }));

◆ count() [1/2]

template<typename R , typename V >
auto rah::count ( R &&  range,
V &&  value 
)

Counts the elements that are equal to value.

assert(rah::count(std::initializer_list<int>{ 4, 4, 4, 3 }, 3) == 1);

◆ count() [2/2]

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

Counts the elements that are equal to value.

Remarks
pipeable syntax
assert((std::initializer_list<int>{ 4, 4, 4, 3 } | rah::count(4)) == 3);

◆ count_if() [1/2]

template<typename R , typename P >
auto rah::count_if ( R &&  range,
P &&  pred 
)

Counts elements for which predicate pred returns true.

Remarks
pipeable syntax
assert(rah::count_if(std::initializer_list<int>{ 4, 4, 4, 3 }, [](auto a) {return a == 4; }) == 3);

◆ count_if() [2/2]

template<typename P >
auto rah::count_if ( P &&  pred)

Counts elements for which predicate pred returns true.

assert((std::initializer_list<int>{ 4, 4, 4, 3 } | rah::count_if([](auto a) {return a == 3; })) == 1);

◆ empty() [1/2]

template<typename R >
bool rah::empty ( R &&  range)

Check if the range if empty.

assert(not (rah::empty(std::vector<int>{ 1, 2, 3 })));
assert(rah::empty(std::vector<int>()));

◆ empty() [2/2]

auto rah::empty ( )
inline

Check if the range if empty.

Remarks
pipeable syntax
assert(not (std::vector<int>{ 1, 2, 3 } | rah::empty()));
assert(std::vector<int>() | rah::empty());

◆ end() [1/3]

template<class T , size_t N>
T * rah::end ( T(&)  array[N])
noexcept

◆ end() [2/3]

template<typename I >
I rah::end ( iterator_range< I > &  r)

Get the "past the" end iterator of the range.

◆ end() [3/3]

template<typename I >
I rah::end ( iterator_range< I > const &  r)

Get the "past the" end iterator of the range.

◆ equal() [1/2]

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

Determines if two sets of elements are the same.

std::vector<int> in1{ 1, 2, 3 };
std::vector<int> in2{ 1, 2, 3 };
std::vector<int> in3{ 11, 12, 13 };
assert(rah::equal(in1, in2));
assert(rah::equal(in1, in3) == false);

◆ equal() [2/2]

template<typename R1 >
auto rah::equal ( R1 &&  range2)

Determines if two sets of elements are the same.

Remarks
pipeable syntax
std::vector<int> in1{ 1, 2, 3 };
std::vector<int> in2{ 1, 2, 3 };
std::vector<int> in3{ 11, 12, 13 };
assert(in1 | rah::equal(in2));
assert(not (in1 | rah::equal(in3)));

◆ equal_range() [1/4]

template<typename R , typename V >
auto rah::equal_range ( R &&  range,
V &&  value,
std ::enable_if_t< is_range< R >::value, int >  = 0 
)

Returns a range containing all elements equivalent to value in the range.

std::vector<int> vecIn1{ 1, 2, 2, 3, 4 };
{
std::vector<int> out;
for (int i : rah::equal_range(vecIn1, 0))
out.push_back(i);
assert(out == std::vector<int>({ }));
}
{
std::vector<int> out;
for (int i : rah::equal_range(vecIn1, 1))
out.push_back(i);
assert(out == std::vector<int>({ 1 }));
}
{
std::vector<int> out;
for (int i : rah::equal_range(vecIn1, 2))
out.push_back(i);
assert(out == std::vector<int>({ 2, 2 }));
}

◆ equal_range() [2/4]

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

Returns a range containing all elements equivalent to value in the range.

Remarks
pipeable syntax
std::vector<int> vecIn1{ 1, 2, 2, 3, 4 };
{
std::vector<int> out;
for (int i : vecIn1 | rah::equal_range(0))
out.push_back(i);
assert(out == std::vector<int>({ }));
}
{
std::vector<int> out;
for (int i : vecIn1 | rah::equal_range(1))
out.push_back(i);
assert(out == std::vector<int>({ 1 }));
}
{
std::vector<int> out;
for (int i : vecIn1 | rah::equal_range(2))
out.push_back(i);
assert(out == std::vector<int>({ 2, 2 }));
}

◆ equal_range() [3/4]

template<typename R , typename V , typename P >
auto rah::equal_range ( R &&  range,
V &&  value,
P &&  pred 
)

Returns a range containing all elements equivalent to value in the range.

struct S
{
int value;
char test;
bool operator==(S rhs) const
{
return value == rhs.value && test == rhs.test;
}
};
struct FindS
{
bool operator()(S s, int val) const { return s.value < val; }
bool operator()(int val, S s) const { return val < s.value; }
};
std::vector<S> vecIn1{ {1, 'a'}, {2, 'b'}, {2, 'c'}, {3, 'd'}, {4, 'e'} };
{
std::vector<S> out;
for (S i : rah::equal_range(vecIn1, 0, FindS{}))
out.push_back(i);
assert(out == std::vector<S>({ }));
}
{
std::vector<S> out;
for (S i : rah::equal_range(vecIn1, 1, FindS{}))
out.push_back(i);
assert(out == std::vector<S>({ {1, 'a'} }));
}
{
std::vector<S> out;
for (S i : rah::equal_range(vecIn1, 2, FindS{}))
out.push_back(i);
assert(out == std::vector<S>({ {2, 'b'}, {2, 'c'} }));
}

◆ equal_range() [4/4]

template<typename V , typename P >
auto rah::equal_range ( V &&  value,
P &&  pred,
std ::enable_if_t<!is_range< V >::value, int >  = 0 
)

Returns a range containing all elements equivalent to value in the range.

Remarks
pipeable syntax
struct S
{
int value;
char test;
bool operator==(S rhs) const
{
return value == rhs.value && test == rhs.test;
}
};
struct FindS
{
bool operator()(S s, int val) const { return s.value < val; }
bool operator()(int val, S s) const { return val < s.value; }
};
std::vector<S> vecIn1{ {1, 'a'}, {2, 'b'}, {2, 'c'}, {3, 'd'}, {4, 'e'} };
{
std::vector<S> out;
for (S i : vecIn1 | rah::equal_range(0, FindS{}))
out.push_back(i);
assert(out == std::vector<S>({ }));
}
{
std::vector<S> out;
for (S i : vecIn1 | rah::equal_range(1, FindS{}))
out.push_back(i);
assert(out == std::vector<S>({ {1, 'a'} }));
}
{
std::vector<S> out;
for (S i : vecIn1 | rah::equal_range(2, FindS{}))
out.push_back(i);
assert(out == std::vector<S>({ {2, 'b'}, {2, 'c'} }));
}

◆ erase() [1/2]

template<typename C , typename R >
auto rah::erase ( C &&  container,
R &&  subrange 
)

Erase a sub-range of a given container.

Returns
A view on the resulting container
std::vector<int> in{ 1, 2, 3, 4, 5 };
assert(in == std::vector<int>({ 4, 5 }));

◆ erase() [2/2]

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

Erase a sub-range of a given container.

Returns
A view on the resulting container
Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 3, 4, 5 };
assert(in == std::vector<int>({ 4, 5 }));

◆ fake()

template<typename T >
T & rah::fake ( )

Used in decltype to get an instance of a type.

◆ fill() [1/2]

template<typename R1 , typename V >
auto rah::fill ( R1 &&  in,
V &&  value 
)

Assigns the given value to the elements in the range [first, last)

std::vector<int> in{ 1, 2, 3 };
std::vector<int> out{ 0, 0, 0, 4, 5 };
// std::vector<int> out{ 0, 0 }; // Trigger an assert
assert(rah::make_iterator_range(rah::copy(in, out), end(out)) | rah::equal(std::initializer_list<int>({ 4, 5 })));
assert(out == (std::vector<int>{ 1, 2, 3, 4, 5 }));

◆ fill() [2/2]

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

Assigns the given value to the elements in the range [first, last)

Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 3 };
std::vector<int> out{ 0, 0, 0, 4, 5 };
auto iter = in | rah::copy(out);
assert((rah::make_iterator_range(iter, end(out)) | rah::equal(std::initializer_list<int>{ 4, 5 })));
assert(out == (std::vector<int>{ 1, 2, 3, 4, 5 }));

◆ find() [1/2]

template<typename R , typename V >
auto rah::find ( R &&  range,
V &&  value 
)

Finds the first element equal to value.

std::vector<int> in{ 1, 2, 3, 4 };
auto iter = rah::find(in, 3);
(rah::make_iterator_range(iter, end(in)) | rah::equal(std::initializer_list<int>({ 3, 4 })))
);

◆ find() [2/2]

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

Finds the first element equal to value.

Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 3, 4 };
auto iter = in | rah::find(3);
(rah::make_iterator_range(iter, end(in)) | rah::equal(std::initializer_list<int>({ 3, 4 })))
);

◆ find_if() [1/2]

template<typename R , typename P >
auto rah::find_if ( R &&  range,
P &&  pred 
)

Finds the first element satisfying specific criteria.

std::vector<int> in{ 1, 2, 3, 4 };
auto iter = rah::find_if(in, [](int i) {return i == 3; });
(rah::make_iterator_range(iter, end(in)) | rah::equal(std::initializer_list<int>({ 3, 4 })))
);

◆ find_if() [2/2]

template<typename P >
auto rah::find_if ( P &&  pred)

Finds the first element satisfying specific criteria.

Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 3, 4 };
auto iter = in | rah::find_if([](int i) {return i == 3; });
(rah::make_iterator_range(iter, end(in)) | rah::equal(std::initializer_list<int>({ 3, 4 })))
);

◆ find_if_not() [1/2]

template<typename R , typename P >
auto rah::find_if_not ( R &&  range,
P &&  pred 
)

Finds the first element not satisfying specific criteria.

std::vector<int> in{ 1, 2, 3, 4 };
auto iter = rah::find_if_not(in, [](int i) {return i < 3; });
assert((rah::make_iterator_range(iter, end(in)) | rah::equal(std::initializer_list<int>({ 3, 4 }))));

◆ find_if_not() [2/2]

template<typename P >
auto rah::find_if_not ( P &&  pred)

Finds the first element not satisfying specific criteria.

Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 3, 4 };
auto iter = in | rah::find_if_not([](int i) {return i < 3; });
assert((rah::make_iterator_range(iter, end(in)) | rah::equal(std::initializer_list<int>({ 3, 4 }))));

◆ for_each() [1/2]

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

Applies the given function func to each element of the range.

std::vector<int> testFE{ 4, 4, 4, 4 };
rah::for_each(testFE, [](auto& value) {return ++value; });
EQUAL_RANGE(testFE, std::initializer_list<int>({ 5, 5, 5, 5 }));

◆ for_each() [2/2]

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

Applies the given function func to each element of the range.

Remarks
pipeable syntax
std::vector<int> testFE{ 4, 4, 4, 4 };
testFE | rah::for_each([](auto& value) {return ++value; });
EQUAL_RANGE(testFE, std::initializer_list<int>({ 5, 5, 5, 5 }));

◆ make_iterator_range()

template<typename I >
auto rah::make_iterator_range ( b,
e 
)

Create a rah::iterator_range with two given iterators.

◆ make_pipeable()

template<typename MakeRange >
auto rah::make_pipeable ( MakeRange &&  make_range)

Call to create a "pipeable" function (UFCS style in c++)

How to create :

auto test_count(int i)
{
return rah::make_pipeable([=](auto&& range) { return std::count(begin(range), end(range), i); });
}

How to use :

std::vector<int> vec{ 0, 1, 2, 2, 3 };
assert((vec | test_count(2)) == 2);

◆ max_element() [1/4]

template<typename R , std ::enable_if_t< is_range< R >::value, int > = 0>
auto rah::max_element ( R &&  range)

Finds the greatest element in the range.

std::vector<int> in{ 1, 5, 3, 4 };
auto iter = rah::max_element(in);
assert(*iter == 5);

◆ max_element() [2/4]

auto rah::max_element ( )
inline

Finds the greatest element in the range.

Remarks
pipeable syntax
std::vector<int> in{ 1, 5, 3, 4 };
auto iter = in | rah::max_element();
assert(*iter == 5);

◆ max_element() [3/4]

template<typename R , typename P >
auto rah::max_element ( R &&  range,
P &&  pred 
)

Finds the greatest element in the range.

std::vector<std::pair<int, int>> in{ {100, 3}, {0, 5}, {0, 1}, {0, 4} };
auto iter = rah::max_element(in, [](auto&& a, auto& b) {return a.second < b.second; });
assert(*iter == (std::pair<int, int>{0, 5}));

◆ max_element() [4/4]

template<typename P , std ::enable_if_t<!is_range< P >::value, int > = 0>
auto rah::max_element ( P &&  pred)

Finds the greatest element in the range.

Remarks
pipeable syntax
std::vector<std::pair<int, int>> in{ {100, 3}, {0, 5}, {0, 1}, {0, 4} };
auto iter = in | rah::max_element([](auto&& a, auto& b) {return a.second < b.second; });
assert(*iter == (std::pair<int, int>{0, 5}));

◆ min_element() [1/4]

template<typename R , std ::enable_if_t< is_range< R >::value, int > = 0>
auto rah::min_element ( R &&  range)

Finds the smallest element in the range.

std::vector<int> in{ 1, -5, 3, 4 };
auto iter = rah::min_element(in);
assert(*iter == -5);

◆ min_element() [2/4]

auto rah::min_element ( )
inline

Finds the smallest element in the range.

Remarks
pipeable syntax
std::vector<int> in{ 1, -5, 3, 4 };
auto iter = in | rah::min_element();
assert(*iter == -5);

◆ min_element() [3/4]

template<typename R , typename P >
auto rah::min_element ( R &&  range,
P &&  pred 
)

Finds the smallest element in the range.

std::vector<std::pair<int, int>> in{ {-100, 3}, {0, -5}, {0, 1}, {0, 4} };
auto iter = rah::min_element(in, [](auto&& a, auto& b) {return a.second < b.second; });
assert(*iter == (std::pair<int, int>{0, -5}));

◆ min_element() [4/4]

template<typename P , std ::enable_if_t<!is_range< P >::value, int > = 0>
auto rah::min_element ( P &&  pred)

Finds the smallest element in the range.

Remarks
pipeable syntax
std::vector<std::pair<int, int>> in{ {-100, 3}, {0, -5}, {0, 1}, {0, 4} };
auto iter = in | rah::min_element([](auto&& a, auto& b) {return a.second < b.second; });
assert(*iter == (std::pair<int, int>{0, -5}));

◆ mismatch()

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

Finds the first position where two ranges differ.

std::vector<int> in1 = { 1, 2, 3, 4 };
std::vector<int> in2 = { 1, 2, 42, 42 };
auto r1_r2 = rah::mismatch(in1, in2);
std::vector<int> out1;
std::vector<int> out2;
std::copy(std::get<0>(r1_r2), end(in1), std::back_inserter(out1));
std::copy(std::get<1>(r1_r2), end(in2), std::back_inserter(out2));
assert(out1 == std::vector<int>({ 3, 4 }));
assert(out2 == std::vector<int>({ 42, 42 }));

◆ none_of() [1/2]

template<typename R , typename P >
bool rah::none_of ( R &&  range,
P &&  pred 
)

Checks if unary predicate pred returns true for no elements in the range.

std::initializer_list<int>{7, 8, 9, 10},
[](auto a) {return a == 11; })
));

◆ none_of() [2/2]

template<typename P >
auto rah::none_of ( P &&  pred)

Checks if unary predicate pred returns true for no elements in the range.

Remarks
pipeable syntax
std::initializer_list<int>{7, 8, 9, 10, 11}
| rah::none_of([](auto a) {return a == 11; })
) == false);

◆ operator|()

template<typename R , typename MakeRange >
auto rah::operator| ( R &&  range,
pipeable< MakeRange > const &  adapter 
) -> decltype(adapter.func( std ::forward<R>(range)))

◆ partition() [1/2]

template<typename R , typename P >
auto rah::partition ( R &&  range,
P &&  pred 
)

Reorders the elements in the range in such a way that all elements for which the predicate pred returns true precede the elements for which predicate pred returns false.

Relative order of the elements is not preserved.

Returns
Iterator to the first element of the second group.
std::vector<int> in{ 1, 2, 3, 4, 5 };
auto boundary = rah::partition(in, [](auto a) {return a >= 4; });
assert(boundary == in.begin() + 2);
std::sort(in.begin(), boundary);
std::sort(boundary, in.end());
assert(in == std::vector<int>({ 4, 5, 1, 2, 3 }));

◆ partition() [2/2]

template<typename P >
auto rah::partition ( P &&  pred)
See also
rah::partition(R&&, P&&)
Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 3, 4, 5 };
auto boundary = in | rah::partition([](auto a) {return a >= 4; });
assert(boundary == in.begin() + 2);
std::sort(in.begin(), boundary);
std::sort(boundary, in.end());
assert(in == std::vector<int>({ 4, 5, 1, 2, 3 }));

◆ reduce() [1/2]

template<typename R , typename I , typename F >
auto rah::reduce ( R &&  range,
I &&  init,
F &&  reducer 
)

Executes a reducer function on each element of the range, resulting in a single output value.

std::vector<int> vecIn1{ 1, 2, 3, 4 };
assert(rah::reduce(vecIn1, 0, [](auto a, auto b) {return a + b; }) == 10);

◆ reduce() [2/2]

template<typename I , typename F >
auto rah::reduce ( I &&  init,
F &&  reducer 
)

Executes a reducer function on each element of the range, resulting in a single output value.

Remarks
pipeable syntax
std::vector<int> vecIn1{ 1, 2, 3, 4 };
assert((vecIn1 | rah::reduce(0, [](auto a, auto b) {return a + b; })) == 10);

◆ remove() [1/2]

template<typename R , typename V >
auto rah::remove ( R &&  range,
V &&  value 
)

Keep at the begining of the range only elements not equal to value
.

Returns
Return iterator to the part of the range to erase.
std::vector<int> in{ 1, 2, 1, 3, 1 };
auto range_to_erase_begin = rah::remove(in, 1);
in.erase(range_to_erase_begin, end(in));
std::sort(in.begin(), in.end());
assert(in == std::vector<int>({ 2, 3 }));

◆ remove() [2/2]

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

Keep at the begining of the range only elements not equal to value
.

Returns
Return iterator to the part of the range to erase.
Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 1, 3, 1 };
auto range_to_erase_begin = in | rah::remove(1);
in.erase(range_to_erase_begin, end(in));
std::sort(in.begin(), in.end());
assert(in == std::vector<int>({ 2, 3 }));

◆ remove_if() [1/2]

template<typename R , typename P >
auto rah::remove_if ( R &&  range,
P &&  pred 
)

Keep at the begining of the range only elements for which pred(elt) is false
.

Returns
Return the (end) part of the range to erase.
std::vector<int> in{ 1, 2, 3, 4, 5 };
auto range_to_erase_begin = rah::remove_if(in, [](auto a) {return a < 4; });
in.erase(range_to_erase_begin, end(in));
std::sort(in.begin(), in.end());
assert(in == std::vector<int>({4, 5}));

◆ remove_if() [2/2]

template<typename P >
auto rah::remove_if ( P &&  pred)

Keep at the begining of the range only elements for which pred(elt) is false
.

Returns
The (end) part of the range to erase.
Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 3, 4, 5 };
auto range_to_erase_begin = in | rah::remove_if([](int a) {return a < 4; });
in.erase(range_to_erase_begin, end(in));
std::sort(in.begin(), in.end());
assert(in == std::vector<int>({ 4, 5 }));

◆ set_difference() [1/2]

template<typename IN1 , typename IN2 , typename OUT >
void rah::set_difference ( IN1 &&  in1,
IN2 &&  in2,
OUT &&  out 
)

Copies the elements from the sorted range in1 which are not found in the sorted range in2 to the range out The resulting range is also sorted.

std::vector<int> in1{ 1, 3, 4 };
std::vector<int> in2{ 1, 2, 3 };
std::vector<int> out{ 0, 0, 0, 0 };
rah::set_difference(in1, in2, out);
assert(out == std::vector<int>({4, 0, 0, 0}));

◆ set_difference() [2/2]

template<typename IN1 , typename IN2 , typename OUT_ >
void rah::set_difference ( IN1 &&  in1,
IN2 &&  in2,
OUT_ &&  out 
)

Copies the elements from the sorted range in1 which are not found in the sorted range in2 to the range out The resulting range is also sorted.

std::vector<int> in1{ 1, 3, 4 };
std::vector<int> in2{ 1, 2, 3 };
std::vector<int> out{ 0, 0, 0, 0 };
rah::set_difference(in1, in2, out);
assert(out == std::vector<int>({4, 0, 0, 0}));

◆ set_intersection() [1/2]

template<typename IN1 , typename IN2 , typename OUT >
void rah::set_intersection ( IN1 &&  in1,
IN2 &&  in2,
OUT &&  out 
)

Copies the elements from the sorted range in1 which are also found in the sorted range in2 to the range out The resulting range is also sorted.

std::vector<int> in1{ 1, 3, 4 };
std::vector<int> in2{ 1, 2, 3 };
std::vector<int> out{ 0, 0, 0, 0 };
rah::set_intersection(in1, in2, out);
assert(out == std::vector<int>({ 1, 3, 0, 0 }));

◆ set_intersection() [2/2]

template<typename IN1 , typename IN2 , typename OUT_ >
void rah::set_intersection ( IN1 &&  in1,
IN2 &&  in2,
OUT_ &&  out 
)

Copies the elements from the sorted range in1 which are also found in the sorted range in2 to the range out The resulting range is also sorted.

std::vector<int> in1{ 1, 3, 4 };
std::vector<int> in2{ 1, 2, 3 };
std::vector<int> out{ 0, 0, 0, 0 };
rah::set_intersection(in1, in2, out);
assert(out == std::vector<int>({ 1, 3, 0, 0 }));

◆ shuffle() [1/2]

template<typename R , typename URBG >
void rah::shuffle ( R &  range,
URBG &&  g 
)

Reorders the elements in the given range such that each possible permutation of those elements has equal probability of appearance.

std::random_device rd;
std::mt19937 g(rd());
std::vector<int> in{ 1, 2, 3, 4, 5, 6 };
rah::shuffle(in, g);

◆ shuffle() [2/2]

template<typename URBG >
auto rah::shuffle ( URBG &&  g)

Reorders the elements in the given range such that each possible permutation of those elements has equal probability of appearance.

Remarks
pipeable syntax
std::random_device rd;
std::mt19937 g(rd());
std::vector<int> in{ 1, 2, 3, 4, 5, 6 };
in | rah::shuffle(g);

◆ size() [1/2]

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

Get the size of range.

std::vector<int> vec3{ 1, 2, 3 };
assert(rah::size(vec3) == 3);

◆ size() [2/2]

auto rah::size ( )
inline

Get the size of range.

Remarks
pipeable syntax
std::vector<int> vec3{ 1, 2, 3 };
assert((vec3 | rah::size()) == 3);

◆ sort() [1/2]

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

Sort a range in place, using the given predicate.

std::vector<int> in{ 2, 1, 5, 3, 4 };
rah::sort(in);
assert(in == std::vector<int>({ 1, 2, 3, 4, 5 }));
std::vector<int> in{ 2, 1, 5, 3, 4 };
rah::sort(in, [](auto a, auto b) {return a < b; });
assert(in == 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::sort ( P &&  pred = {})

Sort a range in place, using the given predicate.

Remarks
pipeable syntax
std::vector<int> in{ 2, 1, 5, 3, 4 };
in | rah::sort();
assert(in == std::vector<int>({ 1, 2, 3, 4, 5 }));
std::vector<int> in{ 2, 1, 5, 3, 4 };
in | rah::sort([](auto a, auto b) {return a < b; });
assert(in == std::vector<int>({ 1, 2, 3, 4, 5 }));

◆ stable_partition() [1/2]

template<typename R , typename P >
auto rah::stable_partition ( R &&  range,
P &&  pred 
)

Reorders the elements in the range in such a way that all elements for which the predicate pred returns true precede the elements for which predicate pred returns false.

Relative order of the elements is preserved.

Returns
Iterator to the first element of the second group.
std::vector<int> in{ 1, 2, 3, 4, 5 };
auto boundary = rah::stable_partition(in, [](auto a) {return a >= 4; });
assert(boundary == in.begin() + 2);
assert(in == std::vector<int>({ 4, 5, 1, 2, 3 }));

◆ stable_partition() [2/2]

template<typename P >
auto rah::stable_partition ( P &&  pred)
See also
rah::stable_partition(R&&, P&&)
Remarks
pipeable syntax
std::vector<int> in{ 1, 2, 3, 4, 5 };
auto boundary = in | rah::stable_partition([](auto a) {return a >= 4; });
assert(boundary == in.begin() + 2);
assert(in == std::vector<int>({ 4, 5, 1, 2, 3 }));

◆ stable_sort() [1/2]

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

Sorts the elements in the range in ascending order.

The order of equivalent elements is guaranteed to be preserved.

struct CmpA
{
int a;
int b;
bool operator<(CmpA rhs) const
{
return a < rhs.a;
}
bool operator==(CmpA rhs) const
{
return a == rhs.a && b == rhs.b;
}
};
{
std::vector<CmpA> in{ { 4, 1 }, { 2, 1 }, { 4, 2 }, { 1, 1 }, { 4, 3 }, { 2, 2 }, { 4, 4 } };
assert(in == std::vector<CmpA>({ { 1, 1 }, { 2, 1 }, { 2, 2 }, { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4, 4 } }));
}
std::vector<CmpA> in{ { 4, 1 }, { 2, 1 }, { 4, 2 }, { 1, 1 }, { 4, 3 }, { 2, 2 }, { 4, 4 } };
rah::stable_sort(in, [](CmpA l, CmpA r) { return l.b < r.b; });
assert(in == std::vector<CmpA>({ { 4, 1 }, { 2, 1 }, { 1, 1 }, { 4, 2 }, { 2, 2 }, { 4, 3 }, { 4, 4 } }));

◆ stable_sort() [2/2]

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

Sorts the elements in the range in ascending order.

The order of equivalent elements is guaranteed to be preserved.

Remarks
pipeable syntax
assert(in == std::vector<CmpA>({ { 1, 1 }, { 2, 1 }, { 2, 2 }, { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4, 4 } }));
std::vector<CmpA> in{ { 4, 1 }, { 2, 1 }, { 4, 2 }, { 1, 1 }, { 4, 3 }, { 2, 2 }, { 4, 4 } };
in | rah::stable_sort([](CmpA l, CmpA r) { return l.b < r.b; });
assert(in == std::vector<CmpA>({ { 4, 1 }, { 2, 1 }, { 1, 1 }, { 4, 2 }, { 2, 2 }, { 4, 3 }, { 4, 4 } }));

◆ stream_inserter()

template<typename S >
auto rah::stream_inserter ( S &&  stream)

Make a range which output to a stream.

std::string in("Test");
std::stringstream out;
assert(out.str() == in);

◆ to_container() [1/2]

template<typename C , typename R >
auto rah::to_container ( R &&  range)

Return a container of type C, filled with the content of range.

std::vector<std::pair<int, char>> in1{ {4, 'a'}, { 5, 'b' }, { 6, 'c' }, { 7, 'd' } };
std::map<int, char> map_4a_5b_6c_7d = rah::to_container<std::map<int, char>>(in1);
map_4a_5b_6c_7d == (std::map<int, char>{ {4, 'a'}, { 5, 'b' }, { 6, 'c' }, { 7, 'd' } })
);
std::list<int> in2{ 4, 5, 6, 7 };
std::vector<int> out = rah::to_container<std::vector<int>>(in2);
assert(out == (std::vector<int>{ 4, 5, 6, 7 }));

◆ to_container() [2/2]

template<typename C >
auto rah::to_container ( )

Return a container of type C, filled with the content of range.

Remarks
pipeable syntax
std::vector<std::pair<int, char>> in1{ {4, 'a'}, { 5, 'b' }, { 6, 'c' }, { 7, 'd' } };
std::map<int, char> map_4a_5b_6c_7d = in1 | rah::to_container<std::map<int, char>>();
map_4a_5b_6c_7d == (std::map<int, char>{ {4, 'a'}, { 5, 'b' }, { 6, 'c' }, { 7, 'd' } })
);
std::list<int> in2{ 4, 5, 6, 7 };
std::vector<int> out = in2 | rah::to_container<std::vector<int>>();
assert(out == (std::vector<int>{ 4, 5, 6, 7 }));

◆ transform() [1/2]

template<typename RI , typename RO , typename F >
auto rah::transform ( RI &&  rangeIn,
RO &&  rangeOut,
F &&  unary_op 
)

Applies the given function unary_op to the range rangeIn and stores the result in the range rangeOut.

std::vector<int> vecIn1{ 0, 1, 2, 3 };
std::vector<int> vecOut;
rah::transform(vecIn1, rah::back_inserter(vecOut), [](int a) {return a + 1; });
assert(vecOut == std::vector<int>({ 1, 2, 3, 4 }));

◆ transform() [2/2]

template<typename RI1 , typename RI2 , typename RO , typename F >
auto rah::transform ( RI1 &&  rangeIn1,
RI2 &&  rangeIn2,
RO &&  rangeOut,
F &&  binary_op 
)

The binary operation binary_op is applied to pairs of elements from two ranges.

std::vector<int> vecIn1{ 0, 1, 2, 3 };
std::vector<int> vecIn2{ 4, 3, 2, 1 };
std::vector<int> vecOut;
rah::transform(vecIn1, vecIn2, rah::back_inserter(vecOut), [](int a, int b) {return a + b; });
assert(vecOut == std::vector<int>({ 4, 4, 4, 4 }));

◆ unique() [1/2]

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

Remove all but first successuve values which are equals.

Without resizing the range.

Returns
The end part of the range, which have to be remove.
std::vector<int> in{ 2, 1, 1, 1, 5, 3, 3, 4 };
in.erase(rah::unique(in), end(in));
assert(in == std::vector<int>({ 2, 1, 5, 3, 4 }));
std::vector<int> in{ 2, 1, 1, 1, 5, 3, 3, 4 };
in.erase(rah::unique(in, [](auto a, auto b) {return a == b; }), end(in));
assert(in == std::vector<int>({ 2, 1, 5, 3, 4 }));

◆ unique() [2/2]

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

Remove all but first successuve values which are equals.

Without resizing the range.

Returns
The end part of the range, which have to be remove.
Remarks
pipeable syntax
std::vector<int> in{ 2, 1, 1, 1, 5, 3, 3, 4 };
in.erase(in | rah::unique(), end(in));
assert(in == std::vector<int>({ 2, 1, 5, 3, 4 }));
std::vector<int> in{ 2, 1, 1, 1, 5, 3, 3, 4 };
in.erase(in | rah::unique([](auto a, auto b) {return a == b; }), end(in));
assert(in == std::vector<int>({ 2, 1, 5, 3, 4 }));

Variable Documentation

◆ End

constexpr intptr_t rah::End = -1

Used with rah::view::slice to point to the end.