diff options
Diffstat (limited to 'libstdc++-v3/include/std')
-rw-r--r-- | libstdc++-v3/include/std/bitset | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/std/chrono | 32 | ||||
-rw-r--r-- | libstdc++-v3/include/std/complex | 15 | ||||
-rw-r--r-- | libstdc++-v3/include/std/debugging | 77 | ||||
-rw-r--r-- | libstdc++-v3/include/std/functional | 113 | ||||
-rw-r--r-- | libstdc++-v3/include/std/inplace_vector | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/std/limits | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/std/mdspan | 359 | ||||
-rw-r--r-- | libstdc++-v3/include/std/memory | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/std/mutex | 4 | ||||
-rw-r--r-- | libstdc++-v3/include/std/ranges | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/std/stop_token | 19 | ||||
-rw-r--r-- | libstdc++-v3/include/std/thread | 14 | ||||
-rw-r--r-- | libstdc++-v3/include/std/type_traits | 22 |
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 |