1 #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
2 #define ENTT_CORE_COMPRESSED_PAIR_HPP
8 #include "../config/config.h"
9 #include "type_traits.hpp"
20 template<
typename Type, std::
size_t,
typename =
void>
21 struct compressed_pair_element {
22 using reference = Type &;
23 using const_reference =
const Type &;
25 template<
bool Dummy = true,
typename = std::enable_if_t<Dummy && std::is_default_constructible_v<Type>>>
26 compressed_pair_element()
29 template<
typename Args,
typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
30 compressed_pair_element(Args &&args)
31 : value{std::forward<Args>(args)} {}
33 template<
typename... Args, std::size_t... Index>
34 compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
35 : value{std::forward<Args>(std::
get<Index>(args))...} {}
37 [[nodiscard]] reference
get() ENTT_NOEXCEPT {
41 [[nodiscard]] const_reference
get() const ENTT_NOEXCEPT {
49 template<
typename Type, std::
size_t Tag>
50 struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
51 using reference = Type &;
52 using const_reference =
const Type &;
53 using base_type = Type;
55 template<
bool Dummy = true,
typename = std::enable_if_t<Dummy && std::is_default_constructible_v<base_type>>>
56 compressed_pair_element()
59 template<
typename Args,
typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Args>>, compressed_pair_element>>>
60 compressed_pair_element(Args &&args)
61 : base_type{std::forward<Args>(args)} {}
63 template<
typename... Args, std::size_t... Index>
64 compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
65 : base_type{std::forward<Args>(std::
get<Index>(args))...} {}
67 [[nodiscard]] reference
get() ENTT_NOEXCEPT {
71 [[nodiscard]] const_reference
get() const ENTT_NOEXCEPT {
92 template<
typename First,
typename Second>
94 : internal::compressed_pair_element<First, 0u>,
95 internal::compressed_pair_element<Second, 1u> {
96 using first_base = internal::compressed_pair_element<First, 0u>;
97 using second_base = internal::compressed_pair_element<Second, 1u>;
113 template<
bool Dummy = true,
typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
137 template<
typename Arg,
typename Other>
139 : first_base{std::forward<Arg>(arg)},
140 second_base{std::forward<Other>(other)} {}
149 template<
typename... Args,
typename... Other>
150 constexpr
compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other)
151 : first_base{std::move(args), std::index_sequence_for<Args...>{}},
152 second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
173 return static_cast<first_base &
>(*this).get();
178 return static_cast<const first_base &
>(*this).get();
186 return static_cast<second_base &
>(*this).get();
191 return static_cast<const second_base &
>(*this).get();
210 template<std::
size_t Index>
211 decltype(
auto)
get() ENTT_NOEXCEPT {
212 if constexpr(Index == 0u) {
215 static_assert(Index == 1u,
"Index out of bounds");
221 template<std::
size_t Index>
222 decltype(
auto)
get() const ENTT_NOEXCEPT {
223 if constexpr(Index == 0u) {
226 static_assert(Index == 1u,
"Index out of bounds");
237 template<
typename Type,
typename Other>
247 template<
typename First,
typename Second>
255 #if !defined __clang_major__ || __clang_major__ > 6
263 template<
typename First,
typename Second>
264 struct tuple_size<
entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
272 template<
size_t Index,
typename First,
typename Second>
273 struct tuple_element<Index,
entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
274 static_assert(Index < 2u,
"Index out of bounds");
void swap(compressed_pair &other)
Swaps two compressed pair objects.
constexpr compressed_pair(const compressed_pair &other)=default
Copy constructor.
const second_type & second() const
Returns the second element that a pair stores.
First first_type
The type of the first element that the pair stores.
constexpr compressed_pair(Arg &&arg, Other &&other)
Constructs a pair from its values.
constexpr compressed_pair & operator=(const compressed_pair &other)=default
Copy assignment operator.
second_type & second()
Returns the second element that a pair stores.
first_type & first()
Returns the first element that a pair stores.
constexpr compressed_pair(compressed_pair &&other)=default
Move constructor.
const first_type & first() const
Returns the first element that a pair stores.
constexpr compressed_pair()
Default constructor, conditionally enabled.
constexpr compressed_pair & operator=(compressed_pair &&other)=default
Move assignment operator.
Second second_type
The type of the second element that the pair stores.
constexpr compressed_pair(std::piecewise_construct_t, std::tuple< Args... > args, std::tuple< Other... > other)
Constructs a pair by forwarding the arguments to its parts.
constexpr get_t< Type... > get
Variable template for lists of observed components.
void swap(compressed_pair< First, Second > &lhs, compressed_pair< First, Second > &rhs)
Swaps two compressed pair objects.