1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
/// \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 <initializer_list>
#include <tuple>
#include <type_traits>
#include <utility>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/detail/adl_get.hpp>
#include <range/v3/functional/invoke.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-utility
/// @{
template<typename Tup>
using tuple_indices_t = meta::make_index_sequence<
std::tuple_size<typename std::remove_reference<Tup>::type>::value>;
struct tuple_apply_fn
{
// clang-format off
private:
template<typename Fun, typename Tup, std::size_t... Is>
static constexpr auto //
CPP_auto_fun(impl)(Fun &&fun, Tup &&tup, meta::index_sequence<Is...>)
(
return invoke(static_cast<Fun &&>(fun),
detail::adl_get<Is>(static_cast<Tup &&>(tup))...)
)
public:
template<typename Fun, typename Tup>
constexpr auto CPP_auto_fun(operator())(Fun &&fun, Tup &&tup)(const)
(
return tuple_apply_fn::impl(static_cast<Fun &&>(fun),
static_cast<Tup &&>(tup),
tuple_indices_t<Tup>{})
)
// 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<typename Tup, typename Fun, std::size_t... Is>
static constexpr auto //
CPP_auto_fun(impl1)(Tup &&tup, Fun &fun, meta::index_sequence<Is...>)
(
return std::tuple<
decltype(fun(detail::adl_get<Is>(static_cast<Tup &&>(tup))))...>{
fun(detail::adl_get<Is>(static_cast<Tup &&>(
tup)))...}
)
template<typename Tup0, typename Tup1, typename Fun, std::size_t... Is>
static constexpr auto CPP_auto_fun(impl2)(Tup0 &&tup0, Tup1 &&tup1, Fun &fun,
meta::index_sequence<Is...>)
(
return std::tuple<
decltype(fun(detail::adl_get<Is>(static_cast<Tup0 &&>(tup0)),
detail::adl_get<Is>(static_cast<Tup1 &&>(tup1))))...>{
fun(detail::adl_get<Is>(static_cast<Tup0 &&>(tup0)),
detail::adl_get<Is>(static_cast<Tup1 &&>(tup1)))...}
)
public:
template<typename Tup, typename Fun>
constexpr auto CPP_auto_fun(operator())(Tup &&tup, Fun fun)(const)
(
return tuple_transform_fn::impl1(
static_cast<Tup &&>(tup), fun,
tuple_indices_t<Tup>{})
)
template<typename Tup0, typename Tup1, typename Fun>
constexpr auto CPP_auto_fun(operator())(Tup0 &&tup0, Tup1 &&tup1, Fun fun)(const)
(
return tuple_transform_fn::impl2(static_cast<Tup0 &&>(tup0),
static_cast<Tup1 &&>(tup1), fun,
tuple_indices_t<Tup0>{})
)
// clang-format on
};
/// \ingroup group-utility
/// \sa `tuple_transform_fn`
RANGES_INLINE_VARIABLE(tuple_transform_fn, tuple_transform)
struct tuple_foldl_fn
{
private:
template<typename Tup, typename Val, typename Fun>
static constexpr Val impl(Tup &&, Val val, Fun &)
{
return val;
}
// clang-format off
template<std::size_t I0, std::size_t... Is, typename Tup, typename Val,
typename Fun, typename Impl = tuple_foldl_fn>
static constexpr auto CPP_auto_fun(impl)(Tup &&tup, Val val, Fun &fun)
(
return Impl::template impl<Is...>(
static_cast<Tup &&>(tup),
fun(std::move(val), detail::adl_get<I0>(static_cast<Tup &&>(tup))),
fun)
)
template<typename Tup, typename Val, typename Fun, std::size_t... Is>
static constexpr auto CPP_auto_fun(impl2)(Tup &&tup, Val val, Fun &fun,
meta::index_sequence<Is...>)
(
return tuple_foldl_fn::impl<Is...>(static_cast<Tup &&>(tup),
std::move(val),
fun)
)
public:
template<typename Tup, typename Val, typename Fun>
constexpr auto CPP_auto_fun(operator())(Tup &&tup, Val val, Fun fun)(const)
(
return tuple_foldl_fn::impl2(static_cast<Tup &&>(tup),
std::move(val),
fun,
tuple_indices_t<Tup>{})
)
// 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<typename Tup, typename Fun, std::size_t... Is>
static constexpr void impl(Tup && tup, Fun & fun, meta::index_sequence<Is...>)
{
(void)std::initializer_list<int>{
((void)fun(detail::adl_get<Is>(static_cast<Tup &&>(tup))), 42)...};
}
public:
template<typename Tup, typename Fun>
constexpr Fun operator()(Tup && tup, Fun fun) const
{
return tuple_for_each_fn::impl(
static_cast<Tup &&>(tup), fun, tuple_indices_t<Tup>{}),
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<typename... Ts>
constexpr auto CPP_auto_fun(operator())(Ts &&... ts)(const)
(
return std::make_tuple(static_cast<Ts &&>(ts)...)
)
// clang-format on
};
/// \ingroup group-utility
/// \sa `make_tuple_fn`
RANGES_INLINE_VARIABLE(make_tuple_fn, make_tuple)
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif
|