LeviLamina
Loading...
Searching...
No Matches
TightPair.h
1#pragma once
2
3#include <type_traits>
4
5namespace ll::data {
6
7constexpr inline struct ZeroThenVariadicArgs {
8} zeroThenVariadicArgs;
9constexpr inline struct OneThenVariadicArgs {
10} oneThenVariadicArgs;
11
12template <class Base, class Other, bool = std::is_empty_v<Base> && !std::is_final_v<Base>>
13class TightPair final : private Base {
14 Other sec;
15
16public:
17 using first_type = Base;
18 using second_type = Other;
19
20 template <class... Ts2>
21 constexpr explicit TightPair(ZeroThenVariadicArgs, Ts2&&... val2) noexcept(
22 std::is_nothrow_default_constructible_v<Base> && std::is_nothrow_constructible_v<Other, Ts2...>
23 )
24 : Base(),
25 sec(std::forward<Ts2>(val2)...) {}
26
27 template <class T1, class... Ts2>
28 constexpr TightPair(OneThenVariadicArgs, T1&& val1, Ts2&&... val2) noexcept(
29 std::is_nothrow_constructible_v<Base, T1> && std::is_nothrow_constructible_v<Other, Ts2...>
30 )
31 : Base(std::forward<T1>(val1)),
32 sec(std::forward<Ts2>(val2)...) {}
33
34 constexpr first_type& first() noexcept { return *this; }
35
36 constexpr first_type const& first() const noexcept { return *this; }
37
38 constexpr second_type& second() noexcept { return sec; }
39
40 constexpr second_type const& second() const noexcept { return sec; }
41};
42
43template <class Base, class Other>
44class TightPair<Base, Other, false> final {
45 Base fst;
46 Other sec;
47
48public:
49 using first_type = Base;
50 using second_type = Other;
51
52 template <class... Ts2>
53 constexpr explicit TightPair(ZeroThenVariadicArgs, Ts2&&... val2) noexcept(
54 std::is_nothrow_default_constructible_v<Base> && std::is_nothrow_constructible_v<Other, Ts2...>
55 )
56 : fst(),
57 sec(std::forward<Ts2>(val2)...) {}
58
59 template <class T1, class... Ts2>
60 constexpr TightPair(OneThenVariadicArgs, T1&& val1, Ts2&&... val2) noexcept(
61 std::is_nothrow_constructible_v<Base, T1> && std::is_nothrow_constructible_v<Other, Ts2...>
62 )
63 : fst(std::forward<T1>(val1)),
64 sec(std::forward<Ts2>(val2)...) {}
65
66 constexpr first_type& first() noexcept { return fst; }
67
68 constexpr first_type const& first() const noexcept { return fst; }
69
70 constexpr second_type& second() noexcept { return sec; }
71
72 constexpr second_type const& second() const noexcept { return sec; }
73};
74} // namespace ll::data
Definition TightPair.h:13
Definition TightPair.h:9
Definition TightPair.h:7