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{
53 template<typename F_TYPE, typename S_TYPE>
54 class couple final : public printable, public comparable<couple<F_TYPE, S_TYPE>>
55 {
56 F_TYPE first_;
57 S_TYPE second_;
58
59 public:
63 explicit couple();
64
71
77 couple(const F_TYPE& first, const S_TYPE& second);
78
85
91
98
104 couple(couple&& other) noexcept;
105
113
118 void swap(couple& other) noexcept;
119
127 template<u_integer IDX>
128 auto& get();
129
137 template<u_integer IDX>
138 const auto& get() const;
139
148 template<u_integer IDX, typename T>
149 couple& set(const T& e);
150
157 integer compareTo(const couple &other) const override;
158
164
170
175 const F_TYPE& first() const;
176
181 const S_TYPE& second() const;
182
186 ~couple() override;
187
192 [[nodiscard]] std::string className() const override;
193
199 [[nodiscard]] std::string toString(bool enter) const override;
200 };
201}
202
203
204namespace std {
212 template<typename F, typename S>
213 void swap(original::couple<F, S>& lhs, original::couple<F, S>& rhs) noexcept; // NOLINT
214
220 template<typename F, typename S>
221 struct tuple_size<original::couple<F, S>> : std::integral_constant<std::size_t, 2> {}; // NOLINT
222
229 template<std::size_t I, typename F, typename S>
230 struct tuple_element<I, original::couple<F, S>> { // NOLINT
231 using type = std::conditional_t<I == 0, F, S>;
232 };
233
243 template<std::size_t I, typename F, typename S>
244 constexpr auto& get(original::couple<F, S>& c) noexcept; // NOLINT
245
255 template<std::size_t I, typename F, typename S>
256 constexpr const auto& get(const original::couple<F, S>& c) noexcept; // NOLINT
257
267 template<std::size_t I, typename F, typename S>
268 constexpr auto&& get(original::couple<F, S>&& c) noexcept; // NOLINT
269}
270
271
272 template <typename F_TYPE, typename S_TYPE>
274
275 template <typename F_TYPE, typename S_TYPE>
277 : first_(*first), second_(*second) {}
278
279 template <typename F_TYPE, typename S_TYPE>
281 : first_(first), second_(second) {}
282
283 template <typename F_TYPE, typename S_TYPE>
285 : first_(std::move(first)), second_(std::move(second)) {}
286
287 template <typename F_TYPE, typename S_TYPE>
289 : first_(other.first_), second_(other.second_) {}
290
291 template <typename F_TYPE, typename S_TYPE>
293 {
294 if (this == &other) return *this;
295 first_ = other.first_;
296 second_ = other.second_;
297 return *this;
298 }
299
300 template<typename F_TYPE, typename S_TYPE>
302 : first_(std::move(other.first_)), second_(std::move(other.second_)) {}
303
304 template<typename F_TYPE, typename S_TYPE>
307 if (this == &other) return *this;
308
309 first_ = std::move(other.first_);
310 second_ = std::move(other.second_);
311 return *this;
312 }
313
314 template <typename F_TYPE, typename S_TYPE>
316 {
317 if (this == &other)
318 return;
319
320 std::swap(this->first_, other.first_);
321 std::swap(this->second_, other.second_);
322 }
323
324 template<typename F_TYPE, typename S_TYPE>
325 template<original::u_integer IDX>
327 staticError<outOfBoundError, (IDX > 1)>::asserts();
328 if constexpr (IDX == 0){
329 return this->first_;
330 }else {
331 return this->second_;
332 }
333 }
334
335 template<typename F_TYPE, typename S_TYPE>
336 template<original::u_integer IDX>
338 staticError<outOfBoundError, (IDX > 1)>::asserts();
339 if constexpr (IDX == 0){
340 return this->first_;
341 }else {
342 return this->second_;
343 }
344 }
345
346 template<typename F_TYPE, typename S_TYPE>
347 template<original::u_integer IDX, typename T>
349 staticError<outOfBoundError, (IDX > 1)>::asserts();
350 if constexpr (IDX == 0){
352 this->first_ = static_cast<F_TYPE>(e);
353 } else{
354 staticError<valueError, !std::is_convertible_v<T, S_TYPE>>::asserts();
355 this->second_ = static_cast<S_TYPE>(e);
356 }
357 return *this;
358 }
359
360 template<typename F_TYPE, typename S_TYPE>
362 {
363 if constexpr (Comparable<F_TYPE>){
364 if (this->first_ < other.first_)
365 return -1;
366 if (this->first_ > other.first_)
367 return 1;
368 }
369 if constexpr (Comparable<S_TYPE>){
370 if (this->second_ < other.second_)
371 return -1;
372 if (this->second_ > other.second_)
373 return 1;
374 }
375 return 0;
376 }
377
378 template <typename F_TYPE, typename S_TYPE>
380 {
381 return this->first_;
382 }
383
384 template <typename F_TYPE, typename S_TYPE>
386 {
387 return this->second_;
388 }
389
390 template<typename F_TYPE, typename S_TYPE>
392 return this->first_;
393 }
394
395 template<typename F_TYPE, typename S_TYPE>
397 return this->second_;
398 }
399
400template <typename F_TYPE, typename S_TYPE>
402
403 template <typename F_TYPE, typename S_TYPE>
405 {
406 return "couple";
407 }
408
409 template <typename F_TYPE, typename S_TYPE>
410 auto original::couple<F_TYPE, S_TYPE>::toString(const bool enter) const -> std::string
411 {
412 std::stringstream ss;
413 ss << this->className() << "(" << formatString(this->first_)
414 << ", " << formatString(this->second_) << ")";
415 if (enter) ss << "\n";
416 return ss.str();
417 }
418
419 template <typename F, typename S>
420 void std::swap(original::couple<F, S>& lhs, original::couple<F, S>& rhs) noexcept // NOLINT
421 {
422 lhs.swap(rhs);
423 }
424
425 template<std::size_t I, typename F, typename S>
426 constexpr auto& std::get(original::couple<F, S> &c) noexcept { // NOLINT
427 return c.template get<I>();
428 }
429
430 template<std::size_t I, typename F, typename S>
431 constexpr const auto& std::get(const original::couple<F, S> &c) noexcept { // NOLINT
432 return c.template get<I>();
433 }
434
435 template<std::size_t I, typename F, typename S>
436 constexpr auto&& std::get(original::couple<F, S> &&c) noexcept { // NOLINT
437 return std::move(c.template get<I>());
438 }
439
440#endif //COUPLE_H
void swap(autoPtr &other) noexcept
Swaps the reference counters between two autoPtr instances.
Definition autoPtr.h:703
Base class for comparable objects.
Definition comparable.h:35
Container for two heterogeneous elements.
Definition couple.h:55
const auto & get() const
Element access template method (const version)
Definition couple.h:337
couple(F_TYPE &&first, S_TYPE &&second)
Constructs from rvalue references.
Definition couple.h:284
std::string className() const override
Gets class name identifier.
Definition couple.h:404
std::string toString(bool enter) const override
Formats pair elements as string.
Definition couple.h:410
~couple() override
Default destructor.
void swap(couple &other) noexcept
Swaps the contents of this couple with another.
Definition couple.h:315
F_TYPE & first()
Access first element.
Definition couple.h:379
S_TYPE & second()
Access second element.
Definition couple.h:385
const F_TYPE & first() const
Access first element (const version)
Definition couple.h:391
couple & operator=(couple &&other) noexcept
Move assignment operator.
Definition couple.h:306
couple(couple &&other) noexcept
Move constructor.
Definition couple.h:301
couple(const F_TYPE &first, const S_TYPE &second)
Constructs from element copies.
Definition couple.h:280
auto & get()
Element access template method (non-const version)
Definition couple.h:326
couple & operator=(const couple &other)
Copy assignment operator.
Definition couple.h:292
couple & set(const T &e)
Element modification template method.
couple()
Default constructs both elements.
Definition couple.h:273
couple(const couple &other)
Copy constructor.
Definition couple.h:288
const S_TYPE & second() const
Access second element (const version)
Definition couple.h:396
integer compareTo(const couple &other) const override
Lexicographical comparison operation.
Definition couple.h:361
couple(F_TYPE *first, S_TYPE *second)
Constructs from pointer elements.
Definition couple.h:276
Exception for container index out-of-range errors.
Definition error.h:192
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
Base class providing polymorphic string conversion capabilities.
Definition printable.h:39
Compile-time error triggering utility.
Definition error.h:167
Interface for objects that can be compared.
Definition types.h:157
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
Standard namespace extensions for original::alternative.
Definition allocator.h:351
void swap(original::objPoolAllocator< TYPE > &lhs, original::objPoolAllocator< TYPE > &rhs) noexcept
Specialization of std::swap for objPoolAllocator.
Definition allocator.h:635
constexpr auto & get(original::couple< F, S > &c) noexcept
Structured binding support - get for non-const lvalue reference.
Definition couple.h:426
Interface for polymorphic string formatting and output.
Core type system foundations and concept definitions.