1#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
2#define ENTT_CORE_COMPRESSED_PAIR_HPP
9#include "type_traits.hpp"
16template<
typename Type, std::
size_t,
typename =
void>
17struct compressed_pair_element {
18 using reference = Type &;
19 using const_reference =
const Type &;
21 template<
typename Dummy = Type,
typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
23 constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
25 template<
typename Arg,
typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
26 constexpr compressed_pair_element(Arg &&arg)
noexcept(std::is_nothrow_constructible_v<Type, Arg>)
27 : value{std::forward<Arg>(arg)} {}
29 template<
typename... Args, std::size_t... Index>
30 constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
noexcept(std::is_nothrow_constructible_v<Type, Args...>)
31 : value{std::forward<Args>(std::
get<Index>(args))...} {}
33 [[nodiscard]]
constexpr reference
get() noexcept {
37 [[nodiscard]]
constexpr const_reference
get() const noexcept {
45template<
typename Type, std::
size_t Tag>
46struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
47 using reference = Type &;
48 using const_reference =
const Type &;
49 using base_type = Type;
51 template<
typename Dummy = Type,
typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
52 constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
55 template<
typename Arg,
typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
56 constexpr compressed_pair_element(Arg &&arg)
noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
57 : base_type{std::forward<Arg>(arg)} {}
59 template<
typename... Args, std::size_t... Index>
60 constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>)
noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
61 : base_type{std::forward<Args>(std::
get<Index>(args))...} {}
63 [[nodiscard]]
constexpr reference
get() noexcept {
67 [[nodiscard]]
constexpr const_reference
get() const noexcept {
84template<
typename First,
typename Second>
86 : internal::compressed_pair_element<First, 0u>,
87 internal::compressed_pair_element<Second, 1u> {
88 using first_base = internal::compressed_pair_element<First, 0u>;
89 using second_base = internal::compressed_pair_element<Second, 1u>;
105 template<
bool Dummy = true,
typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
129 template<
typename Arg,
typename Other>
130 constexpr compressed_pair(
Arg &&arg,
Other &&
other)
noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
141 template<
typename...
Args,
typename...
Other>
142 constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...>
args, std::tuple<Other...>
other)
noexcept(std::is_nothrow_constructible_v<first_base,
Args...> && std::is_nothrow_constructible_v<second_base,
Other...>)
144 second_base{std::move(
other), std::index_sequence_for<
Other...>{}} {}
168 return static_cast<first_base &
>(*this).get();
173 return static_cast<const first_base &
>(*this).get();
181 return static_cast<second_base &
>(*this).get();
186 return static_cast<const second_base &
>(*this).get();
205 template<std::
size_t Index>
207 if constexpr(
Index == 0
u) {
210 static_assert(
Index == 1u,
"Index out of bounds");
216 template<std::
size_t Index>
218 if constexpr(
Index == 0
u) {
221 static_assert(
Index == 1u,
"Index out of bounds");
232template<
typename Type,
typename Other>
242template<
typename First,
typename Second>
256template<
typename First,
typename Second>
257struct tuple_size<
entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
265template<
size_t Index,
typename First,
typename Second>
266struct tuple_element<Index,
entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
267 static_assert(Index < 2u,
"Index out of bounds");
constexpr second_type & second() noexcept
Returns the second element that a pair stores.
constexpr void swap(compressed_pair &other) noexcept
Swaps two compressed pair objects.
constexpr const first_type & first() const noexcept
Returns the first element that a pair stores.
constexpr compressed_pair(compressed_pair &&other) noexcept=default
Move constructor.
constexpr compressed_pair(const compressed_pair &other)=default
Copy constructor.
constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v< first_base, Arg > &&std::is_nothrow_constructible_v< second_base, Other >)
Constructs a pair from its values.
constexpr decltype(auto) get() const noexcept
Extracts an element from the compressed pair.
constexpr decltype(auto) get() noexcept
Extracts an element from the compressed pair.
constexpr first_type & first() noexcept
Returns the first element that a pair stores.
constexpr compressed_pair(std::piecewise_construct_t, std::tuple< Args... > args, std::tuple< Other... > other) noexcept(std::is_nothrow_constructible_v< first_base, Args... > &&std::is_nothrow_constructible_v< second_base, Other... >)
Constructs a pair by forwarding the arguments to its parts.
First first_type
The type of the first element that the pair stores.
constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v< first_base > &&std::is_nothrow_default_constructible_v< second_base >)
Default constructor, conditionally enabled.
constexpr compressed_pair & operator=(const compressed_pair &other)=default
Copy assignment operator.
~compressed_pair()=default
Default destructor.
constexpr const second_type & second() const noexcept
Returns the second element that a pair stores.
Second second_type
The type of the second element that the pair stores.
constexpr compressed_pair & operator=(compressed_pair &&other) noexcept=default
Move assignment operator.
constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args)
Uses-allocator construction utility (waiting for C++20).
constexpr void swap(compressed_pair< First, Second > &lhs, compressed_pair< First, Second > &rhs)
Swaps two compressed pair objects.
constexpr get_t< Type... > get
Variable template for lists of observed elements.