5#ifndef INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_TUPLE_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_TUPLE_HPP_
19#include "arene/base/constraints.hpp"
20#include "arene/base/functional/identity.hpp"
21#include "arene/base/type_list/at.hpp"
22#include "arene/base/type_list/type_list.hpp"
23#include "arene/base/type_manipulation/consume_values.hpp"
24#include "arene/base/type_manipulation/ebo_holder.hpp"
25#include "arene/base/type_traits/all_of.hpp"
26#include "arene/base/type_traits/comparison_traits.hpp"
27#include "arene/base/type_traits/index_of.hpp"
28#include "arene/base/type_traits/is_swappable.hpp"
29#include "arene/base/type_traits/remove_cvref.hpp"
30#include "stdlib/include/stdlib_detail/cstddef.hpp"
31#include "stdlib/include/stdlib_detail/declval.hpp"
32#include "stdlib/include/stdlib_detail/enable_if.hpp"
33#include "stdlib/include/stdlib_detail/forward.hpp"
34#include "stdlib/include/stdlib_detail/integer_sequence.hpp"
35#include "stdlib/include/stdlib_detail/integral_constant.hpp"
36#include "stdlib/include/stdlib_detail/is_assignable.hpp"
37#include "stdlib/include/stdlib_detail/is_constructible.hpp"
38#include "stdlib/include/stdlib_detail/is_copy_assignable.hpp"
39#include "stdlib/include/stdlib_detail/is_copy_constructible.hpp"
40#include "stdlib/include/stdlib_detail/is_default_constructible.hpp"
41#include "stdlib/include/stdlib_detail/is_final.hpp"
42#include "stdlib/include/stdlib_detail/is_move_assignable.hpp"
43#include "stdlib/include/stdlib_detail/is_reference.hpp"
44#include "stdlib/include/stdlib_detail/pair.hpp"
45#include "stdlib/include/stdlib_detail/remove_const.hpp"
46#include "stdlib/include/stdlib_detail/remove_reference.hpp"
47#include "stdlib/include/stdlib_detail/tuple_element.hpp"
48#include "stdlib/include/stdlib_detail/tuple_fwd.hpp"
49#include "stdlib/include/stdlib_detail/tuple_size.hpp"
57template <
class... Types>
58class tuple_size<tuple<Types...>> :
public integral_constant<size_t,
sizeof...(Types)> {};
65template <size_t I,
class... Types>
66class tuple_element<I, tuple<Types...>> {
68 static_assert(I <
sizeof...(Types),
"index out of range for the given tuple");
71 using type = arene::base::type_lists::at_t<arene::base::type_list<Types...>, I>;
80template <
class... Types>
82 return tuple<Types&...>{args...};
104template <size_t I,
class... Types>
108 return __get_tuple_impl<I>(tup).value();
116template <size_t I,
class... Types>
123 return __get_tuple_impl<I>(
const_cast<tuple<Types...>&>(tup)).value();
136template <size_t I,
class... Types>
139 using return_type = tuple_element_t<I, tuple<Types...>>&&;
141 return static_cast<return_type>(__get_tuple_impl<I>(tup).value());
152template <size_t I,
class... Types>
155 using return_type = tuple_element_t<I, tuple<Types...>>
const&&;
160 return static_cast<return_type>(__get_tuple_impl<I>(
const_cast<tuple<Types...>&>(tup)).value());
170template <
class T,
class... Types>
171constexpr auto get(tuple<Types...>& tup)
noexcept -> T& {
172 constexpr size_t first_idx{::arene::base::index_of_v<T, Types...>};
173 constexpr size_t last_idx{::arene::base::last_index_of_v<T, Types...>};
175 first_idx == last_idx,
176 "Type-based std::get<T>(std::tuple<Types...>) can only be used if T appears exactly once in Types, but it "
177 "appears multiple times"
180 return get<first_idx>(tup);
188template <
class T,
class... Types>
189constexpr auto get(tuple<Types...>
const& tup)
noexcept -> T
const& {
190 constexpr size_t first_idx{::arene::base::index_of_v<T, Types...>};
191 constexpr size_t last_idx{::arene::base::last_index_of_v<T, Types...>};
193 first_idx == last_idx,
194 "Type-based std::get<T>(std::tuple<Types...>) can only be used if T appears exactly once in Types, but it "
195 "appears multiple times"
198 return get<first_idx>(tup);
206template <
class T,
class... Types>
207constexpr auto get(tuple<Types...>&& tup)
noexcept -> T&& {
208 constexpr size_t first_idx{::arene::base::index_of_v<T, Types...>};
209 constexpr size_t last_idx{::arene::base::last_index_of_v<T, Types...>};
211 first_idx == last_idx,
212 "Type-based std::get<T>(std::tuple<Types...>) can only be used if T appears exactly once in Types, but it "
213 "appears multiple times"
216 return get<first_idx>(std::move(tup));
224template <
class T,
class... Types>
225constexpr auto get(tuple<Types...>
const&& tup)
noexcept -> T
const&& {
226 constexpr size_t first_idx{::arene::base::index_of_v<T, Types...>};
227 constexpr size_t last_idx{::arene::base::last_index_of_v<T, Types...>};
229 first_idx == last_idx,
230 "Type-based std::get<T>(std::tuple<Types...>) can only be used if T appears exactly once in Types, but it "
231 "appears multiple times"
234 return get<first_idx>(std::move(tup));
245template <
class T,
class =
void>
276 return static_cast<
T>(
value);
302 constexpr auto value() &
noexcept -> T& {
return this->get_value(base_tag_type{}); }
308 constexpr auto value()
const&
noexcept -> T
const& {
return this->get_value(base_tag_type{}); }
320template <
class Indices,
class Types>
337template <
class Dest,
class Source, std::size_t... Indices>
339 ::arene::base::consume_values({std::get<Indices>(dest) = std::get<Indices>(std::forward<Source>(source))...});
348template <
class Lhs,
class Rhs, std::size_t... Indices>
350 ::arene::base::consume_values({(swap(std::get<Indices>(lhs), std::get<Indices>(std::forward<Rhs>(rhs))),
true)...});
363template <
template <
class...>
class Trait,
class TupleTypeList,
class List,
class =
void>
374template <
template <
class...>
class Trait,
class...
T,
class...
U>
400 template <
template <
class...>
class Trait,
class...
U>
467 (
sizeof...(
UTypes) != 0U) &&
496 (
sizeof...(
UTypes) != 0U) &&
521 (
sizeof...(
UTypes) != 0U) &&
618template <std::size_t Idx,
class... LTypes,
class... RTypes,
619 ::arene::base::constraints<enable_if_t<Idx ==
sizeof...(LTypes)>> =
nullptr>
620constexpr auto elements_equal(tuple<LTypes...>
const&, tuple<RTypes...>
const&)
noexcept ->
bool {
632template <std::size_t Idx,
class... LTypes,
class... RTypes,
633 ::arene::base::constraints<enable_if_t<Idx <
sizeof...(LTypes)>> =
nullptr>
634constexpr auto elements_equal(tuple<LTypes...>
const& left, tuple<RTypes...>
const& right)
636 return (get<Idx>(left) == get<Idx>(right)) && ::
std::
tuple_detail::elements_equal<Idx + 1UL>(left, right);
646template <std::size_t Idx,
class... LTypes,
class... RTypes,
647 ::arene::base::constraints<enable_if_t<Idx ==
sizeof...(LTypes)>> =
nullptr>
648constexpr auto elements_less(tuple<LTypes...>
const&, tuple<RTypes...>
const&)
noexcept ->
bool {
660template <std::size_t Idx,
class... LTypes,
class... RTypes,
661 ::arene::base::constraints<enable_if_t<Idx <
sizeof...(LTypes)>> =
nullptr>
662constexpr auto elements_less(tuple<LTypes...>
const& left, tuple<RTypes...>
const& right)
664 if (get<Idx>(left) < get<Idx>(right)) {
667 if (get<Idx>(right) < get<Idx>(left)) {
680template <
class... Types>
722 template <
template <
class...>
class Trait,
class... U>
723 static constexpr bool are_all_arguments_v{
751 (
sizeof...(
UTypes) != 0U) &&
756 tuple_detail::memberwise_forward_assign(*
this, other, type_index_sequence);
776 (
sizeof...(
UTypes) != 0U) &&
780 tuple_detail::memberwise_forward_assign(*
this, std::move(other), type_index_sequence);
799 (
sizeof...(
Types) == 2U) &&
804 tuple_detail::memberwise_forward_assign(*
this, other, type_index_sequence);
823 (
sizeof...(
Types) == 2U) &&
827 tuple_detail::memberwise_forward_assign(*
this, std::move(other), type_index_sequence);
874template <
class... LTypes,
class... RTypes>
879 static_assert(
sizeof...(LTypes) ==
sizeof...(RTypes),
"Only tuples of the same size can be compared");
889template <
class... LTypes,
class... RTypes>
892 return !(left == right);
901template <
class... LTypes,
class... RTypes>
906 static_assert(
sizeof...(LTypes) ==
sizeof...(RTypes),
"Only tuples of the same size can be compared");
916template <
class... LTypes,
class... RTypes>
919 return !(right < left);
928template <
class... LTypes,
class... RTypes>
940template <
class... LTypes,
class... RTypes>
943 return !(left < right);
determine if a trait predicate is true for all pairs of T... and U...
Definition tuple.hpp:364
handles reference binding when initializing a reference from a forwarded argument
Definition tuple.hpp:246
contains a single element of a tuple
Definition tuple.hpp:288
constexpr auto value() const &noexcept -> T const &
obtain the value contained in this leaf
Definition tuple.hpp:308
constexpr auto value() &noexcept -> T &
obtain the value contained in this leaf
Definition tuple.hpp:302
a heterogeneous, fixed-size collection of values
Definition tuple.hpp:681
auto operator=(tuple< UTypes... > const &other) noexcept(are_all_arguments_v< is_nothrow_assignable, UTypes const &... >) -> tuple &
copy-from-other-tuple assignment
Definition tuple.hpp:754
auto operator=(pair< U1, U2 > &&other) noexcept(are_all_arguments_v< is_nothrow_assignable, U1 &&, U2 && >) -> tuple &
move-assign-from-pair constructor
Definition tuple.hpp:826
auto operator=(tuple< UTypes... > &&other) noexcept(are_all_arguments_v< is_nothrow_assignable, UTypes &&... >) -> tuple &
move-from-other-tuple assignment
Definition tuple.hpp:779
auto operator=(pair< U1, U2 > const &other) noexcept(are_all_arguments_v< is_nothrow_assignable, U1 const &, U2 const & >) -> tuple &
copy-assign-from-pair constructor
Definition tuple.hpp:802
constexpr auto elements_less(tuple< LTypes... > const &, tuple< RTypes... > const &) noexcept -> bool
Check if the left tuple is less than the right tuple, starting at Idx and counting up.
Definition tuple.hpp:648
constexpr bool all_elements_nothrow_equality_comparable_v
A type trait to determine the noexcept specification of elementwise equality comparison.
Definition tuple.hpp:587
auto __get_tuple_impl() -> void=delete
poison pill declaration of __get_tuple_impl
constexpr bool all_elements_nothrow_less_than_comparable_v
A type trait to determine the noexcept specification of elementwise less-than comparison.
Definition tuple.hpp:600
void memberwise_forward_assign(Dest &dest, Source &&source, index_sequence< Indices... >)
helper used to implement move assignment
Definition tuple.hpp:338
bool
Check if element Idx and all subsequent elements of the two tuples are equal.
Definition tuple.hpp:635
void memberwise_swap(Lhs &lhs, Rhs &&rhs, index_sequence< Indices... >)
helper used to implement swap
Definition tuple.hpp:349
constexpr auto operator<=(tuple< LTypes... > const &left, tuple< RTypes... > const &right) noexcept(noexcept(right< left)) -> bool
Compare two tuples by doing a lexicographic comparison on their elements starting from 0.
Definition tuple.hpp:917
constexpr auto get(tuple< Types... > const &tup) noexcept -> tuple_element_t< I, tuple< Types... > > const &
access an element of a const lvalue reference to a tuple
Definition tuple.hpp:117
constexpr auto operator>=(tuple< LTypes... > const &left, tuple< RTypes... > const &right) noexcept(noexcept(left< right)) -> bool
Compare two tuples by doing a lexicographic comparison on their elements starting from 0.
Definition tuple.hpp:941
constexpr auto operator<(tuple< LTypes... > const &left, tuple< RTypes... > const &right) noexcept(noexcept(::std::tuple_detail::elements_less< 0UL >(left, right))) -> bool
Compare two tuples by doing a lexicographic comparison on their elements starting from 0.
Definition tuple.hpp:902
constexpr auto operator>(tuple< LTypes... > const &left, tuple< RTypes... > const &right) noexcept(noexcept(right< left)) -> bool
Compare two tuples by doing a lexicographic comparison on their elements starting from 0.
Definition tuple.hpp:929
constexpr auto tie(Types &... args) noexcept -> tuple< Types &... >
Constructs a tuple of references to the given arguments.
Definition tuple.hpp:81
constexpr auto get(tuple< Types... > const &&tup) noexcept -> tuple_element_t< I, tuple< Types... > > const &&
access an element of a const rvalue reference to a tuple
Definition tuple.hpp:153
constexpr auto operator!=(tuple< LTypes... > const &left, tuple< RTypes... > const &right) noexcept(noexcept(left==right)) -> bool
Compare two tuples by doing an equality comparison on their elements starting from 0.
Definition tuple.hpp:890
constexpr auto operator==(tuple< LTypes... > const &left, tuple< RTypes... > const &right) noexcept(noexcept(::std::tuple_detail::elements_equal< 0UL >(left, right))) -> bool
Compare two tuples by doing an equality comparison on their elements starting from 0.
Definition tuple.hpp:875
constexpr auto get(tuple< Types... > &&tup) noexcept -> tuple_element_t< I, tuple< Types... > > &&
access an element of a mutable rvalue reference to a tuple
Definition tuple.hpp:137
constexpr auto get(tuple< Types... > &tup) noexcept -> tuple_element_t< I, tuple< Types... > > &
access an element of a mutable lvalue reference to a tuple
Definition tuple.hpp:105
constexpr auto operator()(::arene::base::result< void, E > const &value) const noexcept(noexcept(hash< E >{}(std::declval< E const & >()))) -> std::size_t
Calculate the hash of a result.
Definition result.hpp:1827