algorithm.hpp
provides an implementation of some algorithms.
stdx::for_each
is similar to
std::for_each
, but
variadic in its inputs.
template <typename InputIt, typename Operation, typename... InputItN>
constexpr auto for_each(InputIt first, InputIt last,
Operation op, InputItN... first_n)
-> for_each_result<Operation, InputItN...>;
The return value is equivalent to a tuple<Operation, InputItN…>
.
In C++20 and later this is a stdx::tuple
, in C++17 a std::tuple
.
Note
|
stdx::for_each is constexpr in C++20 and later, because it uses
std::invoke .
|
stdx::for_each_n
is just like stdx::for_each
, but instead of taking two
iterators to delimit the input range, it takes an iterator and size.
Correspondingly, its return value includes the advanced InputIt
.
template <typename InputIt, typename Size, typename Operation,
typename... InputItN>
constexpr auto for_each_n(InputIt first, Size n,
Operation op, InputItN... first_n);
-> for_each_result<Operation, InputIt, InputItN...>;
stdx::for_each_butlast
is like for_each
but omits the last element of
each range.
template <typename FwdIt, typename Operation,
typename... FwdItN>
constexpr auto for_each_butlast(FwdIt first, FwdIt last,
Operation op, FwdItN... first_n)
-> for_each_result<Operation, FwdIt, FwdItN...>;
stdx::for_each_butlastn
omits the last n
elements of each range.
template <typename FwdIt, typename Size, typename Operation,
typename... FwdItN>
constexpr auto for_each_butlastn(FwdIt first, FwdIt last, N n,
Operation op, FwdItN... first_n)
-> for_each_result<Operation, FwdIt, FwdItN...>;
Note
|
for_each_butlast and for_each_butlastn are defined for forward
iterators (or stronger) only.
|
initial_medial_final
iterates over a range, calling one function
for the initial element, another function for each of the medial elements, and a third
function for the final element.
template <typename FwdIt, typename IOp, typename MOp, typename FOp>
CONSTEXPR_INVOKE auto initial_medial_final(FwdIt first, FwdIt last, IOp iop,
MOp mop, FOp fop)
-> for_each_result<IOp, MOp, FOp>;
If the range is only two elements, there are no medial elements, so mop
is not
called. If the range is only one element, fop
is not called. And if the range
is empty, no functions are called.
stdx::transform
is similar to
std::transform
, but
variadic in its inputs.
template <typename InputIt, typename OutputIt, typename Operation, typename... InputItN>
constexpr auto transform(InputIt first, InputIt last, OutputIt d_first,
Operation op, InputItN... first_n)
-> transform_result<OutputIt, InputIt, InputItN...>;
Without the variadic pack InputItN…
here, a call site looks like regular unary
std::transform
. But with the addition of the pack, stdx::transform
becomes
more like
std::ranges::views::zip_transform
.
It can transform using an n-ary function and n sequences.
Note
|
The return value is equivalent to a tuple<OutputIt, InputIt, InputItN…> .
In C++20 and later this is a stdx::tuple , in C++17 a std::tuple .
|
Note
|
stdx::transform is constexpr in C++20 and later, because it uses
std::invoke .
|
stdx::transform_n
is just like stdx::transform
, but instead of taking two
iterators to delimit the input range, it takes an iterator and size.
template <typename InputIt, typename Size, typename OutputIt, typename Operation,
typename... InputItN>
constexpr auto transform(InputIt first, Size n, OutputIt d_first,
Operation op, InputItN... first_n)
-> transform_result<OutputIt, InputIt, InputItN...>;