EnTT 4.0.0
Loading...
Searching...
No Matches
compressed_pair.hpp
1#ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
2#define ENTT_CORE_COMPRESSED_PAIR_HPP
3
4#include "../stl/concepts.hpp"
5#include "../stl/cstddef.hpp"
6#include "../stl/tuple.hpp"
7#include "../stl/type_traits.hpp"
8#include "../stl/utility.hpp"
9#include "fwd.hpp"
10#include "type_traits.hpp"
11
12namespace entt {
13
15namespace internal {
16
17template<typename Type, stl::size_t>
18struct compressed_pair_element {
19 using reference = Type &;
20 using const_reference = const Type &;
21
22 // NOLINTNEXTLINE(modernize-use-equals-default)
23 constexpr compressed_pair_element() noexcept(stl::is_nothrow_default_constructible_v<Type>)
24 requires stl::default_initializable<Type> {}
25
26 template<typename Arg>
27 constexpr compressed_pair_element(Arg &&arg) noexcept(stl::is_nothrow_constructible_v<Type, Arg>)
28 requires (!stl::same_as<stl::remove_cvref_t<Arg>, compressed_pair_element>)
29 : value{stl::forward<Arg>(arg)} {}
30
31 template<typename... Args, stl::size_t... Index>
32 constexpr compressed_pair_element(stl::tuple<Args...> args, stl::index_sequence<Index...>) noexcept(stl::is_nothrow_constructible_v<Type, Args...>)
33 : value{stl::forward<Args>(stl::get<Index>(args))...} {}
34
35 [[nodiscard]] constexpr reference get() noexcept {
36 return value;
37 }
38
39 [[nodiscard]] constexpr const_reference get() const noexcept {
40 return value;
41 }
42
43private:
44 Type value{};
45};
46
47template<typename Type, stl::size_t Tag>
48requires is_ebco_eligible_v<Type>
49struct compressed_pair_element<Type, Tag>: Type {
50 using reference = Type &;
51 using const_reference = const Type &;
52 using base_type = Type;
53
54 constexpr compressed_pair_element() noexcept(stl::is_nothrow_default_constructible_v<base_type>)
55 requires stl::default_initializable<Type>
56 : base_type{} {}
57
58 template<typename Arg>
59 constexpr compressed_pair_element(Arg &&arg) noexcept(stl::is_nothrow_constructible_v<base_type, Arg>)
60 requires (!stl::same_as<stl::remove_cvref_t<Arg>, compressed_pair_element>)
61 : base_type{stl::forward<Arg>(arg)} {}
62
63 template<typename... Args, stl::size_t... Index>
64 constexpr compressed_pair_element(stl::tuple<Args...> args, stl::index_sequence<Index...>) noexcept(stl::is_nothrow_constructible_v<base_type, Args...>)
65 : base_type{stl::forward<Args>(stl::get<Index>(args))...} {}
66
67 [[nodiscard]] constexpr reference get() noexcept {
68 return *this;
69 }
70
71 [[nodiscard]] constexpr const_reference get() const noexcept {
72 return *this;
73 }
74};
75
76} // namespace internal
78
88template<typename First, typename Second>
89class compressed_pair final
90 : internal::compressed_pair_element<First, 0u>,
91 internal::compressed_pair_element<Second, 1u> {
92 using first_base = internal::compressed_pair_element<First, 0u>;
93 using second_base = internal::compressed_pair_element<Second, 1u>;
94
95public:
97 using first_type = First;
99 using second_type = Second;
100
107 constexpr compressed_pair() noexcept(stl::is_nothrow_default_constructible_v<first_base> && stl::is_nothrow_default_constructible_v<second_base>)
108 requires stl::default_initializable<first_type> && stl::default_initializable<second_type>
109 : first_base{},
110 second_base{} {}
111
116 constexpr compressed_pair(const compressed_pair &other) = default;
117
122 constexpr compressed_pair(compressed_pair &&other) noexcept = default;
123
131 template<typename Arg, typename Other>
132 constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(stl::is_nothrow_constructible_v<first_base, Arg> && stl::is_nothrow_constructible_v<second_base, Other>)
133 : first_base{stl::forward<Arg>(arg)},
134 second_base{stl::forward<Other>(other)} {}
135
143 template<typename... Args, typename... Other>
144 constexpr compressed_pair(stl::piecewise_construct_t, stl::tuple<Args...> args, stl::tuple<Other...> other) noexcept(stl::is_nothrow_constructible_v<first_base, Args...> && stl::is_nothrow_constructible_v<second_base, Other...>)
145 : first_base{stl::move(args), stl::index_sequence_for<Args...>{}},
146 second_base{stl::move(other), stl::index_sequence_for<Other...>{}} {}
147
149 ~compressed_pair() = default;
150
156 constexpr compressed_pair &operator=(const compressed_pair &other) = default;
157
163 constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
164
169 [[nodiscard]] constexpr first_type &first() noexcept {
170 return static_cast<first_base &>(*this).get();
171 }
172
174 [[nodiscard]] constexpr const first_type &first() const noexcept {
175 return static_cast<const first_base &>(*this).get();
176 }
177
182 [[nodiscard]] constexpr second_type &second() noexcept {
183 return static_cast<second_base &>(*this).get();
184 }
185
187 [[nodiscard]] constexpr const second_type &second() const noexcept {
188 return static_cast<const second_base &>(*this).get();
189 }
190
195 constexpr void swap(compressed_pair &other) noexcept {
196 using stl::swap;
197 swap(first(), other.first());
198 swap(second(), other.second());
199 }
200
207 template<stl::size_t Index>
208 requires (Index <= 1u)
209 [[nodiscard]] constexpr decltype(auto) get() noexcept {
210 if constexpr(Index == 0u) {
211 return first();
212 } else {
213 return second();
214 }
215 }
216
218 template<stl::size_t Index>
219 requires (Index <= 1u)
220 [[nodiscard]] constexpr decltype(auto) get() const noexcept {
221 if constexpr(Index == 0u) {
222 return first();
223 } else {
224 return second();
225 }
226 }
227};
228
234template<typename Type, typename Other>
235compressed_pair(Type &&, Other &&) -> compressed_pair<stl::decay_t<Type>, stl::decay_t<Other>>;
236
244template<typename First, typename Second>
246 lhs.swap(rhs);
247}
248
249} // namespace entt
250
252#include <utility>
253
254namespace std {
255
256template<typename First, typename Second>
257struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<entt::stl::size_t, 2u> {};
258
259template<entt::stl::size_t Index, typename First, typename Second>
260requires (Index <= 1u)
261struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {};
262
263} // namespace std
265
266#endif
A compressed pair.
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 decltype(auto) get() noexcept
Extracts an element from the compressed pair.
constexpr compressed_pair(const compressed_pair &other)=default
Copy constructor.
constexpr compressed_pair() noexcept(stl::is_nothrow_default_constructible_v< first_base > &&stl::is_nothrow_default_constructible_v< second_base >)
Default constructor, conditionally enabled.
constexpr compressed_pair(stl::piecewise_construct_t, stl::tuple< Args... > args, stl::tuple< Other... > other) noexcept(stl::is_nothrow_constructible_v< first_base, Args... > &&stl::is_nothrow_constructible_v< second_base, Other... >)
Constructs a pair by forwarding the arguments to its parts.
constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(stl::is_nothrow_constructible_v< first_base, Arg > &&stl::is_nothrow_constructible_v< second_base, Other >)
Constructs a pair from its values.
constexpr first_type & first() noexcept
Returns the first element that a pair stores.
First first_type
The type of the first element that the pair stores.
constexpr compressed_pair & operator=(const compressed_pair &other)=default
Copy assignment operator.
constexpr decltype(auto) get() const noexcept
Extracts an element from the compressed pair.
~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.
Custom EnTT namespace for the standard template library.
Definition entt.hpp:5
EnTT default namespace.
Definition dense_map.hpp:25
constexpr void swap(compressed_pair< First, Second > &lhs, compressed_pair< First, Second > &rhs) noexcept
Swaps two compressed pair objects.
constexpr get_t< Type... > get
Variable template for lists of observed elements.
Definition fwd.hpp:168
stl::integral_constant< decltype(Value), Value > integral_constant
Wraps a static constant.
compressed_pair(Type &&, Other &&) -> compressed_pair< stl::decay_t< Type >, stl::decay_t< Other > >
Deduction guide.