#ifndef CLASS_TUPLE #define CLASS_TUPLE #include namespace std { template struct tuple_size; // template // struct tuple_element; template struct tuple_element; }; static constexpr int maximum(int a, int b) { if (a > b) return a; return b; } template struct ArgType { using type = typename std::conditional< index == 0, A, typename ArgType::type>::type; }; template struct ArgType<0, T> { using type = T; }; template class tuple { public: struct empty { auto operator <=> (const empty& other __attribute__((unused))) const { return 0; } }; template struct elements_t { static const size_t index = _index; M car; typename std::conditional< sizeof...(Es) == 0, empty, elements_t<_index + 1, Es...>>::type cdr; elements_t() { ; } elements_t(M m, Es... e): car(m), cdr(e...) { ; } int operator <=> (const elements_t& other) const { auto car_res = (car <=> other.car); if (car_res > 0) return 1; if (car_res < 0) return -1; auto cdr_res = (cdr <=> other.cdr); if (cdr_res > 0) return 1; if (cdr_res < 0) return -1; return 0; } }; public: elements_t<0, Ts...> elements; public: tuple() { ; } tuple(Ts... _elements): elements(_elements...) { ; } private: template R& helper(T& holder) { if constexpr(T::index == index) return holder.car; else return helper(holder.cdr); }; public: template ArgType::type& get() { return helper::type>(elements); } auto first() { return this->get<0>(); } auto second() { return this->get<1>(); } int operator <=> (const tuple& other) const { return elements <=> other.elements; } ~tuple() { ; } }; template struct std::tuple_size> { static constexpr size_t value = sizeof...(Ts); }; template struct std::tuple_element<0, std::tuple> { using type = car; }; template struct std::tuple_element>: std::tuple_element> { }; template struct std::tuple_element<0, tuple> { using type = car; }; template struct std::tuple_element>: std::tuple_element> { }; #endif