aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std
diff options
context:
space:
mode:
authorJerry DeLisle <jvdelisle@gcc.gnu.org>2025-09-02 15:58:26 -0700
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2025-09-02 15:58:26 -0700
commit071b4126c613881f4cb25b4e5c39032964827f88 (patch)
tree7ed805786566918630d1d617b1ed8f7310f5fd8e /libstdc++-v3/include/std
parent845d23f3ea08ba873197c275a8857eee7edad996 (diff)
parentcaa1c2f42691d68af4d894a5c3e700ecd2dba080 (diff)
downloadgcc-devel/gfortran-test.zip
gcc-devel/gfortran-test.tar.gz
gcc-devel/gfortran-test.tar.bz2
Merge branch 'master' into gfortran-testdevel/gfortran-test
Diffstat (limited to 'libstdc++-v3/include/std')
-rw-r--r--libstdc++-v3/include/std/bitset8
-rw-r--r--libstdc++-v3/include/std/chrono32
-rw-r--r--libstdc++-v3/include/std/complex15
-rw-r--r--libstdc++-v3/include/std/debugging77
-rw-r--r--libstdc++-v3/include/std/functional113
-rw-r--r--libstdc++-v3/include/std/inplace_vector2
-rw-r--r--libstdc++-v3/include/std/limits2
-rw-r--r--libstdc++-v3/include/std/mdspan359
-rw-r--r--libstdc++-v3/include/std/memory1
-rw-r--r--libstdc++-v3/include/std/mutex4
-rw-r--r--libstdc++-v3/include/std/ranges2
-rw-r--r--libstdc++-v3/include/std/stop_token19
-rw-r--r--libstdc++-v3/include/std/thread14
-rw-r--r--libstdc++-v3/include/std/type_traits22
14 files changed, 523 insertions, 147 deletions
diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset
index 93a03f6..92f11f1 100644
--- a/libstdc++-v3/include/std/bitset
+++ b/libstdc++-v3/include/std/bitset
@@ -1040,6 +1040,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#endif
#if __cplusplus >= 201103L
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4294. bitset(const CharT*) constructor needs to be constrained
/**
* Construct from a character %array.
* @param __str An %array of characters `__zero` and `__one`.
@@ -1049,7 +1051,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @throw std::invalid_argument If a character appears in the string
* which is neither `__zero` nor `__one`.
*/
- template<typename _CharT>
+ template<typename _CharT,
+ typename = _Require<is_trivially_copyable<_CharT>,
+ is_standard_layout<_CharT>,
+ is_trivially_default_constructible<_CharT>,
+ __not_<is_array<_CharT>>>>
[[__gnu__::__nonnull__]]
_GLIBCXX23_CONSTEXPR
explicit
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index cb8213e..d1a01fb 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -22,6 +22,8 @@
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
+// [time]
+
/** @file include/chrono
* This is a Standard C++ Library header.
* @ingroup chrono
@@ -42,12 +44,16 @@
# include <bits/c++0x_warning.h>
#else
+#define __glibcxx_want_chrono
+#define __glibcxx_want_chrono_udls
+#include <bits/version.h>
+
#include <bits/chrono.h>
-#if __cplusplus >= 202002L
+#if __cpp_lib_bitops >= 201907L
# include <bit> // __countr_zero
#endif
-#if __cplusplus >= 202002L && _GLIBCXX_HOSTED
+#if __cpp_lib_chrono >= 201803L && _GLIBCXX_HOSTED
# include <sstream>
# include <string>
# include <vector>
@@ -56,10 +62,6 @@
# include <bits/unique_ptr.h>
#endif
-#define __glibcxx_want_chrono
-#define __glibcxx_want_chrono_udls
-#include <bits/version.h>
-
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -79,7 +81,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
namespace chrono
{
-#if __cplusplus >= 202002L
+#if __cpp_lib_chrono >= 201803L
/// @addtogroup chrono
/// @{
struct local_t { };
@@ -175,13 +177,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using period = system_clock::period;
using duration = chrono::duration<rep, period>;
using time_point = chrono::time_point<tai_clock>;
- static constexpr bool is_steady = false; // XXX true for CLOCK_TAI?
+ static constexpr bool is_steady = false;
- // TODO move into lib, use CLOCK_TAI on linux, add extension point.
[[nodiscard]]
static time_point
- now()
- { return from_utc(utc_clock::now()); }
+ now(); // in src/c++20/clock.cc
template<typename _Duration>
[[nodiscard]]
@@ -215,13 +215,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using period = system_clock::period;
using duration = chrono::duration<rep, period>;
using time_point = chrono::time_point<gps_clock>;
- static constexpr bool is_steady = false; // XXX
+ static constexpr bool is_steady = false;
- // TODO move into lib, add extension point.
[[nodiscard]]
static time_point
- now()
- { return from_utc(utc_clock::now()); }
+ now(); // in src/c++20/clock.cc
template<typename _Duration>
[[nodiscard]]
@@ -3321,7 +3319,7 @@ namespace __detail
#endif // C++20
} // namespace chrono
-#if __cplusplus >= 202002L
+#if __cpp_lib_chrono >= 201803L
inline namespace literals
{
inline namespace chrono_literals
@@ -3350,7 +3348,7 @@ namespace __detail
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
-#if __cplusplus >= 202002L && _GLIBCXX_HOSTED
+#if __cpp_lib_chrono >= 201803L && _GLIBCXX_HOSTED
# include <bits/chrono_io.h>
#endif
diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex
index d9d2d8a..4765425 100644
--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -96,7 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex<_Tp> conj(const complex<_Tp>&);
/// Return complex with magnitude @a rho and angle @a theta.
- template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0);
+ template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = _Tp(0));
// Transcendentals:
/// Return complex cosine of @a z.
@@ -1038,7 +1038,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline complex<_Tp>
polar(const _Tp& __rho, const _Tp& __theta)
{
- __glibcxx_assert( __rho >= 0 );
+ __glibcxx_assert( __rho >= _Tp(0) );
return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta));
}
@@ -1238,13 +1238,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__x == _Tp())
{
- _Tp __t = sqrt(abs(__y) / 2);
+ _Tp __t = sqrt(abs(__y) / _Tp(2));
return complex<_Tp>(__t, __y < _Tp() ? -__t : __t);
}
else
{
- _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x)));
- _Tp __u = __t / 2;
+ _Tp __t = sqrt(_Tp(2) * (std::abs(__z) + abs(__x)));
+ _Tp __u = __t / _Tp(2);
return __x > _Tp()
? complex<_Tp>(__u, __y / __t)
: complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u);
@@ -1334,7 +1334,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
complex<_Tp>
__complex_pow_unsigned(complex<_Tp> __x, unsigned __n)
{
- complex<_Tp> __y = __n % 2 ? __x : complex<_Tp>(1);
+ complex<_Tp> __y = __n % 2 ? __x : complex<_Tp>(_Tp(1));
while (__n >>= 1)
{
@@ -1357,7 +1357,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
pow(const complex<_Tp>& __z, int __n)
{
return __n < 0
- ? complex<_Tp>(1) / std::__complex_pow_unsigned(__z, -(unsigned)__n)
+ ? complex<_Tp>(_Tp(1)) / std::__complex_pow_unsigned(__z,
+ -(unsigned)__n)
: std::__complex_pow_unsigned(__z, __n);
}
diff --git a/libstdc++-v3/include/std/debugging b/libstdc++-v3/include/std/debugging
new file mode 100644
index 0000000..4cf7e4a
--- /dev/null
+++ b/libstdc++-v3/include/std/debugging
@@ -0,0 +1,77 @@
+// Debugging support -*- C++ -*-
+
+// Copyright The GNU Toolchain Authors.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/debugging
+ * This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_DEBUGGING
+#define _GLIBCXX_DEBUGGING 1
+
+#define __glibcxx_want_debugging
+#include <bits/version.h>
+
+#if __cpp_lib_debugging // C++ >= 26
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+// N.B. _GLIBCXX_BEGIN_NAMESPACE_VERSION is not used here.
+
+/** Try to determine if the program is running under control of a debugger.
+ *
+ * On GNU/Linux systems this function will only return true if the program
+ * is being traced by another program which is known to be a debugger.
+ * This is determined by checking the command name of the tracing program
+ * against a list of known debuggers, such as "gdb".
+ *
+ * On other POSIX-based systems, this function will return true if the
+ * program is being traced by any other process, which means it can return
+ * true for non-debugger utilities that use the ptrace system call.
+ *
+ * @since C++26
+ */
+bool
+is_debugger_present() noexcept;
+
+/** Stop the program with a breakpoint or debug trap.
+ *
+ * The details of how a breakpoint is implemented are platform-specific.
+ * Some systems provide a special instruction, such as `int3` in x86.
+ * When no more appropriate mechanism is available, this will stop the
+ * program using `__builtin_trap()`. It might not be possible for the
+ * program to continue after such a breakpoint.
+ *
+ * @since C++26
+ */
+void
+breakpoint() noexcept;
+
+/** Stop the program if it is running under control of a debugger.
+ *
+ * @since C++26
+ */
+void
+breakpoint_if_debugging() noexcept;
+
+} // namespace std
+#endif
+#endif // _GLIBCXX_DEBUGGING
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index 307bcb9..b1cda87 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -922,6 +922,53 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#ifdef __cpp_lib_bind_front // C++ >= 20
+ template<size_t, typename _Tp>
+ struct _Indexed_bound_arg
+ {
+ [[no_unique_address]] _Tp _M_val;
+ };
+
+ template<typename... _IndexedArgs>
+ struct _Bound_arg_storage : _IndexedArgs...
+ {
+ template<typename _Fd, typename _Self, typename... _CallArgs>
+ static constexpr
+ decltype(auto)
+ _S_apply_front(_Fd&& __fd, _Self&& __self, _CallArgs&&... __call_args)
+ {
+ return std::invoke(std::forward<_Fd>(__fd),
+ __like_t<_Self, _IndexedArgs>(__self)._M_val...,
+ std::forward<_CallArgs>(__call_args)...);
+ }
+
+ template<typename _Fd, typename _Self, typename... _CallArgs>
+ static constexpr
+ decltype(auto)
+ _S_apply_back(_Fd&& __fd, _Self&& __self, _CallArgs&&... __call_args)
+ {
+ return std::invoke(std::forward<_Fd>(__fd),
+ std::forward<_CallArgs>(__call_args)...,
+ __like_t<_Self, _IndexedArgs>(__self)._M_val...);
+ }
+ };
+
+ template<typename... _BoundArgs, typename... _Args>
+ constexpr auto
+ __make_bound_args(_Args&&... __args)
+ {
+ if constexpr (sizeof...(_BoundArgs) == 1)
+ // pack has one element, so return copy of arg
+ return (_BoundArgs(std::forward<_Args>(__args)), ...);
+ else
+ {
+ auto __impl = [&]<size_t... _Inds>(index_sequence<_Inds...>)
+ {
+ return _Bound_arg_storage<_Indexed_bound_arg<_Inds, _BoundArgs>...>
+ { {_BoundArgs(std::forward<_Args>(__args))}... };
+ };
+ return __impl(index_sequence_for<_BoundArgs...>());
+ }
+ }
template<typename _Fd, typename... _BoundArgs>
struct _Bind_front
@@ -937,7 +984,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(__and_<is_nothrow_constructible<_Fd, _Fn>,
is_nothrow_constructible<_BoundArgs, _Args>...>::value)
: _M_fd(std::forward<_Fn>(__fn)),
- _M_bound_args(std::forward<_Args>(__args)...)
+ _M_bound_args(__make_bound_args<_BoundArgs...>(std::forward<_Args>(__args)...))
{ static_assert(sizeof...(_Args) == sizeof...(_BoundArgs)); }
#if __cpp_explicit_this_parameter
@@ -948,7 +995,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(is_nothrow_invocable_v<__like_t<_Self, _Fd>,
__like_t<_Self, _BoundArgs>..., _CallArgs...>)
{
- return _S_call(__like_t<_Self, _Bind_front>(__self), _BoundIndices(),
+ return _S_call(__like_t<_Self, _Bind_front>(__self),
std::forward<_CallArgs>(__call_args)...);
}
#else
@@ -959,8 +1006,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator()(_CallArgs&&... __call_args) &
noexcept(is_nothrow_invocable_v<_Fd&, _BoundArgs&..., _CallArgs...>)
{
- return _S_call(*this, _BoundIndices(),
- std::forward<_CallArgs>(__call_args)...);
+ return _S_call(*this, std::forward<_CallArgs>(__call_args)...);
}
template<typename... _CallArgs>
@@ -971,8 +1017,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(is_nothrow_invocable_v<const _Fd&, const _BoundArgs&...,
_CallArgs...>)
{
- return _S_call(*this, _BoundIndices(),
- std::forward<_CallArgs>(__call_args)...);
+ return _S_call(*this, std::forward<_CallArgs>(__call_args)...);
}
template<typename... _CallArgs>
@@ -982,8 +1027,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator()(_CallArgs&&... __call_args) &&
noexcept(is_nothrow_invocable_v<_Fd, _BoundArgs..., _CallArgs...>)
{
- return _S_call(std::move(*this), _BoundIndices(),
- std::forward<_CallArgs>(__call_args)...);
+ return _S_call(std::move(*this),
+ std::forward<_CallArgs>(__call_args)...);
}
template<typename... _CallArgs>
@@ -994,8 +1039,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(is_nothrow_invocable_v<const _Fd, const _BoundArgs...,
_CallArgs...>)
{
- return _S_call(std::move(*this), _BoundIndices(),
- std::forward<_CallArgs>(__call_args)...);
+ return _S_call(std::move(*this),
+ std::forward<_CallArgs>(__call_args)...);
}
template<typename... _CallArgs>
@@ -1012,20 +1057,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
private:
- using _BoundIndices = index_sequence_for<_BoundArgs...>;
+ using _BoundArgsStorage
+ // _BoundArgs are required to be move-constructible, so this is valid.
+ = decltype(__make_bound_args<_BoundArgs...>(std::declval<_BoundArgs>()...));
- template<typename _Tp, size_t... _Ind, typename... _CallArgs>
+ template<typename _Tp, typename... _CallArgs>
static constexpr
decltype(auto)
- _S_call(_Tp&& __g, index_sequence<_Ind...>, _CallArgs&&... __call_args)
+ _S_call(_Tp&& __g, _CallArgs&&... __call_args)
{
- return std::invoke(std::forward<_Tp>(__g)._M_fd,
- std::get<_Ind>(std::forward<_Tp>(__g)._M_bound_args)...,
- std::forward<_CallArgs>(__call_args)...);
+ if constexpr (sizeof...(_BoundArgs) == 1)
+ return std::invoke(std::forward<_Tp>(__g)._M_fd,
+ std::forward<_Tp>(__g)._M_bound_args,
+ std::forward<_CallArgs>(__call_args)...);
+ else
+ return _BoundArgsStorage::_S_apply_front(
+ std::forward<_Tp>(__g)._M_fd,
+ std::forward<_Tp>(__g)._M_bound_args,
+ std::forward<_CallArgs>(__call_args)...);
}
[[no_unique_address]] _Fd _M_fd;
- [[no_unique_address]] std::tuple<_BoundArgs...> _M_bound_args;
+ [[no_unique_address]] _BoundArgsStorage _M_bound_args;
};
template<typename _Fn, typename... _Args>
@@ -1066,7 +1119,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(__and_<is_nothrow_constructible<_Fd, _Fn>,
is_nothrow_constructible<_BoundArgs, _Args>...>::value)
: _M_fd(std::forward<_Fn>(__fn)),
- _M_bound_args(std::forward<_Args>(__args)...)
+ _M_bound_args(__make_bound_args<_BoundArgs...>(std::forward<_Args>(__args)...))
{ static_assert(sizeof...(_Args) == sizeof...(_BoundArgs)); }
template<typename _Self, typename... _CallArgs>
@@ -1076,25 +1129,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(is_nothrow_invocable_v<__like_t<_Self, _Fd>,
_CallArgs..., __like_t<_Self, _BoundArgs>...>)
{
- return _S_call(__like_t<_Self, _Bind_back>(__self), _BoundIndices(),
+ return _S_call(__like_t<_Self, _Bind_back>(__self),
std::forward<_CallArgs>(__call_args)...);
}
private:
- using _BoundIndices = index_sequence_for<_BoundArgs...>;
+ using _BoundArgsStorage
+ // _BoundArgs are required to be move-constructible, so this is valid.
+ = decltype(__make_bound_args<_BoundArgs...>(std::declval<_BoundArgs>()...));
- template<typename _Tp, size_t... _Ind, typename... _CallArgs>
+ template<typename _Tp, typename... _CallArgs>
static constexpr
decltype(auto)
- _S_call(_Tp&& __g, index_sequence<_Ind...>, _CallArgs&&... __call_args)
+ _S_call(_Tp&& __g, _CallArgs&&... __call_args)
{
- return std::invoke(std::forward<_Tp>(__g)._M_fd,
- std::forward<_CallArgs>(__call_args)...,
- std::get<_Ind>(std::forward<_Tp>(__g)._M_bound_args)...);
+ if constexpr (sizeof...(_BoundArgs) == 1)
+ return std::invoke(std::forward<_Tp>(__g)._M_fd,
+ std::forward<_CallArgs>(__call_args)...,
+ std::forward<_Tp>(__g)._M_bound_args);
+ else
+ return _BoundArgsStorage::_S_apply_back(
+ std::forward<_Tp>(__g)._M_fd,
+ std::forward<_Tp>(__g)._M_bound_args,
+ std::forward<_CallArgs>(__call_args)...);
}
[[no_unique_address]] _Fd _M_fd;
- [[no_unique_address]] std::tuple<_BoundArgs...> _M_bound_args;
+ [[no_unique_address]] _BoundArgsStorage _M_bound_args;
};
template<typename _Fn, typename... _Args>
diff --git a/libstdc++-v3/include/std/inplace_vector b/libstdc++-v3/include/std/inplace_vector
index 290cf6e..b5a81be 100644
--- a/libstdc++-v3/include/std/inplace_vector
+++ b/libstdc++-v3/include/std/inplace_vector
@@ -1354,7 +1354,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
- template<typename _Tp, size_t _Nm, typename _Up>
+ template<typename _Tp, size_t _Nm, typename _Up = _Tp>
constexpr size_t
erase(inplace_vector<_Tp, _Nm>& __cont, const _Up& __value)
{
diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits
index 3567a32..49ce7c9 100644
--- a/libstdc++-v3/include/std/limits
+++ b/libstdc++-v3/include/std/limits
@@ -2128,7 +2128,7 @@ __glibcxx_float_n(128)
static _GLIBCXX_USE_CONSTEXPR int digits = 113;
static _GLIBCXX_USE_CONSTEXPR int digits10 = 33;
#if __cplusplus >= 201103L
- static constexpr int max_digits10 = 35;
+ static constexpr int max_digits10 = 36;
#endif
static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
static _GLIBCXX_USE_CONSTEXPR bool is_integer = false;
diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
index 055778d..6c7469c 100644
--- a/libstdc++-v3/include/std/mdspan
+++ b/libstdc++-v3/include/std/mdspan
@@ -36,10 +36,14 @@
#include <span>
#include <array>
#include <type_traits>
-#include <limits>
#include <utility>
+#if __cplusplus > 202302L
+#include <bits/align.h>
+#endif
+
#define __glibcxx_want_mdspan
+#define __glibcxx_want_aligned_accessor
#include <bits/version.h>
#ifdef __glibcxx_mdspan
@@ -49,49 +53,66 @@ namespace std _GLIBCXX_VISIBILITY(default)
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace __mdspan
{
- template<typename _IndexType, array _Extents>
- class _ExtentsStorage
- {
- public:
- static consteval bool
- _S_is_dyn(size_t __ext) noexcept
- { return __ext == dynamic_extent; }
+ consteval bool
+ __all_static(std::span<const size_t> __extents)
+ {
+ for(auto __ext : __extents)
+ if (__ext == dynamic_extent)
+ return false;
+ return true;
+ }
- template<typename _OIndexType>
- static constexpr _IndexType
- _S_int_cast(const _OIndexType& __other) noexcept
- { return _IndexType(__other); }
+ consteval bool
+ __all_dynamic(std::span<const size_t> __extents)
+ {
+ for(auto __ext : __extents)
+ if (__ext != dynamic_extent)
+ return false;
+ return true;
+ }
+ template<array _Extents>
+ class _StaticExtents
+ {
+ public:
static constexpr size_t _S_rank = _Extents.size();
- // For __r in [0, _S_rank], _S_dynamic_index[__r] is the number
+ // For __r in [0, _S_rank], _S_dynamic_index(__r) is the number
// of dynamic extents up to (and not including) __r.
//
// If __r is the index of a dynamic extent, then
// _S_dynamic_index[__r] is the index of that extent in
// _M_dyn_exts.
- static constexpr auto _S_dynamic_index = [] consteval
+ static constexpr size_t
+ _S_dynamic_index(size_t __r) noexcept
+ { return _S_dynamic_index_data[__r]; }
+
+ static constexpr auto _S_dynamic_index_data = [] consteval
{
array<size_t, _S_rank+1> __ret;
size_t __dyn = 0;
for (size_t __i = 0; __i < _S_rank; ++__i)
{
__ret[__i] = __dyn;
- __dyn += _S_is_dyn(_Extents[__i]);
+ __dyn += (_Extents[__i] == dynamic_extent);
}
__ret[_S_rank] = __dyn;
return __ret;
}();
- static constexpr size_t _S_rank_dynamic = _S_dynamic_index[_S_rank];
+ static constexpr size_t _S_rank_dynamic = _S_dynamic_index(_S_rank);
- // For __r in [0, _S_rank_dynamic), _S_dynamic_index_inv[__r] is the
+ // For __r in [0, _S_rank_dynamic), _S_dynamic_index_inv(__r) is the
// index of the __r-th dynamic extent in _Extents.
- static constexpr auto _S_dynamic_index_inv = [] consteval
+ static constexpr size_t
+ _S_dynamic_index_inv(size_t __r) noexcept
+ { return _S_dynamic_index_inv_data[__r]; }
+
+ static constexpr auto _S_dynamic_index_inv_data = [] consteval
{
array<size_t, _S_rank_dynamic> __ret;
for (size_t __i = 0, __r = 0; __i < _S_rank; ++__i)
- if (_S_is_dyn(_Extents[__i]))
+ if (_Extents[__i] == dynamic_extent)
__ret[__r++] = __i;
return __ret;
}();
@@ -99,15 +120,66 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static constexpr size_t
_S_static_extent(size_t __r) noexcept
{ return _Extents[__r]; }
+ };
+
+ template<array _Extents>
+ requires (__all_dynamic<_Extents>())
+ class _StaticExtents<_Extents>
+ {
+ public:
+ static constexpr size_t _S_rank = _Extents.size();
+
+ static constexpr size_t
+ _S_dynamic_index(size_t __r) noexcept
+ { return __r; }
+
+ static constexpr size_t _S_rank_dynamic = _S_rank;
+
+ static constexpr size_t
+ _S_dynamic_index_inv(size_t __k) noexcept
+ { return __k; }
+
+ static constexpr size_t
+ _S_static_extent(size_t) noexcept
+ { return dynamic_extent; }
+ };
+
+ template<typename _IndexType, array _Extents>
+ class _ExtentsStorage : public _StaticExtents<_Extents>
+ {
+ private:
+ using _S_base = _StaticExtents<_Extents>;
+
+ public:
+ using _S_base::_S_rank;
+ using _S_base::_S_rank_dynamic;
+ using _S_base::_S_dynamic_index;
+ using _S_base::_S_dynamic_index_inv;
+ using _S_base::_S_static_extent;
+
+ static constexpr bool
+ _S_is_dynamic(size_t __r) noexcept
+ {
+ if constexpr (__all_static(_Extents))
+ return false;
+ else if constexpr (__all_dynamic(_Extents))
+ return true;
+ else
+ return _Extents[__r] == dynamic_extent;
+ }
+
+ template<typename _OIndexType>
+ static constexpr _IndexType
+ _S_int_cast(const _OIndexType& __other) noexcept
+ { return _IndexType(__other); }
constexpr _IndexType
_M_extent(size_t __r) const noexcept
{
- auto __se = _Extents[__r];
- if (__se == dynamic_extent)
- return _M_dyn_exts[_S_dynamic_index[__r]];
+ if (_S_is_dynamic(__r))
+ return _M_dyn_exts[_S_dynamic_index(__r)];
else
- return __se;
+ return _S_static_extent(__r);
}
template<size_t _OtherRank, typename _GetOtherExtent>
@@ -116,7 +188,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
if constexpr (_OtherRank == _S_rank)
for (size_t __i = 0; __i < _S_rank; ++__i)
- if (_Extents[__i] != dynamic_extent
+ if (!_S_is_dynamic(__i)
&& !cmp_equal(_Extents[__i], _S_int_cast(__get_extent(__i))))
return false;
return true;
@@ -131,7 +203,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
size_t __di = __i;
if constexpr (_OtherRank != _S_rank_dynamic)
- __di = _S_dynamic_index_inv[__i];
+ __di = _S_dynamic_index_inv(__i);
_M_dyn_exts[__i] = _S_int_cast(__get_extent(__di));
}
}
@@ -157,18 +229,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __exts[__i]; });
}
- static constexpr span<const size_t>
- _S_static_extents(size_t __begin, size_t __end) noexcept
- {
- return {_Extents.data() + __begin, _Extents.data() + __end};
- }
+ static constexpr const array<size_t, _S_rank>&
+ _S_static_extents() noexcept
+ { return _Extents; }
constexpr span<const _IndexType>
_M_dynamic_extents(size_t __begin, size_t __end) const noexcept
requires (_Extents.size() > 0)
{
- return {_M_dyn_exts + _S_dynamic_index[__begin],
- _M_dyn_exts + _S_dynamic_index[__end]};
+ return {_M_dyn_exts + _S_dynamic_index(__begin),
+ _M_dyn_exts + _S_dynamic_index(__end)};
}
private:
@@ -184,24 +254,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<size_t _Extent, typename _IndexType>
concept
__valid_static_extent = _Extent == dynamic_extent
- || _Extent <= numeric_limits<_IndexType>::max();
- }
+ || _Extent <= __gnu_cxx::__int_traits<_IndexType>::__max;
- namespace __mdspan
- {
template<typename _Extents>
- constexpr span<const size_t>
- __static_extents(size_t __begin = 0, size_t __end = _Extents::rank())
- noexcept
- { return _Extents::_S_storage::_S_static_extents(__begin, __end); }
+ constexpr const array<size_t, _Extents::rank()>&
+ __static_extents() noexcept
+ { return _Extents::_S_storage::_S_static_extents(); }
+
+ // Pre-compute: \prod_{i = 0}^r _Extents[i], for r = 0,..., n (exclusive)
+ template<array _Extents>
+ constexpr auto __fwd_partial_prods = [] consteval
+ {
+ constexpr size_t __rank = _Extents.size();
+ std::array<size_t, __rank> __ret;
+ size_t __prod = 1;
+ for (size_t __r = 0; __r < __rank; ++__r)
+ {
+ __ret[__r] = __prod;
+ if (size_t __ext = _Extents[__r]; __ext != dynamic_extent)
+ __prod *= __ext;
+ }
+ return __ret;
+ }();
+
+ // Pre-compute: \prod_{i = r+1}^{n-1} _Extents[i]
+ template<array _Extents>
+ constexpr auto __rev_partial_prods = [] consteval
+ {
+ constexpr size_t __rank = _Extents.size();
+ std::array<size_t, __rank> __ret;
+ size_t __prod = 1;
+ for (size_t __r = __rank; __r > 0; --__r)
+ {
+ __ret[__r - 1] = __prod;
+ if (size_t __ext = _Extents[__r - 1]; __ext != dynamic_extent)
+ __prod *= __ext;
+ }
+ return __ret;
+ }();
template<typename _Extents>
constexpr span<const typename _Extents::index_type>
__dynamic_extents(const _Extents& __exts, size_t __begin = 0,
size_t __end = _Extents::rank()) noexcept
- {
- return __exts._M_exts._M_dynamic_extents(__begin, __end);
- }
+ { return __exts._M_exts._M_dynamic_extents(__begin, __end); }
}
template<typename _IndexType, size_t... _Extents>
@@ -212,7 +308,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_assert(
(__mdspan::__valid_static_extent<_Extents, _IndexType> && ...),
"Extents must either be dynamic or representable as IndexType");
-
public:
using index_type = _IndexType;
using size_type = make_unsigned_t<index_type>;
@@ -257,8 +352,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_S_ctor_explicit()
{
return (_S_is_less_dynamic(_Extents, _OExtents) || ...)
- || (numeric_limits<index_type>::max()
- < numeric_limits<_OIndexType>::max());
+ || (__gnu_cxx::__int_traits<index_type>::__max
+ < __gnu_cxx::__int_traits<_OIndexType>::__max);
}
template<size_t... _OExtents>
@@ -313,16 +408,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
else
{
- for (size_t __i = 0; __i < __self.rank(); ++__i)
- if (!cmp_equal(__self.extent(__i), __other.extent(__i)))
- return false;
- return true;
+ auto __impl = [&__self, &__other]<size_t... _Counts>(
+ index_sequence<_Counts...>)
+ { return (cmp_equal(__self.extent(_Counts),
+ __other.extent(_Counts)) && ...); };
+ return __impl(make_index_sequence<__self.rank()>());
}
}
private:
- friend span<const size_t>
- __mdspan::__static_extents<extents>(size_t, size_t);
+ friend const array<size_t, rank()>&
+ __mdspan::__static_extents<extents>();
friend span<const index_type>
__mdspan::__dynamic_extents<extents>(const extents&, size_t, size_t);
@@ -347,6 +443,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
}
+ template<typename _Tp, size_t _Nm>
+ consteval bool
+ __contains_zero(const array<_Tp, _Nm>& __exts) noexcept
+ { return __contains_zero(span<const _Tp>(__exts)); }
+
template<typename _Extents>
constexpr bool
__empty(const _Extents& __exts) noexcept
@@ -359,51 +460,75 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
}
- constexpr size_t
- __static_extents_prod(const auto& __sta_exts) noexcept
- {
- size_t __ret = 1;
- for (auto __factor : __sta_exts)
- if (__factor != dynamic_extent)
- __ret *= __factor;
- return __ret;
- }
-
template<typename _Extents>
constexpr typename _Extents::index_type
- __exts_prod(const _Extents& __exts, size_t __begin, size_t __end) noexcept
+ __extents_prod(const _Extents& __exts, size_t __sta_prod, size_t __begin,
+ size_t __end) noexcept
{
- using _IndexType = typename _Extents::index_type;
-
- size_t __ret = 1;
- if constexpr (_Extents::rank_dynamic() != _Extents::rank())
- {
- auto __sta_exts = __static_extents<_Extents>(__begin, __end);
- __ret = __static_extents_prod(__sta_exts);
- if (__ret == 0)
- return 0;
- }
+ if (__sta_prod == 0)
+ return 0;
+ size_t __ret = __sta_prod;
if constexpr (_Extents::rank_dynamic() > 0)
for (auto __factor : __dynamic_extents(__exts, __begin, __end))
__ret *= size_t(__factor);
- return _IndexType(__ret);
+ return static_cast<typename _Extents::index_type>(__ret);
}
+ // Preconditions: _r < _Extents::rank()
template<typename _Extents>
constexpr typename _Extents::index_type
__fwd_prod(const _Extents& __exts, size_t __r) noexcept
- { return __exts_prod(__exts, 0, __r); }
+ {
+ constexpr size_t __rank = _Extents::rank();
+ constexpr auto& __sta_exts = __static_extents<_Extents>();
+ if constexpr (__rank == 1)
+ return 1;
+ else if constexpr (__rank == 2)
+ return __r == 0 ? 1 : __exts.extent(0);
+ else if constexpr (__all_dynamic(std::span(__sta_exts).first(__rank-1)))
+ return __extents_prod(__exts, 1, 0, __r);
+ else
+ {
+ size_t __sta_prod = __fwd_partial_prods<__sta_exts>[__r];
+ return __extents_prod(__exts, __sta_prod, 0, __r);
+ }
+ }
+ // Preconditions: _r < _Extents::rank()
template<typename _Extents>
constexpr typename _Extents::index_type
__rev_prod(const _Extents& __exts, size_t __r) noexcept
- { return __exts_prod(__exts, __r + 1, __exts.rank()); }
+ {
+ constexpr size_t __rank = _Extents::rank();
+ constexpr auto& __sta_exts = __static_extents<_Extents>();
+ if constexpr (__rank == 1)
+ return 1;
+ else if constexpr (__rank == 2)
+ return __r == 0 ? __exts.extent(1) : 1;
+ else if constexpr (__all_dynamic(std::span(__sta_exts).last(__rank-1)))
+ return __extents_prod(__exts, 1, __r + 1, __rank);
+ else
+ {
+ size_t __sta_prod = __rev_partial_prods<__sta_exts>[__r];
+ return __extents_prod(__exts, __sta_prod, __r + 1, __rank);
+ }
+ }
template<typename _Extents>
constexpr typename _Extents::index_type
__size(const _Extents& __exts) noexcept
- { return __fwd_prod(__exts, __exts.rank()); }
+ {
+ constexpr size_t __sta_prod = [] {
+ span<const size_t> __sta_exts = __static_extents<_Extents>();
+ size_t __ret = 1;
+ for(auto __ext : __sta_exts)
+ if (__ext != dynamic_extent)
+ __ret *= __ext;
+ return __ret;
+ }();
+ return __extents_prod(__exts, __sta_prod, 0, _Extents::rank());
+ }
template<typename _IndexType, size_t... _Counts>
auto __build_dextents_type(integer_sequence<size_t, _Counts...>)
@@ -414,6 +539,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using dextents = decltype(__mdspan::__build_dextents_type<_IndexType>(
make_index_sequence<_Rank>()));
+#if __glibcxx_mdspan >= 202406L
+ template<size_t _Rank, typename _IndexType = size_t>
+ using dims = dextents<_IndexType, _Rank>;
+#endif
+
template<typename... _Integrals>
requires (is_convertible_v<_Integrals, size_t> && ...)
explicit extents(_Integrals...) ->
@@ -470,9 +600,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Extents,
typename _IndexType = typename _Extents::index_type>
consteval _IndexType
- __static_quotient(_IndexType __nom = numeric_limits<_IndexType>::max())
+ __static_quotient(_IndexType __nom = __gnu_cxx::__int_traits<_IndexType>
+ ::__max)
{
- auto __sta_exts = __static_extents<_Extents>();
+ std::span<const size_t> __sta_exts = __static_extents<_Extents>();
for (auto __factor : __sta_exts)
{
if (__factor != dynamic_extent)
@@ -919,12 +1050,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_assert(__mdspan::__representable_size<_OExtents, index_type>,
"The size of StridedMapping::extents_type must be representable as"
" index_type");
- if constexpr (cmp_greater(numeric_limits<_OIndexType>::max(),
- numeric_limits<index_type>::max()))
- __glibcxx_assert(!cmp_less(numeric_limits<index_type>::max(),
- __other.required_span_size())
- && "other.required_span_size() must be representable"
- " as index_type");
+ if constexpr (cmp_greater(__gnu_cxx::__int_traits<_OIndexType>::__max,
+ __gnu_cxx::__int_traits<index_type>::__max))
+ __glibcxx_assert(!cmp_less(
+ __gnu_cxx::__int_traits<index_type>::__max,
+ __other.required_span_size())
+ && "other.required_span_size() must be representable"
+ " as index_type");
if constexpr (extents_type::rank() > 0)
for (size_t __i = 0; __i < extents_type::rank(); ++__i)
_M_strides[__i] = index_type(__other.stride(__i));
@@ -1057,6 +1189,54 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __p + __i; }
};
+#ifdef __glibcxx_aligned_accessor
+ template<typename _ElementType, size_t _ByteAlignment>
+ struct aligned_accessor
+ {
+ static_assert(has_single_bit(_ByteAlignment),
+ "ByteAlignment must be a power of two");
+ static_assert(_ByteAlignment >= alignof(_ElementType));
+
+ using offset_policy = default_accessor<_ElementType>;
+ using element_type = _ElementType;
+ using reference = element_type&;
+ using data_handle_type = element_type*;
+
+ static constexpr size_t byte_alignment = _ByteAlignment;
+
+ constexpr
+ aligned_accessor() noexcept = default;
+
+ template<typename _OElementType, size_t _OByteAlignment>
+ requires (_OByteAlignment >= byte_alignment)
+ && is_convertible_v<_OElementType(*)[], element_type(*)[]>
+ constexpr
+ aligned_accessor(aligned_accessor<_OElementType, _OByteAlignment>)
+ noexcept
+ { }
+
+ template<typename _OElementType>
+ requires is_convertible_v<_OElementType(*)[], element_type(*)[]>
+ constexpr explicit
+ aligned_accessor(default_accessor<_OElementType>) noexcept
+ { }
+
+ template<typename _OElementType>
+ requires is_convertible_v<element_type(*)[], _OElementType(*)[]>
+ constexpr
+ operator default_accessor<_OElementType>() const noexcept
+ { return {}; }
+
+ constexpr reference
+ access(data_handle_type __p, size_t __i) const noexcept
+ { return std::assume_aligned<byte_alignment>(__p)[__i]; }
+
+ constexpr typename offset_policy::data_handle_type
+ offset(data_handle_type __p, size_t __i) const noexcept
+ { return std::assume_aligned<byte_alignment>(__p) + __i; }
+ };
+#endif
+
namespace __mdspan
{
template<typename _Extents, typename _IndexType, size_t _Nm>
@@ -1241,16 +1421,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
size() const noexcept
{
__glibcxx_assert(cmp_less_equal(_M_mapping.required_span_size(),
- numeric_limits<size_t>::max()));
+ __gnu_cxx::__int_traits<size_t>
+ ::__max));
return size_type(__mdspan::__size(extents()));
}
[[nodiscard]]
constexpr bool
empty() const noexcept
- {
- return __mdspan::__empty(extents());
- }
+ { return __mdspan::__empty(extents()); }
friend constexpr void
swap(mdspan& __x, mdspan& __y) noexcept
@@ -1299,7 +1478,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr bool
is_strided() const noexcept(noexcept(_M_mapping.is_strided()))
- { return _M_mapping. is_strided(); }
+ { return _M_mapping.is_strided(); }
constexpr index_type
stride(rank_type __r) const { return _M_mapping.stride(__r); }
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index 763a57e..bc59622 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -110,6 +110,7 @@
#define __glibcxx_want_constexpr_memory
#define __glibcxx_want_enable_shared_from_this
#define __glibcxx_want_indirect
+#define __glibcxx_want_is_sufficiently_aligned
#define __glibcxx_want_make_unique
#define __glibcxx_want_out_ptr
#define __glibcxx_want_parallel_algorithm
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index e575a81..631c380 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -190,7 +190,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return static_cast<_Derived*>(this)->_M_timedlock(__ts);
}
-#ifdef _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
+#if _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
template<typename _Duration>
bool
_M_try_lock_until(const chrono::time_point<chrono::steady_clock,
@@ -377,7 +377,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_timedlock(const __gthread_time_t& __ts)
{ return !__gthread_recursive_mutex_timedlock(&_M_mutex, &__ts); }
-#ifdef _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
+#if _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK
bool
_M_clocklock(clockid_t __clockid, const __gthread_time_t& __ts)
{ return !pthread_mutex_clocklock(&_M_mutex, __clockid, &__ts); }
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index efe6296..2970b2c 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1585,8 +1585,6 @@ namespace views::__adaptor
};
template<random_access_range _Range>
- requires (sizeof(range_difference_t<_Range>)
- <= sizeof(iterator_t<_Range>))
struct _CachedPosition<_Range>
{
private:
diff --git a/libstdc++-v3/include/std/stop_token b/libstdc++-v3/include/std/stop_token
index 775ec6a..b593daf 100644
--- a/libstdc++-v3/include/std/stop_token
+++ b/libstdc++-v3/include/std/stop_token
@@ -648,6 +648,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Callback>
stop_callback(stop_token, _Callback) -> stop_callback<_Callback>;
+ /// @cond undocumented
+ namespace __detail::__variant
+ {
+ template<typename> struct _Never_valueless_alt; // see <variant>
+
+ // Provide the strong exception-safety guarantee when emplacing a
+ // stop_token or stop_source into a variant.
+ template<>
+ struct _Never_valueless_alt<std::stop_token>
+ : true_type
+ { };
+
+ template<>
+ struct _Never_valueless_alt<std::stop_source>
+ : true_type
+ { };
+ } // namespace __detail::__variant
+ /// @endcond
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __glibcxx_jthread
diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
index 0de08c0..94ded714 100644
--- a/libstdc++-v3/include/std/thread
+++ b/libstdc++-v3/include/std/thread
@@ -294,6 +294,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
stop_source _M_stop_source;
thread _M_thread;
};
+
+ /// @cond undocumented
+ namespace __detail::__variant
+ {
+ template<typename> struct _Never_valueless_alt; // see <variant>
+
+ // Provide the strong exception-safety guarantee when emplacing a
+ // jthread into a variant.
+ template<>
+ struct _Never_valueless_alt<std::jthread>
+ : true_type
+ { };
+ } // namespace __detail::__variant
+ /// @endcond
#endif // __cpp_lib_jthread
#ifdef __cpp_lib_formatters // C++ >= 23
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index ff23544..4636457 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -4280,6 +4280,28 @@ template<typename _Ret, typename _Fn, typename... _Args>
#endif // C++2a
+#if __cplusplus >= 201103L
+ // Stores a tuple of indices. Used by tuple and pair, and by bind() to
+ // extract the elements in a tuple.
+ template<size_t... _Indexes> struct _Index_tuple { };
+
+ // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
+ template<size_t _Num>
+ struct _Build_index_tuple
+ {
+#if __has_builtin(__make_integer_seq)
+ template<typename, size_t... _Indices>
+ using _IdxTuple = _Index_tuple<_Indices...>;
+
+ // Clang defines __make_integer_seq for this purpose.
+ using __type = __make_integer_seq<_IdxTuple, size_t, _Num>;
+#else
+ // For GCC and other compilers, use __integer_pack instead.
+ using __type = _Index_tuple<__integer_pack(_Num)...>;
+#endif
+ };
+#endif // C++11
+
/// @} group metaprogramming
_GLIBCXX_END_NAMESPACE_VERSION