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#include <bits/inplace_tags.h>
45#ifdef __glibcxx_constant_wrapper // C++ >= 26
46# include <bits/invoke.h>
47#endif
48
49namespace std _GLIBCXX_VISIBILITY(default)
50{
51_GLIBCXX_BEGIN_NAMESPACE_VERSION
52
53 /// Finds the size of a given tuple type.
54 template<typename _Tp>
55 struct tuple_size;
56
57 // _GLIBCXX_RESOLVE_LIB_DEFECTS
58 // 2313. tuple_size should always derive from integral_constant<size_t, N>
59 // 2770. tuple_size<const T> specialization is not SFINAE compatible
60
61 template<typename _Tp,
62 typename _Up = typename remove_cv<_Tp>::type,
63 typename = typename enable_if<is_same<_Tp, _Up>::value>::type,
65 using __enable_if_has_tuple_size = _Tp;
66
67 template<typename _Tp>
68 struct tuple_size<const __enable_if_has_tuple_size<_Tp>>
69 : public tuple_size<_Tp> { };
70
71 template<typename _Tp>
72 struct tuple_size<volatile __enable_if_has_tuple_size<_Tp>>
73 : public tuple_size<_Tp> { };
74
75 template<typename _Tp>
76 struct tuple_size<const volatile __enable_if_has_tuple_size<_Tp>>
77 : public tuple_size<_Tp> { };
78
79#if __cplusplus >= 201703L
80 template<typename _Tp>
81 inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
82#endif
83
84 /// Gives the type of the ith element of a given tuple type.
85 template<size_t __i, typename _Tp>
87
88 // Duplicate of C++14's tuple_element_t for internal use in C++11 mode
89 template<size_t __i, typename _Tp>
90 using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
91
92 template<size_t __i, typename _Tp>
93 struct tuple_element<__i, const _Tp>
94 {
95 using type = const __tuple_element_t<__i, _Tp>;
96 };
97
98 template<size_t __i, typename _Tp>
99 struct tuple_element<__i, volatile _Tp>
100 {
101 using type = volatile __tuple_element_t<__i, _Tp>;
102 };
103
104 template<size_t __i, typename _Tp>
105 struct tuple_element<__i, const volatile _Tp>
106 {
107 using type = const volatile __tuple_element_t<__i, _Tp>;
108 };
109
110#if __cplusplus >= 201402L
111
112 // Return the index of _Tp in _Types, if it occurs exactly once.
113 // Otherwise, return sizeof...(_Types).
114 template<typename _Tp, typename... _Types>
115 constexpr size_t
116 __find_uniq_type_in_pack()
117 {
118 constexpr size_t __sz = sizeof...(_Types);
119 constexpr bool __found[__sz] = { __is_same(_Tp, _Types) ... };
120 size_t __n = __sz;
121 for (size_t __i = 0; __i < __sz; ++__i)
122 {
123 if (__found[__i])
124 {
125 if (__n < __sz) // more than one _Tp found
126 return __sz;
127 __n = __i;
128 }
129 }
130 return __n;
131 }
132#endif // C++14
133
134// The standard says this macro and alias template should be in <tuple> but we
135// define them here, to be available in <array>, <utility> and <ranges> too.
136// _GLIBCXX_RESOLVE_LIB_DEFECTS
137// 3378. tuple_size_v/tuple_element_t should be available when
138// tuple_size/tuple_element are
139#ifdef __glibcxx_tuple_element_t // C++ >= 14
140 template<size_t __i, typename _Tp>
141 using tuple_element_t = typename tuple_element<__i, _Tp>::type;
142#endif
143
144#ifdef __glibcxx_constant_wrapper // C++ >= 26
145 // remove_cvref_t needed due PR115314
146 template<auto _Xv, typename _Vt = remove_cvref_t<decltype(_Xv)>>
147 struct constant_wrapper;
148
149 template<typename _Tp>
150 concept _ConstExprParam = requires
151 {
152 typename constant_wrapper<_Tp::value>;
153 };
154
155 struct _CwOperators
156 {
157 template<_ConstExprParam _Tp>
158 friend constexpr auto
159 operator+(_Tp) noexcept -> constant_wrapper<(+_Tp::value)>
160 { return {}; }
161
162 template<_ConstExprParam _Tp>
163 friend constexpr auto
164 operator-(_Tp) noexcept -> constant_wrapper<(-_Tp::value)>
165 { return {}; }
166
167 template<_ConstExprParam _Tp>
168 friend constexpr auto
169 operator~(_Tp) noexcept -> constant_wrapper<(~_Tp::value)>
170 { return {}; }
171
172 template<_ConstExprParam _Tp>
173 friend constexpr auto
174 operator!(_Tp) noexcept -> constant_wrapper<(!_Tp::value)>
175 { return {}; }
176
177 template<_ConstExprParam _Tp>
178 friend constexpr auto
179 operator&(_Tp) noexcept -> constant_wrapper<(&_Tp::value)>
180 { return {}; }
181
182 template<_ConstExprParam _Tp>
183 friend constexpr auto
184 operator*(_Tp) noexcept -> constant_wrapper<(*_Tp::value)>
185 { return {}; }
186
187 template<_ConstExprParam _Left, _ConstExprParam _Right>
188 friend constexpr auto
189 operator+(_Left, _Right) noexcept
190 -> constant_wrapper<(_Left::value + _Right::value)>
191 { return {}; }
192
193 template<_ConstExprParam _Left, _ConstExprParam _Right>
194 friend constexpr auto
195 operator-(_Left, _Right) noexcept
196 -> constant_wrapper<(_Left::value - _Right::value)>
197 { return {}; }
198
199 template<_ConstExprParam _Left, _ConstExprParam _Right>
200 friend constexpr auto
201 operator*(_Left, _Right) noexcept
202 -> constant_wrapper<(_Left::value * _Right::value)>
203 { return {}; }
204
205 template<_ConstExprParam _Left, _ConstExprParam _Right>
206 friend constexpr auto
207 operator/(_Left, _Right) noexcept
208 -> constant_wrapper<(_Left::value / _Right::value)>
209 { return {}; }
210
211 template<_ConstExprParam _Left, _ConstExprParam _Right>
212 friend constexpr auto
213 operator%(_Left, _Right) noexcept
214 -> constant_wrapper<(_Left::value % _Right::value)>
215 { return {}; }
216
217 template<_ConstExprParam _Left, _ConstExprParam _Right>
218 friend constexpr auto
219 operator<<(_Left, _Right) noexcept
220 -> constant_wrapper<(_Left::value << _Right::value)>
221 { return {}; }
222
223 template<_ConstExprParam _Left, _ConstExprParam _Right>
224 friend constexpr auto
225 operator>>(_Left, _Right) noexcept
226 -> constant_wrapper<(_Left::value >> _Right::value)>
227 { return {}; }
228
229 template<_ConstExprParam _Left, _ConstExprParam _Right>
230 friend constexpr auto
231 operator&(_Left, _Right) noexcept
232 -> constant_wrapper<(_Left::value & _Right::value)>
233 { return {}; }
234
235 template<_ConstExprParam _Left, _ConstExprParam _Right>
236 friend constexpr auto
237 operator|(_Left, _Right) noexcept
238 -> constant_wrapper<(_Left::value | _Right::value)>
239 { return {}; }
240
241 template<_ConstExprParam _Left, _ConstExprParam _Right>
242 friend constexpr auto
243 operator^(_Left, _Right) noexcept
244 -> constant_wrapper<(_Left::value ^ _Right::value)>
245 { return {}; }
246
247 template<_ConstExprParam _Left, _ConstExprParam _Right>
248 requires (!is_constructible_v<bool, decltype(_Left::value)>
249 || !is_constructible_v<bool, decltype(_Right::value)>)
250 friend constexpr auto
251 operator&&(_Left, _Right) noexcept
252 -> constant_wrapper<(_Left::value && _Right::value)>
253 { return {}; }
254
255 template<_ConstExprParam _Left, _ConstExprParam _Right>
256 requires (!is_constructible_v<bool, decltype(_Left::value)>
257 || !is_constructible_v<bool, decltype(_Right::value)>)
258 friend constexpr auto
259 operator||(_Left, _Right) noexcept
260 -> constant_wrapper<(_Left::value || _Right::value)>
261 { return {}; }
262
263 template<_ConstExprParam _Left, _ConstExprParam _Right>
264 friend constexpr auto
265 operator<=>(_Left, _Right) noexcept
266 -> constant_wrapper<(_Left::value <=> _Right::value)>
267 { return {}; }
268
269 template<_ConstExprParam _Left, _ConstExprParam _Right>
270 friend constexpr auto
271 operator<(_Left, _Right) noexcept
272 -> constant_wrapper<(_Left::value < _Right::value)>
273 { return {}; }
274
275 template<_ConstExprParam _Left, _ConstExprParam _Right>
276 friend constexpr auto
277 operator<=(_Left, _Right) noexcept
278 -> constant_wrapper<(_Left::value <= _Right::value)>
279 { return {}; }
280
281 template<_ConstExprParam _Left, _ConstExprParam _Right>
282 friend constexpr auto
283 operator==(_Left, _Right) noexcept
284 -> constant_wrapper<(_Left::value == _Right::value)>
285 { return {}; }
286
287 template<_ConstExprParam _Left, _ConstExprParam _Right>
288 friend constexpr auto
289 operator!=(_Left, _Right) noexcept
290 -> constant_wrapper<(_Left::value != _Right::value)>
291 { return {}; }
292
293 template<_ConstExprParam _Left, _ConstExprParam _Right>
294 friend constexpr auto
295 operator>(_Left, _Right) noexcept
296 -> constant_wrapper<(_Left::value > _Right::value)>
297 { return {}; }
298
299 template<_ConstExprParam _Left, _ConstExprParam _Right>
300 friend constexpr auto
301 operator>=(_Left, _Right) noexcept
302 -> constant_wrapper<(_Left::value >= _Right::value)>
303 { return {}; }
304
305 template<_ConstExprParam _Left, _ConstExprParam _Right>
306 friend constexpr auto
307 operator,(_Left, _Right) noexcept = delete;
308
309 template<_ConstExprParam _Left, _ConstExprParam _Right>
310 friend constexpr auto
311 operator->*(_Left, _Right) noexcept
312 -> constant_wrapper<_Left::value->*(_Right::value)>
313 { return {}; }
314
315 template<_ConstExprParam _Tp>
316 constexpr auto
317 operator++(this _Tp) noexcept
318 -> constant_wrapper<(++_Tp::value)>
319 { return {}; }
320
321 template<_ConstExprParam _Tp>
322 constexpr auto
323 operator++(this _Tp, int) noexcept
324 -> constant_wrapper<(_Tp::value++)>
325 { return {}; }
326
327 template<_ConstExprParam _Tp>
328 constexpr auto
329 operator--(this _Tp) noexcept
330 -> constant_wrapper<(--_Tp::value)>
331 { return {}; }
332
333 template<_ConstExprParam _Tp>
334 constexpr auto
335 operator--(this _Tp, int) noexcept
336 -> constant_wrapper<(_Tp::value--)>
337 { return {}; }
338
339 template<_ConstExprParam _Tp, _ConstExprParam _Right>
340 constexpr auto
341 operator+=(this _Tp, _Right) noexcept
342 -> constant_wrapper<(_Tp::value += _Right::value)>
343 { return {}; }
344
345 template<_ConstExprParam _Tp, _ConstExprParam _Right>
346 constexpr auto
347 operator-=(this _Tp, _Right) noexcept
348 -> constant_wrapper<(_Tp::value -= _Right::value)>
349 { return {}; }
350
351 template<_ConstExprParam _Tp, _ConstExprParam _Right>
352 constexpr auto
353 operator*=(this _Tp, _Right) noexcept
354 -> constant_wrapper<(_Tp::value *= _Right::value)>
355 { return {}; }
356
357 template<_ConstExprParam _Tp, _ConstExprParam _Right>
358 constexpr auto
359 operator/=(this _Tp, _Right) noexcept
360 -> constant_wrapper<(_Tp::value /= _Right::value)>
361 { return {}; }
362
363 template<_ConstExprParam _Tp, _ConstExprParam _Right>
364 constexpr auto
365 operator%=(this _Tp, _Right) noexcept
366 -> constant_wrapper<(_Tp::value %= _Right::value)>
367 { return {}; }
368
369 template<_ConstExprParam _Tp, _ConstExprParam _Right>
370 constexpr auto
371 operator&=(this _Tp, _Right) noexcept
372 -> constant_wrapper<(_Tp::value &= _Right::value)>
373 { return {}; }
374
375 template<_ConstExprParam _Tp, _ConstExprParam _Right>
376 constexpr auto
377 operator|=(this _Tp, _Right) noexcept
378 -> constant_wrapper<(_Tp::value |= _Right::value)>
379 { return {}; }
380
381 template<_ConstExprParam _Tp, _ConstExprParam _Right>
382 constexpr auto
383 operator^=(this _Tp, _Right) noexcept
384 -> constant_wrapper<(_Tp::value ^= _Right::value)>
385 { return {}; }
386
387 template<_ConstExprParam _Tp, _ConstExprParam _Right>
388 constexpr auto
389 operator<<=(this _Tp, _Right) noexcept
390 -> constant_wrapper<(_Tp::value <<= _Right::value)>
391 { return {}; }
392
393 template<_ConstExprParam _Tp, _ConstExprParam _Right>
394 constexpr auto
395 operator>>=(this _Tp, _Right) noexcept
396 -> constant_wrapper<(_Tp::value >>= _Right::value)>
397 { return {}; }
398 };
399
400 template<auto _Xv, typename _Vt>
401 struct constant_wrapper : _CwOperators
402 {
403 // Use decltype((_Xv)) instead of decltype(auto) due PR125188
404 static constexpr decltype((_Xv)) value = (_Xv);
405 using type = constant_wrapper;
406 using value_type = decltype(_Xv);
407 static_assert(is_same_v<value_type, _Vt>);
408
409 template<_ConstExprParam _Right>
410 constexpr auto
411 operator=(_Right) const noexcept
412 -> constant_wrapper<(value = _Right::value)>
413 { return {}; }
414
415 template<typename... _Args,
416 bool _ConstExprInvocable = requires {
417 requires (_ConstExprParam<remove_cvref_t<_Args>> && ...);
418 typename constant_wrapper<std::__invoke(value, remove_cvref_t<_Args>::value...)>;
419 }>
420 requires _ConstExprInvocable || is_invocable_v<const value_type&, _Args...>
421 static constexpr decltype(auto)
422 operator()(_Args&&... __args)
423 noexcept(requires {
424 requires _ConstExprInvocable || is_nothrow_invocable_v<const value_type&, _Args...>;
425 })
426 {
427 if constexpr (_ConstExprInvocable)
428 return constant_wrapper<std::__invoke(value, remove_cvref_t<_Args>::value...)>{};
429 else
430 return std::__invoke(value, std::forward<_Args>(__args)...);
431 }
432
433 template<typename... _Args,
434 bool _ConstExprSubscriptable = requires {
435 requires (_ConstExprParam<remove_cvref_t<_Args>> && ...);
436 typename constant_wrapper<value[remove_cvref_t<_Args>::value...]>;
437 }>
438 requires _ConstExprSubscriptable || requires { value[std::declval<_Args>()...]; }
439 static constexpr decltype(auto)
440 operator[](_Args&&... __args)
441 noexcept(requires {
442 requires _ConstExprSubscriptable || noexcept(value[std::declval<_Args>()...]);
443 })
444 {
445 if constexpr (_ConstExprSubscriptable)
446 return constant_wrapper<value[remove_cvref_t<_Args>::value...]>{};
447 else
448 return value[std::forward<_Args>(__args)...];
449 }
450
451 constexpr
452 operator decltype(value)() const noexcept
453 { return value; }
454 };
455
456 template<typename>
457 constexpr bool __is_constant_wrapper_v = false;
458
459 template<auto __cw, typename _Fn>
460 constexpr bool __is_constant_wrapper_v<constant_wrapper<__cw, _Fn>> = true;
461
462 template<auto _Xv>
463 constexpr auto cw = constant_wrapper<_Xv>{};
464#endif
465
466#ifdef __glibcxx_integer_sequence // C++ >= 14
467
468 /// Class template integer_sequence
469 template<typename _Tp, _Tp... _Idx>
471 {
472#if __cplusplus >= 202002L
473 static_assert(is_integral_v<_Tp>);
474#endif
475 typedef _Tp value_type;
476 static constexpr size_t size() noexcept { return sizeof...(_Idx); }
477 };
478
479#if __glibcxx_integer_sequence >= 202511L // C++ >= 26
480 /** @brief Structured binding support for `integer_sequence`
481
482 * @since C++26
483 * @{
484 */
485 /// Structured binding support
486 template<typename _Tp, _Tp... _Idx>
487 struct tuple_size<integer_sequence<_Tp, _Idx...>>
488 : integral_constant<size_t, sizeof...(_Idx)> { };
489
490 template<size_t __i, class _Tp, _Tp... _Idx>
491 struct tuple_element<__i, integer_sequence<_Tp, _Idx...>>
492 {
493 static_assert(__i < sizeof...(_Idx));
494 using type = _Tp;
495 };
496
497 template<size_t __i, class _Tp, _Tp... _Idx>
498 struct tuple_element<__i, const integer_sequence<_Tp, _Idx...>>
499 {
500 static_assert(__i < sizeof...(_Idx));
501 using type = _Tp;
502 };
503
504 template<size_t __i, class _Tp, _Tp... _Idx>
505 [[nodiscard]]
506 constexpr _Tp
508 {
509 static_assert(__i < sizeof...(_Idx));
510 return _Idx...[__i];
511 }
512 /// @}
513#endif // __glibcxx_integer_sequence >= 202511L
514
515 /// Alias template make_integer_sequence
516 template<typename _Tp, _Tp _Num>
518#if __has_builtin(__make_integer_seq)
519 = __make_integer_seq<integer_sequence, _Tp, _Num>;
520#else
521 = integer_sequence<_Tp, __integer_pack(_Num)...>;
522#endif
523
524 /// Alias template index_sequence
525 template<size_t... _Idx>
526 using index_sequence = integer_sequence<size_t, _Idx...>;
527
528 /// Alias template make_index_sequence
529 template<size_t _Num>
531
532 /// Alias template index_sequence_for
533 template<typename... _Types>
534 using index_sequence_for = make_index_sequence<sizeof...(_Types)>;
535#endif // __glibcxx_integer_sequence
536
537#if __cpp_structured_bindings >= 202411L
538#if __has_builtin(__integer_pack)
539 template <auto _Num, typename _Tp = decltype(_Num)>
540 inline constexpr _Tp
541 _IotaArray[_Num] = {__integer_pack(_Tp(_Num))...};
542#elif defined __glibcxx_integer_sequence
543 template <auto _Num, typename _Tp = decltype(_Num), typename = make_integer_sequence<_Tp, _Num>>
544 inline constexpr _Tp
545 _IotaArray[_Num];
546
547 template <auto _Num, typename _Tp, _Tp... _Is>
548 inline constexpr _Tp
549 _IotaArray<_Num, _Tp, integer_sequence<_Tp, _Is...>>[_Num] = {_Is...};
550#endif // __integer_pack
551#endif // __cpp_structured_bindings >= 202411L
552
553#if _GLIBCXX_USE_BUILTIN_TRAIT(__type_pack_element)
554 template<size_t _Np, typename... _Types>
555 struct _Nth_type
556 { using type = __type_pack_element<_Np, _Types...>; };
557#else
558 template<size_t _Np, typename... _Types>
559 struct _Nth_type
560 { };
561
562 template<typename _Tp0, typename... _Rest>
563 struct _Nth_type<0, _Tp0, _Rest...>
564 { using type = _Tp0; };
565
566 template<typename _Tp0, typename _Tp1, typename... _Rest>
567 struct _Nth_type<1, _Tp0, _Tp1, _Rest...>
568 { using type = _Tp1; };
569
570 template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
571 struct _Nth_type<2, _Tp0, _Tp1, _Tp2, _Rest...>
572 { using type = _Tp2; };
573
574 template<size_t _Np, typename _Tp0, typename _Tp1, typename _Tp2,
575 typename... _Rest>
576#if __cpp_concepts
577 requires (_Np >= 3)
578#endif
579 struct _Nth_type<_Np, _Tp0, _Tp1, _Tp2, _Rest...>
580 : _Nth_type<_Np - 3, _Rest...>
581 { };
582
583#if ! __cpp_concepts // Need additional specializations to avoid ambiguities.
584 template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
585 struct _Nth_type<0, _Tp0, _Tp1, _Tp2, _Rest...>
586 { using type = _Tp0; };
587
588 template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
589 struct _Nth_type<1, _Tp0, _Tp1, _Tp2, _Rest...>
590 { using type = _Tp1; };
591#endif
592#endif
593
594#if __glibcxx_ranges
595 namespace ranges::__detail
596 {
597 template<typename _Range>
598 inline constexpr bool __is_subrange = false;
599 } // namespace __detail
600#endif
601
602 // A class (and instance) which can be used in 'tie' when an element
603 // of a tuple is not required.
604 struct _Swallow_assign
605 {
606 template<class _Tp>
607 constexpr const _Swallow_assign&
608 operator=(const _Tp&) const noexcept
609 { return *this; }
610 };
611
612 // _GLIBCXX_RESOLVE_LIB_DEFECTS
613 // 2773. Making std::ignore constexpr
614 /** Used with `std::tie` to ignore an element of a tuple
615 *
616 * When using `std::tie` to assign the elements of a tuple to variables,
617 * unwanted elements can be ignored by using `std::ignore`. For example:
618 *
619 * ```
620 * int x, y;
621 * std::tie(x, std::ignore, y) = std::make_tuple(1, 2, 3);
622 * ```
623 *
624 * This assignment will perform `x=1; std::ignore=2; y=3;` which results
625 * in the second element being ignored.
626 *
627 * @since C++11
628 */
629 _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
630
631#if __glibcxx_flat_map || __glibcxx_flat_set // >= C++23
632 struct sorted_unique_t { explicit sorted_unique_t() = default; };
633 inline constexpr sorted_unique_t sorted_unique{};
634
635 struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
636 inline constexpr sorted_equivalent_t sorted_equivalent{};
637#endif
638
639_GLIBCXX_END_NAMESPACE_VERSION
640} // namespace
641
642#endif // C++11
643#endif /* _GLIBCXX_UTILITY_H */
auto declval() noexcept -> decltype(__declval< _Tp >(0))
Definition type_traits:2741
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
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition move.h:72
ISO C++ entities toplevel namespace is std.
make_integer_sequence< size_t, _Num > make_index_sequence
Alias template make_index_sequence.
Definition utility.h:528
integer_sequence< size_t, _Idx... > index_sequence
Alias template index_sequence.
Definition utility.h:524
__make_integer_seq< integer_sequence, _Tp, _Num > make_integer_sequence
Alias template make_integer_sequence.
Definition utility.h:517
constexpr _Swallow_assign ignore
Definition utility.h:627
make_index_sequence< sizeof...(_Types)> index_sequence_for
Alias template index_sequence_for.
Definition utility.h:532
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:55
Gives the type of the ith element of a given tuple type.
Definition utility.h:86
Class template integer_sequence.
Definition utility.h:471