compressed_pair.hpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Copyright 2018 Hans Dembinski
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_HISTOGRAM_DETAIL_COMPRESSED_PAIR_HPP
  7. #define BOOST_HISTOGRAM_DETAIL_COMPRESSED_PAIR_HPP
  8. #include <type_traits>
  9. #include <utility>
  10. namespace boost {
  11. namespace histogram {
  12. namespace detail {
  13. template <typename T1, typename T2, bool B>
  14. class compressed_pair_impl;
  15. template <typename T1, typename T2>
  16. class compressed_pair_impl<T1, T2, true> : protected T2 {
  17. public:
  18. template <typename U1, typename U2>
  19. compressed_pair_impl(U1&& u1, U2&& u2)
  20. : T2(std::forward<U2>(u2)), first_(std::forward<U1>(u1)) {}
  21. template <typename U1>
  22. compressed_pair_impl(U1&& u1) : first_(std::forward<U1>(u1)) {}
  23. compressed_pair_impl() = default;
  24. T1& first() { return first_; }
  25. T2& second() { return static_cast<T2&>(*this); }
  26. const T1& first() const { return first_; }
  27. const T2& second() const { return static_cast<const T2&>(*this); }
  28. private:
  29. T1 first_;
  30. };
  31. template <typename T1, typename T2>
  32. class compressed_pair_impl<T1, T2, false> {
  33. public:
  34. template <typename U1, typename U2>
  35. compressed_pair_impl(U1&& u1, U2&& u2)
  36. : first_(std::forward<U1>(u1)), second_(std::forward<U2>(u2)) {}
  37. template <typename U1>
  38. compressed_pair_impl(U1&& u1) : first_(std::forward<U1>(u1)) {}
  39. compressed_pair_impl() = default;
  40. T1& first() { return first_; }
  41. T2& second() { return second_; }
  42. const T1& first() const { return first_; }
  43. const T2& second() const { return second_; }
  44. private:
  45. T1 first_;
  46. T2 second_;
  47. };
  48. template <typename... Ts>
  49. void swap(compressed_pair_impl<Ts...>& a, compressed_pair_impl<Ts...>& b) {
  50. using std::swap;
  51. swap(a.first(), b.first());
  52. swap(a.second(), b.second());
  53. }
  54. template <typename T1, typename T2>
  55. using compressed_pair =
  56. compressed_pair_impl<T1, T2, (!std::is_final<T2>::value && std::is_empty<T2>::value)>;
  57. } // namespace detail
  58. } // namespace histogram
  59. } // namespace boost
  60. #endif