1 // Copyright 2018 Hans Dembinski
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)
7 #ifndef BOOST_HISTOGRAM_DETAIL_COMPRESSED_PAIR_HPP
8 #define BOOST_HISTOGRAM_DETAIL_COMPRESSED_PAIR_HPP
10 #include <type_traits>
17 template <class T1, class T2, bool B>
18 class compressed_pair_impl;
20 // normal implementation
21 template <class T1, class T2>
22 class compressed_pair_impl<T1, T2, false> {
24 using first_type = T1;
25 using second_type = T2;
27 compressed_pair_impl() = default;
29 compressed_pair_impl(first_type&& x, second_type&& y)
30 : first_(std::move(x)), second_(std::move(y)) {}
32 compressed_pair_impl(const first_type& x, const second_type& y)
33 : first_(x), second_(y) {}
35 compressed_pair_impl(first_type&& x) : first_(std::move(x)) {}
36 compressed_pair_impl(const first_type& x) : first_(x) {}
38 first_type& first() noexcept { return first_; }
39 second_type& second() noexcept { return second_; }
40 const first_type& first() const noexcept { return first_; }
41 const second_type& second() const noexcept { return second_; }
48 // compressed implementation, T2 consumes no space
49 template <class T1, class T2>
50 class compressed_pair_impl<T1, T2, true> : protected T2 {
52 using first_type = T1;
53 using second_type = T2;
55 compressed_pair_impl() = default;
57 compressed_pair_impl(first_type&& x, second_type&& y)
58 : T2(std::move(y)), first_(std::move(x)) {}
60 compressed_pair_impl(const first_type& x, const second_type& y) : T2(y), first_(x) {}
62 compressed_pair_impl(first_type&& x) : first_(std::move(x)) {}
63 compressed_pair_impl(const first_type& x) : first_(x) {}
65 first_type& first() noexcept { return first_; }
66 second_type& second() noexcept { return static_cast<second_type&>(*this); }
67 const first_type& first() const noexcept { return first_; }
68 const second_type& second() const noexcept {
69 return static_cast<const second_type&>(*this);
76 template <typename T1, typename T2>
77 using compressed_pair =
78 compressed_pair_impl<T1, T2, (!std::is_final<T2>::value && std::is_empty<T2>::value)>;
80 template <class T, class U>
81 void swap(compressed_pair<T, U>& a, compressed_pair<T, U>& b) noexcept(
82 std::is_nothrow_move_constructible<T>::value&& std::is_nothrow_move_assignable<
83 T>::value&& std::is_nothrow_move_constructible<U>::value&&
84 std::is_nothrow_move_assignable<U>::value) {
86 swap(a.first(), b.first());
87 swap(a.second(), b.second());
91 } // namespace histogram