5 # ifndef VCCC_UTILITY_COMPRESSED_PAIR_HPP
6 # define VCCC_UTILITY_COMPRESSED_PAIR_HPP
9 # include <type_traits>
21 struct compressed_slot {
22 constexpr compressed_slot() =
default;
24 template<
typename U, std::enable_if_t<std::is_same<std::decay_t<U>, compressed_slot>::value == false,
int> = 0>
25 constexpr compressed_slot(U&& u) : value_(
std::forward<U>(u)) {}
27 template<std::
size_t I> constexpr std::enable_if_t<(I == index), T&>
get() & noexcept {
return value_; }
28 template<std::
size_t I> constexpr std::enable_if_t<(I == index), T&&>
get() && noexcept {
return std::move(value_); }
29 template<std::
size_t I> constexpr std::enable_if_t<(I == index),
const T&>
get() const & noexcept {
return value_; }
30 template<std::
size_t I> constexpr std::enable_if_t<(I == index),
const T&&>
get() const && noexcept {
return std::move(value_); }
36 template<
typename T, std::
size_t index>
37 struct compressed_slot<T, index, true> :
public T {
38 constexpr compressed_slot() =
default;
40 template<
typename U, std::enable_if_t<std::is_same<std::decay_t<U>, compressed_slot>::value == false,
int> = 0>
41 constexpr compressed_slot(U&& u) : T(
std::forward<U>(u)) {}
43 template<std::
size_t I> constexpr std::enable_if_t<(I == index), T&>
get() & noexcept {
return static_cast<T&
>(*this); }
44 template<std::
size_t I> constexpr std::enable_if_t<(I == index), T&&>
get() && noexcept {
return static_cast<T&&
>(*this); }
45 template<std::
size_t I> constexpr std::enable_if_t<(I == index),
const T&>
get() const & noexcept {
return static_cast<const T&
>(*this); }
46 template<std::
size_t I> constexpr std::enable_if_t<(I == index),
const T&&>
get() const && noexcept {
return static_cast<const T&&
>(*this); }
59 template<
typename T,
typename U>
60 class compressed_pair :
public detail::compressed_slot<T, 0>,
public detail::compressed_slot<U, 1> {
62 using first_base = detail::compressed_slot<T, 0>;
63 using second_base = detail::compressed_slot<U, 1>;
79 template<
typename T2,
typename U2, std::enable_if_t<
conjunction<
80 std::is_constructible<T, T2>,
81 std::is_constructible<U, U2>
83 constexpr
compressed_pair(T2&& t, U2&& u) : first_base(
std::forward<T2>(t)), second_base(
std::forward<U2>(u)) {}
85 constexpr T&
first() & noexcept {
return first_base::template get<0>(); }
86 constexpr T&&
first() && noexcept {
return std::move(first_base::template get<0>()); }
87 constexpr
const T&
first() const & noexcept {
return first_base::template get<0>(); }
88 constexpr
const T&&
first() const && noexcept {
return std::move(first_base::template get<0>()); }
90 constexpr U&
second() & noexcept {
return second_base::template get<1>(); }
91 constexpr U&&
second() && noexcept {
return std::move(second_base::template get<1>()); }
92 constexpr
const U&
second() const & noexcept {
return second_base::template get<1>(); }
93 constexpr
const U&&
second() const && noexcept {
return std::move(second_base::template get<1>()); }
106 template<
typename T,
typename U>
107 constexpr std::enable_if_t<conjunction<is_swappable<T>, is_swappable<U>>
::value>
118 template<std::
size_t I>
struct compressed_pair_getter;
120 struct compressed_pair_getter<0> {
121 template<
typename T,
typename U>
static constexpr T&
get(compressed_pair<T, U>& p) noexcept {
return p.first(); }
122 template<
typename T,
typename U>
static constexpr
const T&
get(
const compressed_pair<T, U>& p) noexcept {
return p.first(); }
123 template<
typename T,
typename U>
static constexpr T&&
get(compressed_pair<T, U>&& p) noexcept {
return std::move(p.first()); }
124 template<
typename T,
typename U>
static constexpr
const T&&
get(
const compressed_pair<T, U>&& p) noexcept {
return std::move(p.first()); }
127 struct compressed_pair_getter<1> {
128 template<
typename T,
typename U>
static constexpr U&
get(compressed_pair<T, U>& p) noexcept {
return p.second(); }
129 template<
typename T,
typename U>
static constexpr
const U&
get(
const compressed_pair<T, U>& p) noexcept {
return p.second(); }
130 template<
typename T,
typename U>
static constexpr U&&
get(compressed_pair<T, U>&& p) noexcept {
return std::move(p.second()); }
131 template<
typename T,
typename U>
static constexpr
const U&&
get(
const compressed_pair<T, U>&& p) noexcept {
return std::move(p.second()); }
140 template<
typename T,
typename U>
struct tuple_element<0,
vccc::compressed_pair<T, U>> {
using type = T; };
141 template<
typename T,
typename U>
struct tuple_element<1,
vccc::compressed_pair<T, U>> {
using type = U; };
142 template<
typename T,
typename U>
struct tuple_size<
vccc::compressed_pair<T, U>> : std::integral_constant<std::size_t, 2> {};
144 template<std::
size_t I,
typename T,
typename U>
148 template<std::
size_t I,
typename T,
typename U>
152 template<std::
size_t I,
typename T,
typename U>
156 template<std::
size_t I,
typename T,
typename U>
An size-optimized pair using empty base optimization.
Definition: compressed_pair.hpp:60
constexpr T & first() &noexcept
Definition: compressed_pair.hpp:85
constexpr compressed_pair()=default
constexpr const U && second() const &&noexcept
Definition: compressed_pair.hpp:93
constexpr compressed_pair(compressed_pair_empty_t, U2 &&u)
Definition: compressed_pair.hpp:77
constexpr compressed_pair(T2 &&t, compressed_pair_empty_t)
Definition: compressed_pair.hpp:74
constexpr compressed_pair(T2 &&t, U2 &&u)
Definition: compressed_pair.hpp:83
constexpr std::enable_if_t< conjunction< is_swappable< T >, is_swappable< U > >::value > swap(compressed_pair &other) noexcept(conjunction< is_nothrow_swappable< T >, is_nothrow_swappable< U >>::value)
Definition: compressed_pair.hpp:96
constexpr U && second() &&noexcept
Definition: compressed_pair.hpp:91
constexpr const U & second() const &noexcept
Definition: compressed_pair.hpp:92
U second_type
Definition: compressed_pair.hpp:67
constexpr T && first() &&noexcept
Definition: compressed_pair.hpp:86
constexpr U & second() &noexcept
Definition: compressed_pair.hpp:90
constexpr const T && first() const &&noexcept
Definition: compressed_pair.hpp:88
T first_type
Definition: compressed_pair.hpp:66
constexpr const T & first() const &noexcept
Definition: compressed_pair.hpp:87
void swap(::vccc::optional< T > &lhs, ::vccc::optional< T > &rhs) noexcept(noexcept(lhs.swap(rhs)))
Definition: swap.h:30
constexpr std::enable_if_t< conjunction< is_swappable< T >, is_swappable< U > >::value > swap(compressed_pair< T, U > &lhs, compressed_pair< T, U > &rhs) noexcept(conjunction< is_nothrow_swappable< T >, is_nothrow_swappable< U >>::value)
Definition: compressed_pair.hpp:108
constexpr VCCC_INLINE_OR_STATIC compressed_pair_empty_t compressed_pair_empty
Definition: compressed_pair.hpp:55
constexpr variant_alternative_t< I, variant< Types... > > & get(variant< Types... > &v)
Definition: variant.hpp:770
#define VCCC_INLINE_OR_STATIC
Definition: inline_or_static.hpp:9
Definition: matrix.hpp:495
constexpr std::enable_if_t<(I< m *n), typename vccc::Matrix< T, m, n >::value_type & > get(vccc::Matrix< T, m, n > &matrix)
Definition: matrix.hpp:499
constexpr const T && get(const vccc::compressed_pair< U, T > &&p) noexcept
Definition: compressed_pair.hpp:169
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
T type
Definition: compressed_pair.hpp:140
U type
Definition: compressed_pair.hpp:141
Definition: compressed_pair.hpp:54
Definition: conjunction.hpp:22
Definition: is_swappable.hpp:125
Definition: is_swappable.hpp:119