#pragma once #include #if __cplusplus >= 202002L #include #else #include #endif namespace stdx { inline namespace v1 { namespace detail { #if __cplusplus >= 202002L template using result_tuple_t = stdx::tuple; #define CONSTEXPR_INVOKE constexpr #else template using result_tuple_t = std::tuple; #define CONSTEXPR_INVOKE #endif } // namespace detail template using transform_result = detail::result_tuple_t; template CONSTEXPR_INVOKE auto transform(InputIt first, InputIt last, OutputIt d_first, Operation op, InputItN... first_n) -> transform_result { while (first != last) { *d_first = std::invoke(op, *first, *first_n...); static_cast(++first), (static_cast(++first_n), ...), ++d_first; } return {d_first, first, first_n...}; } template CONSTEXPR_INVOKE auto transform_n(InputIt first, Size n, OutputIt d_first, Operation op, InputItN... first_n) -> transform_result { while (n-- > 0) { *d_first = std::invoke(op, *first, *first_n...); static_cast(++first), (static_cast(++first_n), ...), ++d_first; } return {d_first, first, first_n...}; } template CONSTEXPR_INVOKE auto for_each(InputIt first, InputIt last, Operation op, InputItN... first_n) -> Operation { while (first != last) { std::invoke(op, *first, *first_n...); static_cast(++first), (static_cast(++first_n), ...); } return op; } template CONSTEXPR_INVOKE auto for_each_n(InputIt first, Size n, Operation op, InputItN... first_n) -> Operation { while (n-- > 0) { std::invoke(op, *first, *first_n...); static_cast(++first), (static_cast(++first_n), ...); } return op; } #undef CONSTEXPR_INVOKE } // namespace v1 } // namespace stdx