libstdc++
utility.h
Go to the documentation of this file.
1 // Utilities used throughout the library -*- C++ -*-
2 
3 // Copyright (C) 2004-2026 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file include/bits/utility.h
26  * This is an internal header file, included by other library headers.
27  * Do not attempt to use it directly. @headername{utility}
28  *
29  * This file contains the parts of `<utility>` needed by other headers,
30  * so they don't need to include the whole of `<utility>`.
31  */
32 
33 #ifndef _GLIBCXX_UTILITY_H
34 #define _GLIBCXX_UTILITY_H 1
35 
36 #ifdef _GLIBCXX_SYSHDR
37 #pragma GCC system_header
38 #endif
39 
40 #if __cplusplus >= 201103L
41 
42 #include <type_traits>
43 #include <bits/move.h>
44 #ifdef __glibcxx_constant_wrapper // C++ >= 26
45 # include <bits/invoke.h>
46 #endif
47 
48 namespace std _GLIBCXX_VISIBILITY(default)
49 {
50 _GLIBCXX_BEGIN_NAMESPACE_VERSION
51 
52  /// Finds the size of a given tuple type.
53  template<typename _Tp>
54  struct tuple_size;
55 
56  // _GLIBCXX_RESOLVE_LIB_DEFECTS
57  // 2313. tuple_size should always derive from integral_constant<size_t, N>
58  // 2770. tuple_size<const T> specialization is not SFINAE compatible
59 
60  template<typename _Tp,
61  typename _Up = typename remove_cv<_Tp>::type,
62  typename = typename enable_if<is_same<_Tp, _Up>::value>::type,
63  size_t = tuple_size<_Tp>::value>
64  using __enable_if_has_tuple_size = _Tp;
65 
66  template<typename _Tp>
67  struct tuple_size<const __enable_if_has_tuple_size<_Tp>>
68  : public tuple_size<_Tp> { };
69 
70  template<typename _Tp>
71  struct tuple_size<volatile __enable_if_has_tuple_size<_Tp>>
72  : public tuple_size<_Tp> { };
73 
74  template<typename _Tp>
75  struct tuple_size<const volatile __enable_if_has_tuple_size<_Tp>>
76  : public tuple_size<_Tp> { };
77 
78 #if __cplusplus >= 201703L
79  template<typename _Tp>
80  inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
81 #endif
82 
83  /// Gives the type of the ith element of a given tuple type.
84  template<size_t __i, typename _Tp>
85  struct tuple_element;
86 
87  // Duplicate of C++14's tuple_element_t for internal use in C++11 mode
88  template<size_t __i, typename _Tp>
89  using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
90 
91  template<size_t __i, typename _Tp>
92  struct tuple_element<__i, const _Tp>
93  {
94  using type = const __tuple_element_t<__i, _Tp>;
95  };
96 
97  template<size_t __i, typename _Tp>
98  struct tuple_element<__i, volatile _Tp>
99  {
100  using type = volatile __tuple_element_t<__i, _Tp>;
101  };
102 
103  template<size_t __i, typename _Tp>
104  struct tuple_element<__i, const volatile _Tp>
105  {
106  using type = const volatile __tuple_element_t<__i, _Tp>;
107  };
108 
109 #if __cplusplus >= 201402L
110 
111  // Return the index of _Tp in _Types, if it occurs exactly once.
112  // Otherwise, return sizeof...(_Types).
113  template<typename _Tp, typename... _Types>
114  constexpr size_t
115  __find_uniq_type_in_pack()
116  {
117  constexpr size_t __sz = sizeof...(_Types);
118  constexpr bool __found[__sz] = { __is_same(_Tp, _Types) ... };
119  size_t __n = __sz;
120  for (size_t __i = 0; __i < __sz; ++__i)
121  {
122  if (__found[__i])
123  {
124  if (__n < __sz) // more than one _Tp found
125  return __sz;
126  __n = __i;
127  }
128  }
129  return __n;
130  }
131 #endif // C++14
132 
133 // The standard says this macro and alias template should be in <tuple> but we
134 // define them here, to be available in <array>, <utility> and <ranges> too.
135 // _GLIBCXX_RESOLVE_LIB_DEFECTS
136 // 3378. tuple_size_v/tuple_element_t should be available when
137 // tuple_size/tuple_element are
138 #ifdef __glibcxx_tuple_element_t // C++ >= 14
139  template<size_t __i, typename _Tp>
140  using tuple_element_t = typename tuple_element<__i, _Tp>::type;
141 #endif
142 
143 #ifdef __glibcxx_constant_wrapper // C++ >= 26
144  // remove_cvref_t needed due PR115314
145  template<auto _Xv, typename _Vt = remove_cvref_t<decltype(_Xv)>>
146  struct constant_wrapper;
147 
148  template<typename _Tp>
149  concept _ConstExprParam = requires
150  {
151  typename constant_wrapper<_Tp::value>;
152  };
153 
154  struct _CwOperators
155  {
156  template<_ConstExprParam _Tp>
157  friend constexpr auto
158  operator+(_Tp) noexcept -> constant_wrapper<(+_Tp::value)>
159  { return {}; }
160 
161  template<_ConstExprParam _Tp>
162  friend constexpr auto
163  operator-(_Tp) noexcept -> constant_wrapper<(-_Tp::value)>
164  { return {}; }
165 
166  template<_ConstExprParam _Tp>
167  friend constexpr auto
168  operator~(_Tp) noexcept -> constant_wrapper<(~_Tp::value)>
169  { return {}; }
170 
171  template<_ConstExprParam _Tp>
172  friend constexpr auto
173  operator!(_Tp) noexcept -> constant_wrapper<(!_Tp::value)>
174  { return {}; }
175 
176  template<_ConstExprParam _Tp>
177  friend constexpr auto
178  operator&(_Tp) noexcept -> constant_wrapper<(&_Tp::value)>
179  { return {}; }
180 
181  template<_ConstExprParam _Tp>
182  friend constexpr auto
183  operator*(_Tp) noexcept -> constant_wrapper<(*_Tp::value)>
184  { return {}; }
185 
186  template<_ConstExprParam _Left, _ConstExprParam _Right>
187  friend constexpr auto
188  operator+(_Left, _Right) noexcept
189  -> constant_wrapper<(_Left::value + _Right::value)>
190  { return {}; }
191 
192  template<_ConstExprParam _Left, _ConstExprParam _Right>
193  friend constexpr auto
194  operator-(_Left, _Right) noexcept
195  -> constant_wrapper<(_Left::value - _Right::value)>
196  { return {}; }
197 
198  template<_ConstExprParam _Left, _ConstExprParam _Right>
199  friend constexpr auto
200  operator*(_Left, _Right) noexcept
201  -> constant_wrapper<(_Left::value * _Right::value)>
202  { return {}; }
203 
204  template<_ConstExprParam _Left, _ConstExprParam _Right>
205  friend constexpr auto
206  operator/(_Left, _Right) noexcept
207  -> constant_wrapper<(_Left::value / _Right::value)>
208  { return {}; }
209 
210  template<_ConstExprParam _Left, _ConstExprParam _Right>
211  friend constexpr auto
212  operator%(_Left, _Right) noexcept
213  -> constant_wrapper<(_Left::value % _Right::value)>
214  { return {}; }
215 
216  template<_ConstExprParam _Left, _ConstExprParam _Right>
217  friend constexpr auto
218  operator<<(_Left, _Right) noexcept
219  -> constant_wrapper<(_Left::value << _Right::value)>
220  { return {}; }
221 
222  template<_ConstExprParam _Left, _ConstExprParam _Right>
223  friend constexpr auto
224  operator>>(_Left, _Right) noexcept
225  -> constant_wrapper<(_Left::value >> _Right::value)>
226  { return {}; }
227 
228  template<_ConstExprParam _Left, _ConstExprParam _Right>
229  friend constexpr auto
230  operator&(_Left, _Right) noexcept
231  -> constant_wrapper<(_Left::value & _Right::value)>
232  { return {}; }
233 
234  template<_ConstExprParam _Left, _ConstExprParam _Right>
235  friend constexpr auto
236  operator|(_Left, _Right) noexcept
237  -> constant_wrapper<(_Left::value | _Right::value)>
238  { return {}; }
239 
240  template<_ConstExprParam _Left, _ConstExprParam _Right>
241  friend constexpr auto
242  operator^(_Left, _Right) noexcept
243  -> constant_wrapper<(_Left::value ^ _Right::value)>
244  { return {}; }
245 
246  template<_ConstExprParam _Left, _ConstExprParam _Right>
247  requires (!is_constructible_v<bool, decltype(_Left::value)>
248  || !is_constructible_v<bool, decltype(_Right::value)>)
249  friend constexpr auto
250  operator&&(_Left, _Right) noexcept
251  -> constant_wrapper<(_Left::value && _Right::value)>
252  { return {}; }
253 
254  template<_ConstExprParam _Left, _ConstExprParam _Right>
255  requires (!is_constructible_v<bool, decltype(_Left::value)>
256  || !is_constructible_v<bool, decltype(_Right::value)>)
257  friend constexpr auto
258  operator||(_Left, _Right) noexcept
259  -> constant_wrapper<(_Left::value || _Right::value)>
260  { return {}; }
261 
262  template<_ConstExprParam _Left, _ConstExprParam _Right>
263  friend constexpr auto
264  operator<=>(_Left, _Right) noexcept
265  -> constant_wrapper<(_Left::value <=> _Right::value)>
266  { return {}; }
267 
268  template<_ConstExprParam _Left, _ConstExprParam _Right>
269  friend constexpr auto
270  operator<(_Left, _Right) noexcept
271  -> constant_wrapper<(_Left::value < _Right::value)>
272  { return {}; }
273 
274  template<_ConstExprParam _Left, _ConstExprParam _Right>
275  friend constexpr auto
276  operator<=(_Left, _Right) noexcept
277  -> constant_wrapper<(_Left::value <= _Right::value)>
278  { return {}; }
279 
280  template<_ConstExprParam _Left, _ConstExprParam _Right>
281  friend constexpr auto
282  operator==(_Left, _Right) noexcept
283  -> constant_wrapper<(_Left::value == _Right::value)>
284  { return {}; }
285 
286  template<_ConstExprParam _Left, _ConstExprParam _Right>
287  friend constexpr auto
288  operator!=(_Left, _Right) noexcept
289  -> constant_wrapper<(_Left::value != _Right::value)>
290  { return {}; }
291 
292  template<_ConstExprParam _Left, _ConstExprParam _Right>
293  friend constexpr auto
294  operator>(_Left, _Right) noexcept
295  -> constant_wrapper<(_Left::value > _Right::value)>
296  { return {}; }
297 
298  template<_ConstExprParam _Left, _ConstExprParam _Right>
299  friend constexpr auto
300  operator>=(_Left, _Right) noexcept
301  -> constant_wrapper<(_Left::value >= _Right::value)>
302  { return {}; }
303 
304  template<_ConstExprParam _Left, _ConstExprParam _Right>
305  friend constexpr auto
306  operator,(_Left, _Right) noexcept = delete;
307 
308  template<_ConstExprParam _Left, _ConstExprParam _Right>
309  friend constexpr auto
310  operator->*(_Left, _Right) noexcept
311  -> constant_wrapper<_Left::value->*(_Right::value)>
312  { return {}; }
313 
314  template<_ConstExprParam _Tp>
315  constexpr auto
316  operator++(this _Tp) noexcept
317  -> constant_wrapper<(++_Tp::value)>
318  { return {}; }
319 
320  template<_ConstExprParam _Tp>
321  constexpr auto
322  operator++(this _Tp, int) noexcept
323  -> constant_wrapper<(_Tp::value++)>
324  { return {}; }
325 
326  template<_ConstExprParam _Tp>
327  constexpr auto
328  operator--(this _Tp) noexcept
329  -> constant_wrapper<(--_Tp::value)>
330  { return {}; }
331 
332  template<_ConstExprParam _Tp>
333  constexpr auto
334  operator--(this _Tp, int) noexcept
335  -> constant_wrapper<(_Tp::value--)>
336  { return {}; }
337 
338  template<_ConstExprParam _Tp, _ConstExprParam _Right>
339  constexpr auto
340  operator+=(this _Tp, _Right) noexcept
341  -> constant_wrapper<(_Tp::value += _Right::value)>
342  { return {}; }
343 
344  template<_ConstExprParam _Tp, _ConstExprParam _Right>
345  constexpr auto
346  operator-=(this _Tp, _Right) noexcept
347  -> constant_wrapper<(_Tp::value -= _Right::value)>
348  { return {}; }
349 
350  template<_ConstExprParam _Tp, _ConstExprParam _Right>
351  constexpr auto
352  operator*=(this _Tp, _Right) noexcept
353  -> constant_wrapper<(_Tp::value *= _Right::value)>
354  { return {}; }
355 
356  template<_ConstExprParam _Tp, _ConstExprParam _Right>
357  constexpr auto
358  operator/=(this _Tp, _Right) noexcept
359  -> constant_wrapper<(_Tp::value /= _Right::value)>
360  { return {}; }
361 
362  template<_ConstExprParam _Tp, _ConstExprParam _Right>
363  constexpr auto
364  operator%=(this _Tp, _Right) noexcept
365  -> constant_wrapper<(_Tp::value %= _Right::value)>
366  { return {}; }
367 
368  template<_ConstExprParam _Tp, _ConstExprParam _Right>
369  constexpr auto
370  operator&=(this _Tp, _Right) noexcept
371  -> constant_wrapper<(_Tp::value &= _Right::value)>
372  { return {}; }
373 
374  template<_ConstExprParam _Tp, _ConstExprParam _Right>
375  constexpr auto
376  operator|=(this _Tp, _Right) noexcept
377  -> constant_wrapper<(_Tp::value |= _Right::value)>
378  { return {}; }
379 
380  template<_ConstExprParam _Tp, _ConstExprParam _Right>
381  constexpr auto
382  operator^=(this _Tp, _Right) noexcept
383  -> constant_wrapper<(_Tp::value ^= _Right::value)>
384  { return {}; }
385 
386  template<_ConstExprParam _Tp, _ConstExprParam _Right>
387  constexpr auto
388  operator<<=(this _Tp, _Right) noexcept
389  -> constant_wrapper<(_Tp::value <<= _Right::value)>
390  { return {}; }
391 
392  template<_ConstExprParam _Tp, _ConstExprParam _Right>
393  constexpr auto
394  operator>>=(this _Tp, _Right) noexcept
395  -> constant_wrapper<(_Tp::value >>= _Right::value)>
396  { return {}; }
397  };
398 
399  template<auto _Xv, typename _Vt>
400  struct constant_wrapper : _CwOperators
401  {
402  // Use decltype((_Xv)) instead of decltype(auto) due PR125188
403  static constexpr decltype((_Xv)) value = (_Xv);
404  using type = constant_wrapper;
405  using value_type = decltype(_Xv);
406  static_assert(is_same_v<value_type, _Vt>);
407 
408  template<_ConstExprParam _Right>
409  constexpr auto
410  operator=(_Right) const noexcept
411  -> constant_wrapper<(value = _Right::value)>
412  { return {}; }
413 
414  template<typename... _Args,
415  bool _ConstExprInvocable = requires {
416  requires (_ConstExprParam<remove_cvref_t<_Args>> && ...);
417  typename constant_wrapper<std::__invoke(value, remove_cvref_t<_Args>::value...)>;
418  }>
419  requires _ConstExprInvocable || is_invocable_v<const value_type&, _Args...>
420  static constexpr decltype(auto)
421  operator()(_Args&&... __args)
422  noexcept(requires {
423  requires _ConstExprInvocable || is_nothrow_invocable_v<const value_type&, _Args...>;
424  })
425  {
426  if constexpr (_ConstExprInvocable)
427  return constant_wrapper<std::__invoke(value, remove_cvref_t<_Args>::value...)>{};
428  else
429  return std::__invoke(value, std::forward<_Args>(__args)...);
430  }
431 
432  template<typename... _Args,
433  bool _ConstExprSubscriptable = requires {
434  requires (_ConstExprParam<remove_cvref_t<_Args>> && ...);
435  typename constant_wrapper<value[remove_cvref_t<_Args>::value...]>;
436  }>
437  requires _ConstExprSubscriptable || requires { value[std::declval<_Args>()...]; }
438  static constexpr decltype(auto)
439  operator[](_Args&&... __args)
440  noexcept(requires {
441  requires _ConstExprSubscriptable || noexcept(value[std::declval<_Args>()...]);
442  })
443  {
444  if constexpr (_ConstExprSubscriptable)
445  return constant_wrapper<value[remove_cvref_t<_Args>::value...]>{};
446  else
447  return value[std::forward<_Args>(__args)...];
448  }
449 
450  constexpr
451  operator decltype(value)() const noexcept
452  { return value; }
453  };
454 
455  template<typename>
456  constexpr bool __is_constant_wrapper_v = false;
457 
458  template<auto __cw, typename _Fn>
459  constexpr bool __is_constant_wrapper_v<constant_wrapper<__cw, _Fn>> = true;
460 
461  template<auto _Xv>
462  constexpr auto cw = constant_wrapper<_Xv>{};
463 #endif
464 
465 #ifdef __glibcxx_integer_sequence // C++ >= 14
466 
467  /// Class template integer_sequence
468  template<typename _Tp, _Tp... _Idx>
470  {
471 #if __cplusplus >= 202002L
472  static_assert(is_integral_v<_Tp>);
473 #endif
474  typedef _Tp value_type;
475  static constexpr size_t size() noexcept { return sizeof...(_Idx); }
476  };
477 
478 #if __glibcxx_integer_sequence >= 202511L // C++ >= 26
479  /** @brief Structured binding support for `integer_sequence`
480 
481  * @since C++26
482  * @{
483  */
484  /// Structured binding support
485  template<typename _Tp, _Tp... _Idx>
486  struct tuple_size<integer_sequence<_Tp, _Idx...>>
487  : integral_constant<size_t, sizeof...(_Idx)> { };
488 
489  template<size_t __i, class _Tp, _Tp... _Idx>
490  struct tuple_element<__i, integer_sequence<_Tp, _Idx...>>
491  {
492  static_assert(__i < sizeof...(_Idx));
493  using type = _Tp;
494  };
495 
496  template<size_t __i, class _Tp, _Tp... _Idx>
497  struct tuple_element<__i, const integer_sequence<_Tp, _Idx...>>
498  {
499  static_assert(__i < sizeof...(_Idx));
500  using type = _Tp;
501  };
502 
503  template<size_t __i, class _Tp, _Tp... _Idx>
504  [[nodiscard]]
505  constexpr _Tp
506  get(integer_sequence<_Tp, _Idx...>) noexcept
507  {
508  static_assert(__i < sizeof...(_Idx));
509  return _Idx...[__i];
510  }
511  /// @}
512 #endif // __glibcxx_integer_sequence >= 202511L
513 
514  /// Alias template make_integer_sequence
515  template<typename _Tp, _Tp _Num>
517 #if __has_builtin(__make_integer_seq)
518  = __make_integer_seq<integer_sequence, _Tp, _Num>;
519 #else
520  = integer_sequence<_Tp, __integer_pack(_Num)...>;
521 #endif
522 
523  /// Alias template index_sequence
524  template<size_t... _Idx>
525  using index_sequence = integer_sequence<size_t, _Idx...>;
526 
527  /// Alias template make_index_sequence
528  template<size_t _Num>
530 
531  /// Alias template index_sequence_for
532  template<typename... _Types>
533  using index_sequence_for = make_index_sequence<sizeof...(_Types)>;
534 #endif // __glibcxx_integer_sequence
535 
536 #if __cpp_structured_bindings >= 202411L
537 #if __has_builtin(__integer_pack)
538  template <auto _Num, typename _Tp = decltype(_Num)>
539  inline constexpr _Tp
540  _IotaArray[_Num] = {__integer_pack(_Tp(_Num))...};
541 #elif defined __glibcxx_integer_sequence
542  template <auto _Num, typename _Tp = decltype(_Num), typename = make_integer_sequence<_Tp, _Num>>
543  inline constexpr _Tp
544  _IotaArray[_Num];
545 
546  template <auto _Num, typename _Tp, _Tp... _Is>
547  inline constexpr _Tp
548  _IotaArray<_Num, _Tp, integer_sequence<_Tp, _Is...>>[_Num] = {_Is...};
549 #endif // __integer_pack
550 #endif // __cpp_structured_bindings >= 202411L
551 
552 #if __cplusplus >= 201703L
553 
554  struct in_place_t {
555  explicit in_place_t() = default;
556  };
557 
558  inline constexpr in_place_t in_place{};
559 
560  template<typename _Tp> struct in_place_type_t
561  {
562  explicit in_place_type_t() = default;
563  };
564 
565  template<typename _Tp>
566  inline constexpr in_place_type_t<_Tp> in_place_type{};
567 
568  template<size_t _Idx> struct in_place_index_t
569  {
570  explicit in_place_index_t() = default;
571  };
572 
573  template<size_t _Idx>
574  inline constexpr in_place_index_t<_Idx> in_place_index{};
575 
576  template<typename>
577  inline constexpr bool __is_in_place_type_v = false;
578 
579  template<typename _Tp>
580  inline constexpr bool __is_in_place_type_v<in_place_type_t<_Tp>> = true;
581 
582  template<typename>
583  inline constexpr bool __is_in_place_index_v = false;
584 
585  template<size_t _Nm>
586  inline constexpr bool __is_in_place_index_v<in_place_index_t<_Nm>> = true;
587 
588 #endif // C++17
589 
590 #if _GLIBCXX_USE_BUILTIN_TRAIT(__type_pack_element)
591  template<size_t _Np, typename... _Types>
592  struct _Nth_type
593  { using type = __type_pack_element<_Np, _Types...>; };
594 #else
595  template<size_t _Np, typename... _Types>
596  struct _Nth_type
597  { };
598 
599  template<typename _Tp0, typename... _Rest>
600  struct _Nth_type<0, _Tp0, _Rest...>
601  { using type = _Tp0; };
602 
603  template<typename _Tp0, typename _Tp1, typename... _Rest>
604  struct _Nth_type<1, _Tp0, _Tp1, _Rest...>
605  { using type = _Tp1; };
606 
607  template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
608  struct _Nth_type<2, _Tp0, _Tp1, _Tp2, _Rest...>
609  { using type = _Tp2; };
610 
611  template<size_t _Np, typename _Tp0, typename _Tp1, typename _Tp2,
612  typename... _Rest>
613 #if __cpp_concepts
614  requires (_Np >= 3)
615 #endif
616  struct _Nth_type<_Np, _Tp0, _Tp1, _Tp2, _Rest...>
617  : _Nth_type<_Np - 3, _Rest...>
618  { };
619 
620 #if ! __cpp_concepts // Need additional specializations to avoid ambiguities.
621  template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
622  struct _Nth_type<0, _Tp0, _Tp1, _Tp2, _Rest...>
623  { using type = _Tp0; };
624 
625  template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
626  struct _Nth_type<1, _Tp0, _Tp1, _Tp2, _Rest...>
627  { using type = _Tp1; };
628 #endif
629 #endif
630 
631 #if __glibcxx_ranges
632  namespace ranges::__detail
633  {
634  template<typename _Range>
635  inline constexpr bool __is_subrange = false;
636  } // namespace __detail
637 #endif
638 
639  // A class (and instance) which can be used in 'tie' when an element
640  // of a tuple is not required.
641  struct _Swallow_assign
642  {
643  template<class _Tp>
644  constexpr const _Swallow_assign&
645  operator=(const _Tp&) const noexcept
646  { return *this; }
647  };
648 
649  // _GLIBCXX_RESOLVE_LIB_DEFECTS
650  // 2773. Making std::ignore constexpr
651  /** Used with `std::tie` to ignore an element of a tuple
652  *
653  * When using `std::tie` to assign the elements of a tuple to variables,
654  * unwanted elements can be ignored by using `std::ignore`. For example:
655  *
656  * ```
657  * int x, y;
658  * std::tie(x, std::ignore, y) = std::make_tuple(1, 2, 3);
659  * ```
660  *
661  * This assignment will perform `x=1; std::ignore=2; y=3;` which results
662  * in the second element being ignored.
663  *
664  * @since C++11
665  */
666  _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
667 
668 #if __glibcxx_flat_map || __glibcxx_flat_set // >= C++23
669  struct sorted_unique_t { explicit sorted_unique_t() = default; };
670  inline constexpr sorted_unique_t sorted_unique{};
671 
672  struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
673  inline constexpr sorted_equivalent_t sorted_equivalent{};
674 #endif
675 
676 _GLIBCXX_END_NAMESPACE_VERSION
677 } // namespace
678 
679 #endif // C++11
680 #endif /* _GLIBCXX_UTILITY_H */
constexpr duration< __common_rep_t< _Rep1, __disable_if_is_duration< _Rep2 > >, _Period > operator%(const duration< _Rep1, _Period > &__d, const _Rep2 &__s)
Definition: chrono.h:783
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:859
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:873
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:826
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:866
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:434
constexpr complex< _Tp > operator/(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x divided by y.
Definition: complex:464
requires requires
Definition: complex:1948
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition: complex:404
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition: complex:374
constexpr __invoke_result< _Callable, _Args... >::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_invocable< _Callable, _Args... >::value)
Invoke a callable object.
Definition: invoke.h:92
ISO C++ entities toplevel namespace is std.
std::basic_istream< _CharT, _Traits > & operator>>(std::basic_istream< _CharT, _Traits > &__is, bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition: bitset:1658
constexpr bitset< _Nb > operator&(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1618
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition: bitset:1754
make_integer_sequence< size_t, _Num > make_index_sequence
Alias template make_index_sequence.
Definition: utility.h:529
constexpr bitset< _Nb > operator|(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1628
constexpr _Swallow_assign ignore
Definition: utility.h:666
constexpr bitset< _Nb > operator^(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1638
__make_integer_seq< integer_sequence, _Tp, _Num > make_integer_sequence
Alias template make_integer_sequence.
Definition: utility.h:518
make_index_sequence< sizeof...(_Types)> index_sequence_for
Alias template index_sequence_for.
Definition: utility.h:533
integral_constant
Definition: type_traits:96
Define a member typedef type only if a boolean constant is true.
Definition: type_traits:137
Finds the size of a given tuple type.
Definition: utility.h:54
Gives the type of the ith element of a given tuple type.
Definition: utility.h:85
Class template integer_sequence.
Definition: utility.h:470