CommonLibVR
BSTTuple.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "RE/M/MemoryManager.h"
4 
5 namespace RE
6 {
7  template <class T1, class T2>
8  struct BSTTuple
9  {
10  public:
11  using first_type = T1;
12  using second_type = T2;
13 
14  // 1)
15  BSTTuple() //
16  noexcept(std::is_nothrow_default_constructible_v<first_type>&&
17  std::is_nothrow_default_constructible_v<second_type>) //
18  requires(std::is_default_constructible_v<first_type>&&
19  std::is_default_constructible_v<second_type>) :
20  first(),
21  second()
22  {}
23 
24  // 2)
25  explicit(!std::is_convertible_v<const first_type&, first_type> ||
26  !std::is_convertible_v<const second_type&, second_type>) //
27  BSTTuple(const first_type& a_first, const second_type& a_second) //
28  noexcept(std::is_nothrow_copy_constructible_v<first_type>&&
29  std::is_nothrow_copy_constructible_v<second_type>) //
30  requires(std::is_copy_constructible_v<first_type>&&
31  std::is_copy_constructible_v<second_type>) :
32  first(a_first),
33  second(a_second)
34  {}
35 
36  // 3)
37  template <class U1, class U2>
38  explicit(!std::is_convertible_v<U1&&, first_type> ||
39  !std::is_convertible_v<U2&&, second_type>) //
40  BSTTuple(U1&& a_first, U2&& a_second) //
41  noexcept(std::is_nothrow_constructible_v<first_type, U1&&>&&
42  std::is_nothrow_constructible_v<second_type, U2&&>) //
43  requires(std::is_constructible_v<first_type, U1&&>&&
44  std::is_constructible_v<second_type, U2&&>) :
45  first(std::forward<U1>(a_first)),
46  second(std::forward<U2>(a_second))
47  {}
48 
49  // 4)
50  template <class U1, class U2>
51  explicit(!std::is_convertible_v<const U1&, first_type> ||
52  !std::is_convertible_v<const U2&, second_type>) //
53  BSTTuple(const BSTTuple<U1, U2>& a_rhs) //
54  noexcept(std::is_nothrow_constructible_v<first_type, const U1&>&&
55  std::is_nothrow_constructible_v<second_type, const U2&>) //
56  requires(std::is_constructible_v<first_type, const U1&>&&
57  std::is_constructible_v<second_type, const U2&>) :
58  first(a_rhs.first),
59  second(a_rhs.second)
60  {}
61 
62  // 5)
63  template <class U1, class U2>
64  explicit(!std::is_convertible_v<U1&&, first_type> ||
65  !std::is_convertible_v<U2&&, second_type>) //
66  BSTTuple(BSTTuple<U1, U2>&& a_rhs) //
67  noexcept(std::is_nothrow_constructible_v<first_type, U1&&>&&
68  std::is_nothrow_constructible_v<second_type, U2&&>) //
69  requires(std::is_constructible_v<first_type, U1&&>&&
70  std::is_constructible_v<second_type, U2&&>) :
71  first(std::forward<U1>(a_rhs.first)),
72  second(std::forward<U2>(a_rhs.second))
73  {}
74 
75  // 6)
76  template <
77  class... Args1,
78  class... Args2>
79  BSTTuple(std::piecewise_construct_t, std::tuple<Args1...> a_firstArgs, std::tuple<Args2...> a_secondArgs) :
80  BSTTuple(a_firstArgs, a_secondArgs, std::index_sequence_for<Args1...>(), std::index_sequence_for<Args2...>())
81  {}
82 
83  private:
84  // 6) impl
85  template <
86  class Tuple1,
87  class Tuple2,
88  std::size_t... I1,
89  std::size_t... I2>
90  BSTTuple(Tuple1& a_firstArgs, Tuple2& a_secondArgs, std::index_sequence<I1...>, std::index_sequence<I2...>) :
91  first(std::get<I1>(std::move(a_firstArgs))...),
92  second(std::get<I2>(std::move(a_secondArgs))...)
93  {}
94 
95  public:
96  // 7)
97  BSTTuple(const BSTTuple&) = default;
98 
99  // 8)
100  BSTTuple(BSTTuple&&) = default;
101 
102  ~BSTTuple() = default;
103 
104  // 1)
105  BSTTuple& operator=(const BSTTuple& a_rhs) //
106  noexcept(std::is_nothrow_copy_assignable_v<first_type>&&
107  std::is_nothrow_copy_assignable_v<second_type>) //
108  requires(std::is_copy_assignable_v<first_type>&&
109  std::is_copy_assignable_v<second_type>)
110  {
111  if (this != std::addressof(a_rhs)) {
112  first = a_rhs.first;
113  second = a_rhs.second;
114  }
115  return *this;
116  }
117 
118  // 2)
119  template <class U1, class U2>
121  noexcept(std::is_nothrow_assignable_v<first_type&, const U1&>&&
122  std::is_nothrow_assignable_v<second_type&, const U2&>) //
123  requires(std::is_assignable_v<first_type&, const U1&>&&
124  std::is_assignable_v<second_type&, const U2&>)
125  {
126  first = a_rhs.first;
127  second = a_rhs.second;
128  return *this;
129  }
130 
131  // 3)
133  noexcept(std::is_nothrow_move_assignable_v<first_type>&&
134  std::is_nothrow_move_assignable_v<second_type>) //
135  requires(std::is_move_assignable_v<first_type>&&
136  std::is_move_assignable_v<second_type>)
137  {
138  if (this != std::addressof(a_rhs)) {
139  first = std::move(a_rhs.first);
140  second = std::move(a_rhs.second);
141  }
142  return *this;
143  }
144 
145  // 4)
146  template <class U1, class U2>
148  noexcept(std::is_nothrow_assignable_v<first_type&, U1>&&
149  std::is_nothrow_assignable_v<second_type&, U2>) //
150  requires(std::is_assignable_v<first_type&, U1>&&
151  std::is_assignable_v<second_type&, U2>)
152  {
153  first = std::move(a_rhs.first);
154  second = std::move(a_rhs.second);
155  return *this;
156  }
157 
159 
160  void swap(BSTTuple& a_rhs) //
161  noexcept(std::is_nothrow_swappable_v<first_type>&&
162  std::is_nothrow_swappable_v<second_type>)
163  {
164  using std::swap;
165  if (this != std::addressof(a_rhs)) {
166  swap(first, a_rhs.first);
167  swap(second, a_rhs.second);
168  }
169  }
170 
171  // members
174  private:
175  KEEP_FOR_RE()
176  };
177 
178  template <class T1, class T2>
179  [[nodiscard]] auto make_pair(T1&& a_first, T2&& a_second)
180  {
181  using result_t =
182  BSTTuple<
183  std::decay_t<T1>,
184  std::decay_t<T2>>;
185  return result_t(std::forward<T1>(a_first), std::forward<T2>(a_second));
186  }
187 
188  template <class T1, class T2>
189  [[nodiscard]] auto make_tuple(T1&& a_first, T2&& a_second)
190  {
191  using result_t =
192  BSTTuple<
193  std::decay_t<T1>,
194  std::decay_t<T2>>;
195  return result_t(std::forward<T1>(a_first), std::forward<T2>(a_second));
196  }
197 
198  template <class T1, class T2>
199  [[nodiscard]] bool operator==(const BSTTuple<T1, T2>& a_lhs, const BSTTuple<T1, T2>& a_rhs)
200  {
201  return a_lhs.first == a_rhs.first && a_lhs.second == a_rhs.second;
202  }
203 
204  template <class T1, class T2>
205  [[nodiscard]] bool operator<(const BSTTuple<T1, T2>& a_lhs, const BSTTuple<T1, T2>& a_rhs)
206  {
207  return a_lhs.first < a_rhs.first ? true :
208  a_rhs.first < a_lhs.first ? false :
209  a_lhs.second < a_rhs.second ? true :
210  false;
211  }
212 
213  template <class T1, class T2>
214  void swap(BSTTuple<T1, T2>& a_lhs, BSTTuple<T1, T2>& a_rhs) //
215  noexcept(noexcept(a_lhs.swap(a_rhs))) //
216  requires(std::is_swappable_v<T1>&&
217  std::is_swappable_v<T2>)
218  {
219  a_lhs.swap(a_rhs);
220  }
221 
222  template <class T1, class T2>
224 }
#define KEEP_FOR_RE()
Definition: PCH.h:713
Definition: AbsorbEffect.h:6
auto make_pair(T1 &&a_first, T2 &&a_second)
Definition: BSTTuple.h:179
BSTTuple(T1, T2) -> BSTTuple< T1, T2 >
constexpr bool operator==(const BSTSmartPointer< T1 > &a_lhs, const BSTSmartPointer< T2 > &a_rhs)
Definition: BSTSmartPointer.h:241
void swap(BSTTuple< T1, T2 > &a_lhs, BSTTuple< T1, T2 > &a_rhs) noexcept(noexcept(a_lhs.swap(a_rhs))) requires(std
Definition: BSTTuple.h:214
auto make_tuple(T1 &&a_first, T2 &&a_second)
Definition: BSTTuple.h:189
bool operator<(const BSTTuple< T1, T2 > &a_lhs, const BSTTuple< T1, T2 > &a_rhs)
Definition: BSTTuple.h:205
requires(std::invocable< std::remove_reference_t< EF >>) class scope_exit
Definition: PCH.h:151
Definition: EffectArchetypes.h:65
Definition: BSTTuple.h:9
BSTTuple & operator=(const BSTTuple &a_rhs) noexcept(std::is_nothrow_copy_assignable_v< first_type > &&std::is_nothrow_copy_assignable_v< second_type >) requires(std
Definition: BSTTuple.h:105
U2 &a_rhs noexcept(std::is_nothrow_constructible_v< first_type, const U1 & > &&std::is_nothrow_constructible_v< second_type, const U2 & >) requires(std
Definition: BSTTuple.h:54
U2 &&a_rhs noexcept(std::is_nothrow_constructible_v< first_type, U1 && > &&std::is_nothrow_constructible_v< second_type, U2 && >) requires(std
Definition: BSTTuple.h:67
BSTTuple & operator=(const BSTTuple< U1, U2 > &a_rhs) noexcept(std::is_nothrow_assignable_v< first_type &, const U1 & > &&std::is_nothrow_assignable_v< second_type &, const U2 & >) requires(std
Definition: BSTTuple.h:120
BSTTuple(std::piecewise_construct_t, std::tuple< Args1... > a_firstArgs, std::tuple< Args2... > a_secondArgs)
Definition: BSTTuple.h:79
first_type first
Definition: BSTTuple.h:172
second_type second
Definition: BSTTuple.h:173
~BSTTuple()=default
T2 second_type
Definition: BSTTuple.h:12
BSTTuple & operator=(BSTTuple< U1, U2 > &&a_rhs) noexcept(std::is_nothrow_assignable_v< first_type &, U1 > &&std::is_nothrow_assignable_v< second_type &, U2 >) requires(std
Definition: BSTTuple.h:147
void swap(BSTTuple &a_rhs) noexcept(std::is_nothrow_swappable_v< first_type > &&std::is_nothrow_swappable_v< second_type >)
Definition: BSTTuple.h:160
BSTTuple & operator=(BSTTuple &&a_rhs) noexcept(std::is_nothrow_move_assignable_v< first_type > &&std::is_nothrow_move_assignable_v< second_type >) requires(std
Definition: BSTTuple.h:132
T1 first_type
Definition: BSTTuple.h:11
BSTTuple(BSTTuple &&)=default
U2 &&a_second noexcept(std::is_nothrow_constructible_v< first_type, U1 && > &&std::is_nothrow_constructible_v< second_type, U2 && >) requires(std
Definition: BSTTuple.h:41
const second_type &a_second noexcept(std::is_nothrow_copy_constructible_v< first_type > &&std::is_nothrow_copy_constructible_v< second_type >) requires(std
Definition: BSTTuple.h:28
BSTTuple(const BSTTuple &)=default
BSTTuple() noexcept(std::is_nothrow_default_constructible_v< first_type > &&std::is_nothrow_default_constructible_v< second_type >) requires(std
Definition: BSTTuple.h:15