libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
pair.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <cstddef>
14#include <utility>
15#include <tuple>
16#include <promeki/namespace.h>
17
18PROMEKI_NAMESPACE_BEGIN
19
40template <typename A, typename B> class Pair {
41 public:
43 using FirstType = A;
44
46 using SecondType = B;
47
49 Pair() = default;
50
68 template <typename A2, typename B2,
69 typename = std::enable_if_t<std::is_constructible_v<A, A2 &&> &&
70 std::is_constructible_v<B, B2 &&>>>
71 Pair(A2 &&a, B2 &&b) : d(std::forward<A2>(a), std::forward<B2>(b)) {}
72
77 Pair(const std::pair<A, B> &p) : d(p) {}
78
83 Pair(std::pair<A, B> &&p) : d(std::move(p)) {}
84
86 Pair(const Pair &other) = default;
87
89 Pair(Pair &&other) noexcept = default;
90
92 ~Pair() = default;
93
95 Pair &operator=(const Pair &other) = default;
96
98 Pair &operator=(Pair &&other) noexcept = default;
99
101 A &first() { return d.first; }
102
104 const A &first() const { return d.first; }
105
107 B &second() { return d.second; }
108
110 const B &second() const { return d.second; }
111
116 void setFirst(const A &a) { d.first = a; }
117
122 void setSecond(const B &b) { d.second = b; }
123
128 const std::pair<A, B> &toStdPair() const { return d; }
129
134 void swap(Pair &other) noexcept {
135 d.swap(other.d);
136 return;
137 }
138
145 static Pair make(A a, B b) { return Pair(std::move(a), std::move(b)); }
146
148 friend bool operator==(const Pair &lhs, const Pair &rhs) { return lhs.d == rhs.d; }
149
151 friend bool operator!=(const Pair &lhs, const Pair &rhs) { return lhs.d != rhs.d; }
152
154 friend bool operator<(const Pair &lhs, const Pair &rhs) { return lhs.d < rhs.d; }
155
161 template <std::size_t I> auto &get() & {
162 if constexpr (I == 0)
163 return d.first;
164 else
165 return d.second;
166 }
167
169 template <std::size_t I> const auto &get() const & {
170 if constexpr (I == 0)
171 return d.first;
172 else
173 return d.second;
174 }
175
177 template <std::size_t I> auto &&get() && {
178 if constexpr (I == 0)
179 return std::move(d.first);
180 else
181 return std::move(d.second);
182 }
183
184 private:
185 std::pair<A, B> d;
186};
187
188PROMEKI_NAMESPACE_END
189
190// Structured bindings support
191namespace std {
192 template <typename A, typename B>
193 struct tuple_size<promeki::Pair<A, B>> : std::integral_constant<std::size_t, 2> {};
194
195 template <typename A, typename B> struct tuple_element<0, promeki::Pair<A, B>> {
196 using type = A;
197 };
198
199 template <typename A, typename B> struct tuple_element<1, promeki::Pair<A, B>> {
200 using type = B;
201 };
202} // namespace std
203
204#endif // PROMEKI_ENABLE_CORE