/// \file // Range v3 library // // Copyright Eric Niebler 2013-present // // Use, modification and distribution is subject to the // Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Project home: https://github.com/ericniebler/range-v3 // #ifndef RANGES_V3_UTILITY_TUPLE_ALGORITHM_HPP #define RANGES_V3_UTILITY_TUPLE_ALGORITHM_HPP #include #include #include #include #include #include #include #include #include namespace ranges { /// \addtogroup group-utility /// @{ template using tuple_indices_t = meta::make_index_sequence< std::tuple_size::type>::value>; struct tuple_apply_fn { // clang-format off private: template static constexpr auto CPP_auto_fun(impl)(Fun &&fun, Tup &&tup, meta::index_sequence) ( return invoke(static_cast(fun), detail::adl_get(static_cast(tup))...) ) public: template constexpr auto CPP_auto_fun(operator())(Fun &&fun, Tup &&tup)(const) ( return tuple_apply_fn::impl(static_cast(fun), static_cast(tup), tuple_indices_t{}) ) // clang-format on }; /// \ingroup group-utility /// \sa `tuple_apply_fn` RANGES_INLINE_VARIABLE(tuple_apply_fn, tuple_apply) struct tuple_transform_fn { // clang-format off private: template static constexpr auto CPP_auto_fun(impl1)(Tup &&tup, Fun &fun, meta::index_sequence) ( return std::tuple< decltype(fun(detail::adl_get(static_cast(tup))))...>{ fun(detail::adl_get(static_cast( tup)))...} ) template static constexpr auto CPP_auto_fun(impl2)(Tup0 &&tup0, Tup1 &&tup1, Fun &fun, meta::index_sequence) ( return std::tuple< decltype(fun(detail::adl_get(static_cast(tup0)), detail::adl_get(static_cast(tup1))))...>{ fun(detail::adl_get(static_cast(tup0)), detail::adl_get(static_cast(tup1)))...} ) public: template constexpr auto CPP_auto_fun(operator())(Tup &&tup, Fun fun)(const) ( return tuple_transform_fn::impl1( static_cast(tup), fun, tuple_indices_t{}) ) template constexpr auto CPP_auto_fun(operator())(Tup0 &&tup0, Tup1 &&tup1, Fun fun)(const) ( return tuple_transform_fn::impl2(static_cast(tup0), static_cast(tup1), fun, tuple_indices_t{}) ) // clang-format on }; /// \ingroup group-utility /// \sa `tuple_transform_fn` RANGES_INLINE_VARIABLE(tuple_transform_fn, tuple_transform) struct tuple_foldl_fn { private: template static constexpr Val impl(Tup &&, Val val, Fun &) { return val; } // clang-format off template static constexpr auto CPP_auto_fun(impl)(Tup &&tup, Val val, Fun &fun) ( return Impl::template impl( static_cast(tup), fun(std::move(val), detail::adl_get(static_cast(tup))), fun) ) template static constexpr auto CPP_auto_fun(impl2)(Tup &&tup, Val val, Fun &fun, meta::index_sequence) ( return tuple_foldl_fn::impl(static_cast(tup), std::move(val), fun) ) public: template constexpr auto CPP_auto_fun(operator())(Tup &&tup, Val val, Fun fun)(const) ( return tuple_foldl_fn::impl2(static_cast(tup), std::move(val), fun, tuple_indices_t{}) ) // clang-format on }; /// \ingroup group-utility /// \sa `tuple_foldl_fn` RANGES_INLINE_VARIABLE(tuple_foldl_fn, tuple_foldl) struct tuple_for_each_fn { private: template static constexpr void impl(Tup && tup, Fun & fun, meta::index_sequence) { (void)std::initializer_list{ ((void)fun(detail::adl_get(static_cast(tup))), 42)...}; } public: template constexpr Fun operator()(Tup && tup, Fun fun) const { return tuple_for_each_fn::impl( static_cast(tup), fun, tuple_indices_t{}), fun; } }; /// \ingroup group-utility /// \sa `tuple_for_each_fn` RANGES_INLINE_VARIABLE(tuple_for_each_fn, tuple_for_each) struct make_tuple_fn { // clang-format off template constexpr auto CPP_auto_fun(operator())(Ts &&... ts)(const) ( return std::make_tuple(static_cast(ts)...) ) // clang-format on }; /// \ingroup group-utility /// \sa `make_tuple_fn` RANGES_INLINE_VARIABLE(make_tuple_fn, make_tuple) /// @} } // namespace ranges #endif