compressed_pair 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #ifndef __GBLIBCPP_BITS_COMPRESSED_PAIR__
  2. #define __GBLIBCPP_BITS_COMPRESSED_PAIR__
  3. #include <utility>
  4. namespace std::impl {
  5. struct default_construct_t { };
  6. template <typename T, int, bool is_empty = __is_empty(T)>
  7. struct compressed_pair_element
  8. {
  9. constexpr compressed_pair_element() = default;
  10. constexpr compressed_pair_element(const compressed_pair_element&) = default;
  11. constexpr compressed_pair_element(compressed_pair_element&&) = default;
  12. constexpr compressed_pair_element& operator=(const compressed_pair_element&) = default;
  13. constexpr compressed_pair_element& operator=(compressed_pair_element&&) = default;
  14. constexpr compressed_pair_element(default_construct_t): value{} { }
  15. constexpr compressed_pair_element(const T& x): value{x} { }
  16. constexpr compressed_pair_element(T&& x): value{std::move(x)} { }
  17. constexpr T& get() noexcept { return value; }
  18. constexpr const T& get() const noexcept { return value; }
  19. T value;
  20. };
  21. template <typename T, int N>
  22. struct compressed_pair_element<T, N, true> : private T
  23. {
  24. constexpr compressed_pair_element() = default;
  25. constexpr compressed_pair_element(const compressed_pair_element&) = default;
  26. constexpr compressed_pair_element(compressed_pair_element&&) = default;
  27. constexpr compressed_pair_element& operator=(const compressed_pair_element&) = default;
  28. constexpr compressed_pair_element& operator=(compressed_pair_element&&) = default;
  29. constexpr compressed_pair_element(default_construct_t): T{} { }
  30. constexpr compressed_pair_element(const T& x): T{x} { }
  31. constexpr compressed_pair_element(T&& x): T{std::move(x)} { }
  32. constexpr T& get() noexcept { return *this; }
  33. constexpr const T& get() const noexcept { return *this; }
  34. };
  35. template <typename T1, typename T2>
  36. struct compressed_pair
  37. : private compressed_pair_element<T1, 0>, private compressed_pair_element<T2, 1> {
  38. using Base1 = compressed_pair_element<T1, 0>;
  39. using Base2 = compressed_pair_element<T2, 1>;
  40. constexpr compressed_pair() = default;
  41. constexpr compressed_pair(const compressed_pair&) = default;
  42. constexpr compressed_pair(compressed_pair&&) = default;
  43. constexpr compressed_pair& operator=(const compressed_pair&) = default;
  44. constexpr compressed_pair& operator=(compressed_pair&&) = default;
  45. constexpr compressed_pair(default_construct_t): Base1{default_construct_t{}}, Base2{default_construct_t{}} { }
  46. constexpr compressed_pair(const T1& x, const T2& y): Base1{x}, Base2{y} { }
  47. constexpr compressed_pair(T1&& x, T2&& y): Base1{std::move(x)}, Base2{std::move(y)} { }
  48. constexpr T1& first() noexcept { return Base1::get(); }
  49. constexpr const T1& first() const noexcept { return Base1::get(); }
  50. constexpr T2& second() noexcept { return Base2::get(); }
  51. constexpr const T2& second() const noexcept { return Base2::get(); }
  52. };
  53. } // namespace std::impl
  54. #endif