Backport
utility.hpp
Go to the documentation of this file.
1 
7 /*
8  The MIT License (MIT)
9 
10  Copyright (c) 2020 Matthew Rodusek All rights reserved.
11 
12  Permission is hereby granted, free of charge, to any person obtaining a copy
13  of this software and associated documentation files (the "Software"), to deal
14  in the Software without restriction, including without limitation the rights
15  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16  copies of the Software, and to permit persons to whom the Software is
17  furnished to do so, subject to the following conditions:
18 
19  The above copyright notice and this permission notice shall be included in
20  all copies or substantial portions of the Software.
21 
22  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28  SOFTWARE.
29 */
30 #ifndef BPSTD_UTILITY_HPP
31 #define BPSTD_UTILITY_HPP
32 
33 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
34 # pragma once
35 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
36 
37 #include "detail/config.hpp"
38 #include "detail/move.hpp" // IWYU pragma: export
39 #include "type_traits.hpp" // add_const_t
40 
41 #include <utility> // to proxy the API
42 #include <cstddef> // std::size_t
43 
44 BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
45 
46 namespace bpstd {
47 
48  //============================================================================
49  // struct : in_place_t
50  //============================================================================
51 
56  struct in_place_t
57  {
58  explicit in_place_t() = default;
59  };
60  BPSTD_CPP17_INLINE constexpr in_place_t in_place{};
61 
62  //============================================================================
63  // in_place_type_t
64  //============================================================================
65 
70  template<typename T>
72  {
73  explicit in_place_type_t() = default;
74  };
75 
76 #if BPSTD_HAS_TEMPLATE_VARIABLES
77  template<typename T>
78  BPSTD_CPP17_INLINE constexpr in_place_type_t<T> in_place_type{};
79 #endif
80 
81  //============================================================================
82  // in_place_index_t
83  //============================================================================
84 
89  template<std::size_t I> struct in_place_index_t
90  {
91  explicit in_place_index_t() = default;
92  };
93 
94 #if BPSTD_HAS_TEMPLATE_VARIABLES
95  template<std::size_t I>
96  BPSTD_CPP17_INLINE constexpr in_place_index_t<I> in_place_index{};
97 #endif
98 
99  //============================================================================
100  // non-member functions
101  //============================================================================
102 
103  //----------------------------------------------------------------------------
104  // Utilities
105  //----------------------------------------------------------------------------
106 
111  template <typename T>
112  constexpr typename bpstd::conditional<
113  !bpstd::is_nothrow_move_constructible<T>::value && bpstd::is_copy_constructible<T>::value,
114  const T&,
115  T&&
116  >::type move_if_noexcept(T& x) noexcept;
117 
122  template <typename T>
123  constexpr add_const_t<T>& as_const(T& t) noexcept;
124  template <typename T>
125  void as_const(const T&&) = delete;
126 
137  template <typename T, typename U = T>
138  BPSTD_CPP14_CONSTEXPR T exchange(T& obj, U&& new_value);
139 
140  //============================================================================
141  // class : pair
142  //============================================================================
143 
144  template <typename T, typename U>
145  using pair = std::pair<T,U>;
146 
147  //============================================================================
148  // non-member functions : class : pair
149  //============================================================================
150 
151  //----------------------------------------------------------------------------
152  // Utilities
153  //----------------------------------------------------------------------------
154 
155  // C++11 does not implement const pair&&
156  template <std::size_t N, typename T, typename U>
157  constexpr conditional_t<N==0,T,U>& get(pair<T, U>& p) noexcept;
158  template <std::size_t N, typename T, typename U>
159  constexpr conditional_t<N==0,T,U>&& get(pair<T, U>&& p) noexcept;
160  template <std::size_t N, typename T, typename U>
161  constexpr const conditional_t<N==0,T,U>& get(const pair<T, U>& p) noexcept;
162  template <std::size_t N, typename T, typename U>
163  constexpr const conditional_t<N==0,T,U>&& get(const pair<T, U>&& p) noexcept;
164 
165  template <typename T, typename U>
166  constexpr T& get(pair<T, U>& p) noexcept;
167  template <typename T, typename U>
168  constexpr T&& get(pair<T, U>&& p) noexcept;
169  template <typename T, typename U>
170  constexpr const T& get(const pair<T, U>& p) noexcept;
171  template <typename T, typename U>
172  constexpr const T&& get(const pair<T, U>&& p) noexcept;
173 
174  template <typename T, typename U>
175  constexpr T& get(pair<U, T>& p) noexcept;
176  template <typename T, typename U>
177  constexpr const T& get(const pair<U, T>& p) noexcept;
178  template <typename T, typename U>
179  constexpr T&& get(pair<U, T>&& p) noexcept;
180  template <typename T, typename U>
181  constexpr const T&& get(const pair<U, T>&& p) noexcept;
182 
183  //============================================================================
184  // struct : integer_sequence
185  //============================================================================
186 
187  template <typename T, T... Ints>
189  {
190  using value_type = T;
191 
192  static constexpr std::size_t size() noexcept { return sizeof...(Ints); }
193  };
194 
195  template <std::size_t... Ints>
196  using index_sequence = integer_sequence<std::size_t, Ints...>;
197 
198  namespace detail {
199  template <typename T, bool End, T N, T...Tails>
200  struct make_integer_sequence_impl
201  : make_integer_sequence_impl<T,((N-1) == T(0)), N-1, N-1, Tails...>{};
202 
203  template <typename T, T N, T...Tails>
204  struct make_integer_sequence_impl<T, true, N, Tails...>
205  : type_identity<integer_sequence<T, Tails...>>{};
206 
207  } // namespace detail
208 
209  template <typename T, T N>
210  using make_integer_sequence
211  = typename detail::make_integer_sequence_impl<T, (N==T(0)), N>::type;
212 
213  template<std::size_t N>
214  using make_index_sequence = make_integer_sequence<std::size_t, N>;
215 
216  template<typename... T>
217  using index_sequence_for = make_index_sequence<sizeof...(T)>;
218 
219 } // namespace bpstd
220 
221 //==============================================================================
222 // non-member functions
223 //==============================================================================
224 
225 //------------------------------------------------------------------------------
226 // Utilities
227 //------------------------------------------------------------------------------
228 
229 template <typename T>
230 inline BPSTD_INLINE_VISIBILITY constexpr
231 typename bpstd::conditional<
232  !bpstd::is_nothrow_move_constructible<T>::value && bpstd::is_copy_constructible<T>::value,
233  const T&,
234  T&&
235 >::type bpstd::move_if_noexcept(T& x)
236  noexcept
237 {
238  using result_type = conditional_t<
239  !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value,
240  const T&,
241  T&&
242  >;
243 
244  return static_cast<result_type>(x);
245 }
246 
247 template <typename T>
248 inline BPSTD_INLINE_VISIBILITY constexpr
249 bpstd::add_const_t<T>& bpstd::as_const(T& t)
250  noexcept
251 {
252  return t;
253 }
254 
255 template <typename T, typename U>
256 inline BPSTD_INLINE_VISIBILITY BPSTD_CPP14_CONSTEXPR
257 T bpstd::exchange(T& obj, U&& new_value)
258 {
259  auto old_value = bpstd::move(obj);
260  obj = bpstd::forward<U>(new_value);
261  return old_value;
262 }
263 
264 //==============================================================================
265 // definitions : non-member functions : class : pair
266 //==============================================================================
267 
268 //------------------------------------------------------------------------------
269 // Utilities
270 //------------------------------------------------------------------------------
271 
272 template <std::size_t N, typename T, typename U>
273 inline BPSTD_INLINE_VISIBILITY constexpr
274 bpstd::conditional_t<N==0,T,U>&
275  bpstd::get(pair<T, U>& p)
276  noexcept
277 {
278  static_assert(N<=1, "N must be either 0 or 1 for get<N>(pair<T,U>)");
279 
280  return std::get<N>(p);
281 }
282 
283 template <std::size_t N, typename T, typename U>
284 inline BPSTD_INLINE_VISIBILITY constexpr
285 bpstd::conditional_t<N==0,T,U>&&
286  bpstd::get(pair<T, U>&& p)
287  noexcept
288 {
289  static_assert(N<=1, "N must be either 0 or 1 for get<N>(pair<T,U>)");
290 
291  return move(std::get<N>(p));
292 }
293 
294 template <std::size_t N, typename T, typename U>
295 inline BPSTD_INLINE_VISIBILITY constexpr
296 const bpstd::conditional_t<N==0,T,U>&
297  bpstd::get(const pair<T, U>& p)
298  noexcept
299 {
300  static_assert(N<=1, "N must be either 0 or 1 for get<N>(pair<T,U>)");
301 
302  return std::get<N>(p);
303 }
304 
305 template <std::size_t N, typename T, typename U>
306 inline BPSTD_INLINE_VISIBILITY constexpr
307 const bpstd::conditional_t<N==0,T,U>&&
308  bpstd::get(const pair<T, U>&& p)
309  noexcept
310 {
311  static_assert(N<=1, "N must be either 0 or 1 for get<N>(pair<T,U>)");
312 
313  return move(std::get<N>(p));
314 }
315 
316 template <typename T, typename U>
317 inline BPSTD_INLINE_VISIBILITY constexpr
318 T& bpstd::get(pair<T, U>& p)
319  noexcept
320 {
321  return p.first;
322 }
323 
324 template <typename T, typename U>
325 inline BPSTD_INLINE_VISIBILITY constexpr
326 const T& bpstd::get(const pair<T, U>& p)
327  noexcept
328 {
329  return p.first;
330 }
331 
332 template <typename T, typename U>
333 inline BPSTD_INLINE_VISIBILITY constexpr
334 T&& bpstd::get(pair<T, U>&& p)
335  noexcept
336 {
337  return move(p.first);
338 }
339 
340 template <typename T, typename U>
341 inline BPSTD_INLINE_VISIBILITY constexpr
342 const T&& bpstd::get(const pair<T, U>&& p)
343  noexcept
344 {
345  return move(p.first);
346 }
347 
348 template <typename T, typename U>
349 inline BPSTD_INLINE_VISIBILITY constexpr
350 T& bpstd::get(pair<U, T>& p)
351  noexcept
352 {
353  return p.second;
354 }
355 
356 template <typename T, typename U>
357 inline BPSTD_INLINE_VISIBILITY constexpr
358 const T& bpstd::get(const pair<U, T>& p)
359  noexcept
360 {
361  return p.second;
362 }
363 
364 template <typename T, typename U>
365 inline BPSTD_INLINE_VISIBILITY constexpr
366 T&& bpstd::get(pair<U, T>&& p)
367  noexcept
368 {
369  return move(p.second);
370 }
371 
372 template <typename T, typename U>
373 inline BPSTD_INLINE_VISIBILITY constexpr
374 const T&& bpstd::get(const pair<U, T>&& p)
375  noexcept
376 {
377  return move(p.second);
378 }
379 
380 BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE
381 
382 #endif /* BPSTD_UTILITY_HPP */
bpstd::in_place_t
This function is a special disambiguation tag for variadic functions, used in any and optional.
Definition: utility.hpp:56
bpstd::in_place_index_t
This function is a special disambiguation tag for variadic functions, used in any and optional.
Definition: utility.hpp:89
type_traits.hpp
This header provides definitions from the C++ header <type_traits>
bpstd::exchange
BPSTD_CPP14_CONSTEXPR T exchange(T &obj, U &&new_value)
Replaces the value of obj with new_value and returns the old value of obj.
bpstd::get
const BPSTD_CPP14_CONSTEXPR T && get(const variant< Types... > &&v)
Gets the underlying element of the variant with the specified type.
bpstd::integer_sequence
Definition: utility.hpp:188
bpstd::move_if_noexcept
constexpr bpstd::conditional< !bpstd::is_nothrow_move_constructible< T >::value &&bpstd::is_copy_constructible< T >::value, const T &, T && >::type move_if_noexcept(T &x) noexcept
Moves a type x if it move-construction is non-throwing.
bpstd::in_place_type_t
This function is a special disambiguation tag for variadic functions, used in any and optional.
Definition: utility.hpp:71