/* Utilities for OctaSTD. * * This file is part of OctaSTD. See COPYING.md for futher information. */ #ifndef OSTD_UTILITY_HH #define OSTD_UTILITY_HH #include #include #include #include #include "ostd/types.hh" namespace ostd { namespace detail { template, std::remove_cv_t>, bool = std::is_empty_v, bool = std::is_empty_v > constexpr size_t CompressedPairSwitch = detail::Undefined(); /* neither empty */ template constexpr size_t CompressedPairSwitch = 0; /* first empty */ template constexpr size_t CompressedPairSwitch = 1; /* second empty */ template constexpr size_t CompressedPairSwitch = 2; /* both empty, not the same */ template constexpr size_t CompressedPairSwitch = 3; /* both empty and same */ template constexpr size_t CompressedPairSwitch = 1; template> struct CompressedPairBase; template struct CompressedPairBase { T p_first; U p_second; template CompressedPairBase(TT &&a, UU &&b): p_first(std::forward(a)), p_second(std::forward(b)) {} template CompressedPairBase( std::piecewise_construct_t, std::tuple &fa, std::tuple &sa, std::index_sequence, std::index_sequence ); T &first() { return p_first; } T const &first() const { return p_first; } U &second() { return p_second; } U const &second() const { return p_second; } void swap(CompressedPairBase &v) { swap_adl(p_first, v.p_first); swap_adl(p_second, v.p_second); } }; template struct CompressedPairBase: T { U p_second; template CompressedPairBase(TT &&a, UU &&b): T(std::forward(a)), p_second(std::forward(b)) {} template CompressedPairBase( std::piecewise_construct_t, std::tuple &fa, std::tuple &sa, std::index_sequence, std::index_sequence ); T &first() { return *this; } T const &first() const { return *this; } U &second() { return p_second; } U const &second() const { return p_second; } void swap(CompressedPairBase &v) { swap_adl(p_second, v.p_second); } }; template struct CompressedPairBase: U { T p_first; template CompressedPairBase(TT &&a, UU &&b): U(std::forward(b)), p_first(std::forward(a)) {} template CompressedPairBase( std::piecewise_construct_t, std::tuple &fa, std::tuple &sa, std::index_sequence, std::index_sequence ); T &first() { return p_first; } T const &first() const { return p_first; } U &second() { return *this; } U const &second() const { return *this; } void swap(CompressedPairBase &v) { swap_adl(p_first, v.p_first); } }; template struct CompressedPairBase: T, U { template CompressedPairBase(TT &&a, UU &&b): T(std::forward(a)), U(std::forward(b)) {} template CompressedPairBase( std::piecewise_construct_t, std::tuple &fa, std::tuple &sa, std::index_sequence, std::index_sequence ); T &first() { return *this; } T const &first() const { return *this; } U &second() { return *this; } U const &second() const { return *this; } void swap(CompressedPairBase &) {} }; template struct CompressedPair: CompressedPairBase { using Base = CompressedPairBase; template CompressedPair(TT &&a, UU &&b): Base(std::forward(a), std::forward(b)) {} template CompressedPair( std::piecewise_construct_t pc, std::tuple fa, std::tuple sa ): Base( pc, fa, sa, std::make_index_sequence(), std::make_index_sequence() ) {} T &first() { return Base::first(); } T const &first() const { return Base::first(); } U &second() { return Base::second(); } U const &second() const { return Base::second(); } void swap(CompressedPair &v) { Base::swap(v); } }; template template CompressedPairBase::CompressedPairBase( std::piecewise_construct_t, std::tuple &fa, std::tuple &sa, std::index_sequence, std::index_sequence ): p_first(std::forward(std::get(fa))...), p_second(std::forward(std::get(sa))...) {} template template CompressedPairBase::CompressedPairBase( std::piecewise_construct_t, std::tuple &fa, std::tuple &sa, std::index_sequence, std::index_sequence ): T(std::forward(std::get(fa))...), p_second(std::forward(std::get(sa))...) {} template template CompressedPairBase::CompressedPairBase( std::piecewise_construct_t, std::tuple &fa, std::tuple &sa, std::index_sequence, std::index_sequence ): U(std::forward(std::get(sa))...), p_first(std::forward(std::get(fa))...) {} template template CompressedPairBase::CompressedPairBase( std::piecewise_construct_t, std::tuple &fa, std::tuple &sa, std::index_sequence, std::index_sequence ): T(std::forward(std::get(fa))...), U(std::forward(std::get(sa))...) {} } /* namespace detail */ } /* namespace ostd */ #endif