52 template<
typename... TYPES>
54 static constexpr u_integer SIZE =
sizeof...(TYPES);
70 template<u_
integer I,
typename T>
78 explicit tupleImpl(
const T& cur = T{});
80 tupleImpl(tupleImpl<I, T>&& other)
noexcept;
82 tupleImpl(
const tupleImpl<I, T>& other);
84 tupleImpl<I, T>&
operator=(tupleImpl<I, T>&& other)
noexcept;
86 template<u_
integer I_DIFF>
87 const auto&
get()
const;
89 template<u_
integer I_DIFF>
92 template<u_
integer I_DIFF,
typename E>
98 std::string
toString(
bool enter)
const override;
101 template<u_
integer I,
typename T,
typename TS>
104 tupleImpl<I + 1, TS> next;
111 explicit tupleImpl(
const T& cur = T{},
const TS& next_elems = TS{});
113 tupleImpl(tupleImpl<I, T, TS>&& other)
noexcept;
115 tupleImpl(
const tupleImpl<I, T, TS>& other);
117 tupleImpl<I, T, TS>&
operator=(tupleImpl<I, T, TS>&& other)
noexcept;
119 template<u_
integer I_DIFF>
120 const auto&
get()
const;
122 template<u_
integer I_DIFF>
125 template<u_
integer I_DIFF,
typename E>
126 void set(
const E& e);
131 std::string
toString(
bool enter)
const override;
134 template<
u_integer I,
typename T,
typename... TS>
135 class tupleImpl<I, T, TS...> :
public printable,
public comparable<tupleImpl<I, T, TS...>>{
137 tupleImpl<I + 1, TS...> next;
144 explicit tupleImpl(
const T& cur,
const TS&... next_elems);
146 explicit tupleImpl(
const T& cur = T{},
const tupleImpl<I + 1, TS...>& nt = tupleImpl<I + 1, TS...>{});
148 tupleImpl(tupleImpl<I, T, TS...>&& other)
noexcept;
150 tupleImpl(
const tupleImpl<I, T, TS...>& other);
152 tupleImpl<I, T, TS...>&
operator=(tupleImpl<I, T, TS...>&& other)
noexcept;
154 template<u_
integer I_DIFF>
155 const auto&
get()
const;
157 template<u_
integer I_DIFF>
160 template<u_
integer I_DIFF,
typename E>
161 void set(
const E& e);
166 std::string
toString(
bool enter)
const override;
169 tupleImpl<0, TYPES...> elems;
178 auto _slice(std::integer_sequence<u_integer, IDX_S...> indexes,
179 std::integral_constant<u_integer, BEGIN_IDX> begin)
const;
192 tuple<TYPES..., O_TYPES...> _concat(
const tuple<O_TYPES...>& other,
193 std::integer_sequence<u_integer, T_SIZE...> ts,
194 std::integer_sequence<u_integer, O_SIZE...> os)
const;
204 explicit tuple(
const TYPES&... e);
210 tuple(
const tuple& other);
223 tuple(tuple&& other)
noexcept;
230 tuple&
operator=(tuple&& other)
noexcept;
246 template<u_
integer IDX>
247 const auto&
get()
const;
257 template<u_
integer IDX>
272 template<u_
integer IDX,
typename E>
281 template<u_
integer BEGIN_IDX, u_
integer N_ELEMS>
304 std::string
toString(
bool enter)
const override;
312 ~tuple()
override =
default;
321 template<
typename F_TYPE,
typename S_TYPE>
332 template<
typename... L_TYPES,
typename... R_TYPES>
333 friend tuple<L_TYPES..., R_TYPES...>
operator+(
const tuple<L_TYPES...>& lt,
const tuple<R_TYPES...>& rt);
336 template<
typename F_TYPE,
typename S_TYPE>
339 template<
typename... L_TYPES,
typename... R_TYPES>
349 template<
typename... TYPES>
351 : std::integral_constant<std::size_t, sizeof...(TYPES)> {};
364 template<std::size_t I,
typename... TYPES>
365 struct tuple_element<I,
original::tuple<TYPES...>> {
366 using type = std::tuple_element_t<I, std::tuple<TYPES...>>;
377 template<std::size_t I,
typename... TYPES>
388 template<std::size_t I,
typename... TYPES>
399 template<std::size_t I,
typename... TYPES>
404template<
typename... TYPES>
405template<original::u_
integer I,
typename T>
409template<
typename... TYPES>
410template<original::u_
integer I,
typename T>
411original::tuple<TYPES...>::tupleImpl<I, T>::tupleImpl(tupleImpl<I, T>&& other) noexcept
412 : cur_elem(std::move(other.cur_elem)) {}
414template<
typename... TYPES>
415template<original::u_
integer I,
typename T>
416original::tuple<TYPES...>::tupleImpl<I, T>::tupleImpl(
const tupleImpl<I, T>& other)
417 : cur_elem(other.cur_elem) {}
419template<
typename... TYPES>
420template<original::u_
integer I,
typename T>
425 cur_elem = std::move(other.cur_elem);
429template<
typename... TYPES>
430template<original::u_
integer I,
typename T>
431template<original::u_
integer I_DIFF>
433 staticError<outOfBoundError, (I_DIFF > 0)>{};
438template<
typename... TYPES>
439template<original::u_
integer I,
typename T>
440template<original::u_
integer I_DIFF>
442 staticError<outOfBoundError, (I_DIFF > 0)>{};
447template<
typename... TYPES>
448template<original::u_
integer I,
typename T>
449template<original::u_
integer I_DIFF,
typename E>
451 staticError<outOfBoundError, (I_DIFF > 0)>{};
452 staticError<valueError, !std::is_convertible_v<E, T>>{};
454 cur_elem =
static_cast<T
>(e);
457template<
typename... TYPES>
458template<original::u_
integer I,
typename T>
461 if constexpr (Comparable<T>){
462 if (cur_elem != other.cur_elem)
463 return cur_elem < other.cur_elem ? -1 : 1;
468template<
typename... TYPES>
469template<original::u_
integer I,
typename T>
471 std::stringstream ss;
472 if constexpr (I != 0)
474 ss << formatString(cur_elem);
478template<
typename... TYPES>
479template<original::u_
integer I,
typename T,
typename TS>
480original::tuple<TYPES...>::tupleImpl<I, T, TS>::tupleImpl(
const T& cur,
const TS& next_elems)
481 : cur_elem(cur), next(next_elems) {}
483template<
typename... TYPES>
484template<original::u_
integer I,
typename T,
typename TS>
485original::tuple<TYPES...>::tupleImpl<I, T, TS>::tupleImpl(tupleImpl<I, T, TS>&& other) noexcept
486 : cur_elem(std::move(other.cur_elem)), next(std::move(other.next)) {}
488template<
typename... TYPES>
489template<original::u_
integer I,
typename T,
typename TS>
490original::tuple<TYPES...>::tupleImpl<I, T, TS>::tupleImpl(
const tupleImpl<I, T, TS>& other)
491 : cur_elem(other.cur_elem), next(other.next) {}
493template<
typename... TYPES>
494template<original::u_
integer I,
typename T,
typename TS>
496 tupleImpl<I, T, TS>&& other)
noexcept -> tupleImpl<I, T, TS>&
500 cur_elem = std::move(other.cur_elem);
501 next = std::move(other.next);
505template<
typename... TYPES>
506template<original::u_
integer I,
typename T,
typename TS>
507template<original::u_
integer I_DIFF>
509 if constexpr (I_DIFF == 0){
512 return next.template
get<I_DIFF - 1>();
516template<
typename... TYPES>
517template<original::u_
integer I,
typename T,
typename TS>
518template<original::u_
integer I_DIFF>
520 if constexpr (I_DIFF == 0){
523 return next.template
get<I_DIFF - 1>();
527template<
typename... TYPES>
528template<original::u_
integer I,
typename T,
typename TS>
529template<original::u_
integer I_DIFF,
typename E>
531 if constexpr (I_DIFF == 0){
532 staticError<valueError, !std::is_convertible_v<E, T>>{};
534 cur_elem =
static_cast<T
>(e);
536 next.template set<I_DIFF - 1,
E>(e);
540template<
typename... TYPES>
541template<original::u_
integer I,
typename T,
typename TS>
543 const tupleImpl<I, T, TS>& other)
const ->
integer
545 if constexpr (Comparable<T>){
546 if (cur_elem != other.cur_elem)
547 return cur_elem < other.cur_elem ? -1 : 1;
549 return next.compareTo(other.next);
552template<
typename... TYPES>
553template<original::u_
integer I,
typename T,
typename TS>
555 std::stringstream ss;
556 if constexpr (I != 0)
558 ss << formatString(cur_elem);
559 ss << formatString(next);
563template<
typename... TYPES>
565original::tuple<TYPES...>::tupleImpl<I, T, TS...>::tupleImpl(
const T& cur,
const TS&... next_elems)
566 : cur_elem(cur), next(next_elems...) {}
568template<
typename... TYPES>
570original::tuple<TYPES...>::tupleImpl<I, T, TS...>::tupleImpl(
const T& cur,
const tupleImpl<I + 1, TS...>& nt)
571 : cur_elem(cur), next(nt) {}
573template<
typename... TYPES>
575original::tuple<TYPES...>::tupleImpl<I, T, TS...>::tupleImpl(tupleImpl<I, T, TS...> &&other) noexcept
576 : cur_elem(std::move(other.cur_elem)), next(std::move(other.next)) {}
578template<
typename... TYPES>
580original::tuple<TYPES...>::tupleImpl<I, T, TS...>::tupleImpl(
const tupleImpl<I, T, TS...>& other)
581 : cur_elem(other.cur_elem), next(other.next) {}
583template<
typename... TYPES>
586 tupleImpl<I, T, TS...>&& other)
noexcept -> tupleImpl<I, T, TS...>&
590 cur_elem = std::move(other.cur_elem);
591 next = std::move(other.next);
595template<
typename... TYPES>
597template<original::u_
integer I_DIFF>
599 if constexpr (I_DIFF == 0){
602 return next.template
get<I_DIFF - 1>();
606template<
typename... TYPES>
608template<original::u_
integer I_DIFF>
610 if constexpr (I_DIFF == 0){
613 return next.template
get<I_DIFF - 1>();
617template<
typename... TYPES>
619template<original::u_
integer I_DIFF,
typename E>
621 if constexpr (I_DIFF == 0){
622 staticError<valueError, !std::is_convertible_v<E, T>>{};
624 cur_elem =
static_cast<T
>(e);
626 next.template set<I_DIFF - 1,
E>(e);
630template<
typename... TYPES>
634 if constexpr (Comparable<T>){
635 if (cur_elem != other.cur_elem)
636 return cur_elem < other.cur_elem ? -1 : 1;
641template<
typename... TYPES>
644 std::stringstream ss;
645 if constexpr (I != 0)
647 ss << formatString(cur_elem);
648 ss << formatString(next);
652template<
typename... TYPES>
654auto original::tuple<TYPES...>::_slice(std::integer_sequence<u_integer, IDX_S...>,
655 std::integral_constant<u_integer, BEGIN_IDX>)
const {
659template<
typename... TYPES>
661original::tuple<TYPES..., O_TYPES...>
662original::tuple<TYPES...>::_concat(
const tuple<O_TYPES...> &other,
663 std::integer_sequence<u_integer, T_SIZE...>,
664 std::integer_sequence<u_integer, O_SIZE...>)
const {
668template<
typename... TYPES>
669original::tuple<TYPES...>::tuple() : elems() {}
671template<
typename... TYPES>
672original::tuple<TYPES...>::tuple(
const TYPES&... e) : elems(e...) {}
674template<
typename... TYPES>
675original::tuple<TYPES...>::tuple(
const tuple& other) : elems(other.elems) {}
677template<
typename... TYPES>
679 if (
this == &other)
return *
this;
680 this->elems = other.elems;
684template<
typename... TYPES>
685original::tuple<TYPES...>::tuple(tuple&& other) noexcept
686 : elems(std::move(other.elems)) {}
688template<
typename... TYPES>
690 if (
this == &other)
return *
this;
691 this->elems = std::move(other.elems);
695template<
typename... TYPES>
701template<
typename... TYPES>
702template<original::u_
integer IDX>
707template<
typename... TYPES>
708template<original::u_
integer IDX>
713template<
typename... TYPES>
714template<original::u_
integer IDX,
typename E>
720template<
typename... TYPES>
721template<original::u_
integer BEGIN_IDX, original::u_
integer N_ELEMS>
723 constexpr bool out_of_bound = BEGIN_IDX >= SIZE || BEGIN_IDX + N_ELEMS > SIZE;
727 std::make_integer_sequence<u_integer, N_ELEMS>{},
728 std::integral_constant<u_integer, BEGIN_IDX>{}
732template<
typename... TYPES>
734 return elems.compareTo(other.elems);
737template<
typename... TYPES>
739 std::stringstream ss;
741 ss <<
"(" << elems <<
")";
745template<
typename... TYPES>
750template<
typename F_TYPE,
typename S_TYPE>
755template<
typename... L_TYPES,
typename... R_TYPES>
756original::tuple<L_TYPES..., R_TYPES...>
758 return lt._concat(rt,
759 std::make_integer_sequence<
u_integer,
sizeof...(L_TYPES)>{},
760 std::make_integer_sequence<
u_integer,
sizeof...(R_TYPES)>{});
763template<std::size_t I,
typename... TYPES>
765 return t.template
get<I>();
768template<std::size_t I,
typename... TYPES>
770 return t.template
get<I>();
773template<std::size_t I,
typename... TYPES>
775 return std::move(t.template
get<I>());
Base class for comparable objects.
Definition comparable.h:31
Container for two heterogeneous elements.
Definition couple.h:37
Base class providing polymorphic string conversion capabilities.
Definition printable.h:29
Abstract base class for unique element containers.
Definition set.h:44
Compile-time error assertion utility.
Definition error.h:73
Container for multiple heterogeneous elements.
Definition tuple.h:53
tuple & operator=(const tuple &other)
Copy assignment operator.
Definition tuple.h:678
std::string toString(bool enter) const override
Generate formatted string representation.
Definition tuple.h:738
const auto & get() const
Access element by index (const lvalue-reference version)
Definition tuple.h:703
friend tuple< L_TYPES..., R_TYPES... > operator+(const tuple< L_TYPES... > <, const tuple< R_TYPES... > &rt)
Concatenate two tuples (friend function)
std::string className() const override
Get class name identifier.
Definition tuple.h:746
integer compareTo(const tuple &other) const override
Compare two tuples lexicographically.
Definition tuple.h:733
static constexpr u_integer size()
Get the number of elements in the tuple.
Definition tuple.h:696
tuple & set(const E &e)
Set (modify) the value of the element at the specified index.
friend tuple< F_TYPE, S_TYPE > makeTuple(const couple< F_TYPE, S_TYPE > &cp)
Create a tuple from a couple.
auto slice() const
Slice the tuple from a specific index.
Definition tuple.h:722
Interface for objects that can be compared.
Generic pair container implementation.
constexpr auto & get(original::couple< F, S > &c) noexcept
Structured binding support - get for non-const lvalue reference.
Definition couple.h:364
Main namespace for the project Original.
Definition algorithms.h:21
auto operator+(const iterator< T > &it, integer steps) -> iterator< T > *
Adds a number of steps to the iterator's current position and returns a new iterator.
std::uint32_t u_integer
32-bit unsigned integer type for sizes and indexes
Definition config.h:43
std::int64_t integer
64-bit signed integer type for arithmetic operations
Definition config.h:35
tuple< F_TYPE, S_TYPE > makeTuple(const couple< F_TYPE, S_TYPE > &cp)
constexpr long double E
The mathematical constant E (Euler's number).
Definition maths.h:22
Interface for polymorphic string formatting and output.
Core type system foundations and concept definitions.