tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
pair.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2
3#ifndef TETL_UTILITY_PAIR_HPP
4#define TETL_UTILITY_PAIR_HPP
5
21#include <etl/_utility/move.hpp>
22#include <etl/_utility/swap.hpp>
23
24namespace etl {
25
35template <typename T1, typename T2>
36struct pair {
37 using first_type = T1;
38 using second_type = T2;
39
48
51 T1 const& t1,
52 T2 const& t2
53 )
55 : first(t1)
57 {
58 }
59
61 template <typename U1 = T1, typename U2 = T2>
63 explicit(not is_convertible_v<U1&&, T1> || not is_convertible_v<U2&&, T2>) constexpr pair(U1&& x, U2&& y)
64 : first(etl::forward<U1>(x))
66 {
67 }
68
70 template <typename U1, typename U2>
74 )
75 : first(p.first)
77 {
78 }
79
81 template <typename U1, typename U2>
84 : first(etl::forward<U1>(p.first))
86 {
87 }
88
91 constexpr pair(pair const& p) = default;
92
95 constexpr pair(pair&& p) noexcept = default;
96
98 ~pair() noexcept = default;
99
100 constexpr auto operator=(pair const& p) -> pair& = default;
101
102 template <typename U1, typename U2>
103 constexpr auto operator=(pair<U1, U2> const& p)
104 -> pair& requires((is_assignable_v<first_type&, U1 const&> and is_assignable_v<second_type&, U2 const&>)) {
105 first = p.first;
106 second = p.second;
107 return *this;
108 }
109
110 constexpr auto operator=(pair&& p) noexcept
112 first = etl::move(p.first);
113 second = etl::move(p.second);
114 return *this;
115 }
116
117 template <typename U1, typename U2>
119 constexpr auto operator=(pair<U1, U2>&& p) -> pair&
120 {
121 first = etl::move(p.first);
122 second = etl::move(p.second);
123 return *this;
124 }
125
126 constexpr auto swap(pair& other)
128 {
129 using etl::swap;
130 swap(first, other.first);
131 swap(second, other.second);
132 }
133
136
137}; // namespace etl
138
139// One deduction guide is provided for pair to account for the edge
140// cases missed by the implicit deduction guides. In particular, non-copyable
141// arguments and array to pointer conversion.
142template <typename T1, typename T2>
144
145template <typename T, typename U>
146inline constexpr auto is_tuple_like<etl::pair<T, U>> = true;
147
149template <typename T1, typename T2>
150constexpr auto swap(pair<T1, T2>& lhs, pair<T1, T2>& rhs) noexcept(noexcept(lhs.swap(rhs))) -> void
151{
152 lhs.swap(rhs);
153}
154
163template <typename T1, typename T2>
164[[nodiscard]] constexpr auto make_pair(T1&& t, T2&& u) -> pair<decay_t<T1>, decay_t<T2>>
165{
166 return {etl::forward<T1>(t), etl::forward<T2>(u)};
167}
168
171template <typename T1, typename T2>
172constexpr auto operator==(pair<T1, T2> const& lhs, pair<T1, T2> const& rhs) -> bool
173{
174 return (lhs.first == rhs.first) and (lhs.second == rhs.second);
175}
176
180template <typename T1, typename T2>
181constexpr auto operator<(pair<T1, T2> const& lhs, pair<T1, T2> const& rhs) -> bool
182{
183 if (lhs.first < rhs.first) {
184 return true;
185 }
186 if (rhs.first < lhs.first) {
187 return false;
188 }
189 if (lhs.second < rhs.second) {
190 return true;
191 }
192 return false;
193}
194
198template <typename T1, typename T2>
199constexpr auto operator<=(pair<T1, T2> const& lhs, pair<T1, T2> const& rhs) -> bool
200{
201 return !(rhs < lhs);
202}
203
207template <typename T1, typename T2>
208constexpr auto operator>(pair<T1, T2> const& lhs, pair<T1, T2> const& rhs) -> bool
209{
210 return rhs < lhs;
211}
212
216template <typename T1, typename T2>
217constexpr auto operator>=(pair<T1, T2> const& lhs, pair<T1, T2> const& rhs) -> bool
218{
219 return !(lhs < rhs);
220}
221
225template <typename T1, typename T2>
226struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
227
231template <size_t I, typename T1, typename T2>
232struct tuple_element<I, pair<T1, T2>> {
233 static_assert(I < 2, "pair index out of range");
235};
236
242template <size_t I, typename T1, typename T2>
243constexpr auto get(pair<T1, T2>& p) noexcept -> tuple_element_t<I, pair<T1, T2>>&
244{
245 if constexpr (I == 0) {
246 return p.first;
247 } else {
248 return p.second;
249 }
250}
251
257template <size_t I, typename T1, typename T2>
258[[nodiscard]] constexpr auto get(pair<T1, T2> const& p) noexcept -> tuple_element_t<I, pair<T1, T2>> const&
259{
260 if constexpr (I == 0) {
261 return p.first;
262 } else {
263 return p.second;
264 }
265}
266
272template <size_t I, typename T1, typename T2>
273[[nodiscard]] constexpr auto get(pair<T1, T2>&& p) noexcept -> tuple_element_t<I, pair<T1, T2>>&&
274{
275 if constexpr (I == 0) {
276 return etl::move(p.first);
277 } else {
278 return etl::move(p.second);
279 }
280}
281
287template <size_t I, typename T1, typename T2>
288[[nodiscard]] constexpr auto get(pair<T1, T2> const&& p) noexcept -> tuple_element_t<I, pair<T1, T2>> const&&
289{
290 if constexpr (I == 0) {
291 return etl::move(p.first);
292 } else {
293 return etl::move(p.second);
294 }
295}
296
297template <
298 typename T1,
299 typename T2,
300 typename U1,
301 typename U2,
302 template <typename> typename TQual,
303 template <typename> typename UQual>
304 requires requires {
305 typename pair<common_reference_t<TQual<T1>, UQual<U1>>, common_reference_t<TQual<T2>, UQual<U2>>>;
306 }
307struct basic_common_reference<pair<T1, T2>, pair<U1, U2>, TQual, UQual> {
309};
310
311} // namespace etl
312
313#endif // TETL_UTILITY_PAIR_HPP
#define TETL_NO_UNIQUE_ADDRESS
Definition attributes.hpp:41
constexpr auto move(InputIt first, InputIt last, OutputIt destination) -> OutputIt
Moves the elements in the range [first, last), to another range beginning at destination,...
Definition move.hpp:26
Definition adjacent_find.hpp:8
constexpr bool is_copy_constructible_v
Definition is_copy_constructible.hpp:30
constexpr auto operator==(inplace_function< R(Args...), Capacity, Alignment > const &f, nullptr_t) noexcept -> bool
Compares a etl::inplace_function with a null pointer. Empty functions (that is, functions without a c...
Definition inplace_function.hpp:262
typename conditional< B, T, F >::type conditional_t
Definition conditional.hpp:21
pair(T1, T2) -> pair< T1, T2 >
constexpr bool is_constructible_v
Definition is_constructible.hpp:24
constexpr auto is_tuple_like
Definition is_tuple_like.hpp:9
typename etl::decay< T >::type decay_t
Definition decay.hpp:32
constexpr auto get(complex< X > &z) noexcept -> X &
Definition complex.hpp:92
constexpr bool is_default_constructible_v
Definition is_default_constructible.hpp:26
constexpr bool is_assignable_v
Definition is_assignable.hpp:20
constexpr auto is_implicit_default_constructible_v
Definition is_implicit_default_constructible.hpp:26
constexpr auto operator<(etl::reverse_iterator< Iter1 > const &lhs, etl::reverse_iterator< Iter2 > const &rhs) -> bool
Compares the underlying iterators. Inverse comparisons are applied in order to take into account that...
Definition reverse_iterator.hpp:167
constexpr auto make_pair(T1 &&t, T2 &&u) -> pair< decay_t< T1 >, decay_t< T2 > >
Creates a etl::pair object, deducing the target type from the types of arguments.
Definition pair.hpp:164
constexpr auto operator<=(etl::reverse_iterator< Iter1 > const &lhs, etl::reverse_iterator< Iter2 > const &rhs) -> bool
Compares the underlying iterators. Inverse comparisons are applied in order to take into account that...
Definition reverse_iterator.hpp:177
auto swap(inplace_function< R(Args...), Capacity, Alignment > &lhs, inplace_function< R(Args...), Capacity, Alignment > &rhs) noexcept -> void
Overloads the etl::swap algorithm for etl::inplace_function. Exchanges the state of lhs with that of ...
Definition inplace_function.hpp:249
constexpr auto operator>(etl::reverse_iterator< Iter1 > const &lhs, etl::reverse_iterator< Iter2 > const &rhs) -> bool
Compares the underlying iterators. Inverse comparisons are applied in order to take into account that...
Definition reverse_iterator.hpp:185
constexpr auto operator>=(etl::reverse_iterator< Iter1 > const &lhs, etl::reverse_iterator< Iter2 > const &rhs) -> bool
Compares the underlying iterators. Inverse comparisons are applied in order to take into account that...
Definition reverse_iterator.hpp:195
constexpr bool is_convertible_v
Definition is_convertible.hpp:46
typename tuple_element< I, T >::type tuple_element_t
Definition tuple_element.hpp:20
constexpr auto forward(remove_reference_t< T > &param) noexcept -> T &&
Forwards lvalues as either lvalues or as rvalues, depending on T. When t is a forwarding reference (a...
Definition forward.hpp:18
constexpr bool is_nothrow_swappable_v
Definition is_nothrow_swappable.hpp:19
constexpr bool is_move_assignable_v
Definition is_move_assignable.hpp:29
typename common_reference< T... >::type common_reference_t
Definition common_reference.hpp:38
pair< common_reference_t< TQual< T1 >, UQual< U1 > >, common_reference_t< TQual< T2 >, UQual< U2 > > > type
Definition pair.hpp:308
The class template basic_common_reference is a customization point that allows users to influence the...
Definition basic_common_reference.hpp:12
Definition integral_constant.hpp:9
etl::pair is a class template that provides a way to store two heterogeneous objects as a single unit...
Definition pair.hpp:36
constexpr auto operator=(pair &&p) noexcept -> pair &requires((is_move_assignable_v< first_type > and is_move_assignable_v< second_type >))
Definition pair.hpp:110
T1 first_type
Definition pair.hpp:37
constexpr auto swap(pair &other) noexcept(is_nothrow_swappable_v< first_type > and is_nothrow_swappable_v< second_type >) -> void
Definition pair.hpp:126
constexpr pair(pair const &p)=default
Copy constructor is defaulted, and is constexpr if copying of both elements satisfies the requirement...
T2 second_type
Definition pair.hpp:38
~pair() noexcept=default
Defaulted destructor.
constexpr pair(pair &&p) noexcept=default
Move constructor is defaulted, and is constexpr if moving of both elements satisfies the requirements...
conditional_t< I==0, T1, T2 > type
Definition pair.hpp:234
Provides compile-time indexed access to the type of the elements of the array using tuple-like interf...
Definition array.hpp:267
Definition tuple_size.hpp:15