ORIGINAL
Loading...
Searching...
No Matches
couple.h
Go to the documentation of this file.
1#ifndef COUPLE_H
2#define COUPLE_H
3
12#include "printable.h"
13#include "comparable.h"
14#include "types.h"
15#include "error.h"
16
17
18namespace original
19{
35 template<typename F_TYPE, typename S_TYPE>
36 class couple final : public printable, public comparable<couple<F_TYPE, S_TYPE>>
37 {
38 F_TYPE first_;
39 S_TYPE second_;
40
41 public:
45 explicit couple();
46
52 couple(F_TYPE* first, S_TYPE* second);
53
59 couple(const F_TYPE& first, const S_TYPE& second);
60
61 couple(F_TYPE&& first, S_TYPE&& second);
62
67 couple(const couple& other);
68
74 couple& operator=(const couple& other);
75
81 couple(couple&& other) noexcept;
82
89 couple& operator=(couple&& other) noexcept;
90
98 template<u_integer IDX>
99 auto& get();
100
108 template<u_integer IDX>
109 const auto& get() const;
110
118 template<u_integer IDX, typename T>
119 couple& set(const T& e);
120
127 integer compareTo(const couple &other) const override;
128
133 F_TYPE& first();
134
139 S_TYPE& second();
140
145 const F_TYPE& first() const;
146
151 const S_TYPE& second() const;
152
156 ~couple() override;
157
162 [[nodiscard]] std::string className() const override;
163
169 [[nodiscard]] std::string toString(bool enter) const override;
170 };
171}
172
173
174namespace std {
180 template<typename F, typename S>
181 struct tuple_size<original::couple<F, S>> : std::integral_constant<std::size_t, 2> {}; // NOLINT
182
189 template<std::size_t I, typename F, typename S>
190 struct tuple_element<I, original::couple<F, S>> { // NOLINT
191 using type = std::conditional_t<I == 0, F, S>;
192 };
193
203 template<std::size_t I, typename F, typename S>
204 constexpr auto& get(original::couple<F, S>& c) noexcept; // NOLINT
205
215 template<std::size_t I, typename F, typename S>
216 constexpr const auto& get(const original::couple<F, S>& c) noexcept; // NOLINT
217
227 template<std::size_t I, typename F, typename S>
228 constexpr auto&& get(original::couple<F, S>&& c) noexcept; // NOLINT
229}
230
231
232 template <typename F_TYPE, typename S_TYPE>
234
235 template <typename F_TYPE, typename S_TYPE>
236 original::couple<F_TYPE, S_TYPE>::couple(F_TYPE* first, S_TYPE* second)
237 : first_(*first), second_(*second) {}
238
239 template <typename F_TYPE, typename S_TYPE>
240 original::couple<F_TYPE, S_TYPE>::couple(const F_TYPE& first, const S_TYPE& second)
241 : first_(first), second_(second) {}
242
243 template <typename F_TYPE, typename S_TYPE>
244 original::couple<F_TYPE, S_TYPE>::couple(F_TYPE&& first, S_TYPE&& second)
245 : first_(std::move(first)), second_(std::move(second)) {}
246
247 template <typename F_TYPE, typename S_TYPE>
249 : first_(other.first_), second_(other.second_) {}
250
251 template <typename F_TYPE, typename S_TYPE>
253 {
254 if (this == &other) return *this;
255 first_ = other.first_;
256 second_ = other.second_;
257 return *this;
258 }
259
260 template<typename F_TYPE, typename S_TYPE>
262 : first_(std::move(other.first_)), second_(std::move(other.second_)) {}
263
264 template<typename F_TYPE, typename S_TYPE>
267 if (this == &other) return *this;
268
269 first_ = std::move(other.first_);
270 second_ = std::move(other.second_);
271 return *this;
272 }
273
274 template<typename F_TYPE, typename S_TYPE>
275 template<original::u_integer IDX>
277 staticError<outOfBoundError, (IDX > 1)>::asserts();
278 if constexpr (IDX == 0){
279 return this->first_;
280 }else {
281 return this->second_;
282 }
283 }
284
285 template<typename F_TYPE, typename S_TYPE>
286 template<original::u_integer IDX>
288 staticError<outOfBoundError, (IDX > 1)>::asserts();
289 if constexpr (IDX == 0){
290 return this->first_;
291 }else {
292 return this->second_;
293 }
294 }
295
296 template<typename F_TYPE, typename S_TYPE>
297 template<original::u_integer IDX, typename T>
299 staticError<outOfBoundError, (IDX > 1)>::asserts();
300 if constexpr (IDX == 0){
302 this->first_ = static_cast<F_TYPE>(e);
303 } else{
304 staticError<valueError, !std::is_convertible_v<T, S_TYPE>>::asserts();
305 this->second_ = static_cast<S_TYPE>(e);
306 }
307 return *this;
308 }
309
310 template<typename F_TYPE, typename S_TYPE>
312 {
313 if constexpr (Comparable<F_TYPE>){
314 if (this->first_ < other.first_)
315 return -1;
316 if (this->first_ > other.first_)
317 return 1;
318 }
319 if constexpr (Comparable<S_TYPE>){
320 if (this->second_ < other.second_)
321 return -1;
322 if (this->second_ > other.second_)
323 return 1;
324 }
325 return 0;
326 }
327
328 template <typename F_TYPE, typename S_TYPE>
330 {
331 return this->first_;
332 }
333
334 template <typename F_TYPE, typename S_TYPE>
336 {
337 return this->second_;
338 }
339
340 template<typename F_TYPE, typename S_TYPE>
342 return this->first_;
343 }
344
345 template<typename F_TYPE, typename S_TYPE>
347 return this->second_;
348 }
349
350template <typename F_TYPE, typename S_TYPE>
352
353 template <typename F_TYPE, typename S_TYPE>
355 {
356 return "couple";
357 }
358
359 template <typename F_TYPE, typename S_TYPE>
360 auto original::couple<F_TYPE, S_TYPE>::toString(const bool enter) const -> std::string
361 {
362 std::stringstream ss;
363 ss << this->className() << "(" << formatString(this->first_)
364 << ", " << formatString(this->second_) << ")";
365 if (enter) ss << "\n";
366 return ss.str();
367 }
368
369 template<std::size_t I, typename F, typename S>
370 constexpr auto& std::get(original::couple<F, S> &c) noexcept { // NOLINT
371 return c.template get<I>();
372 }
373
374 template<std::size_t I, typename F, typename S>
375 constexpr const auto& std::get(const original::couple<F, S> &c) noexcept { // NOLINT
376 return c.template get<I>();
377 }
378
379 template<std::size_t I, typename F, typename S>
380 constexpr auto&& std::get(original::couple<F, S> &&c) noexcept { // NOLINT
381 return std::move(c.template get<I>());
382 }
383
384#endif //COUPLE_H
Base class for comparable objects.
Definition comparable.h:32
Container for two heterogeneous elements.
Definition couple.h:37
const auto & get() const
Element access template method (const version)
Definition couple.h:287
std::string className() const override
Gets class name identifier.
Definition couple.h:354
std::string toString(bool enter) const override
Formats pair elements as string.
Definition couple.h:360
~couple() override
Default destructor.
F_TYPE & first()
Access first element.
Definition couple.h:329
S_TYPE & second()
Access second element.
Definition couple.h:335
const F_TYPE & first() const
Access first element (const version)
Definition couple.h:341
couple & operator=(couple &&other) noexcept
Move assignment operator.
Definition couple.h:266
couple(couple &&other) noexcept
Move constructor.
Definition couple.h:261
couple(const F_TYPE &first, const S_TYPE &second)
Constructs from element copies.
Definition couple.h:240
auto & get()
Element access template method (non-const version)
Definition couple.h:276
couple & operator=(const couple &other)
Copy assignment operator.
Definition couple.h:252
couple & set(const T &e)
element modifies the template method
couple()
Default constructs both elements.
Definition couple.h:233
couple(const couple &other)
Copy constructor.
Definition couple.h:248
const S_TYPE & second() const
Access second element (const version)
Definition couple.h:346
integer compareTo(const couple &other) const override
Lexicographical comparison operation.
Definition couple.h:311
couple(F_TYPE *first, S_TYPE *second)
Constructs from pointer elements.
Definition couple.h:236
Exception for container index out-of-range errors.
Definition error.h:129
Base class providing polymorphic string conversion capabilities.
Definition printable.h:39
Compile-time error triggering utility.
Definition error.h:112
Interface for objects that can be compared.
Definition types.h:157
constexpr auto & get(original::couple< F, S > &c) noexcept
Structured binding support - get for non-const lvalue reference.
Definition couple.h:370
Custom exception classes and callback validation utilities.
std::int64_t integer
64-bit signed integer type for arithmetic operations
Definition config.h:254
Main namespace for the project Original.
Definition algorithms.h:21
Interface for polymorphic string formatting and output.
Core type system foundations and concept definitions.