Horizon
compressed_pair.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Eric Niebler 2013-present
5 // Copyright Casey Carter 2016
6 //
7 // Use, modification and distribution is subject to the
8 // Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11 //
12 // Project home: https://github.com/ericniebler/range-v3
13 //
14 
15 #ifndef RANGES_V3_UTILITY_COMPRESSED_PAIR_HPP
16 #define RANGES_V3_UTILITY_COMPRESSED_PAIR_HPP
17 
18 #include <type_traits>
19 #include <utility>
20 
21 #include <meta/meta.hpp>
22 
23 #include <concepts/concepts.hpp>
24 
25 #include <range/v3/range_fwd.hpp>
26 
27 #include <range/v3/utility/box.hpp>
28 #include <range/v3/utility/static_const.hpp>
29 
30 #include <range/v3/detail/prologue.hpp>
31 
32 namespace ranges
33 {
35  namespace compressed_tuple_detail
36  {
37  // tagging individual elements with the complete type list disambiguates
38  // base classes when composing compressed_tuples recursively.
39  template<typename T, std::size_t I, typename... Ts>
40  using storage = box<T, meta::list<meta::size_t<I>, Ts...>>;
41 
42  template<typename List, typename Indices>
43  struct compressed_tuple_;
44  template<typename... Ts, std::size_t... Is>
45  struct RANGES_EMPTY_BASES
46  compressed_tuple_<meta::list<Ts...>, meta::index_sequence<Is...>>
47  : storage<Ts, Is, Ts...>...
48  {
49  static_assert(same_as<meta::index_sequence<Is...>,
50  meta::make_index_sequence<sizeof...(Is)>>,
51  "What madness is this?!?");
52 
53  compressed_tuple_() = default;
54 
55  template<typename... Args,
56  meta::if_<meta::and_c<META_IS_CONSTRUCTIBLE(Ts, Args)...>, int> = 0>
57  constexpr compressed_tuple_(Args &&... args) noexcept(
58  meta::strict_and<std::is_nothrow_constructible<storage<Ts, Is, Ts...>,
59  Args>...>::value)
60  : storage<Ts, Is, Ts...>{static_cast<Args &&>(args)}...
61  {}
62 
63  template<
64  typename... Us,
65  meta::if_<meta::and_c<META_IS_CONSTRUCTIBLE(Us, Ts const &)...>, int> = 0>
66  constexpr operator std::tuple<Us...>() const noexcept(
67  meta::strict_and<std::is_nothrow_constructible<Us, Ts const &>...>::value)
68  {
69  return std::tuple<Us...>{get<Is>(*this)...};
70  }
71 
72  template<std::size_t I, typename T = meta::at_c<meta::list<Ts...>, I>>
73  friend constexpr T & get(compressed_tuple_ & tuple) noexcept
74  {
75  return static_cast<storage<T, I, Ts...> &>(tuple).get();
76  }
77  template<std::size_t I, typename T = meta::at_c<meta::list<Ts...>, I>>
78  friend constexpr T const & get(compressed_tuple_ const & tuple) noexcept
79  {
80  return static_cast<storage<T, I, Ts...> const &>(tuple).get();
81  }
82  template<std::size_t I, typename T = meta::at_c<meta::list<Ts...>, I>>
83  friend constexpr T && get(compressed_tuple_ && tuple) noexcept
84  {
85  return static_cast<storage<T, I, Ts...> &&>(tuple).get();
86  }
87  template<std::size_t I, typename T = meta::at_c<meta::list<Ts...>, I>>
88  friend constexpr T const && get(compressed_tuple_ const && tuple) noexcept
89  {
90  return static_cast<storage<T, I, Ts...> const &&>(tuple).get();
91  }
92  };
93 
94  template<typename... Ts>
95  using compressed_tuple RANGES_DEPRECATED(
96  "ranges::compressed_tuple is deprecated.") =
97  compressed_tuple_<meta::list<Ts...>,
98  meta::make_index_sequence<sizeof...(Ts)>>;
99  } // namespace compressed_tuple_detail
101 
102  using compressed_tuple_detail::compressed_tuple;
103 
105  {
106  // clang-format off
107  template<typename... Args>
108  constexpr auto CPP_auto_fun(operator())(Args &&... args) (const)
109  (
110  return compressed_tuple<bind_element_t<Args>...>{
111  static_cast<Args &&>(args)...}
112  )
113  // clang-format on
114  };
115 
118  RANGES_INLINE_VARIABLE(make_compressed_tuple_fn, make_compressed_tuple)
119 
120  template<typename First, typename Second>
121  struct RANGES_EMPTY_BASES compressed_pair
122  : box<First, meta::size_t<0>>
123  , box<Second, meta::size_t<1>>
124  {
125  using first_type = First;
126  using second_type = Second;
127 
128  compressed_pair() = default;
129 
130  template(typename U, typename V)(
131  requires constructible_from<First, U> AND constructible_from<Second, V>)
132  constexpr compressed_pair(U && u, V && v) //
133  noexcept(noexcept(First((U &&) u)) && noexcept(Second((V &&) v)))
134  : box<First, meta::size_t<0>>{(U &&) u}
135  , box<Second, meta::size_t<1>>{(V &&) v}
136  {}
137 
138  constexpr First & first() &
139  {
140  return this->box<First, meta::size_t<0>>::get();
141  }
142  constexpr First const & first() const &
143  {
144  return this->box<First, meta::size_t<0>>::get();
145  }
146  constexpr First && first() &&
147  {
148  return static_cast<First &&>(this->box<First, meta::size_t<0>>::get());
149  }
150 
151  constexpr Second & second() &
152  {
153  return this->box<Second, meta::size_t<1>>::get();
154  }
155  constexpr Second const & second() const &
156  {
157  return this->box<Second, meta::size_t<1>>::get();
158  }
159  constexpr Second && second() &&
160  {
161  return static_cast<Second &&>(this->box<Second, meta::size_t<1>>::get());
162  }
163 
164  template(typename F, typename S)(
165  requires convertible_to<First const &, F> AND
166  convertible_to<Second const &, S>)
167  constexpr
168  operator std::pair<F, S>() const
169  {
170  return std::pair<F, S>{first(), second()};
171  }
172  };
173 
175  {
176  // clang-format off
177  template<typename First, typename Second>
178  constexpr auto CPP_auto_fun(operator())(First &&f, Second &&s) (const)
179  (
180  return compressed_pair<bind_element_t<First>, bind_element_t<Second>>{
181  static_cast<First &&>(f), static_cast<Second &&>(s)
182  }
183  )
184  // clang-format on
185  };
186 
189  RANGES_INLINE_VARIABLE(make_compressed_pair_fn, make_compressed_pair)
190 } // namespace ranges
191 
192 RANGES_DIAGNOSTIC_PUSH
193 RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
194 namespace std
195 {
196  template<typename... Ts, size_t... Is>
197  struct tuple_size<::ranges::compressed_tuple_detail::compressed_tuple_<
198  ::meta::list<Ts...>, ::meta::index_sequence<Is...>>>
199  : integral_constant<size_t, sizeof...(Ts)>
200  {};
201 
202  template<size_t I, typename... Ts, size_t... Is>
203  struct tuple_element<I, ::ranges::compressed_tuple_detail::compressed_tuple_<
204  ::meta::list<Ts...>, ::meta::index_sequence<Is...>>>
205  {
206  using type = ::meta::at_c<::meta::list<Ts...>, I>;
207  };
208 
209  template<typename First, typename Second>
210  struct tuple_size<::ranges::compressed_pair<First, Second>>
211  : integral_constant<size_t, 2>
212  {};
213 
214  template<typename First, typename Second>
215  struct tuple_element<0, ::ranges::compressed_pair<First, Second>>
216  {
217  using type = First;
218  };
219 
220  template<typename First, typename Second>
221  struct tuple_element<1, ::ranges::compressed_pair<First, Second>>
222  {
223  using type = Second;
224  };
225 } // namespace std
226 RANGES_DIAGNOSTIC_POP
227 
228 #include <range/v3/detail/epilogue.hpp>
229 
230 #endif
Definition: box.hpp:163
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
_t< detail::make_indices_< N, index_sequence< 0 >, detail::strategy_(1, N)> > make_index_sequence
Generate index_sequence containing integer constants [0,1,2,...,N-1].
Definition: meta.hpp:473
std::integral_constant< std::size_t, N > size_t
An integral constant wrapper for std::size_t.
Definition: meta.hpp:163
_t< detail::at_< L, N > > at_c
Return the N th element in the meta::list L.
Definition: meta.hpp:1962
front< Pair > first
Retrieve the first element of the pair Pair.
Definition: meta.hpp:2251
front< pop_front< Pair > > second
Retrieve the first element of the pair Pair.
Definition: meta.hpp:2256
_t< detail::_if_< list< Args... > >> if_
Select one type or another depending on a compile-time Boolean.
Definition: meta.hpp:1247
Tiny meta-programming library.
Tiny metaprogramming library.
Definition: meta.hpp:116
Definition: meta.hpp:1383
A container for a sequence of compile-time integer constants.
Definition: meta.hpp:434
A list of types.
Definition: meta.hpp:1684
Definition: compressed_pair.hpp:124
Definition: compressed_pair.hpp:175
Definition: compressed_pair.hpp:105