30 #ifndef BPSTD_TUPLE_HPP
31 #define BPSTD_TUPLE_HPP
33 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
35 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
44 BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
52 template <
typename...Types>
53 using tuple = std::tuple<Types...>;
59 template <std::
size_t I,
typename T>
60 using tuple_element = std::tuple_element<I,T>;
62 template <std::
size_t I,
typename T>
63 using tuple_element_t =
typename tuple_element<I, T>::type;
68 using tuple_size = std::tuple_size<T>;
70 #if BPSTD_HAS_TEMPLATE_VARIABLES
72 BPSTD_CPP17_INLINE constexpr
auto tuple_size_v = tuple_size<T>::value;
85 struct is_tuple : false_type{};
87 template <
typename...Types>
88 struct is_tuple<std::tuple<Types...>> : true_type{};
91 template <std::size_t N,
typename Tuple,
92 typename = enable_if_t<detail::is_tuple<remove_cvref_t<Tuple>>::value && is_lvalue_reference<Tuple>::value>>
93 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
94 tuple_element_t<N,remove_reference_t<Tuple>>&
95 get(Tuple&& t) noexcept
97 return std::get<N>(t);
100 template <std::size_t N,
typename Tuple,
101 typename = enable_if_t<detail::is_tuple<remove_cvref_t<Tuple>>::value && !is_lvalue_reference<Tuple>::value>>
102 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
103 tuple_element_t<N,remove_reference_t<Tuple>>&&
104 get(Tuple&& t) noexcept
106 return bpstd::move(std::get<N>(t));
109 template <
typename T,
typename... Types>
110 BPSTD_CPP14_CONSTEXPR T& get(tuple<Types...>& t) noexcept;
111 template <
typename T,
typename... Types>
112 BPSTD_CPP14_CONSTEXPR T&& get(tuple<Types...>&& t) noexcept;
113 template <
typename T,
typename... Types>
114 BPSTD_CPP14_CONSTEXPR
const T& get(
const tuple<Types...>& t) noexcept;
115 template <
typename T,
typename... Types>
116 BPSTD_CPP14_CONSTEXPR
const T&& get(
const tuple<Types...>&& t) noexcept;
123 template <
typename Fn,
typename Seq,
typename Tuple>
124 struct apply_result_impl;
126 template <
typename Fn, std::size_t...Idx,
typename Tuple>
127 struct apply_result_impl<Fn, index_sequence<Idx...>, Tuple>
128 : invoke_result<Fn, tuple_element_t<Idx, Tuple>...>{};
130 template <
typename Fn,
typename Tuple>
131 struct apply_result : apply_result_impl<
133 make_index_sequence<tuple_size<remove_reference_t<Tuple>>::value>,
137 template <
typename Fn,
typename Tuple>
138 using apply_result_t =
typename apply_result<Fn, Tuple>::type;
149 template <
typename Fn,
typename Tuple>
150 constexpr detail::apply_result_t<Fn, Tuple>
apply(Fn&& fn, Tuple&& tuple);
156 template <
typename T,
typename Tuple>
169 namespace bpstd {
namespace detail {
171 template <
typename T, std::size_t Index,
typename...Types>
172 struct index_of_impl;
174 template <
typename T, std::size_t Index,
typename Type0,
typename...Types>
175 struct index_of_impl<T, Index, Type0, Types...>
176 : index_of_impl<T, Index + 1, Types...>{};
178 template <
typename T, std::size_t Index,
typename...Types>
179 struct index_of_impl<T, Index, T, Types...>
180 : integral_constant<std::size_t, Index>{};
182 template <
typename T,
typename...Types>
183 struct index_of : index_of_impl<T,0,Types...>{};
187 template <
typename T,
typename... Types>
188 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
192 return std::get<detail::index_of<T,Types...>::value>(t);
195 template <
typename T,
typename... Types>
196 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
200 return move(std::get<detail::index_of<T,Types...>::value>(t));
203 template <
typename T,
typename... Types>
204 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
208 return std::get<detail::index_of<T,Types...>::value>(t);
211 template <
typename T,
typename... Types>
212 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
213 const T&&
bpstd::get(
const tuple<Types...>&& t)
216 return move(std::get<detail::index_of<T,Types...>::value>(t));
223 #if defined(_MSC_VER)
224 # pragma warning(push)
225 # pragma warning(disable:4100) // MSVC warns that 'tuple' is not used below
230 template <
typename Fn,
typename Tuple, std::size_t... I>
231 inline BPSTD_INLINE_VISIBILITY constexpr
232 apply_result_t<Fn,Tuple> apply_impl(Fn&& fn, Tuple&& tuple, index_sequence<I...>)
234 return ::bpstd::invoke(
235 bpstd::forward<Fn>(fn),
236 std::get<I>(bpstd::forward<Tuple>(tuple))...
242 #if defined(_MSC_VER)
243 # pragma warning(pop)
246 template <
typename Fn,
typename Tuple>
247 inline BPSTD_INLINE_VISIBILITY constexpr
248 bpstd::detail::apply_result_t<Fn, Tuple>
bpstd::apply(Fn&& fn, Tuple&& tuple)
250 return detail::apply_impl(
251 bpstd::forward<Fn>(fn),
252 bpstd::forward<Tuple>(tuple),
253 make_index_sequence<tuple_size<remove_reference_t<Tuple>>::value>{}
261 #if defined(_MSC_VER)
262 # pragma warning(push)
263 # pragma warning(disable:4100) // MSVC warns that 'tuple' is not used below
268 template <
typename T,
typename Tuple, std::size_t... I>
269 inline BPSTD_INLINE_VISIBILITY constexpr
270 T make_from_tuple_impl(Tuple&& tuple, index_sequence<I...>)
272 return T(std::get<I>(bpstd::forward<Tuple>(tuple))...);
277 #if defined(_MSC_VER)
278 # pragma warning(pop)
281 template <
typename T,
typename Tuple>
282 inline BPSTD_INLINE_VISIBILITY constexpr
285 return detail::make_from_tuple_impl<T>(
286 bpstd::forward<Tuple>(tuple),
287 make_index_sequence<tuple_size<remove_reference_t<Tuple>>::value>{}
291 BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE