SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
common_pair.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, Knut Reinert & MPI für molekulare Genetik
4// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6// -----------------------------------------------------------------------------------------------------
7
13#pragma once
14
15#include <utility>
16
18
19namespace seqan3
20{
21
26template <class T1, class T2>
27struct common_pair : public std::pair<T1, T2>
28{
29private:
32
33public:
37 common_pair() = default;
38 common_pair(common_pair const &) = default;
39 common_pair & operator=(common_pair const &) = default;
40 ~common_pair() = default;
42
43 using base_t::first;
44 using base_t::second;
45
50 template <class U1, class U2>
51 requires (std::is_constructible_v<T1, U1 &> && std::is_constructible_v<T2, U2 &>)
52 constexpr common_pair(U1 & first, U2 & second) : base_t(first, second)
53 {}
54
55 template <class U1, class U2>
56 requires (std::is_constructible_v<T1, U1 const> && std::is_constructible_v<T2, U2 const>)
57 constexpr common_pair(U1 const & first, U2 const & second) : base_t(first, second)
58 {}
59
60 template <class U1, class U2>
61 requires (std::is_constructible_v<T1, U1> && std::is_constructible_v<T2, U2>)
62 constexpr common_pair(U1 && first, U2 && second) : base_t(std::forward<U1>(first), std::forward<U2>(second))
63 {}
64
65 template <class U1, class U2>
66 requires (std::is_constructible_v<T1, U1 const> && std::is_constructible_v<T2, U2 const>)
67 constexpr common_pair(U1 const && first, U2 const && second) :
68 base_t(std::forward<U1 const>(first), std::forward<U2 const>(second))
69 {}
72
77 template <class U1, class U2>
78 requires (std::is_constructible_v<T1, U1 &> && std::is_constructible_v<T2, U2 &>)
79 constexpr common_pair(common_pair<U1, U2> & other) : base_t(other.first, other.second)
80 {}
81
82 template <class U1, class U2>
83 requires (std::is_constructible_v<T1, U1 const> && std::is_constructible_v<T2, U2 const>)
84 constexpr common_pair(common_pair<U1, U2> const & other) : base_t(other.first, other.second)
85 {}
86
87 template <class U1, class U2>
88 requires (std::is_constructible_v<T1, U1> && std::is_constructible_v<T2, U2>)
89 constexpr common_pair(common_pair<U1, U2> && other) :
90 base_t(std::forward<U1>(other.first), std::forward<U2>(other.second))
91 {}
92
93 template <class U1, class U2>
94 requires (std::is_constructible_v<T1, U1 const> && std::is_constructible_v<T2, U2 const>)
95 constexpr common_pair(common_pair<U1, U2> const && other) :
96 base_t(std::forward<U1 const>(other.first), std::forward<U2 const>(other.second))
97 {}
100
105 template <class U1, class U2>
106 requires (std::is_constructible_v<T1, U1 &> && std::is_constructible_v<T2, U2 &>)
107 constexpr common_pair(std::pair<U1, U2> & other) : base_t(other.first, other.second)
108 {}
109
110 template <class U1, class U2>
111 requires (std::is_constructible_v<T1, U1 const> && std::is_constructible_v<T2, U2 const>)
112 constexpr common_pair(std::pair<U1, U2> const & other) : base_t(other.first, other.second)
113 {}
114
115 template <class U1, class U2>
116 requires (std::is_constructible_v<T1, U1> && std::is_constructible_v<T2, U2>)
117 constexpr common_pair(std::pair<U1, U2> && other) :
118 base_t(std::forward<U1>(other.first), std::forward<U2>(other.second))
119 {}
120
121 template <class U1, class U2>
122 requires (std::is_constructible_v<T1, U1 const> && std::is_constructible_v<T2, U2 const>)
123 constexpr common_pair(std::pair<U1, U2> const && other) :
124 base_t(std::forward<U1 const>(other.first), std::forward<U2 const>(other.second))
125 {}
128
133 template <class U1, class U2>
134 requires (std::is_assignable_v<T1, U1 &> && std::is_assignable_v<T2, U2 &>)
135 constexpr common_pair & operator=(common_pair<U1, U2> & other)
136 {
137 first = other.first;
138 second = other.second;
139 return *this;
140 }
141
142 template <class U1, class U2>
143 requires (std::is_assignable_v<T1, U1 const> && std::is_assignable_v<T2, U2 const>)
144 constexpr common_pair & operator=(common_pair<U1, U2> const & other)
145 {
146 first = other.first;
147 second = other.second;
148 return *this;
149 }
150
151 template <class U1, class U2>
152 requires (std::is_assignable_v<T1, U1> && std::is_assignable_v<T2, U2>)
153 constexpr common_pair & operator=(common_pair<U1, U2> && other)
154 {
155 first = std::move(other.first);
156 second = std::move(other.second);
157 return *this;
158 }
159
160 template <class U1, class U2>
161 requires (std::is_assignable_v<T1, U1 const> && std::is_assignable_v<T2, U2 const>)
162 constexpr common_pair & operator=(common_pair<U1, U2> const && other)
163 {
164 first = std::move(other.first);
165 second = std::move(other.second);
166 return *this;
167 }
168
169 template <class U1, class U2>
170 requires (std::is_assignable_v<T1 const, U1 &> && std::is_assignable_v<T2 const, U2 &>)
171 constexpr common_pair const & operator=(common_pair<U1, U2> & other) const
172 {
173 first = other.first;
174 second = other.second;
175 return *this;
176 }
177
178 template <class U1, class U2>
179 requires (std::is_assignable_v<T1 const, U1 const> && std::is_assignable_v<T2 const, U2 const>)
180 constexpr common_pair const & operator=(common_pair<U1, U2> const & other) const
181 {
182 first = other.first;
183 second = other.second;
184 return *this;
185 }
186
187 template <class U1, class U2>
188 requires (std::is_assignable_v<T1 const, U1> && std::is_assignable_v<T2 const, U2>)
189 constexpr common_pair const & operator=(common_pair<U1, U2> && other) const
190 {
191 first = std::move(other.first);
192 second = std::move(other.second);
193 return *this;
194 }
195
196 template <class U1, class U2>
197 requires (std::is_assignable_v<T1 const, U1 const> && std::is_assignable_v<T2 const, U2 const>)
198 constexpr common_pair const & operator=(common_pair<U1, U2> const && other) const
199 {
200 first = std::move(other.first);
201 second = std::move(other.second);
202 return *this;
203 }
206
211 template <class U1, class U2>
212 requires (std::is_assignable_v<T1, U1 &> && std::is_assignable_v<T2, U2 &>)
213 constexpr common_pair & operator=(std::pair<U1, U2> & other)
214 {
215 first = other.first;
216 second = other.second;
217 return *this;
218 }
219
220 template <class U1, class U2>
221 requires (std::is_assignable_v<T1, U1 const> && std::is_assignable_v<T2, U2 const>)
222 constexpr common_pair & operator=(std::pair<U1, U2> const & other)
223 {
224 first = other.first;
225 second = other.second;
226 return *this;
227 }
228
229 template <class U1, class U2>
230 requires (std::is_assignable_v<T1, U1> && std::is_assignable_v<T2, U2>)
231 constexpr common_pair & operator=(std::pair<U1, U2> && other)
232 {
233 first = std::move(other.first);
234 second = std::move(other.second);
235 return *this;
236 }
237
238 template <class U1, class U2>
239 requires (std::is_assignable_v<T1, U1 const> && std::is_assignable_v<T2, U2 const>)
240 constexpr common_pair & operator=(std::pair<U1, U2> const && other)
241 {
242 first = std::move(other.first);
243 second = std::move(other.second);
244 return *this;
245 }
246
247 template <class U1, class U2>
248 requires (std::is_assignable_v<T1 const, U1 &> && std::is_assignable_v<T2 const, U2 &>)
249 constexpr common_pair const & operator=(std::pair<U1, U2> & other) const
250 {
251 first = other.first;
252 second = other.second;
253 return *this;
254 }
255
256 template <class U1, class U2>
257 requires (std::is_assignable_v<T1 const, U1 const> && std::is_assignable_v<T2 const, U2 const>)
258 constexpr common_pair const & operator=(std::pair<U1, U2> const & other) const
259 {
260 first = other.first;
261 second = other.second;
262 return *this;
263 }
264
265 template <class U1, class U2>
266 requires (std::is_assignable_v<T1 const, U1> && std::is_assignable_v<T2 const, U2>)
267 constexpr common_pair const & operator=(std::pair<U1, U2> && other) const
268 {
269 first = std::move(other.first);
270 second = std::move(other.second);
271 return *this;
272 }
273
274 template <class U1, class U2>
275 requires (std::is_assignable_v<T1 const, U1 const> && std::is_assignable_v<T2 const, U2 const>)
276 constexpr common_pair const & operator=(std::pair<U1, U2> const && other) const
277 {
278 first = std::move(other.first);
279 second = std::move(other.second);
280 return *this;
281 }
284
289 template <class U1, class U2>
290 requires (std::is_constructible_v<U1, T1 &> && std::is_constructible_v<U2, T2 &>)
291 operator std::pair<U1, U2>() &
292 {
293 return {first, second};
294 }
295
296 template <class U1, class U2>
297 requires (std::is_constructible_v<U1, T1 const> && std::is_constructible_v<U2, T2 const>)
298 operator std::pair<U1, U2>() const &
299 {
300 return {first, second};
301 }
302
303 template <class U1, class U2>
304 requires (std::is_constructible_v<U1, T1> && std::is_constructible_v<U2, T2>)
305 operator std::pair<U1, U2>() &&
306 {
307 return {std::move(first), std::move(second)};
308 }
309
310 template <class U1, class U2>
311 requires (std::is_constructible_v<U1, T1 const> && std::is_constructible_v<U2, T2 const>)
312 operator std::pair<U1, U2>() const &&
313 {
314 return {std::move(first), std::move(second)};
315 }
318
329 template <class U1, class U2>
330 requires (std::equality_comparable_with<T1, U1> && std::equality_comparable_with<T2, U2>)
331 constexpr friend bool operator==(common_pair const & lhs, common_pair<U1, U2> const & rhs)
332 {
333 return lhs.first == rhs.first && lhs.second == rhs.second;
334 }
335
343 template <class U1, class U2>
344 requires (std::equality_comparable_with<T1, U1> && std::equality_comparable_with<T2, U2>)
345 constexpr friend bool operator!=(common_pair const & lhs, common_pair<U1, U2> const & rhs)
346 {
347 return lhs.first != rhs.first && lhs.second != rhs.second;
348 }
349
357 template <class U1, class U2>
358 requires (std::totally_ordered_with<T1, U1> && std::totally_ordered_with<T2, U2>)
359 constexpr friend bool operator<(common_pair const & lhs, common_pair<U1, U2> const & rhs)
360 {
361 return lhs.first < rhs.first && lhs.second < rhs.second;
362 }
363
371 template <class U1, class U2>
372 requires (std::totally_ordered_with<T1, U1> && std::totally_ordered_with<T2, U2>)
373 constexpr friend bool operator<=(common_pair const & lhs, common_pair<U1, U2> const & rhs)
374 {
375 return lhs.first <= rhs.first && lhs.second <= rhs.second;
376 }
377
385 template <class U1, class U2>
386 requires (std::totally_ordered_with<T1, U1> && std::totally_ordered_with<T2, U2>)
387 constexpr friend bool operator>(common_pair const & lhs, common_pair<U1, U2> const & rhs)
388 {
389 return lhs.first > rhs.first && lhs.second > rhs.second;
390 }
391
399 template <class U1, class U2>
400 requires (std::totally_ordered_with<T1, U1> && std::totally_ordered_with<T2, U2>)
401 constexpr friend bool operator>=(common_pair const & lhs, common_pair<U1, U2> const & rhs)
402 {
403 return lhs.first >= rhs.first && lhs.second >= rhs.second;
404 }
405
406#ifdef __cpp_lib_three_way_comparison
415 template <class U1, class U2>
416 requires (std::three_way_comparable_with<T1, U1> && std::three_way_comparable_with<T2, U2>)
417 constexpr friend std::common_comparison_category_t<std::compare_three_way_result_t<U1, T1>,
418 std::compare_three_way_result_t<U2, T2>>
419 operator<=>(common_pair const & lhs, common_pair<U1, U2> const & rhs)
420 {
421 if (auto cmp = lhs.first <=> rhs.first; cmp != 0)
422 return cmp;
423 return lhs.second <=> rhs.second;
424 }
425#endif // __cpp_lib_three_way_comparison
427
438 template <class U1, class U2>
439 requires (std::equality_comparable_with<T1, U1> && std::equality_comparable_with<T2, U2>)
440 constexpr friend bool operator==(common_pair const & lhs, std::pair<U1, U2> const & rhs)
441 {
442 return lhs.first == rhs.first && lhs.second == rhs.second;
443 }
444
452 template <class U1, class U2>
453 requires (std::equality_comparable_with<T1, U1> && std::equality_comparable_with<T2, U2>)
454 constexpr friend bool operator!=(common_pair const & lhs, std::pair<U1, U2> const & rhs)
455 {
456 return lhs.first != rhs.first && lhs.second != rhs.second;
457 }
458
466 template <class U1, class U2>
467 requires (std::totally_ordered_with<T1, U1> && std::totally_ordered_with<T2, U2>)
468 constexpr friend bool operator<(common_pair const & lhs, std::pair<U1, U2> const & rhs)
469 {
470 return lhs.first < rhs.first && lhs.second < rhs.second;
471 }
472
480 template <class U1, class U2>
481 requires (std::totally_ordered_with<T1, U1> && std::totally_ordered_with<T2, U2>)
482 constexpr friend bool operator<=(common_pair const & lhs, std::pair<U1, U2> const & rhs)
483 {
484 return lhs.first <= rhs.first && lhs.second <= rhs.second;
485 }
486
494 template <class U1, class U2>
495 requires (std::totally_ordered_with<T1, U1> && std::totally_ordered_with<T2, U2>)
496 constexpr friend bool operator>(common_pair const & lhs, std::pair<U1, U2> const & rhs)
497 {
498 return lhs.first > rhs.first && lhs.second > rhs.second;
499 }
500
508 template <class U1, class U2>
509 requires (std::totally_ordered_with<T1, U1> && std::totally_ordered_with<T2, U2>)
510 constexpr friend bool operator>=(common_pair const & lhs, std::pair<U1, U2> const & rhs)
511 {
512 return lhs.first >= rhs.first && lhs.second >= rhs.second;
513 }
514
515#ifdef __cpp_lib_three_way_comparison
524 template <class U1, class U2>
525 requires (std::three_way_comparable_with<T1, U1> && std::three_way_comparable_with<T2, U2>)
526 constexpr friend std::common_comparison_category_t<std::compare_three_way_result_t<U1, T1>,
527 std::compare_three_way_result_t<U2, T2>>
528 operator<=>(common_pair const & lhs, std::pair<U1, U2> const & rhs)
529 {
530 if (auto cmp = lhs.first <=> rhs.first; cmp != 0)
531 return cmp;
532 return lhs.second <=> rhs.second;
533 }
534#endif // __cpp_lib_three_way_comparison
536};
537
539template <class T1, class T2>
541
542} // namespace seqan3
543
545namespace std
546{
547
548template <class T1, class T2>
549struct tuple_size<seqan3::common_pair<T1, T2>> : public tuple_size<std::pair<T1, T2>>
550{};
551
552template <size_t index, class T1, class T2>
553struct tuple_element<index, seqan3::common_pair<T1, T2>> : public tuple_element<index, std::pair<T1, T2>>
554{};
555
556template <class T1, class T2, class U1, class U2>
558struct common_type<seqan3::common_pair<T1, T2>, seqan3::common_pair<U1, U2>>
559{
561};
562
563template <class T1, class T2, class U1, class U2>
565struct common_type<std::pair<T1, T2>, seqan3::common_pair<U1, U2>>
566{
568};
569
570template <class T1, class T2, class U1, class U2>
572struct common_type<seqan3::common_pair<T1, T2>, std::pair<U1, U2>>
573{
575};
576
577template <class T1, class T2, class U1, class U2, template <class> class TQual, template <class> class UQual>
578 requires requires {
581 }
582struct basic_common_reference<seqan3::common_pair<T1, T2>, seqan3::common_pair<U1, U2>, TQual, UQual>
583{
586};
587
588template <class T1, class T2, class U1, class U2, template <class> class TQual, template <class> class UQual>
589 requires requires {
592 }
593struct basic_common_reference<std::pair<T1, T2>, seqan3::common_pair<U1, U2>, TQual, UQual>
594{
597};
598
599template <class T1, class T2, class U1, class U2, template <class> class TQual, template <class> class UQual>
600 requires requires {
603 }
604struct basic_common_reference<seqan3::common_pair<T1, T2>, std::pair<U1, U2>, TQual, UQual>
605{
608};
609
610template <std::size_t i, class T1, class T2>
611constexpr std::tuple_element_t<i, seqan3::common_pair<T1, T2>> & get(seqan3::common_pair<T1, T2> & t) noexcept
612 requires (i < 2)
613{
614 return std::get<i>(static_cast<std::pair<T1, T2> &>(t));
615}
616
617template <std::size_t i, class T1, class T2>
618constexpr std::tuple_element_t<i, seqan3::common_pair<T1, T2>> const &
619get(seqan3::common_pair<T1, T2> const & t) noexcept
620 requires (i < 2)
621{
622 return std::get<i>(static_cast<std::pair<T1, T2> const &>(t));
623}
624
625template <std::size_t i, class T1, class T2>
626constexpr std::tuple_element_t<i, seqan3::common_pair<T1, T2>> && get(seqan3::common_pair<T1, T2> && t) noexcept
627 requires (i < 2)
628{
629 return std::get<i>(static_cast<std::pair<T1, T2> &&>(std::move(t)));
630}
631
632template <std::size_t i, class T1, class T2>
633constexpr std::tuple_element_t<i, seqan3::common_pair<T1, T2>> const &&
634get(seqan3::common_pair<T1, T2> const && t) noexcept
635 requires (i < 2)
636{
637 return std::get<i>(static_cast<std::pair<T1, T2> const &&>(std::move(t)));
638}
639
640template <typename type, class T1, class T2>
641constexpr type & get(seqan3::common_pair<T1, T2> & t) noexcept
642 requires (!std::same_as<T1, T2>)
643{
644 return std::get<type>(static_cast<std::pair<T1, T2> &>(t));
645}
646
647template <typename type, class T1, class T2>
648constexpr type const & get(seqan3::common_pair<T1, T2> const & t) noexcept
649 requires (!std::same_as<T1, T2>)
650{
651 return std::get<type>(static_cast<std::pair<T1, T2> const &>(t));
652}
653
654template <typename type, class T1, class T2>
655constexpr type && get(seqan3::common_pair<T1, T2> && t) noexcept
656 requires (!std::same_as<T1, T2>)
657{
658 return std::get<type>(static_cast<std::pair<T1, T2> &&>(std::move(t)));
659}
660
661template <typename type, class T1, class T2>
662constexpr type const && get(seqan3::common_pair<T1, T2> const && t) noexcept
663 requires (!std::same_as<T1, T2>)
664{
665 return std::get<type>(static_cast<std::pair<T1, T2> const &&>(std::move(t)));
666}
667
668} // namespace std
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
common_pair(T1, T2) -> common_pair< T1, T2 >
Class template argument deduction guide.
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: configuration.hpp:415
SeqAn specific customisations in the standard namespace.
Provides platform and dependency checks.
A std::pair implementation that incorporates most changes from C++23's standard library.
Definition: common_pair.hpp:28
constexpr common_pair(std::pair< U1, U2 > const &&other)
Constructs from std::pair.
Definition: common_pair.hpp:123
common_pair(common_pair const &)=default
Defaulted.
constexpr friend std::common_comparison_category_t< std::compare_three_way_result_t< U1, T1 >, std::compare_three_way_result_t< U2, T2 > > operator<=>(common_pair const &lhs, common_pair< U1, U2 > const &rhs)
Performs a three-way comparison between lhs and rhs
Definition: common_pair.hpp:419
constexpr common_pair(U1 const &&first, U2 const &&second)
Constructs from arguments.
Definition: common_pair.hpp:67
constexpr common_pair(U1 &&first, U2 &&second)
Constructs from arguments.
Definition: common_pair.hpp:62
constexpr common_pair(std::pair< U1, U2 > &other)
Constructs from std::pair.
Definition: common_pair.hpp:107
constexpr common_pair(common_pair< U1, U2 > &&other)
Constructs from common_pair.
Definition: common_pair.hpp:89
~common_pair()=default
constexpr common_pair(U1 const &first, U2 const &second)
Constructs from arguments.
Definition: common_pair.hpp:57
constexpr common_pair(U1 &first, U2 &second)
Constructs from arguments.
Definition: common_pair.hpp:52
constexpr common_pair(std::pair< U1, U2 > const &other)
Constructs from std::pair.
Definition: common_pair.hpp:112
constexpr common_pair(std::pair< U1, U2 > &&other)
Constructs from std::pair.
Definition: common_pair.hpp:117
constexpr common_pair(common_pair< U1, U2 > const &&other)
Constructs from common_pair.
Definition: common_pair.hpp:95
constexpr common_pair(common_pair< U1, U2 > const &other)
Constructs from common_pair.
Definition: common_pair.hpp:84
constexpr common_pair(common_pair< U1, U2 > &other)
Constructs from common_pair.
Definition: common_pair.hpp:79
common_pair()=default
Defaulted.
common_pair & operator=(common_pair const &)=default
Defaulted.