Skip to content

Instantly share code, notes, and snippets.

@DrkWithT
Created July 9, 2024 03:47
Show Gist options
  • Save DrkWithT/5bf1d13cbfa553d6736bc052a61accf4 to your computer and use it in GitHub Desktop.
Save DrkWithT/5bf1d13cbfa553d6736bc052a61accf4 to your computer and use it in GitHub Desktop.
My toy implementation of C++ STL pair class.
#include <type_traits>
#include <utility>
#include <stdexcept>
#include <print>
template <std::size_t Index, typename T1, typename T2>
struct TpChooser {};
template <typename T1, typename T2>
struct TpChooser<0, T1, T2>
{
using type = T1;
};
template <typename T1, typename T2>
struct TpChooser<1, T1, T2>
{
using type = T2;
};
template <std::size_t Index, typename T1, typename T2>
using chosen_type_t = typename TpChooser<Index, T1, T2>::type;
template <std::size_t Pos, typename T>
class Cell
{
private:
using naked_tp_t = std::remove_cv_t<T>;
naked_tp_t value;
public:
constexpr Cell() noexcept
: value {} {}
template <typename CT>
constexpr Cell(CT&& fw_arg)
: value {fw_arg} {}
void setValue(const T& next_value)
{
this->value = next_value;
}
constexpr const naked_tp_t& getValue() const noexcept { return value; }
};
template <typename T1, typename T2>
class Pair : public Cell<0, T1>, public Cell<1, T2>
{
private:
using head_t = Cell<0, T1>;
using tail_t = Cell<1, T2>;
public:
static constexpr std::size_t length = 2;
constexpr Pair() noexcept
: head_t (), tail_t () {}
template <typename CT1, typename CT2>
constexpr Pair(CT1&& fw0, CT2&& fw1)
: head_t (fw0), tail_t (fw1) {}
constexpr const T1& getHead() const noexcept
{
return head_t::getValue();
}
constexpr const T2& getTail() const noexcept
{
return tail_t::getValue();
}
Pair<T1, T2>& operator=(const Pair<T1, T2>& other) noexcept
{
if (&other == this)
return *this;
head_t::setValue(other.getHead());
tail_t::setValue(other.getTail());
return *this;
}
friend constexpr bool operator==(const Pair& lhs, const Pair& rhs) noexcept
{
return lhs.getHead() == rhs.getHead() && lhs.getTail() == rhs.getTail();
}
};
template <typename T1, typename T2>
constexpr auto makePair(T1&& a, T2&& b)
{
return Pair<T1, T2> {a, b};
}
template <std::size_t Index, typename T1, typename T2>
constexpr auto getFromPairAt(const Pair<T1, T2>& arg) noexcept -> chosen_type_t<Index, T1, T2>
{
static_assert(Index < arg.length);
if constexpr (Index == 0)
return arg.getHead();
return arg.getTail();
}
template <std::size_t Index, typename T1, typename T2>
constexpr auto getFromPairAt(const Pair<T1, T2>&& arg) noexcept -> chosen_type_t<Index, T1, T2>
{
static_assert(Index < arg.length);
if constexpr (Index == 0)
return arg.getHead();
return arg.getTail();
}
int main()
{
Pair<int, double> nums0;
auto nums1 = makePair(42, 10.5);
auto nums2 = makePair(69, 6.9);
std::print("nums0 = {}, {}\n", nums0.getHead(), nums0.getTail());
std::print("nums1 = {}, {}\n", nums1.getHead(), nums1.getTail());
std::print("nums2 = {}, {}\n", nums2.getHead(), nums2.getTail());
std::print("nums0[0] = {}\n", getFromPairAt<0>(nums0));
std::print("nums0[1] = {}\n", getFromPairAt<1>(nums0));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment