== `algorithm.hpp` https://github.com/intel/cpp-std-extensions/blob/main/include/stdx/algorithm.hpp[`algorithm.hpp`] provides an implementation of some algorithms. === `for_each` and `for_each_n` `stdx::for_each` is similar to https://en.cppreference.com/w/cpp/algorithm/for_each[`std::for_each`], but variadic in its inputs. [source,cpp] ---- template constexpr auto for_each(InputIt first, InputIt last, Operation op, InputItN... first_n) -> for_each_result; ---- The return value is equivalent to a `tuple`. 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 https://en.cppreference.com/w/cpp/utility/functional/invoke[`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`. [source,cpp] ---- template constexpr auto for_each_n(InputIt first, Size n, Operation op, InputItN... first_n); -> for_each_result; ---- === `for_each_butlast`, `for_each_butlastn` `stdx::for_each_butlast` is like `for_each` but omits the last element of each range. [source,cpp] ---- template constexpr auto for_each_butlast(FwdIt first, FwdIt last, Operation op, FwdItN... first_n) -> for_each_result; ---- `stdx::for_each_butlastn` omits the last `n` elements of each range. [source,cpp] ---- template constexpr auto for_each_butlastn(FwdIt first, FwdIt last, N n, Operation op, FwdItN... first_n) -> for_each_result; ---- NOTE: `for_each_butlast` and `for_each_butlastn` are defined for forward iterators (or stronger) only. === `initial_medial_final` `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. [source,cpp] ---- template CONSTEXPR_INVOKE auto initial_medial_final(FwdIt first, FwdIt last, IOp iop, MOp mop, FOp fop) -> for_each_result; ---- 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. === `transform` and `transform_n` `stdx::transform` is similar to https://en.cppreference.com/w/cpp/algorithm/transform[`std::transform`], but variadic in its inputs. [source,cpp] ---- template constexpr auto transform(InputIt first, InputIt last, OutputIt d_first, Operation op, InputItN... first_n) -> transform_result; ---- 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 https://en.cppreference.com/w/cpp/ranges/zip_transform_view[`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`. 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 https://en.cppreference.com/w/cpp/utility/functional/invoke[`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. [source,cpp] ---- template constexpr auto transform(InputIt first, Size n, OutputIt d_first, Operation op, InputItN... first_n) -> transform_result; ----