ORIGINAL
Loading...
Searching...
No Matches
couple.h
Go to the documentation of this file.
1#ifndef COUPLE_H
2#define COUPLE_H
3
11
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
65 couple(const couple& other);
66
72 couple& operator=(const couple& other);
73
79 couple(couple&& other) noexcept;
80
87 couple& operator=(couple&& other) noexcept;
88
96 template<u_integer IDX>
97 auto& get();
98
106 template<u_integer IDX>
107 const auto& get() const;
108
116 template<u_integer IDX, typename T>
117 couple& set(const T& e);
118
125 integer compareTo(const couple &other) const override;
126
131 F_TYPE& first();
132
137 S_TYPE& second();
138
143 const F_TYPE& first() const;
144
149 const S_TYPE& second() const;
150
154 ~couple() override;
155
160 [[nodiscard]] std::string className() const override;
161
167 [[nodiscard]] std::string toString(bool enter) const override;
168 };
169}
170
171
172namespace std {
178 template<typename F, typename S>
179 struct tuple_size<original::couple<F, S>> : std::integral_constant<std::size_t, 2> {}; // NOLINT
180
187 template<std::size_t I, typename F, typename S>
188 struct tuple_element<I, original::couple<F, S>> { // NOLINT
189 using type = std::conditional_t<I == 0, F, S>;
190 };
191
201 template<std::size_t I, typename F, typename S>
202 constexpr auto& get(original::couple<F, S>& c) noexcept; // NOLINT
203
213 template<std::size_t I, typename F, typename S>
214 constexpr const auto& get(const original::couple<F, S>& c) noexcept; // NOLINT
215
225 template<std::size_t I, typename F, typename S>
226 constexpr auto&& get(original::couple<F, S>&& c) noexcept; // NOLINT
227}
228
229
230 template <typename F_TYPE, typename S_TYPE>
232
233 template <typename F_TYPE, typename S_TYPE>
235 : first_(*first), second_(*second) {}
236
237 template <typename F_TYPE, typename S_TYPE>
239 : first_(first), second_(second) {}
240
241 template <typename F_TYPE, typename S_TYPE>
243 : first_(other.first_), second_(other.second_) {}
244
245 template <typename F_TYPE, typename S_TYPE>
247 {
248 if (this == &other) return *this;
249 first_ = other.first_;
250 second_ = other.second_;
251 return *this;
252 }
253
254 template<typename F_TYPE, typename S_TYPE>
256 : first_(std::move(other.first_)), second_(std::move(other.second_)) {}
257
258 template<typename F_TYPE, typename S_TYPE>
261 if (this == &other) return *this;
262
263 first_ = std::move(other.first_);
264 second_ = std::move(other.second_);
265 return *this;
266 }
267
268 template<typename F_TYPE, typename S_TYPE>
269 template<original::u_integer IDX>
271 staticError<outOfBoundError, (IDX > 1)>{};
272 if constexpr (IDX == 0){
273 return this->first_;
274 }else {
275 return this->second_;
276 }
277 }
278
279 template<typename F_TYPE, typename S_TYPE>
280 template<original::u_integer IDX>
282 staticError<outOfBoundError, (IDX > 1)>{};
283 if constexpr (IDX == 0){
284 return this->first_;
285 }else {
286 return this->second_;
287 }
288 }
289
290 template<typename F_TYPE, typename S_TYPE>
291 template<original::u_integer IDX, typename T>
293 staticError<outOfBoundError, (IDX > 1)>{};
294 if constexpr (IDX == 0){
295 staticError<valueError, !std::is_convertible_v<T, F_TYPE>>{};
296 this->first_ = static_cast<F_TYPE>(e);
297 } else{
299 this->second_ = static_cast<S_TYPE>(e);
300 }
301 return *this;
302 }
303
304 template<typename F_TYPE, typename S_TYPE>
306 {
307 if constexpr (Comparable<F_TYPE>){
308 if (this->first_ < other.first_)
309 return -1;
310 if (this->first_ > other.first_)
311 return 1;
312 }
313 if constexpr (Comparable<S_TYPE>){
314 if (this->second_ < other.second_)
315 return -1;
316 if (this->second_ > other.second_)
317 return 1;
318 }
319 return 0;
320 }
321
322 template <typename F_TYPE, typename S_TYPE>
324 {
325 return this->first_;
326 }
327
328 template <typename F_TYPE, typename S_TYPE>
330 {
331 return this->second_;
332 }
333
334 template<typename F_TYPE, typename S_TYPE>
336 return this->first_;
337 }
338
339 template<typename F_TYPE, typename S_TYPE>
341 return this->second_;
342 }
343
344template <typename F_TYPE, typename S_TYPE>
346
347 template <typename F_TYPE, typename S_TYPE>
349 {
350 return "couple";
351 }
352
353 template <typename F_TYPE, typename S_TYPE>
354 auto original::couple<F_TYPE, S_TYPE>::toString(const bool enter) const -> std::string
355 {
356 std::stringstream ss;
357 ss << this->className() << "(" << formatString(this->first_)
358 << ", " << formatString(this->second_) << ")";
359 if (enter) ss << "\n";
360 return ss.str();
361 }
362
363 template<std::size_t I, typename F, typename S>
364 constexpr auto& std::get(original::couple<F, S> &c) noexcept { // NOLINT
365 return c.template get<I>();
366 }
367
368 template<std::size_t I, typename F, typename S>
369 constexpr const auto& std::get(const original::couple<F, S> &c) noexcept { // NOLINT
370 return c.template get<I>();
371 }
372
373 template<std::size_t I, typename F, typename S>
374 constexpr auto&& std::get(original::couple<F, S> &&c) noexcept { // NOLINT
375 return std::move(c.template get<I>());
376 }
377
378#endif //COUPLE_H
Base class for comparable objects.
Definition comparable.h:31
Container for two heterogeneous elements.
Definition couple.h:37
const auto & get() const
Element access template method (const version)
Definition couple.h:281
std::string className() const override
Gets class name identifier.
Definition couple.h:348
std::string toString(bool enter) const override
Formats pair elements as string.
Definition couple.h:354
~couple() override
Default destructor.
const K_TYPE & first()
Definition couple.h:323
V_TYPE & second()
Definition couple.h:329
const F_TYPE & first() const
Access first element (const version)
Definition couple.h:335
couple & operator=(couple &&other) noexcept
Move assignment operator.
Definition couple.h:260
couple(couple &&other) noexcept
Move constructor.
Definition couple.h:255
couple(const F_TYPE &first, const S_TYPE &second)
Constructs from element copies.
Definition couple.h:238
auto & get()
Element access template method (non-const version)
Definition couple.h:270
couple & operator=(const couple &other)
Copy assignment operator.
Definition couple.h:246
couple & set(const T &e)
element modifies the template method
couple()
Default constructs both elements.
Definition couple.h:231
couple(const couple &other)
Copy constructor.
Definition couple.h:242
const S_TYPE & second() const
Access second element (const version)
Definition couple.h:340
integer compareTo(const couple &other) const override
Lexicographical comparison operation.
Definition couple.h:305
couple(F_TYPE *first, S_TYPE *second)
Constructs from pointer elements.
Definition couple.h:234
Exception for container index out-of-range errors.
Definition error.h:84
Base class providing polymorphic string conversion capabilities.
Definition printable.h:29
static std::string formatString(const TYPE &t)
Universal value-to-string conversion.
Compile-time error assertion utility.
Definition error.h:73
Interface for objects that can be compared.
Requires type to support all comparison operators.
Definition types.h:45
constexpr auto & get(original::couple< F, S > &c) noexcept
Structured binding support - get for non-const lvalue reference.
Definition couple.h:364
Custom exception classes and callback validation utilities.
Main namespace for the project Original.
Definition algorithms.h:21
std::int64_t integer
64-bit signed integer type for arithmetic operations
Definition config.h:35
Interface for polymorphic string formatting and output.
Core type system foundations and concept definitions.