sat-solver/tuple.hpp
2025-03-07 09:45:39 -06:00

206 lines
4.5 KiB
C++

#ifndef CLASS_TUPLE
#define CLASS_TUPLE
#include <type_traits>
namespace std
{
template<class T>
struct tuple_size;
// template<std::size_t I, class... Types>
// struct tuple_element;
template<size_t __i, typename _Tp>
struct tuple_element;
};
static constexpr int maximum(int a, int b)
{
if (a > b)
return a;
return b;
}
template<int index, typename A = void, typename... Args>
struct ArgType
{
using type =
typename std::conditional<
index == 0,
A,
typename ArgType<maximum(index - 1, 0), Args...>::type>::type;
};
template<typename T>
struct ArgType<0, T>
{
using type = T;
};
template<typename... Ts>
class tuple
{
public:
struct empty
{
auto operator <=> (const empty& other __attribute__((unused))) const
{
return 0;
}
};
template <size_t _index, typename M = void, typename... Es>
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<size_t index, typename R, typename T>
R& helper(T& holder)
{
if constexpr(T::index == index)
return holder.car;
else
return helper<index, R>(holder.cdr);
};
public:
template<size_t index>
ArgType<index, Ts...>::type& get()
{
return helper<index, typename ArgType<index, Ts...>::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<typename... Ts>
struct std::tuple_size<tuple<Ts ...>>
{
static constexpr size_t value = sizeof...(Ts);
};
template<class car, class... cdr>
struct std::tuple_element<0, std::tuple<car, cdr ...>>
{
using type = car;
};
template<std::size_t I, class car, class... cdr>
struct std::tuple_element<I, std::tuple<car, cdr ...>>:
std::tuple_element<I - 1, std::tuple<cdr ...>>
{
};
template<class car, class... cdr>
struct std::tuple_element<0, tuple<car, cdr ...>>
{
using type = car;
};
template<std::size_t I, class car, class... cdr>
struct std::tuple_element<I, tuple<car, cdr ...>>:
std::tuple_element<I - 1, tuple<cdr ...>>
{
};
#endif