diff options
author | Ian Lance Taylor <iant@golang.org> | 2023-06-21 11:04:04 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2023-06-21 11:04:04 -0700 |
commit | 97e31a0a2a2d2273687fcdb4e5416aab1a2186e1 (patch) | |
tree | d5c1cae4de436a0fe54a5f0a2a197d309f3d654c /libstdc++-v3/include | |
parent | 6612f4f8cb9b0d5af18ec69ad04e56debc3e6ced (diff) | |
parent | 577223aebc7acdd31e62b33c1682fe54a622ae27 (diff) | |
download | gcc-97e31a0a2a2d2273687fcdb4e5416aab1a2186e1.zip gcc-97e31a0a2a2d2273687fcdb4e5416aab1a2186e1.tar.gz gcc-97e31a0a2a2d2273687fcdb4e5416aab1a2186e1.tar.bz2 |
Merge from trunk revision 577223aebc7acdd31e62b33c1682fe54a622ae27.
Diffstat (limited to 'libstdc++-v3/include')
102 files changed, 3184 insertions, 1366 deletions
diff --git a/libstdc++-v3/include/bits/algorithmfwd.h b/libstdc++-v3/include/bits/algorithmfwd.h index 03e6278..0d62390 100644 --- a/libstdc++-v3/include/bits/algorithmfwd.h +++ b/libstdc++-v3/include/bits/algorithmfwd.h @@ -622,7 +622,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) // set_symmetric_difference // set_union -#if (__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99_STDINT_TR1) +#if __cplusplus >= 201103L template<typename _RAIter, typename _UGenerator> void shuffle(_RAIter, _RAIter, _UGenerator&&); diff --git a/libstdc++-v3/include/bits/basic_ios.h b/libstdc++-v3/include/bits/basic_ios.h index de5719c..c7c391c 100644 --- a/libstdc++-v3/include/bits/basic_ios.h +++ b/libstdc++-v3/include/bits/basic_ios.h @@ -66,6 +66,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits> class basic_ios : public ios_base { +#if __cplusplus >= 202002L + static_assert(is_same_v<_CharT, typename _Traits::char_type>); +#endif + public: ///@{ /** diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 5d040e2..d15f0f0 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -69,6 +69,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * * @ingroup strings * @ingroup sequences + * @headerfile string + * @since C++98 * * @tparam _CharT Type of character * @tparam _Traits Traits for character type, defaults to @@ -84,39 +86,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename _CharT, typename _Traits, typename _Alloc> class basic_string { +#if __cplusplus >= 202002L + static_assert(is_same_v<_CharT, typename _Traits::char_type>); + static_assert(is_same_v<_CharT, typename _Alloc::value_type>); + using _Char_alloc_type = _Alloc; +#else typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_CharT>::other _Char_alloc_type; +#endif -#if __cpp_lib_constexpr_string < 201907L typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits; -#else - template<typename _Traits2, typename _Dummy_for_PR85282> - struct _Alloc_traits_impl : __gnu_cxx::__alloc_traits<_Char_alloc_type> - { - typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Base; - - [[__gnu__::__always_inline__]] - static constexpr typename _Base::pointer - allocate(_Char_alloc_type& __a, typename _Base::size_type __n) - { - pointer __p = _Base::allocate(__a, __n); - if (std::is_constant_evaluated()) - // Begin the lifetime of characters in allocated storage. - for (size_type __i = 0; __i < __n; ++__i) - std::construct_at(__builtin_addressof(__p[__i])); - return __p; - } - }; - - template<typename _Dummy_for_PR85282> - struct _Alloc_traits_impl<char_traits<_CharT>, _Dummy_for_PR85282> - : __gnu_cxx::__alloc_traits<_Char_alloc_type> - { - // std::char_traits begins the lifetime of characters. - }; - - using _Alloc_traits = _Alloc_traits_impl<_Traits, void>; -#endif // Types: public: @@ -147,6 +126,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #endif private: + static _GLIBCXX20_CONSTEXPR pointer + _S_allocate(_Char_alloc_type& __a, size_type __n) + { + pointer __p = _Alloc_traits::allocate(__a, __n); +#if __cpp_lib_constexpr_string >= 201907L + // std::char_traits begins the lifetime of characters, + // but custom traits might not, so do it here. + if constexpr (!is_same_v<_Traits, char_traits<_CharT>>) + if (std::__is_constant_evaluated()) + // Begin the lifetime of characters in allocated storage. + for (size_type __i = 0; __i < __n; ++__i) + std::construct_at(__builtin_addressof(__p[__i])); +#endif + return __p; + } + #if __cplusplus >= 201703L // A helper type for avoiding boiler-plate. typedef basic_string_view<_CharT, _Traits> __sv_type; @@ -758,7 +753,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX20_CONSTEXPR basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc()) - : _M_dataplus(_M_local_data(), __a) + : _M_dataplus(_M_local_data(), __a), _M_string_length(0) { #if __cplusplus >= 201103L _M_construct(__beg, __end, std::__iterator_category(__beg)); @@ -1594,7 +1589,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 const auto __len = __str.size(); auto __alloc = __str._M_get_allocator(); // If this allocation throws there are no effects: - auto __ptr = _Alloc_traits::allocate(__alloc, __len + 1); + auto __ptr = _S_allocate(__alloc, __len + 1); _M_destroy(_M_allocated_capacity); _M_data(__ptr); _M_capacity(__len); diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 99fdbee..d8a279f 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -152,7 +152,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // NB: Need an array of char_type[__capacity], plus a terminating // null char_type() element. - return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1); + return _S_allocate(_M_get_allocator(), __capacity + 1); } // NB: This is the special case for Input Iterators, used in @@ -376,8 +376,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION else if (__length < __capacity) try { - pointer __tmp - = _Alloc_traits::allocate(_M_get_allocator(), __length + 1); + pointer __tmp = _S_allocate(_M_get_allocator(), __length + 1); this->_S_copy(__tmp, _M_data(), __length + 1); _M_dispose(); _M_data(__tmp); @@ -521,8 +520,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cpp_lib_is_constant_evaluated if (std::is_constant_evaluated()) { - auto __newp = _Alloc_traits::allocate(_M_get_allocator(), - __new_size); + auto __newp = _S_allocate(_M_get_allocator(), __new_size); _S_copy(__newp, this->_M_data(), __pos); _S_copy(__newp + __pos, __s, __len2); _S_copy(__newp + __pos + __len2, __p + __len1, __how_much); diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index 71f2401..009a017 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -30,6 +30,8 @@ #ifndef _GLIBCXX_CXX_CONFIG_H #define _GLIBCXX_CXX_CONFIG_H 1 +#pragma GCC system_header + // The major release number for the GCC release the C++ library belongs to. #define _GLIBCXX_RELEASE @@ -397,6 +399,13 @@ _GLIBCXX_END_NAMESPACE_VERSION # define _GLIBCXX_END_INLINE_ABI_NAMESPACE(X) } // inline namespace X #endif +// In the case that we don't have a hosted environment, we can't provide the +// debugging mode. Instead, we do our best and downgrade to assertions. +#if defined(_GLIBCXX_DEBUG) && !__STDC_HOSTED__ +#undef _GLIBCXX_DEBUG +#define _GLIBCXX_ASSERTIONS 1 +#endif + // Inline namespaces for special modes: debug, parallel. #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) namespace std diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h index 68ed827..0928137 100644 --- a/libstdc++-v3/include/bits/char_traits.h +++ b/libstdc++-v3/include/bits/char_traits.h @@ -762,10 +762,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef char16_t char_type; #ifdef __UINT_LEAST16_TYPE__ typedef __UINT_LEAST16_TYPE__ int_type; -#elif defined _GLIBCXX_USE_C99_STDINT_TR1 - typedef uint_least16_t int_type; #else - typedef make_unsigned<char16_t>::type int_type; + typedef uint_least16_t int_type; #endif #if _GLIBCXX_HOSTED typedef streamoff off_type; @@ -891,10 +889,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef char32_t char_type; #ifdef __UINT_LEAST32_TYPE__ typedef __UINT_LEAST32_TYPE__ int_type; -#elif defined _GLIBCXX_USE_C99_STDINT_TR1 - typedef uint_least32_t int_type; #else - typedef make_unsigned<char32_t>::type int_type; + typedef uint_least32_t int_type; #endif #if _GLIBCXX_HOSTED typedef streamoff off_type; diff --git a/libstdc++-v3/include/bits/chrono.h b/libstdc++-v3/include/bits/chrono.h index fb99fe5..81b92d7 100644 --- a/libstdc++-v3/include/bits/chrono.h +++ b/libstdc++-v3/include/bits/chrono.h @@ -884,7 +884,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @} /// @cond undocumented -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 +#ifdef _GLIBCXX_USE_C99_STDINT # define _GLIBCXX_CHRONO_INT64_T int64_t #elif defined __INT64_TYPE__ # define _GLIBCXX_CHRONO_INT64_T __INT64_TYPE__ diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h index 1ee84e6..e5f094f 100644 --- a/libstdc++-v3/include/bits/cow_string.h +++ b/libstdc++-v3/include/bits/cow_string.h @@ -54,6 +54,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * @ingroup strings * @ingroup sequences + * @headerfile string + * @since C++98 * * @tparam _CharT Type of character * @tparam _Traits Traits for character type, defaults to @@ -907,17 +909,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: // Capacity: + /// Returns the number of characters in the string, not including any /// null-termination. size_type size() const _GLIBCXX_NOEXCEPT - { return _M_rep()->_M_length; } + { +#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && __OPTIMIZE__ + if (_S_empty_rep()._M_length != 0) + __builtin_unreachable(); +#endif + return _M_rep()->_M_length; + } /// Returns the number of characters in the string, not including any /// null-termination. size_type length() const _GLIBCXX_NOEXCEPT - { return _M_rep()->_M_length; } + { return size(); } /// Returns the size() of the largest possible %string. size_type diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index e1e68bd..72b1ef4 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -406,6 +406,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * and fixed time insertion/deletion at any point in the sequence. * * @ingroup sequences + * @headerfile forward_list + * @since C++11 * * @tparam _Tp Type of element. * @tparam _Alloc Allocator type, defaults to allocator<_Tp>. diff --git a/libstdc++-v3/include/bits/fs_dir.h b/libstdc++-v3/include/bits/fs_dir.h index b4adf49..9dd0f89 100644 --- a/libstdc++-v3/include/bits/fs_dir.h +++ b/libstdc++-v3/include/bits/fs_dir.h @@ -52,6 +52,10 @@ namespace filesystem */ /// Information about a file's type and permissions. + /** + * @headerfile filesystem + * @since C++17 + */ class file_status { public: @@ -94,6 +98,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 class recursive_directory_iterator; /// The value type used by directory iterators + /** + * @headerfile filesystem + * @since C++17 + */ class directory_entry { public: @@ -354,7 +362,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 file_type _M_type = file_type::none; }; + /// @cond undocumented + /// Proxy returned by post-increment on directory iterators. + /** + * @headerfile filesystem + * @since C++17 + */ struct __directory_iterator_proxy { const directory_entry& operator*() const& noexcept { return _M_entry; } @@ -370,8 +384,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 directory_entry _M_entry; }; + /// @endcond /// Iterator type for traversing the entries in a single directory. + /** + * @headerfile filesystem + * @since C++17 + */ class directory_iterator { public: @@ -451,7 +470,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 std::__shared_ptr<_Dir> _M_dir; }; - /// @relates std::filesystem::directory_iterator @{ + /** @relates std::filesystem::directory_iterator + * @headerfile filesystem + * @since C++17 + * @{ + */ /** @brief Enable range-based `for` using directory_iterator. * @@ -468,6 +491,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 /// @} /// Iterator type for recursively traversing a directory hierarchy. + /** + * @headerfile filesystem + * @since C++17 + */ class recursive_directory_iterator { public: @@ -566,7 +593,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 filesystem::remove_all(const path&); }; - /// @relates std::filesystem::recursive_directory_iterator @{ + /** @relates std::filesystem::directory_iterator + * @headerfile filesystem + * @since C++17 + * @{ + */ /** @brief Enable range-based `for` using recursive_directory_iterator. * diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h index 0d7bb10..853c55f 100644 --- a/libstdc++-v3/include/bits/fs_path.h +++ b/libstdc++-v3/include/bits/fs_path.h @@ -285,7 +285,11 @@ namespace __detail /// @{ /// A filesystem path - /// @ingroup filesystem + /** + * @ingroup filesystem + * @headerfile filesystem + * @since C++17 + */ class path { public: @@ -736,6 +740,10 @@ namespace __detail /// @} /// Exception type thrown by the Filesystem library + /** + * @headerfile filesystem + * @since C++17 + */ class filesystem_error : public std::system_error { public: @@ -798,6 +806,8 @@ namespace __detail /** Create a path from a UTF-8-encoded sequence of char * * @relates std::filesystem::path + * @headerfile filesystem + * @since C++17 */ template<typename _InputIterator, typename _Require = __detail::_Path2<_InputIterator>, @@ -822,6 +832,8 @@ namespace __detail /** Create a path from a UTF-8-encoded sequence of char * * @relates std::filesystem::path + * @headerfile filesystem + * @since C++17 */ template<typename _Source, typename _Require = __detail::_Path<_Source>, @@ -923,6 +935,10 @@ namespace __detail /// @endcond /// An iterator for the components of a path + /** + * @headerfile filesystem + * @since C++17 + */ class path::iterator { public: diff --git a/libstdc++-v3/include/bits/gslice_array.h b/libstdc++-v3/include/bits/gslice_array.h index f117a17..6a48d41 100644 --- a/libstdc++-v3/include/bits/gslice_array.h +++ b/libstdc++-v3/include/bits/gslice_array.h @@ -183,6 +183,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Array<size_t>(_M_index)); } + /// @cond undocumented #undef _DEFINE_VALARRAY_OPERATOR #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ template<typename _Tp> \ @@ -214,6 +215,7 @@ _DEFINE_VALARRAY_OPERATOR(<<, __shift_left) _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) #undef _DEFINE_VALARRAY_OPERATOR + /// @endcond /// @} group numeric_arrays diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index d2ff153..954a1c7 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -401,8 +401,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void _M_update_bbegin() { - if (_M_begin()) - _M_buckets[_M_bucket_index(*_M_begin())] = &_M_before_begin; + if (auto __begin = _M_begin()) + _M_buckets[_M_bucket_index(*__begin)] = &_M_before_begin; } void @@ -458,7 +458,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Gets bucket begin, deals with the fact that non-empty buckets contain // their before begin node. __node_ptr - _M_bucket_begin(size_type __bkt) const; + _M_bucket_begin(size_type __bkt) const + { + __node_base_ptr __n = _M_buckets[__bkt]; + return __n ? static_cast<__node_ptr>(__n->_M_nxt) : nullptr; + } __node_ptr _M_begin() const @@ -831,19 +835,57 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Insert a node at the beginning of a bucket. void - _M_insert_bucket_begin(size_type, __node_ptr); + _M_insert_bucket_begin(size_type __bkt, __node_ptr __node) + { + if (_M_buckets[__bkt]) + { + // Bucket is not empty, we just need to insert the new node + // after the bucket before begin. + __node->_M_nxt = _M_buckets[__bkt]->_M_nxt; + _M_buckets[__bkt]->_M_nxt = __node; + } + else + { + // The bucket is empty, the new node is inserted at the + // beginning of the singly-linked list and the bucket will + // contain _M_before_begin pointer. + __node->_M_nxt = _M_before_begin._M_nxt; + _M_before_begin._M_nxt = __node; + + if (__node->_M_nxt) + // We must update former begin bucket that is pointing to + // _M_before_begin. + _M_buckets[_M_bucket_index(*__node->_M_next())] = __node; + + _M_buckets[__bkt] = &_M_before_begin; + } + } // Remove the bucket first node void _M_remove_bucket_begin(size_type __bkt, __node_ptr __next_n, - size_type __next_bkt); + size_type __next_bkt) + { + if (!__next_n || __next_bkt != __bkt) + { + // Bucket is now empty + // First update next bucket if any + if (__next_n) + _M_buckets[__next_bkt] = _M_buckets[__bkt]; + + // Second update before begin node if necessary + if (&_M_before_begin == _M_buckets[__bkt]) + _M_before_begin._M_nxt = __next_n; + _M_buckets[__bkt] = nullptr; + } + } // Get the node before __n in the bucket __bkt __node_base_ptr _M_get_previous_node(size_type __bkt, __node_ptr __n); - pair<const_iterator, __hash_code> - _M_compute_hash_code(const_iterator __hint, const key_type& __k) const; + pair<__node_ptr, __hash_code> + _M_compute_hash_code(__node_ptr __hint, const key_type& __k) const; // Insert node __n with hash code __code, in bucket __bkt if no // rehash (assumes no element with same key already present). @@ -1157,20 +1199,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _ExtractKey, typename _Equal, typename _Hash, typename _RangeHash, typename _Unused, typename _RehashPolicy, typename _Traits> - auto - _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, - _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>:: - _M_bucket_begin(size_type __bkt) const - -> __node_ptr - { - __node_base_ptr __n = _M_buckets[__bkt]; - return __n ? static_cast<__node_ptr>(__n->_M_nxt) : nullptr; - } - - template<typename _Key, typename _Value, typename _Alloc, - typename _ExtractKey, typename _Equal, - typename _Hash, typename _RangeHash, typename _Unused, - typename _RehashPolicy, typename _Traits> _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>:: _Hashtable(size_type __bkt_count_hint, @@ -1653,9 +1681,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (size() <= __small_size_threshold()) { - for (auto __it = begin(); __it != end(); ++__it) - if (this->_M_key_equals(__k, *__it._M_cur)) - return __it; + for (auto __it = _M_begin(); __it; __it = __it->_M_next()) + if (this->_M_key_equals(__k, *__it)) + return iterator(__it); return end(); } @@ -1676,9 +1704,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (size() <= __small_size_threshold()) { - for (auto __it = begin(); __it != end(); ++__it) - if (this->_M_key_equals(__k, *__it._M_cur)) - return __it; + for (auto __it = _M_begin(); __it; __it = __it->_M_next()) + if (this->_M_key_equals(__k, *__it)) + return const_iterator(__it); return end(); } @@ -1988,63 +2016,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _ExtractKey, typename _Equal, typename _Hash, typename _RangeHash, typename _Unused, typename _RehashPolicy, typename _Traits> - void - _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, - _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>:: - _M_insert_bucket_begin(size_type __bkt, __node_ptr __node) - { - if (_M_buckets[__bkt]) - { - // Bucket is not empty, we just need to insert the new node - // after the bucket before begin. - __node->_M_nxt = _M_buckets[__bkt]->_M_nxt; - _M_buckets[__bkt]->_M_nxt = __node; - } - else - { - // The bucket is empty, the new node is inserted at the - // beginning of the singly-linked list and the bucket will - // contain _M_before_begin pointer. - __node->_M_nxt = _M_before_begin._M_nxt; - _M_before_begin._M_nxt = __node; - - if (__node->_M_nxt) - // We must update former begin bucket that is pointing to - // _M_before_begin. - _M_buckets[_M_bucket_index(*__node->_M_next())] = __node; - - _M_buckets[__bkt] = &_M_before_begin; - } - } - - template<typename _Key, typename _Value, typename _Alloc, - typename _ExtractKey, typename _Equal, - typename _Hash, typename _RangeHash, typename _Unused, - typename _RehashPolicy, typename _Traits> - void - _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, - _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>:: - _M_remove_bucket_begin(size_type __bkt, __node_ptr __next, - size_type __next_bkt) - { - if (!__next || __next_bkt != __bkt) - { - // Bucket is now empty - // First update next bucket if any - if (__next) - _M_buckets[__next_bkt] = _M_buckets[__bkt]; - - // Second update before begin node if necessary - if (&_M_before_begin == _M_buckets[__bkt]) - _M_before_begin._M_nxt = __next; - _M_buckets[__bkt] = nullptr; - } - } - - template<typename _Key, typename _Value, typename _Alloc, - typename _ExtractKey, typename _Equal, - typename _Hash, typename _RangeHash, typename _Unused, - typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>:: @@ -2073,10 +2044,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const key_type& __k = _ExtractKey{}(__node._M_node->_M_v()); if (size() <= __small_size_threshold()) { - for (auto __it = begin(); __it != end(); ++__it) - if (this->_M_key_equals(__k, *__it._M_cur)) + for (auto __it = _M_begin(); __it; __it = __it->_M_next()) + if (this->_M_key_equals(__k, *__it)) // There is already an equivalent node, no insertion - return { __it, false }; + return { iterator(__it), false }; } __hash_code __code = this->_M_hash_code(__k); @@ -2108,10 +2079,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Scoped_node __node { this, std::forward<_Args>(__args)... }; const key_type& __k = _ExtractKey{}(__node._M_node->_M_v()); - auto __res = this->_M_compute_hash_code(__hint, __k); + auto __res = this->_M_compute_hash_code(__hint._M_cur, __k); auto __pos - = _M_insert_multi_node(__res.first._M_cur, __res.second, - __node._M_node); + = _M_insert_multi_node(__res.first, __res.second, __node._M_node); __node._M_node = nullptr; return __pos; } @@ -2123,21 +2093,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>:: - _M_compute_hash_code(const_iterator __hint, const key_type& __k) const - -> pair<const_iterator, __hash_code> + _M_compute_hash_code(__node_ptr __hint, const key_type& __k) const + -> pair<__node_ptr, __hash_code> { if (size() <= __small_size_threshold()) { - if (__hint != cend()) + if (__hint) { - for (auto __it = __hint; __it != cend(); ++__it) - if (this->_M_key_equals(__k, *__it._M_cur)) - return { __it, this->_M_hash_code(*__it._M_cur) }; + for (auto __it = __hint; __it; __it = __it->_M_next()) + if (this->_M_key_equals(__k, *__it)) + return { __it, this->_M_hash_code(*__it) }; } - for (auto __it = cbegin(); __it != __hint; ++__it) - if (this->_M_key_equals(__k, *__it._M_cur)) - return { __it, this->_M_hash_code(*__it._M_cur) }; + for (auto __it = _M_begin(); __it != __hint; __it = __it->_M_next()) + if (this->_M_key_equals(__k, *__it)) + return { __it, this->_M_hash_code(*__it) }; + + __hint = nullptr; } return { __hint, this->_M_hash_code(__k) }; @@ -2242,9 +2214,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION -> pair<iterator, bool> { if (size() <= __small_size_threshold()) - for (auto __it = begin(); __it != end(); ++__it) - if (this->_M_key_equals_tr(__k, *__it._M_cur)) - return { __it, false }; + for (auto __it = _M_begin(); __it; __it = __it->_M_next()) + if (this->_M_key_equals_tr(__k, *__it)) + return { iterator(__it), false }; __hash_code __code = this->_M_hash_code_tr(__k); size_type __bkt = _M_bucket_index(__code); @@ -2284,11 +2256,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Second compute the hash code so that we don't rehash if it throws. auto __res = this->_M_compute_hash_code( - __hint, _ExtractKey{}(__node._M_node->_M_v())); + __hint._M_cur, _ExtractKey{}(__node._M_node->_M_v())); auto __pos - = _M_insert_multi_node(__res.first._M_cur, __res.second, - __node._M_node); + = _M_insert_multi_node(__res.first, __res.second, __node._M_node); __node._M_node = nullptr; return __pos; } diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h index cce4e28..347d468 100644 --- a/libstdc++-v3/include/bits/hashtable_policy.h +++ b/libstdc++-v3/include/bits/hashtable_policy.h @@ -156,7 +156,7 @@ namespace __detail template<typename _Kt, typename _Arg, typename _NodeGenerator> static auto _S_build(_Kt&& __k, _Arg&& __arg, const _NodeGenerator& __node_gen) - -> typename _NodeGenerator::__node_type* + -> typename _NodeGenerator::__node_ptr { return __node_gen(std::forward<_Kt>(__k), std::forward<_Arg>(__arg).second); @@ -169,7 +169,7 @@ namespace __detail template<typename _Kt, typename _Arg, typename _NodeGenerator> static auto _S_build(_Kt&& __k, _Arg&&, const _NodeGenerator& __node_gen) - -> typename _NodeGenerator::__node_type* + -> typename _NodeGenerator::__node_ptr { return __node_gen(std::forward<_Kt>(__k)); } }; @@ -188,9 +188,9 @@ namespace __detail typename __hashtable_alloc::__node_alloc_traits; public: - using __node_type = typename __hashtable_alloc::__node_type; + using __node_ptr = typename __hashtable_alloc::__node_ptr; - _ReuseOrAllocNode(__node_type* __nodes, __hashtable_alloc& __h) + _ReuseOrAllocNode(__node_ptr __nodes, __hashtable_alloc& __h) : _M_nodes(__nodes), _M_h(__h) { } _ReuseOrAllocNode(const _ReuseOrAllocNode&) = delete; @@ -198,12 +198,12 @@ namespace __detail { _M_h._M_deallocate_nodes(_M_nodes); } template<typename... _Args> - __node_type* + __node_ptr operator()(_Args&&... __args) const { if (_M_nodes) { - __node_type* __node = _M_nodes; + __node_ptr __node = _M_nodes; _M_nodes = _M_nodes->_M_next(); __node->_M_nxt = nullptr; auto& __a = _M_h._M_node_allocator(); @@ -224,7 +224,7 @@ namespace __detail } private: - mutable __node_type* _M_nodes; + mutable __node_ptr _M_nodes; __hashtable_alloc& _M_h; }; @@ -237,13 +237,13 @@ namespace __detail using __hashtable_alloc = _Hashtable_alloc<_NodeAlloc>; public: - using __node_type = typename __hashtable_alloc::__node_type; + using __node_ptr = typename __hashtable_alloc::__node_ptr; _AllocNode(__hashtable_alloc& __h) : _M_h(__h) { } template<typename... _Args> - __node_type* + __node_ptr operator()(_Args&&... __args) const { return _M_h._M_allocate_node(std::forward<_Args>(__args)...); } @@ -1809,22 +1809,22 @@ namespace __detail _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, true>:: _M_equal(const __hashtable& __other) const { - using __node_type = typename __hashtable::__node_type; + using __node_ptr = typename __hashtable::__node_ptr; const __hashtable* __this = static_cast<const __hashtable*>(this); if (__this->size() != __other.size()) return false; - for (auto __itx = __this->begin(); __itx != __this->end(); ++__itx) + for (auto __x_n = __this->_M_begin(); __x_n; __x_n = __x_n->_M_next()) { - std::size_t __ybkt = __other._M_bucket_index(*__itx._M_cur); + std::size_t __ybkt = __other._M_bucket_index(*__x_n); auto __prev_n = __other._M_buckets[__ybkt]; if (!__prev_n) return false; - for (__node_type* __n = static_cast<__node_type*>(__prev_n->_M_nxt);; + for (__node_ptr __n = static_cast<__node_ptr>(__prev_n->_M_nxt);; __n = __n->_M_next()) { - if (__n->_M_v() == *__itx) + if (__n->_M_v() == __x_n->_M_v()) break; if (!__n->_M_nxt @@ -1861,31 +1861,32 @@ namespace __detail _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, false>:: _M_equal(const __hashtable& __other) const { - using __node_type = typename __hashtable::__node_type; + using __node_ptr = typename __hashtable::__node_ptr; + using const_iterator = typename __hashtable::const_iterator; const __hashtable* __this = static_cast<const __hashtable*>(this); if (__this->size() != __other.size()) return false; - for (auto __itx = __this->begin(); __itx != __this->end();) + for (auto __x_n = __this->_M_begin(); __x_n;) { std::size_t __x_count = 1; - auto __itx_end = __itx; - for (++__itx_end; __itx_end != __this->end() - && __this->key_eq()(_ExtractKey{}(*__itx), - _ExtractKey{}(*__itx_end)); - ++__itx_end) + auto __x_n_end = __x_n->_M_next(); + for (; __x_n_end + && __this->key_eq()(_ExtractKey{}(__x_n->_M_v()), + _ExtractKey{}(__x_n_end->_M_v())); + __x_n_end = __x_n_end->_M_next()) ++__x_count; - std::size_t __ybkt = __other._M_bucket_index(*__itx._M_cur); + std::size_t __ybkt = __other._M_bucket_index(*__x_n); auto __y_prev_n = __other._M_buckets[__ybkt]; if (!__y_prev_n) return false; - __node_type* __y_n = static_cast<__node_type*>(__y_prev_n->_M_nxt); + __node_ptr __y_n = static_cast<__node_ptr>(__y_prev_n->_M_nxt); for (;;) { if (__this->key_eq()(_ExtractKey{}(__y_n->_M_v()), - _ExtractKey{}(*__itx))) + _ExtractKey{}(__x_n->_M_v()))) break; auto __y_ref_n = __y_n; @@ -1897,18 +1898,20 @@ namespace __detail return false; } - typename __hashtable::const_iterator __ity(__y_n); - for (auto __ity_end = __ity; __ity_end != __other.end(); ++__ity_end) + auto __y_n_end = __y_n; + for (; __y_n_end; __y_n_end = __y_n_end->_M_next()) if (--__x_count == 0) break; if (__x_count != 0) return false; + const_iterator __itx(__x_n), __itx_end(__x_n_end); + const_iterator __ity(__y_n); if (!std::is_permutation(__itx, __itx_end, __ity)) return false; - __itx = __itx_end; + __x_n = __x_n_end; } return true; } diff --git a/libstdc++-v3/include/bits/indirect_array.h b/libstdc++-v3/include/bits/indirect_array.h index deeed99..8d34a36 100644 --- a/libstdc++-v3/include/bits/indirect_array.h +++ b/libstdc++-v3/include/bits/indirect_array.h @@ -174,6 +174,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION indirect_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const { std::__valarray_copy(__e, _M_sz, _M_array, _M_index); } + /// @cond undocumented #undef _DEFINE_VALARRAY_OPERATOR #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ template<typename _Tp> \ @@ -203,6 +204,7 @@ _DEFINE_VALARRAY_OPERATOR(<<, __shift_left) _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) #undef _DEFINE_VALARRAY_OPERATOR + /// @endcond /// @} group numeric_arrays diff --git a/libstdc++-v3/include/bits/locale_classes.tcc b/libstdc++-v3/include/bits/locale_classes.tcc index 94838cd7..2351dd5 100644 --- a/libstdc++-v3/include/bits/locale_classes.tcc +++ b/libstdc++-v3/include/bits/locale_classes.tcc @@ -129,9 +129,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_STD_FACET(time_put<wchar_t>); _GLIBCXX_STD_FACET(messages<wchar_t>); #endif -#ifdef _GLIBCXX_USE_CHAR8_T - _GLIBCXX_STD_FACET(codecvt<char8_t, char, mbstate_t>); -#endif #if __cplusplus >= 201103L _GLIBCXX_STD_FACET(codecvt<char16_t, char, mbstate_t>); _GLIBCXX_STD_FACET(codecvt<char32_t, char, mbstate_t>); diff --git a/libstdc++-v3/include/bits/mask_array.h b/libstdc++-v3/include/bits/mask_array.h index d4112a9..a3174dd 100644 --- a/libstdc++-v3/include/bits/mask_array.h +++ b/libstdc++-v3/include/bits/mask_array.h @@ -181,6 +181,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::__valarray_copy(__e, __e.size(), _M_array, _M_mask); } + /// @cond undocumented #undef _DEFINE_VALARRAY_OPERATOR #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ template<typename _Tp> \ @@ -213,6 +214,7 @@ _DEFINE_VALARRAY_OPERATOR(<<, __shift_left) _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) #undef _DEFINE_VALARRAY_OPERATOR + /// @endcond /// @} group numeric_arrays diff --git a/libstdc++-v3/include/bits/max_size_type.h b/libstdc++-v3/include/bits/max_size_type.h index 92b8168..4796135 100644 --- a/libstdc++-v3/include/bits/max_size_type.h +++ b/libstdc++-v3/include/bits/max_size_type.h @@ -560,7 +560,8 @@ namespace ranges // Arithmetic right shift. const auto __msb = _M_rep._M_msb; _M_rep >>= __r._M_rep; - _M_rep._M_msb |= __msb; + if (__msb) + _M_rep |= ~(__max_size_type(-1) >> __r._M_rep); return *this; } diff --git a/libstdc++-v3/include/bits/memory_resource.h b/libstdc++-v3/include/bits/memory_resource.h index 1b9e51d..f12555d 100644 --- a/libstdc++-v3/include/bits/memory_resource.h +++ b/libstdc++-v3/include/bits/memory_resource.h @@ -53,6 +53,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace pmr { /// Class memory_resource + /** + * @ingroup pmr + * @headerfile memory_resource + * @since C++17 + */ class memory_resource { static constexpr size_t _S_max_align = alignof(max_align_t); @@ -104,6 +109,13 @@ namespace pmr #endif // C++17 23.12.3 Class template polymorphic_allocator + + /// Class template polymorphic_allocator + /** + * @ingroup pmr + * @headerfile memory_resource + * @since C++17 + */ template<typename _Tp> class polymorphic_allocator { diff --git a/libstdc++-v3/include/bits/mofunc_impl.h b/libstdc++-v3/include/bits/mofunc_impl.h index 47e1e50..318a55e 100644 --- a/libstdc++-v3/include/bits/mofunc_impl.h +++ b/libstdc++-v3/include/bits/mofunc_impl.h @@ -51,14 +51,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @headerfile functional * * The `std::move_only_function` class template is a call wrapper similar - * to * `std::function`, but does not require the stored target function + * to `std::function`, but does not require the stored target function * to be copyable. * * It also supports const-qualification, ref-qualification, and * no-throw guarantees. The qualifications and exception-specification * of the `move_only_function::operator()` member function are respected * when invoking the target function. - * */ template<typename _Res, typename... _ArgTypes, bool _Noex> class move_only_function<_Res(_ArgTypes...) _GLIBCXX_MOF_CV diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h index 6bc70e8..4a8fcef 100644 --- a/libstdc++-v3/include/bits/move.h +++ b/libstdc++-v3/include/bits/move.h @@ -33,6 +33,8 @@ #include <bits/c++config.h> #if __cplusplus < 201103L # include <bits/concept_check.h> +#else +# include <type_traits> // Brings in std::declval too. #endif namespace std _GLIBCXX_VISIBILITY(default) @@ -51,15 +53,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L -_GLIBCXX_END_NAMESPACE_VERSION -} // namespace - -#include <type_traits> // Brings in std::declval too. - -namespace std _GLIBCXX_VISIBILITY(default) -{ -_GLIBCXX_BEGIN_NAMESPACE_VERSION - /** * @addtogroup utilities * @{ diff --git a/libstdc++-v3/include/bits/ptr_traits.h b/libstdc++-v3/include/bits/ptr_traits.h index dc42a74..8a919ec 100644 --- a/libstdc++-v3/include/bits/ptr_traits.h +++ b/libstdc++-v3/include/bits/ptr_traits.h @@ -34,12 +34,15 @@ #include <bits/move.h> +/* Duplicate definition with unique_ptr.h. */ +#if __cplusplus > 202002L && defined(__cpp_constexpr_dynamic_alloc) +# define __cpp_lib_constexpr_memory 202202L +#elif __cplusplus > 201703L +# define __cpp_lib_constexpr_memory 201811L +#endif + #if __cplusplus > 201703L #include <concepts> -# ifndef __cpp_lib_constexpr_memory -// Defined to a newer value in bits/unique_ptr.h for C++23 -# define __cpp_lib_constexpr_memory 201811L -# endif namespace __gnu_debug { struct _Safe_iterator_base; } #endif diff --git a/libstdc++-v3/include/bits/quoted_string.h b/libstdc++-v3/include/bits/quoted_string.h index 0644b07..ae961a9 100644 --- a/libstdc++-v3/include/bits/quoted_string.h +++ b/libstdc++-v3/include/bits/quoted_string.h @@ -85,14 +85,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Inserter for quoted strings. * - * _GLIBCXX_RESOLVE_LIB_DEFECTS - * DR 2344 quoted()'s interaction with padding is unclear + * @headerfile iomanip */ template<typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const _Quoted_string<const _CharT*, _CharT>& __str) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 2344 quoted()'s interaction with padding is unclear std::basic_ostringstream<_CharT, _Traits> __ostr; __ostr << __str._M_delim; for (const _CharT* __c = __str._M_string; *__c; ++__c) @@ -109,14 +110,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Inserter for quoted strings. * - * _GLIBCXX_RESOLVE_LIB_DEFECTS - * DR 2344 quoted()'s interaction with padding is unclear + * @headerfile iomanip */ template<typename _CharT, typename _Traits, typename _String> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const _Quoted_string<_String, _CharT>& __str) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 2344 quoted()'s interaction with padding is unclear std::basic_ostringstream<_CharT, _Traits> __ostr; __ostr << __str._M_delim; for (auto __c : __str._M_string) @@ -133,6 +135,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Extractor for delimited strings. * The left and right delimiters can be different. + * + * @headerfile iomanip */ template<typename _CharT, typename _Traits, typename _Alloc> std::basic_istream<_CharT, _Traits>& diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h index 42f37c1..58b5dd7 100644 --- a/libstdc++-v3/include/bits/random.h +++ b/libstdc++-v3/include/bits/random.h @@ -256,6 +256,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * parameters @p __a and @p __c must be less than @p __m. * * The size of the state is @f$1@f$. + * + * @headerfile random + * @since C++11 */ template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> class linear_congruential_engine @@ -471,6 +474,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @tparam __c The second left-shift tempering matrix mask. * @tparam __l The second right-shift tempering matrix parameter. * @tparam __f Initialization multiplier. + * + * @headerfile random + * @since C++11 */ template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, @@ -697,6 +703,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * The size of the state is @f$r@f$ * and the maximum period of the generator is @f$(m^r - m^s - 1)@f$. + * + * @headerfile random + * @since C++11 */ template<typename _UIntType, size_t __w, size_t __s, size_t __r> class subtract_with_carry_engine @@ -890,7 +899,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * Produces random numbers from some base engine by discarding blocks of * data. * - * 0 <= @p __r <= @p __p + * @pre @f$ 0 \leq r \leq p @f$ + * + * @headerfile random + * @since C++11 */ template<typename _RandomNumberEngine, size_t __p, size_t __r> class discard_block_engine @@ -1114,6 +1126,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * Produces random numbers by combining random numbers from some base * engine to produce random numbers with a specified number of bits @p __w. + * + * @headerfile random + * @since C++11 */ template<typename _RandomNumberEngine, size_t __w, typename _UIntType> class independent_bits_engine @@ -1338,6 +1353,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * The values from the base engine are stored in a sequence of size @p __k * and shuffled by an algorithm that depends on those values. + * + * @headerfile random + * @since C++11 */ template<typename _RandomNumberEngine, size_t __k> class shuffle_order_engine @@ -1625,6 +1643,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * A standard interface to a platform-specific non-deterministic * random number generator (if any are available). + * + * @headerfile random + * @since C++11 */ class random_device { @@ -1750,6 +1771,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * A continuous random distribution on the range [min, max) with equal * probability throughout the range. The URNG should be real-valued and * deliver number in the range [0, 1). + * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class uniform_real_distribution @@ -1984,6 +2008,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}} * e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} } * @f] + * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class normal_distribution @@ -2208,6 +2235,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * p(x|m,s) = \frac{1}{sx\sqrt{2\pi}} * \exp{-\frac{(\ln{x} - m)^2}{2s^2}} * @f] + * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class lognormal_distribution @@ -2414,6 +2444,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return !(__d1 == __d2); } #endif + /// @} group random_distributions_normal + + /** + * @addtogroup random_distributions_poisson Poisson Distributions + * @ingroup random_distributions + * @{ + */ + /** * @brief A gamma continuous distribution for random numbers. * @@ -2422,6 +2460,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)} * (x/\beta)^{\alpha - 1} e^{-x/\beta} * @f] + * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class gamma_distribution @@ -2645,14 +2686,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline bool operator!=(const std::gamma_distribution<_RealType>& __d1, const std::gamma_distribution<_RealType>& __d2) - { return !(__d1 == __d2); } + { return !(__d1 == __d2); } #endif + /// @} group random_distributions_poisson + + /** + * @addtogroup random_distributions_normal Normal Distributions + * @ingroup random_distributions + * @{ + */ + /** * @brief A chi_squared_distribution random number distribution. * * The formula for the normal probability mass function is * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$ + * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class chi_squared_distribution @@ -2880,6 +2932,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * The formula for the normal probability mass function is * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$ + * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class cauchy_distribution @@ -3092,6 +3147,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * (\frac{m}{n})^{m/2} x^{(m/2)-1} * (1 + \frac{mx}{n})^{-(m+n)/2} * @f] + * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class fisher_f_distribution @@ -3328,6 +3386,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)} * (1 + \frac{x^2}{n}) ^{-(n+1)/2} * @f] + * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class student_t_distribution @@ -3559,6 +3620,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * Generates a sequence of true and false values with likelihood @f$p@f$ * that true will come up and @f$(1 - p)@f$ that false will appear. + * + * @headerfile random + * @since C++11 */ class bernoulli_distribution { @@ -3779,6 +3843,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * The formula for the binomial probability density function is * @f$p(i|t,p) = \binom{t}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$ * and @f$p@f$ are the parameters of the distribution. + * + * @headerfile random + * @since C++11 */ template<typename _IntType = int> class binomial_distribution @@ -3834,7 +3901,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION double _M_p; double _M_q; -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS double _M_d1, _M_d2, _M_s1, _M_s2, _M_c, _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p; #endif @@ -3948,7 +4015,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION friend bool operator==(const binomial_distribution& __d1, const binomial_distribution& __d2) -#ifdef _GLIBCXX_USE_C99_MATH_TR1 +#ifdef _GLIBCXX_USE_C99_MATH_FUNCS { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; } #else { return __d1._M_param == __d2._M_param; } @@ -4001,7 +4068,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION param_type _M_param; - // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. + // NB: Unused when _GLIBCXX_USE_C99_MATH_FUNCS is undefined. std::normal_distribution<double> _M_nd; }; @@ -4022,6 +4089,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * The formula for the geometric probability density function is * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the * distribution. + * + * @headerfile random + * @since C++11 */ template<typename _IntType = int> class geometric_distribution @@ -4236,6 +4306,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * The formula for the negative binomial probability mass function is * @f$p(i) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$ * and @f$p@f$ are the parameters of the distribution. + * + * @headerfile random + * @since C++11 */ template<typename _IntType = int> class negative_binomial_distribution @@ -4470,6 +4543,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * The formula for the Poisson probability density function is * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the * parameter of the distribution. + * + * @headerfile random + * @since C++11 */ template<typename _IntType = int> class poisson_distribution @@ -4519,7 +4595,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION double _M_mean; double _M_lm_thr; -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb; #endif }; @@ -4624,7 +4700,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION friend bool operator==(const poisson_distribution& __d1, const poisson_distribution& __d2) -#ifdef _GLIBCXX_USE_C99_MATH_TR1 +#ifdef _GLIBCXX_USE_C99_MATH_FUNCS { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; } #else { return __d1._M_param == __d2._M_param; } @@ -4670,7 +4746,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION param_type _M_param; - // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. + // NB: Unused when _GLIBCXX_USE_C99_MATH_FUNCS is undefined. std::normal_distribution<double> _M_nd; }; @@ -4699,6 +4775,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr> * <tr><td>Standard Deviation</td><td>@f$\frac{1}{\lambda}@f$</td></tr> * </table> + * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class exponential_distribution @@ -4918,6 +4997,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * p(x|\alpha,\beta) = \frac{\alpha}{\beta} (\frac{x}{\beta})^{\alpha-1} * \exp{(-(\frac{x}{\beta})^\alpha)} * @f] + * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class weibull_distribution @@ -5132,6 +5214,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * p(x|a,b) = \frac{1}{b} * \exp( \frac{a-x}{b} - \exp(\frac{a-x}{b})) * @f] + * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class extreme_value_distribution @@ -5337,12 +5422,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator>>(std::basic_istream<_CharT, _Traits>& __is, std::extreme_value_distribution<_RealType>& __x); + /// @} group random_distributions_poisson + + /** + * @addtogroup random_distributions_sampling Sampling Distributions + * @ingroup random_distributions + * @{ + */ /** * @brief A discrete_distribution random number distribution. * - * The formula for the discrete probability mass function is + * This distribution produces random numbers @f$ i, 0 \leq i < n @f$, + * distributed according to the probability mass function + * @f$ p(i | p_0, ..., p_{n-1}) = p_i @f$. * + * @headerfile random + * @since C++11 */ template<typename _IntType = int> class discrete_distribution @@ -5579,8 +5675,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief A piecewise_constant_distribution random number distribution. * - * The formula for the piecewise constant probability mass function is + * This distribution produces random numbers @f$ x, b_0 \leq x < b_n @f$, + * uniformly distributed over each subinterval @f$ [b_i, b_{i+1}) @f$ + * according to the probability mass function + * @f[ + * p(x | b_0, ..., b_n, \rho_0, ..., \rho_{n-1}) + * = \rho_i \cdot \frac{b_{i+1} - x}{b_{i+1} - b_i} + * + \rho_{i+1} \cdot \frac{ x - b_i}{b_{i+1} - b_i} + * @f] + * for @f$ b_i \leq x < b_{i+1} @f$. * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class piecewise_constant_distribution @@ -5853,8 +5959,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief A piecewise_linear_distribution random number distribution. * - * The formula for the piecewise linear probability mass function is + * This distribution produces random numbers @f$ x, b_0 \leq x < b_n @f$, + * distributed over each subinterval @f$ [b_i, b_{i+1}) @f$ + * according to the probability mass function + * @f$ p(x | b_0, ..., b_n, \rho_0, ..., \rho_n) = \rho_i @f$, + * for @f$ b_i \leq x < b_{i+1} @f$. * + * @headerfile random + * @since C++11 */ template<typename _RealType = double> class piecewise_linear_distribution @@ -6126,7 +6238,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return !(__d1 == __d2); } #endif - /// @} group random_distributions_poisson + /// @} group random_distributions_sampling /// @} *group random_distributions @@ -6139,6 +6251,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief The seed_seq class generates sequences of seeds for random * number generators. + * + * @headerfile random + * @since C++11 */ class seed_seq { diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc index f092b5c..24a5987 100644 --- a/libstdc++-v3/include/bits/random.tcc +++ b/libstdc++-v3/include/bits/random.tcc @@ -1267,7 +1267,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION poisson_distribution<_IntType>::param_type:: _M_initialize() { -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS if (_M_mean >= 12) { const double __m = std::floor(_M_mean); @@ -1295,7 +1295,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * A rejection algorithm when mean >= 12 and a simple method based * upon the multiplication of uniform random variates otherwise. - * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 + * NB: The former is available only if _GLIBCXX_USE_C99_MATH_FUNCS * is defined. * * Reference: @@ -1311,7 +1311,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS if (__param.mean() >= 12) { double __x; @@ -1479,7 +1479,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_easy = true; -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS if (_M_t * __p12 >= 8) { _M_easy = false; @@ -1550,7 +1550,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * A rejection algorithm when t * p >= 8 and a simple waiting time * method - the second in the referenced book - otherwise. - * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 + * NB: The former is available only if _GLIBCXX_USE_C99_MATH_FUNCS * is defined. * * Reference: @@ -1571,7 +1571,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS if (!__param._M_easy) { double __x; @@ -3367,7 +3367,7 @@ namespace __detail __ret = __sum / __tmp; if (__builtin_expect(__ret >= _RealType(1), 0)) { -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS __ret = std::nextafter(_RealType(1), _RealType(0)); #else __ret = _RealType(1) diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index 5d039bd..da66ff8 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -32,6 +32,9 @@ #if __cplusplus > 201703L +#if __cplusplus > 202002L +#include <optional> +#endif #include <bits/ranges_algobase.h> #include <bits/ranges_util.h> #include <bits/uniform_int_dist.h> // concept uniform_random_bit_generator @@ -1561,7 +1564,6 @@ namespace ranges inline constexpr __sample_fn sample{}; -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 struct __shuffle_fn { template<random_access_iterator _Iter, sentinel_for<_Iter> _Sent, @@ -1588,7 +1590,6 @@ namespace ranges }; inline constexpr __shuffle_fn shuffle{}; -#endif struct __push_heap_fn { @@ -3465,6 +3466,9 @@ namespace ranges inline constexpr __prev_permutation_fn prev_permutation{}; #if __cplusplus > 202002L + +#define __cpp_lib_ranges_contains 202207L + struct __contains_fn { template<input_iterator _Iter, sentinel_for<_Iter> _Sent, @@ -3518,6 +3522,8 @@ namespace ranges inline constexpr __contains_subrange_fn contains_subrange{}; +#define __cpp_lib_ranges_iota 202202L + template<typename _Out, typename _Tp> struct out_value_result { @@ -3566,6 +3572,8 @@ namespace ranges inline constexpr __iota_fn iota{}; +#define __cpp_lib_ranges_find_last 202207L + struct __find_last_fn { template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Tp, typename _Proj = identity> @@ -3691,6 +3699,254 @@ namespace ranges }; inline constexpr __find_last_if_not_fn find_last_if_not{}; + +#define __cpp_lib_ranges_fold 202207L + + template<typename _Iter, typename _Tp> + struct in_value_result + { + [[no_unique_address]] _Iter in; + [[no_unique_address]] _Tp value; + + template<typename _Iter2, typename _Tp2> + requires convertible_to<const _Iter&, _Iter2> + && convertible_to<const _Tp&, _Tp2> + constexpr + operator in_value_result<_Iter2, _Tp2>() const & + { return {in, value}; } + + template<typename _Iter2, typename _Tp2> + requires convertible_to<_Iter, _Iter2> + && convertible_to<_Tp, _Tp2> + constexpr + operator in_value_result<_Iter2, _Tp2>() && + { return {std::move(in), std::move(value)}; } + }; + + namespace __detail + { + template<typename _Fp> + class __flipped + { + _Fp _M_f; + + public: + template<typename _Tp, typename _Up> + requires invocable<_Fp&, _Up, _Tp> + invoke_result_t<_Fp&, _Up, _Tp> + operator()(_Tp&&, _Up&&); // not defined + }; + + template<typename _Fp, typename _Tp, typename _Iter, typename _Up> + concept __indirectly_binary_left_foldable_impl = movable<_Tp> && movable<_Up> + && convertible_to<_Tp, _Up> + && invocable<_Fp&, _Up, iter_reference_t<_Iter>> + && assignable_from<_Up&, invoke_result_t<_Fp&, _Up, iter_reference_t<_Iter>>>; + + template<typename _Fp, typename _Tp, typename _Iter> + concept __indirectly_binary_left_foldable = copy_constructible<_Fp> + && indirectly_readable<_Iter> + && invocable<_Fp&, _Tp, iter_reference_t<_Iter>> + && convertible_to<invoke_result_t<_Fp&, _Tp, iter_reference_t<_Iter>>, + decay_t<invoke_result_t<_Fp&, _Tp, iter_reference_t<_Iter>>>> + && __indirectly_binary_left_foldable_impl + <_Fp, _Tp, _Iter, decay_t<invoke_result_t<_Fp&, _Tp, iter_reference_t<_Iter>>>>; + + template <typename _Fp, typename _Tp, typename _Iter> + concept __indirectly_binary_right_foldable + = __indirectly_binary_left_foldable<__flipped<_Fp>, _Tp, _Iter>; + } // namespace __detail + + template<typename _Iter, typename _Tp> + using fold_left_with_iter_result = in_value_result<_Iter, _Tp>; + + struct __fold_left_with_iter_fn + { + template<typename _Ret_iter, + typename _Iter, typename _Sent, typename _Tp, typename _Fp> + static constexpr auto + _S_impl(_Iter __first, _Sent __last, _Tp __init, _Fp __f) + { + using _Up = decay_t<invoke_result_t<_Fp&, _Tp, iter_reference_t<_Iter>>>; + using _Ret = fold_left_with_iter_result<_Ret_iter, _Up>; + + if (__first == __last) + return _Ret{std::move(__first), _Up(std::move(__init))}; + + _Up __accum = std::__invoke(__f, std::move(__init), *__first); + for (++__first; __first != __last; ++__first) + __accum = std::__invoke(__f, std::move(__accum), *__first); + return _Ret{std::move(__first), std::move(__accum)}; + } + + template<input_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Tp, + __detail::__indirectly_binary_left_foldable<_Tp, _Iter> _Fp> + constexpr auto + operator()(_Iter __first, _Sent __last, _Tp __init, _Fp __f) const + { + using _Ret_iter = _Iter; + return _S_impl<_Ret_iter>(std::move(__first), __last, + std::move(__init), std::move(__f)); + } + + template<input_range _Range, typename _Tp, + __detail::__indirectly_binary_left_foldable<_Tp, iterator_t<_Range>> _Fp> + constexpr auto + operator()(_Range&& __r, _Tp __init, _Fp __f) const + { + using _Ret_iter = borrowed_iterator_t<_Range>; + return _S_impl<_Ret_iter>(ranges::begin(__r), ranges::end(__r), + std::move(__init), std::move(__f)); + } + }; + + inline constexpr __fold_left_with_iter_fn fold_left_with_iter{}; + + struct __fold_left_fn + { + template<input_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Tp, + __detail::__indirectly_binary_left_foldable<_Tp, _Iter> _Fp> + constexpr auto + operator()(_Iter __first, _Sent __last, _Tp __init, _Fp __f) const + { + return ranges::fold_left_with_iter(std::move(__first), __last, + std::move(__init), std::move(__f)).value; + } + + template<input_range _Range, typename _Tp, + __detail::__indirectly_binary_left_foldable<_Tp, iterator_t<_Range>> _Fp> + constexpr auto + operator()(_Range&& __r, _Tp __init, _Fp __f) const + { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__init), std::move(__f)); } + }; + + inline constexpr __fold_left_fn fold_left{}; + + template<typename _Iter, typename _Tp> + using fold_left_first_with_iter_result = in_value_result<_Iter, _Tp>; + + struct __fold_left_first_with_iter_fn + { + template<typename _Ret_iter, typename _Iter, typename _Sent, typename _Fp> + static constexpr auto + _S_impl(_Iter __first, _Sent __last, _Fp __f) + { + using _Up = decltype(ranges::fold_left(std::move(__first), __last, + iter_value_t<_Iter>(*__first), __f)); + using _Ret = fold_left_first_with_iter_result<_Ret_iter, optional<_Up>>; + + if (__first == __last) + return _Ret{std::move(__first), optional<_Up>()}; + + optional<_Up> __init(in_place, *__first); + for (++__first; __first != __last; ++__first) + *__init = std::__invoke(__f, std::move(*__init), *__first); + return _Ret{std::move(__first), std::move(__init)}; + } + + template<input_iterator _Iter, sentinel_for<_Iter> _Sent, + __detail::__indirectly_binary_left_foldable<iter_value_t<_Iter>, _Iter> _Fp> + requires constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>> + constexpr auto + operator()(_Iter __first, _Sent __last, _Fp __f) const + { + using _Ret_iter = _Iter; + return _S_impl<_Ret_iter>(std::move(__first), __last, std::move(__f)); + } + + template<input_range _Range, + __detail::__indirectly_binary_left_foldable<range_value_t<_Range>, iterator_t<_Range>> _Fp> + requires constructible_from<range_value_t<_Range>, range_reference_t<_Range>> + constexpr auto + operator()(_Range&& __r, _Fp __f) const + { + using _Ret_iter = borrowed_iterator_t<_Range>; + return _S_impl<_Ret_iter>(ranges::begin(__r), ranges::end(__r), std::move(__f)); + } + }; + + inline constexpr __fold_left_first_with_iter_fn fold_left_first_with_iter{}; + + struct __fold_left_first_fn + { + template<input_iterator _Iter, sentinel_for<_Iter> _Sent, + __detail::__indirectly_binary_left_foldable<iter_value_t<_Iter>, _Iter> _Fp> + requires constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>> + constexpr auto + operator()(_Iter __first, _Sent __last, _Fp __f) const + { + return ranges::fold_left_first_with_iter(std::move(__first), __last, + std::move(__f)).value; + } + + template<input_range _Range, + __detail::__indirectly_binary_left_foldable<range_value_t<_Range>, iterator_t<_Range>> _Fp> + requires constructible_from<range_value_t<_Range>, range_reference_t<_Range>> + constexpr auto + operator()(_Range&& __r, _Fp __f) const + { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__f)); } + }; + + inline constexpr __fold_left_first_fn fold_left_first{}; + + struct __fold_right_fn + { + template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Tp, + __detail::__indirectly_binary_right_foldable<_Tp, _Iter> _Fp> + constexpr auto + operator()(_Iter __first, _Sent __last, _Tp __init, _Fp __f) const + { + using _Up = decay_t<invoke_result_t<_Fp&, iter_reference_t<_Iter>, _Tp>>; + + if (__first == __last) + return _Up(std::move(__init)); + + _Iter __tail = ranges::next(__first, __last); + _Up __accum = std::__invoke(__f, *--__tail, std::move(__init)); + while (__first != __tail) + __accum = std::__invoke(__f, *--__tail, std::move(__accum)); + return __accum; + } + + template<bidirectional_range _Range, typename _Tp, + __detail::__indirectly_binary_right_foldable<_Tp, iterator_t<_Range>> _Fp> + constexpr auto + operator()(_Range&& __r, _Tp __init, _Fp __f) const + { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__init), std::move(__f)); } + }; + + inline constexpr __fold_right_fn fold_right{}; + + struct __fold_right_last_fn + { + template<bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, + __detail::__indirectly_binary_right_foldable<iter_value_t<_Iter>, _Iter> _Fp> + requires constructible_from<iter_value_t<_Iter>, iter_reference_t<_Iter>> + constexpr auto + operator()(_Iter __first, _Sent __last, _Fp __f) const + { + using _Up = decltype(ranges::fold_right(__first, __last, + iter_value_t<_Iter>(*__first), __f)); + + if (__first == __last) + return optional<_Up>(); + + _Iter __tail = ranges::prev(ranges::next(__first, std::move(__last))); + return optional<_Up>(in_place, + ranges::fold_right(std::move(__first), __tail, + iter_value_t<_Iter>(*__tail), + std::move(__f))); + } + + template<bidirectional_range _Range, + __detail::__indirectly_binary_right_foldable<range_value_t<_Range>, iterator_t<_Range>> _Fp> + requires constructible_from<range_value_t<_Range>, range_reference_t<_Range>> + constexpr auto + operator()(_Range&& __r, _Fp __f) const + { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__f)); } + }; + + inline constexpr __fold_right_last_fn fold_right_last{}; #endif // C++23 } // namespace ranges diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index 86952b3..698dac7 100644 --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -177,45 +177,6 @@ namespace ranges } }; - // If _To is an lvalue-reference, return const _Tp&, otherwise const _Tp&&. - template<typename _To, typename _Tp> - constexpr decltype(auto) - __as_const(_Tp& __t) noexcept - { - static_assert(std::is_same_v<_To&, _Tp&>); - - if constexpr (is_lvalue_reference_v<_To>) - return const_cast<const _Tp&>(__t); - else - return static_cast<const _Tp&&>(__t); - } - - struct _CBegin - { - template<typename _Tp> - [[nodiscard]] - constexpr auto - operator()(_Tp&& __e) const - noexcept(noexcept(_Begin{}(__cust_access::__as_const<_Tp>(__e)))) - requires requires { _Begin{}(__cust_access::__as_const<_Tp>(__e)); } - { - return _Begin{}(__cust_access::__as_const<_Tp>(__e)); - } - }; - - struct _CEnd final - { - template<typename _Tp> - [[nodiscard]] - constexpr auto - operator()(_Tp&& __e) const - noexcept(noexcept(_End{}(__cust_access::__as_const<_Tp>(__e)))) - requires requires { _End{}(__cust_access::__as_const<_Tp>(__e)); } - { - return _End{}(__cust_access::__as_const<_Tp>(__e)); - } - }; - template<typename _Tp> concept __member_rbegin = requires(_Tp& __t) { @@ -337,32 +298,6 @@ namespace ranges } }; - struct _CRBegin - { - template<typename _Tp> - [[nodiscard]] - constexpr auto - operator()(_Tp&& __e) const - noexcept(noexcept(_RBegin{}(__cust_access::__as_const<_Tp>(__e)))) - requires requires { _RBegin{}(__cust_access::__as_const<_Tp>(__e)); } - { - return _RBegin{}(__cust_access::__as_const<_Tp>(__e)); - } - }; - - struct _CREnd - { - template<typename _Tp> - [[nodiscard]] - constexpr auto - operator()(_Tp&& __e) const - noexcept(noexcept(_REnd{}(__cust_access::__as_const<_Tp>(__e)))) - requires requires { _REnd{}(__cust_access::__as_const<_Tp>(__e)); } - { - return _REnd{}(__cust_access::__as_const<_Tp>(__e)); - } - }; - template<typename _Tp> concept __member_size = !disable_sized_range<remove_cvref_t<_Tp>> && requires(_Tp& __t) @@ -547,36 +482,18 @@ namespace ranges } }; - struct _CData - { - template<typename _Tp> - [[nodiscard]] - constexpr auto - operator()(_Tp&& __e) const - noexcept(noexcept(_Data{}(__cust_access::__as_const<_Tp>(__e)))) - requires requires { _Data{}(__cust_access::__as_const<_Tp>(__e)); } - { - return _Data{}(__cust_access::__as_const<_Tp>(__e)); - } - }; - } // namespace __cust_access inline namespace __cust { inline constexpr __cust_access::_Begin begin{}; inline constexpr __cust_access::_End end{}; - inline constexpr __cust_access::_CBegin cbegin{}; - inline constexpr __cust_access::_CEnd cend{}; inline constexpr __cust_access::_RBegin rbegin{}; inline constexpr __cust_access::_REnd rend{}; - inline constexpr __cust_access::_CRBegin crbegin{}; - inline constexpr __cust_access::_CREnd crend{}; inline constexpr __cust_access::_Size size{}; inline constexpr __cust_access::_SSize ssize{}; inline constexpr __cust_access::_Empty empty{}; inline constexpr __cust_access::_Data data{}; - inline constexpr __cust_access::_CData cdata{}; } /// [range.range] The range concept. @@ -598,6 +515,17 @@ namespace ranges template<range _Range> using sentinel_t = decltype(ranges::end(std::declval<_Range&>())); +#if __cplusplus > 202002L + template<range _Range> + using const_iterator_t = const_iterator<iterator_t<_Range>>; + + template<range _Range> + using const_sentinel_t = const_sentinel<sentinel_t<_Range>>; + + template<range _Range> + using range_const_reference_t = iter_const_reference_t<iterator_t<_Range>>; +#endif + template<range _Range> using range_difference_t = iter_difference_t<iterator_t<_Range>>; @@ -690,6 +618,185 @@ namespace ranges concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>; +#if __cplusplus > 202002L + template<typename _Tp> + concept constant_range + = input_range<_Tp> && std::__detail::__constant_iterator<iterator_t<_Tp>>; +#endif + + namespace __cust_access + { +#if __cplusplus > 202020L + template<typename _Range> + constexpr auto& + __possibly_const_range(_Range& __r) noexcept + { + if constexpr (constant_range<const _Range> && !constant_range<_Range>) + return const_cast<const _Range&>(__r); + else + return __r; + } +#else + // If _To is an lvalue-reference, return const _Tp&, otherwise const _Tp&&. + template<typename _To, typename _Tp> + constexpr decltype(auto) + __as_const(_Tp& __t) noexcept + { + static_assert(std::is_same_v<_To&, _Tp&>); + + if constexpr (is_lvalue_reference_v<_To>) + return const_cast<const _Tp&>(__t); + else + return static_cast<const _Tp&&>(__t); + } +#endif + + struct _CBegin + { +#if __cplusplus > 202002L + template<__maybe_borrowed_range _Tp> + [[nodiscard]] + constexpr auto + operator()(_Tp&& __t) const + noexcept(noexcept(std::make_const_iterator + (ranges::begin(__cust_access::__possibly_const_range(__t))))) + requires requires { std::make_const_iterator + (ranges::begin(__cust_access::__possibly_const_range(__t))); } + { + auto& __r = __cust_access::__possibly_const_range(__t); + return const_iterator_t<decltype(__r)>(ranges::begin(__r)); + } +#else + template<typename _Tp> + [[nodiscard]] + constexpr auto + operator()(_Tp&& __e) const + noexcept(noexcept(_Begin{}(__cust_access::__as_const<_Tp>(__e)))) + requires requires { _Begin{}(__cust_access::__as_const<_Tp>(__e)); } + { + return _Begin{}(__cust_access::__as_const<_Tp>(__e)); + } +#endif + }; + + struct _CEnd final + { +#if __cplusplus > 202002L + template<__maybe_borrowed_range _Tp> + [[nodiscard]] + constexpr auto + operator()(_Tp&& __t) const + noexcept(noexcept(std::make_const_sentinel + (ranges::end(__cust_access::__possibly_const_range(__t))))) + requires requires { std::make_const_sentinel + (ranges::end(__cust_access::__possibly_const_range(__t))); } + { + auto& __r = __cust_access::__possibly_const_range(__t); + return const_sentinel_t<decltype(__r)>(ranges::end(__r)); + } +#else + template<typename _Tp> + [[nodiscard]] + constexpr auto + operator()(_Tp&& __e) const + noexcept(noexcept(_End{}(__cust_access::__as_const<_Tp>(__e)))) + requires requires { _End{}(__cust_access::__as_const<_Tp>(__e)); } + { + return _End{}(__cust_access::__as_const<_Tp>(__e)); + } +#endif + }; + + struct _CRBegin + { +#if __cplusplus > 202002L + template<__maybe_borrowed_range _Tp> + [[nodiscard]] + constexpr auto + operator()(_Tp&& __t) const + noexcept(noexcept(std::make_const_iterator + (ranges::rbegin(__cust_access::__possibly_const_range(__t))))) + requires requires { std::make_const_iterator + (ranges::rbegin(__cust_access::__possibly_const_range(__t))); } + { + auto& __r = __cust_access::__possibly_const_range(__t); + return const_iterator<decltype(ranges::rbegin(__r))>(ranges::rbegin(__r)); + } +#else + template<typename _Tp> + [[nodiscard]] + constexpr auto + operator()(_Tp&& __e) const + noexcept(noexcept(_RBegin{}(__cust_access::__as_const<_Tp>(__e)))) + requires requires { _RBegin{}(__cust_access::__as_const<_Tp>(__e)); } + { + return _RBegin{}(__cust_access::__as_const<_Tp>(__e)); + } +#endif + }; + + struct _CREnd + { +#if __cplusplus > 202002L + template<__maybe_borrowed_range _Tp> + [[nodiscard]] + constexpr auto + operator()(_Tp&& __t) const + noexcept(noexcept(std::make_const_sentinel + (ranges::rend(__cust_access::__possibly_const_range(__t))))) + requires requires { std::make_const_sentinel + (ranges::rend(__cust_access::__possibly_const_range(__t))); } + { + auto& __r = __cust_access::__possibly_const_range(__t); + return const_sentinel<decltype(ranges::rend(__r))>(ranges::rend(__r)); + } +#else + template<typename _Tp> + [[nodiscard]] + constexpr auto + operator()(_Tp&& __e) const + noexcept(noexcept(_REnd{}(__cust_access::__as_const<_Tp>(__e)))) + requires requires { _REnd{}(__cust_access::__as_const<_Tp>(__e)); } + { + return _REnd{}(__cust_access::__as_const<_Tp>(__e)); + } +#endif + }; + + struct _CData + { +#if __cplusplus > 202002L + template<__maybe_borrowed_range _Tp> + [[nodiscard]] + constexpr const auto* + operator()(_Tp&& __t) const + noexcept(noexcept(ranges::data(__cust_access::__possibly_const_range(__t)))) + requires requires { ranges::data(__cust_access::__possibly_const_range(__t)); } + { return ranges::data(__cust_access::__possibly_const_range(__t)); } +#else + template<typename _Tp> + [[nodiscard]] + constexpr auto + operator()(_Tp&& __e) const + noexcept(noexcept(_Data{}(__cust_access::__as_const<_Tp>(__e)))) + requires requires { _Data{}(__cust_access::__as_const<_Tp>(__e)); } + { + return _Data{}(__cust_access::__as_const<_Tp>(__e)); + } +#endif + }; + + } // namespace __cust_access + + inline namespace __cust + { + inline constexpr __cust_access::_CBegin cbegin{}; + inline constexpr __cust_access::_CEnd cend{}; + inline constexpr __cust_access::_CRBegin crbegin{}; + inline constexpr __cust_access::_CREnd crend{}; + inline constexpr __cust_access::_CData cdata{}; + } + namespace __detail { template<typename _Tp> diff --git a/libstdc++-v3/include/bits/ranges_cmp.h b/libstdc++-v3/include/bits/ranges_cmp.h index 85c1a77..6710d82 100644 --- a/libstdc++-v3/include/bits/ranges_cmp.h +++ b/libstdc++-v3/include/bits/ranges_cmp.h @@ -57,7 +57,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef __cpp_lib_concepts // Define this here, included by all the headers that need to define it. +#if __cplusplus > 202002L +#define __cpp_lib_ranges 202202L +#else #define __cpp_lib_ranges 202110L +#endif namespace ranges { diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h index 880a0ce..f7e3538 100644 --- a/libstdc++-v3/include/bits/ranges_util.h +++ b/libstdc++-v3/include/bits/ranges_util.h @@ -53,9 +53,7 @@ namespace ranges concept __has_arrow = input_iterator<_It> && (is_pointer_v<_It> || requires(_It __it) { __it.operator->(); }); - template<typename _Tp, typename _Up> - concept __different_from - = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>; + using std::__detail::__different_from; } // namespace __detail /// The ranges::view_interface class template @@ -192,6 +190,24 @@ namespace ranges constexpr decltype(auto) operator[](range_difference_t<_Range> __n) const { return ranges::begin(_M_derived())[__n]; } + +#if __cplusplus > 202002L + constexpr auto + cbegin() requires input_range<_Derived> + { return ranges::cbegin(_M_derived()); } + + constexpr auto + cbegin() const requires input_range<const _Derived> + { return ranges::cbegin(_M_derived()); } + + constexpr auto + cend() requires input_range<_Derived> + { return ranges::cend(_M_derived()); } + + constexpr auto + cend() const requires input_range<const _Derived> + { return ranges::cend(_M_derived()); } +#endif }; namespace __detail diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index 79903fa..26ac6a2 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -1006,6 +1006,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { return this->_M_str().compare({__s, __n}); } /// @endcond + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3204. sub_match::swap only swaps the base class + /// Swap the values of two sub_match objects. + void + swap(sub_match& __s) noexcept(__is_nothrow_swappable<_BiIter>::value) + { + this->pair<_BiIter, _BiIter>::swap(__s); + std::swap(matched, __s.matched); + } + private: // Simplified basic_string_view for C++11 struct __string_view diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc index a58ed3f..6f0a486 100644 --- a/libstdc++-v3/include/bits/regex.tcc +++ b/libstdc++-v3/include/bits/regex.tcc @@ -116,8 +116,6 @@ namespace __detail /// @endcond } // namespace __detail - /// @cond - template<typename _Ch_type> template<typename _Fwd_iter> typename regex_traits<_Ch_type>::string_type @@ -665,7 +663,5 @@ namespace __detail _M_result = nullptr; } - /// @endcond - _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/bits/slice_array.h b/libstdc++-v3/include/bits/slice_array.h index 571e372..42b136d 100644 --- a/libstdc++-v3/include/bits/slice_array.h +++ b/libstdc++-v3/include/bits/slice_array.h @@ -245,6 +245,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION slice_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const { std::__valarray_copy(__e, _M_sz, _M_array, _M_stride); } + /// @cond undocumented #undef _DEFINE_VALARRAY_OPERATOR #define _DEFINE_VALARRAY_OPERATOR(_Op,_Name) \ template<typename _Tp> \ @@ -275,6 +276,7 @@ _DEFINE_VALARRAY_OPERATOR(<<, __shift_left) _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) #undef _DEFINE_VALARRAY_OPERATOR + /// @endcond /// @} group numeric_arrays diff --git a/libstdc++-v3/include/bits/std_abs.h b/libstdc++-v3/include/bits/std_abs.h index 1bb7ffbc..c70c8e4 100644 --- a/libstdc++-v3/include/bits/std_abs.h +++ b/libstdc++-v3/include/bits/std_abs.h @@ -135,11 +135,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __extension__ inline _GLIBCXX_CONSTEXPR __float128 abs(__float128 __x) - { return __x < 0 ? -__x : __x; } + { +#if defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) + return __builtin_fabsl(__x); +#elif defined(_GLIBCXX_HAVE_FLOAT128_MATH) + return __builtin_fabsf128(__x); +#else + // Assume that __builtin_signbit works for __float128. + return __builtin_signbit(__x) ? -__x : __x; +#endif + } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace -} // extern "C"++" +} // extern "C++" #endif // _GLIBCXX_BITS_STD_ABS_H diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 3d37091..2c52ed5 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -140,54 +140,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // count // count_if // search - - template<typename _ForwardIterator1, typename _ForwardIterator2, - typename _BinaryPredicate> - _GLIBCXX20_CONSTEXPR - _ForwardIterator1 - __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __predicate) - { - // Test for empty ranges - if (__first1 == __last1 || __first2 == __last2) - return __first1; - - // Test for a pattern of length 1. - _ForwardIterator2 __p1(__first2); - if (++__p1 == __last2) - return std::__find_if(__first1, __last1, - __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); - - // General case. - _ForwardIterator1 __current = __first1; - - for (;;) - { - __first1 = - std::__find_if(__first1, __last1, - __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); - - if (__first1 == __last1) - return __last1; - - _ForwardIterator2 __p = __p1; - __current = __first1; - if (++__current == __last1) - return __last1; - - while (__predicate(__current, __p)) - { - if (++__p == __last2) - return __first1; - if (++__current == __last1) - return __last1; - } - ++__first1; - } - return __first1; - } - // search_n /** @@ -3692,7 +3644,6 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) #endif // C++17 #endif // C++14 -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 /** * @brief Generate two uniformly distributed integers using a * single distribution invocation. @@ -3803,8 +3754,6 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) std::iter_swap(__i, __first + __d(__g, __p_type(0, __i - __first))); } -#endif // USE C99_STDINT - #endif // C++11 _GLIBCXX_BEGIN_NAMESPACE_ALGO @@ -4151,48 +4100,6 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO } /** - * @brief Search a sequence for a matching sub-sequence using a predicate. - * @ingroup non_mutating_algorithms - * @param __first1 A forward iterator. - * @param __last1 A forward iterator. - * @param __first2 A forward iterator. - * @param __last2 A forward iterator. - * @param __predicate A binary predicate. - * @return The first iterator @c i in the range - * @p [__first1,__last1-(__last2-__first2)) such that - * @p __predicate(*(i+N),*(__first2+N)) is true for each @c N in the range - * @p [0,__last2-__first2), or @p __last1 if no such iterator exists. - * - * Searches the range @p [__first1,__last1) for a sub-sequence that - * compares equal value-by-value with the sequence given by @p - * [__first2,__last2), using @p __predicate to determine equality, - * and returns an iterator to the first element of the - * sub-sequence, or @p __last1 if no such iterator exists. - * - * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2) - */ - template<typename _ForwardIterator1, typename _ForwardIterator2, - typename _BinaryPredicate> - _GLIBCXX20_CONSTEXPR - inline _ForwardIterator1 - search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __predicate) - { - // concept requirements - __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) - __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) - __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, - typename iterator_traits<_ForwardIterator1>::value_type, - typename iterator_traits<_ForwardIterator2>::value_type>) - __glibcxx_requires_valid_range(__first1, __last1); - __glibcxx_requires_valid_range(__first2, __last2); - - return std::__search(__first1, __last1, __first2, __last2, - __gnu_cxx::__ops::__iter_comp_iter(__predicate)); - } - - /** * @brief Search a sequence for a number of consecutive values. * @ingroup non_mutating_algorithms * @param __first A forward iterator. diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index 4a6f8195d..dd95e94 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -2150,6 +2150,53 @@ _GLIBCXX_END_NAMESPACE_ALGO return __result; } + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> + _GLIBCXX20_CONSTEXPR + _ForwardIterator1 + __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __predicate) + { + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIterator2 __p1(__first2); + if (++__p1 == __last2) + return std::__find_if(__first1, __last1, + __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); + + // General case. + _ForwardIterator1 __current = __first1; + + for (;;) + { + __first1 = + std::__find_if(__first1, __last1, + __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); + + if (__first1 == __last1) + return __last1; + + _ForwardIterator2 __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (__predicate(__current, __p)) + { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + ++__first1; + } + return __first1; + } + #if __cplusplus >= 201103L template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> @@ -2220,6 +2267,51 @@ _GLIBCXX_END_NAMESPACE_ALGO } #endif // C++11 +_GLIBCXX_BEGIN_NAMESPACE_ALGO + + /** + * @brief Search a sequence for a matching sub-sequence using a predicate. + * @ingroup non_mutating_algorithms + * @param __first1 A forward iterator. + * @param __last1 A forward iterator. + * @param __first2 A forward iterator. + * @param __last2 A forward iterator. + * @param __predicate A binary predicate. + * @return The first iterator @c i in the range + * @p [__first1,__last1-(__last2-__first2)) such that + * @p __predicate(*(i+N),*(__first2+N)) is true for each @c N in the range + * @p [0,__last2-__first2), or @p __last1 if no such iterator exists. + * + * Searches the range @p [__first1,__last1) for a sub-sequence that + * compares equal value-by-value with the sequence given by @p + * [__first2,__last2), using @p __predicate to determine equality, + * and returns an iterator to the first element of the + * sub-sequence, or @p __last1 if no such iterator exists. + * + * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2) + */ + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> + _GLIBCXX20_CONSTEXPR + inline _ForwardIterator1 + search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __predicate) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return std::__search(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__predicate)); + } + +_GLIBCXX_END_NAMESPACE_ALGO _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index d4d4bfc..ad462c5 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -684,6 +684,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * access to individual elements in any order. * * @ingroup sequences + * @headerfile vector + * @since C++98 * * @tparam _Alloc Allocator type. * diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index a6a09db..b22d9a4 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -102,6 +102,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Cat, typename _Limit, typename _Otherwise = _Cat> using __clamp_iter_cat = __conditional_t<derived_from<_Cat, _Limit>, _Limit, _Otherwise>; + + template<typename _Tp, typename _Up> + concept __different_from + = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>; } #endif @@ -2578,6 +2582,369 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION add_pointer_t<iter_reference_t<_It>>, void>; }; + +#if __cplusplus > 202020L + template<indirectly_readable _It> + using iter_const_reference_t + = common_reference_t<const iter_value_t<_It>&&, iter_reference_t<_It>>; + + template<input_iterator _It> class basic_const_iterator; + + namespace __detail + { + template<typename _It> + concept __constant_iterator = input_iterator<_It> + && same_as<iter_const_reference_t<_It>, iter_reference_t<_It>>; + + template<typename _Tp> + inline constexpr bool __is_const_iterator = false; + + template<typename _It> + inline constexpr bool __is_const_iterator<basic_const_iterator<_It>> = true; + + template<typename _Tp> + concept __not_a_const_iterator = !__is_const_iterator<_Tp>; + + template<indirectly_readable _It> + using __iter_const_rvalue_reference_t + = common_reference_t<const iter_value_t<_It>&&, iter_rvalue_reference_t<_It>>; + + template<typename _It> + struct __basic_const_iterator_iter_cat + { }; + + template<forward_iterator _It> + struct __basic_const_iterator_iter_cat<_It> + { using iterator_category = iterator_traits<_It>::iterator_category; }; + } // namespace detail + + template<input_iterator _It> + using const_iterator + = __conditional_t<__detail::__constant_iterator<_It>, _It, basic_const_iterator<_It>>; + + namespace __detail + { + template<typename _Sent> + struct __const_sentinel + { using type = _Sent; }; + + template<input_iterator _Sent> + struct __const_sentinel<_Sent> + { using type = const_iterator<_Sent>; }; + } // namespace __detail + + template<semiregular _Sent> + using const_sentinel = typename __detail::__const_sentinel<_Sent>::type; + + template<input_iterator _It> + class basic_const_iterator + : public __detail::__basic_const_iterator_iter_cat<_It> + { + _It _M_current = _It(); + using __reference = iter_const_reference_t<_It>; + using __rvalue_reference = __detail::__iter_const_rvalue_reference_t<_It>; + + static auto + _S_iter_concept() + { + if constexpr (contiguous_iterator<_It>) + return contiguous_iterator_tag{}; + else if constexpr (random_access_iterator<_It>) + return random_access_iterator_tag{}; + else if constexpr (bidirectional_iterator<_It>) + return bidirectional_iterator_tag{}; + else if constexpr (forward_iterator<_It>) + return forward_iterator_tag{}; + else + return input_iterator_tag{}; + } + + template<input_iterator _It2> friend class basic_const_iterator; + + public: + using iterator_concept = decltype(_S_iter_concept()); + using value_type = iter_value_t<_It>; + using difference_type = iter_difference_t<_It>; + + basic_const_iterator() requires default_initializable<_It> = default; + + constexpr + basic_const_iterator(_It __current) + noexcept(is_nothrow_move_constructible_v<_It>) + : _M_current(std::move(__current)) + { } + + template<convertible_to<_It> _It2> + constexpr + basic_const_iterator(basic_const_iterator<_It2> __current) + noexcept(is_nothrow_constructible_v<_It, _It2>) + : _M_current(std::move(__current._M_current)) + { } + + template<__detail::__different_from<basic_const_iterator> _Tp> + requires convertible_to<_Tp, _It> + constexpr + basic_const_iterator(_Tp&& __current) + noexcept(is_nothrow_constructible_v<_It, _Tp>) + : _M_current(std::forward<_Tp>(__current)) + { } + + constexpr const _It& + base() const & noexcept + { return _M_current; } + + constexpr _It + base() && + noexcept(is_nothrow_move_constructible_v<_It>) + { return std::move(_M_current); } + + constexpr __reference + operator*() const + noexcept(noexcept(static_cast<__reference>(*_M_current))) + { return static_cast<__reference>(*_M_current); } + + constexpr const auto* + operator->() const + noexcept(contiguous_iterator<_It> || noexcept(*_M_current)) + requires is_lvalue_reference_v<iter_reference_t<_It>> + && same_as<remove_cvref_t<iter_reference_t<_It>>, value_type> + { + if constexpr (contiguous_iterator<_It>) + return std::to_address(_M_current); + else + return std::__addressof(*_M_current); + } + + constexpr basic_const_iterator& + operator++() + noexcept(noexcept(++_M_current)) + { + ++_M_current; + return *this; + } + + constexpr void + operator++(int) + noexcept(noexcept(++_M_current)) + { ++_M_current; } + + constexpr basic_const_iterator + operator++(int) + noexcept(noexcept(++*this) && is_nothrow_copy_constructible_v<basic_const_iterator>) + requires forward_iterator<_It> + { + auto __tmp = *this; + ++*this; + return __tmp; + } + + constexpr basic_const_iterator& + operator--() + noexcept(noexcept(--_M_current)) + requires bidirectional_iterator<_It> + { + --_M_current; + return *this; + } + + constexpr basic_const_iterator + operator--(int) + noexcept(noexcept(--*this) && is_nothrow_copy_constructible_v<basic_const_iterator>) + requires bidirectional_iterator<_It> + { + auto __tmp = *this; + --*this; + return __tmp; + } + + constexpr basic_const_iterator& + operator+=(difference_type __n) + noexcept(noexcept(_M_current += __n)) + requires random_access_iterator<_It> + { + _M_current += __n; + return *this; + } + + constexpr basic_const_iterator& + operator-=(difference_type __n) + noexcept(noexcept(_M_current -= __n)) + requires random_access_iterator<_It> + { + _M_current -= __n; + return *this; + } + + constexpr __reference + operator[](difference_type __n) const + noexcept(noexcept(static_cast<__reference>(_M_current[__n]))) + requires random_access_iterator<_It> + { return static_cast<__reference>(_M_current[__n]); } + + template<sentinel_for<_It> _Sent> + constexpr bool + operator==(const _Sent& __s) const + noexcept(noexcept(_M_current == __s)) + { return _M_current == __s; } + + constexpr bool + operator<(const basic_const_iterator& __y) const + noexcept(noexcept(_M_current < __y._M_current)) + requires random_access_iterator<_It> + { return _M_current < __y._M_current; } + + constexpr bool + operator>(const basic_const_iterator& __y) const + noexcept(noexcept(_M_current > __y._M_current)) + requires random_access_iterator<_It> + { return _M_current > __y._M_current; } + + constexpr bool + operator<=(const basic_const_iterator& __y) const + noexcept(noexcept(_M_current <= __y._M_current)) + requires random_access_iterator<_It> + { return _M_current <= __y._M_current; } + + constexpr bool + operator>=(const basic_const_iterator& __y) const + noexcept(noexcept(_M_current >= __y._M_current)) + requires random_access_iterator<_It> + { return _M_current >= __y._M_current; } + + constexpr auto + operator<=>(const basic_const_iterator& __y) const + noexcept(noexcept(_M_current <=> __y._M_current)) + requires random_access_iterator<_It> && three_way_comparable<_It> + { return _M_current <=> __y._M_current; } + + template<__detail::__different_from<basic_const_iterator> _It2> + constexpr bool + operator<(const _It2& __y) const + noexcept(noexcept(_M_current < __y)) + requires random_access_iterator<_It> && totally_ordered_with<_It, _It2> + { return _M_current < __y; } + + template<__detail::__different_from<basic_const_iterator> _It2> + constexpr bool + operator>(const _It2& __y) const + noexcept(noexcept(_M_current > __y)) + requires random_access_iterator<_It> && totally_ordered_with<_It, _It2> + { return _M_current > __y; } + + template<__detail::__different_from<basic_const_iterator> _It2> + constexpr bool + operator<=(const _It2& __y) const + noexcept(noexcept(_M_current <= __y)) + requires random_access_iterator<_It> && totally_ordered_with<_It, _It2> + { return _M_current <= __y; } + + template<__detail::__different_from<basic_const_iterator> _It2> + constexpr bool + operator>=(const _It2& __y) const + noexcept(noexcept(_M_current >= __y)) + requires random_access_iterator<_It> && totally_ordered_with<_It, _It2> + { return _M_current >= __y; } + + template<__detail::__different_from<basic_const_iterator> _It2> + constexpr auto + operator<=>(const _It2& __y) const + noexcept(noexcept(_M_current <=> __y)) + requires random_access_iterator<_It> && totally_ordered_with<_It, _It2> + && three_way_comparable_with<_It, _It2> + { return _M_current <=> __y; } + + template<__detail::__not_a_const_iterator _It2> + friend constexpr bool + operator<(const _It2& __x, const basic_const_iterator& __y) + noexcept(noexcept(__x < __y._M_current)) + requires random_access_iterator<_It> && totally_ordered_with<_It, _It2> + { return __x < __y._M_current; } + + template<__detail::__not_a_const_iterator _It2> + friend constexpr bool + operator>(const _It2& __x, const basic_const_iterator& __y) + noexcept(noexcept(__x > __y._M_current)) + requires random_access_iterator<_It> && totally_ordered_with<_It, _It2> + { return __x > __y._M_current; } + + template<__detail::__not_a_const_iterator _It2> + friend constexpr bool + operator<=(const _It2& __x, const basic_const_iterator& __y) + noexcept(noexcept(__x <= __y._M_current)) + requires random_access_iterator<_It> && totally_ordered_with<_It, _It2> + { return __x <= __y._M_current; } + + template<__detail::__not_a_const_iterator _It2> + friend constexpr bool + operator>=(const _It2& __x, const basic_const_iterator& __y) + noexcept(noexcept(__x >= __y._M_current)) + requires random_access_iterator<_It> && totally_ordered_with<_It, _It2> + { return __x >= __y._M_current; } + + friend constexpr basic_const_iterator + operator+(const basic_const_iterator& __i, difference_type __n) + noexcept(noexcept(basic_const_iterator(__i._M_current + __n))) + requires random_access_iterator<_It> + { return basic_const_iterator(__i._M_current + __n); } + + friend constexpr basic_const_iterator + operator+(difference_type __n, const basic_const_iterator& __i) + noexcept(noexcept(basic_const_iterator(__i._M_current + __n))) + requires random_access_iterator<_It> + { return basic_const_iterator(__i._M_current + __n); } + + friend constexpr basic_const_iterator + operator-(const basic_const_iterator& __i, difference_type __n) + noexcept(noexcept(basic_const_iterator(__i._M_current - __n))) + requires random_access_iterator<_It> + { return basic_const_iterator(__i._M_current - __n); } + + template<sized_sentinel_for<_It> _Sent> + constexpr difference_type + operator-(const _Sent& __y) const + noexcept(noexcept(_M_current - __y)) + { return _M_current - __y; } + + template<__detail::__not_a_const_iterator _Sent> + requires sized_sentinel_for<_Sent, _It> + friend constexpr difference_type + operator-(const _Sent& __x, const basic_const_iterator& __y) + noexcept(noexcept(__x - __y._M_current)) + { return __x - __y._M_current; } + + friend constexpr __rvalue_reference + iter_move(const basic_const_iterator& __i) + noexcept(noexcept(static_cast<__rvalue_reference>(ranges::iter_move(__i._M_current)))) + { return static_cast<__rvalue_reference>(ranges::iter_move(__i._M_current)); } + }; + + template<typename _Tp, common_with<_Tp> _Up> + requires input_iterator<common_type_t<_Tp, _Up>> + struct common_type<basic_const_iterator<_Tp>, _Up> + { using type = basic_const_iterator<common_type_t<_Tp, _Up>>; }; + + template<typename _Tp, common_with<_Tp> _Up> + requires input_iterator<common_type_t<_Tp, _Up>> + struct common_type<_Up, basic_const_iterator<_Tp>> + { using type = basic_const_iterator<common_type_t<_Tp, _Up>>; }; + + template<typename _Tp, common_with<_Tp> _Up> + requires input_iterator<common_type_t<_Tp, _Up>> + struct common_type<basic_const_iterator<_Tp>, basic_const_iterator<_Up>> + { using type = basic_const_iterator<common_type_t<_Tp, _Up>>; }; + + template<input_iterator _It> + constexpr const_iterator<_It> + make_const_iterator(_It __it) + noexcept(is_nothrow_convertible_v<_It, const_iterator<_It>>) + { return __it; } + + template<semiregular _Sent> + constexpr const_sentinel<_Sent> + make_const_sentinel(_Sent __s) + noexcept(is_nothrow_convertible_v<_Sent, const_sentinel<_Sent>>) + { return __s; } +#endif // C++23 #endif // C++20 /// @} group iterators diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h index e1ce90e..059916d 100644 --- a/libstdc++-v3/include/bits/stl_map.h +++ b/libstdc++-v3/include/bits/stl_map.h @@ -76,6 +76,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * retrieved based on a key, in logarithmic time. * * @ingroup associative_containers + * @headerfile map + * @since C++98 * * @tparam _Key Type of key objects. * @tparam _Tp Type of mapped objects. diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h index 6b11d4b..2efd53d 100644 --- a/libstdc++-v3/include/bits/stl_multimap.h +++ b/libstdc++-v3/include/bits/stl_multimap.h @@ -74,6 +74,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * retrieved based on a key, in logarithmic time. * * @ingroup associative_containers + * @headerfile map + * @since C++98 * * @tparam _Key Type of key objects. * @tparam _Tp Type of mapped objects. diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h index 8f70f89..a399877 100644 --- a/libstdc++-v3/include/bits/stl_multiset.h +++ b/libstdc++-v3/include/bits/stl_multiset.h @@ -74,7 +74,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * in logarithmic time. * * @ingroup associative_containers - * + * @headerfile set + * @since C++98 * * @tparam _Key Type of key objects. * @tparam _Compare Comparison function object type, defaults to less<_Key>. diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h index 9ce05e0..ddaf7fe 100644 --- a/libstdc++-v3/include/bits/stl_set.h +++ b/libstdc++-v3/include/bits/stl_set.h @@ -74,6 +74,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * retrieved in logarithmic time. * * @ingroup associative_containers + * @headerfile set + * @since C++98 * * @tparam _Key Type of key objects. * @tparam _Compare Comparison function object type, defaults to less<_Key>. diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 86ff83d..70ced3d 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -388,6 +388,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } protected: + _GLIBCXX20_CONSTEXPR void _M_create_storage(size_t __n) @@ -403,6 +404,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * individual elements in any order. * * @ingroup sequences + * @headerfile vector + * @since C++98 * * @tparam _Tp Type of element. * @tparam _Alloc Allocator type, defaults to allocator<_Tp>. @@ -1071,8 +1074,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR size_type capacity() const _GLIBCXX_NOEXCEPT - { return size_type(this->_M_impl._M_end_of_storage - - this->_M_impl._M_start); } + { + return size_type(this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + } /** * Returns true if the %vector is empty. (Thus begin() would diff --git a/libstdc++-v3/include/bits/uniform_int_dist.h b/libstdc++-v3/include/bits/uniform_int_dist.h index 5776e5d..7ccf930 100644 --- a/libstdc++-v3/include/bits/uniform_int_dist.h +++ b/libstdc++-v3/include/bits/uniform_int_dist.h @@ -44,6 +44,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef __cpp_lib_concepts /// Requirements for a uniform random bit generator. + /** + * @ingroup random_distributions_uniform + * @headerfile random + * @since C++20 + */ template<typename _Gen> concept uniform_random_bit_generator = invocable<_Gen&> && unsigned_integral<invoke_result_t<_Gen&>> @@ -55,6 +60,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; #endif + /// @cond undocumented namespace __detail { // Determine whether number is a power of two. @@ -67,11 +73,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return ((__x - 1) & __x) == 0; } } + /// @endcond /** * @brief Uniform discrete distribution for random numbers. * A discrete random distribution on the range @f$[min, max]@f$ with equal * probability throughout the range. + * + * @ingroup random_distributions_uniform + * @headerfile random + * @since C++11 */ template<typename _IntType = int> class uniform_int_distribution diff --git a/libstdc++-v3/include/bits/unique_lock.h b/libstdc++-v3/include/bits/unique_lock.h index f14674e..c28e645 100644 --- a/libstdc++-v3/include/bits/unique_lock.h +++ b/libstdc++-v3/include/bits/unique_lock.h @@ -37,6 +37,7 @@ #else #include <bits/chrono.h> +#include <bits/error_constants.h> // for std::errc #include <bits/move.h> // for std::swap #include <bits/std_mutex.h> // for std::defer_lock_t diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index c8daff4..f0c6d23 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -43,12 +43,11 @@ # endif #endif -#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc -# if __cpp_lib_constexpr_memory < 202202L -// Defined with older value in bits/ptr_traits.h for C++20 -# undef __cpp_lib_constexpr_memory -# define __cpp_lib_constexpr_memory 202202L -# endif +/* Duplicate definition with ptr_traits.h. */ +#if __cplusplus > 202002L && defined(__cpp_constexpr_dynamic_alloc) +# define __cpp_lib_constexpr_memory 202202L +#elif __cplusplus > 201703L +# define __cpp_lib_constexpr_memory 201811L #endif namespace std _GLIBCXX_VISIBILITY(default) diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h index f11ccda..2f63bc5 100644 --- a/libstdc++-v3/include/bits/unordered_map.h +++ b/libstdc++-v3/include/bits/unordered_map.h @@ -83,6 +83,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * with the keys. * * @ingroup unordered_associative_containers + * @headerfile unordered_map + * @since C++11 * * @tparam _Key Type of key objects. * @tparam _Tp Type of mapped objects. @@ -1226,6 +1228,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * values of another type with the keys. * * @ingroup unordered_associative_containers + * @headerfile unordered_map + * @since C++11 * * @tparam _Key Type of key objects. * @tparam _Tp Type of mapped objects. diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h index 68fcfd2..f3b0c07 100644 --- a/libstdc++-v3/include/bits/unordered_set.h +++ b/libstdc++-v3/include/bits/unordered_set.h @@ -80,6 +80,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * the elements themselves. * * @ingroup unordered_associative_containers + * @headerfile unordered_set + * @since C++11 * * @tparam _Value Type of key objects. * @tparam _Hash Hashing function object type, defaults to hash<_Value>. @@ -948,6 +950,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * elements' keys are the elements themselves. * * @ingroup unordered_associative_containers + * @headerfile unordered_set + * @since C++11 * * @tparam _Value Type of key objects. * @tparam _Hash Hashing function object type, defaults to hash<_Value>. diff --git a/libstdc++-v3/include/bits/uses_allocator.h b/libstdc++-v3/include/bits/uses_allocator.h index d1841bb..d3b26c7 100644 --- a/libstdc++-v3/include/bits/uses_allocator.h +++ b/libstdc++-v3/include/bits/uses_allocator.h @@ -22,6 +22,11 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +/** @file include/bits/uses_allocator_args.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{memory} + */ + #ifndef _USES_ALLOCATOR_H #define _USES_ALLOCATOR_H 1 diff --git a/libstdc++-v3/include/bits/utility.h b/libstdc++-v3/include/bits/utility.h index abaaae2..4692aa0 100644 --- a/libstdc++-v3/include/bits/utility.h +++ b/libstdc++-v3/include/bits/utility.h @@ -224,6 +224,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // C++17 #endif // C++14 +#if __has_builtin(__type_pack_element) + template<size_t _Np, typename... _Types> + struct _Nth_type + { using type = __type_pack_element<_Np, _Types...>; }; +#else template<size_t _Np, typename... _Types> struct _Nth_type { }; @@ -262,6 +267,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _Nth_type<1, _Tp0, _Tp1, _Tp2, _Rest...> { using type = _Tp1; }; #endif +#endif #if __cplusplus > 202002L #define __cpp_lib_ranges_zip 202110L // for <tuple> and <utility> diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index d6fdea2..acd11e2 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -270,15 +270,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER vector<_Tp, _Alloc>:: _M_fill_assign(size_t __n, const value_type& __val) { + const size_type __sz = size(); if (__n > capacity()) { + if (__n <= __sz) + __builtin_unreachable(); vector __tmp(__n, __val, _M_get_Tp_allocator()); __tmp._M_impl._M_swap_data(this->_M_impl); } - else if (__n > size()) + else if (__n > __sz) { std::fill(begin(), end(), __val); - const size_type __add = __n - size(); + const size_type __add = __n - __sz; _GLIBCXX_ASAN_ANNOTATE_GROW(__add); this->_M_impl._M_finish = std::__uninitialized_fill_n_a(this->_M_impl._M_finish, @@ -316,10 +319,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { + const size_type __sz = size(); const size_type __len = std::distance(__first, __last); if (__len > capacity()) { + if (__len <= __sz) + __builtin_unreachable(); + _S_check_init_len(__len, _M_get_Tp_allocator()); pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, @@ -332,14 +339,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_finish = this->_M_impl._M_start + __len; this->_M_impl._M_end_of_storage = this->_M_impl._M_finish; } - else if (size() >= __len) + else if (__sz >= __len) _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start)); else { _ForwardIterator __mid = __first; - std::advance(__mid, size()); + std::advance(__mid, __sz); std::copy(__first, __mid, this->_M_impl._M_start); - const size_type __attribute__((__unused__)) __n = __len - size(); + const size_type __attribute__((__unused__)) __n = __len - __sz; _GLIBCXX_ASAN_ANNOTATE_GROW(__n); this->_M_impl._M_finish = std::__uninitialized_copy_a(__mid, __last, diff --git a/libstdc++-v3/include/c_compatibility/fenv.h b/libstdc++-v3/include/c_compatibility/fenv.h index 70ce3f8..83e930f 100644 --- a/libstdc++-v3/include/c_compatibility/fenv.h +++ b/libstdc++-v3/include/c_compatibility/fenv.h @@ -38,7 +38,7 @@ #if __cplusplus >= 201103L -#if _GLIBCXX_USE_C99_FENV_TR1 +#if _GLIBCXX_USE_C99_FENV #undef feclearexcept #undef fegetexceptflag @@ -74,7 +74,7 @@ namespace std using ::feupdateenv; } // namespace -#endif // _GLIBCXX_USE_C99_FENV_TR1 +#endif // _GLIBCXX_USE_C99_FENV #endif // C++11 diff --git a/libstdc++-v3/include/c_compatibility/inttypes.h b/libstdc++-v3/include/c_compatibility/inttypes.h index 9c2b7d6..070fcbc 100644 --- a/libstdc++-v3/include/c_compatibility/inttypes.h +++ b/libstdc++-v3/include/c_compatibility/inttypes.h @@ -48,7 +48,7 @@ # endif # endif -#ifdef _GLIBCXX_USE_C99_INTTYPES_TR1 +#ifdef _GLIBCXX_USE_C99_INTTYPES namespace std { @@ -72,13 +72,13 @@ namespace std using ::strtoimax; using ::strtoumax; -#if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1 +#if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_INTTYPES_WCHAR_T using ::wcstoimax; using ::wcstoumax; #endif } // namespace -#endif _GLIBCXX_USE_C99_INTTYPES_TR1 +#endif _GLIBCXX_USE_C99_INTTYPES #else diff --git a/libstdc++-v3/include/c_compatibility/math.h b/libstdc++-v3/include/c_compatibility/math.h index 1206117..cedb11d 100644 --- a/libstdc++-v3/include/c_compatibility/math.h +++ b/libstdc++-v3/include/c_compatibility/math.h @@ -74,7 +74,7 @@ using std::islessgreater; using std::isunordered; #endif -#if __cplusplus >= 201103L && defined(_GLIBCXX_USE_C99_MATH_TR1) +#if __cplusplus >= 201103L && defined(_GLIBCXX_USE_C99_MATH_FUNCS) using std::acosh; using std::asinh; using std::atanh; @@ -109,7 +109,7 @@ using std::scalbln; using std::scalbn; using std::tgamma; using std::trunc; -#endif // C++11 && _GLIBCXX_USE_C99_MATH_TR1 +#endif // C++11 && _GLIBCXX_USE_C99_MATH_FUNCS // The mathematical special functions are only added to the global namespace // by IS 29124, but not by C++17. diff --git a/libstdc++-v3/include/c_compatibility/stdatomic.h b/libstdc++-v3/include/c_compatibility/stdatomic.h index b565a1c..0b63326 100644 --- a/libstdc++-v3/include/c_compatibility/stdatomic.h +++ b/libstdc++-v3/include/c_compatibility/stdatomic.h @@ -62,7 +62,7 @@ using std::atomic_char8_t; using std::atomic_char16_t; using std::atomic_char32_t; using std::atomic_wchar_t; -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 +#ifdef _GLIBCXX_USE_C99_STDINT using std::atomic_int8_t; using std::atomic_uint8_t; using std::atomic_int16_t; @@ -92,7 +92,7 @@ using std::atomic_intptr_t; using std::atomic_uintptr_t; using std::atomic_size_t; using std::atomic_ptrdiff_t; -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 +#ifdef _GLIBCXX_USE_C99_STDINT using std::atomic_intmax_t; using std::atomic_uintmax_t; #endif diff --git a/libstdc++-v3/include/c_compatibility/stdint.h b/libstdc++-v3/include/c_compatibility/stdint.h index c264e97..85948a5 100644 --- a/libstdc++-v3/include/c_compatibility/stdint.h +++ b/libstdc++-v3/include/c_compatibility/stdint.h @@ -56,7 +56,7 @@ # endif # endif -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 +#ifdef _GLIBCXX_USE_C99_STDINT namespace std { @@ -97,7 +97,7 @@ namespace std using ::uintptr_t; } // namespace -#endif // _GLIBCXX_USE_C99_STDINT_TR1 +#endif // _GLIBCXX_USE_C99_STDINT #else diff --git a/libstdc++-v3/include/c_global/cctype b/libstdc++-v3/include/c_global/cctype index bd667fb..e6ff120 100644 --- a/libstdc++-v3/include/c_global/cctype +++ b/libstdc++-v3/include/c_global/cctype @@ -78,7 +78,7 @@ namespace std #if __cplusplus >= 201103L -#ifdef _GLIBCXX_USE_C99_CTYPE_TR1 +#ifdef _GLIBCXX_USE_C99_CTYPE #undef isblank @@ -87,7 +87,7 @@ namespace std using ::isblank; } // namespace std -#endif // _GLIBCXX_USE_C99_CTYPE_TR1 +#endif // _GLIBCXX_USE_C99_CTYPE #endif // C++11 diff --git a/libstdc++-v3/include/c_global/cfenv b/libstdc++-v3/include/c_global/cfenv index 6704dc5..3a1d9c4 100644 --- a/libstdc++-v3/include/c_global/cfenv +++ b/libstdc++-v3/include/c_global/cfenv @@ -41,7 +41,7 @@ # include <fenv.h> #endif -#ifdef _GLIBCXX_USE_C99_FENV_TR1 +#ifdef _GLIBCXX_USE_C99_FENV #undef feclearexcept #undef fegetexceptflag @@ -77,7 +77,7 @@ namespace std using ::feupdateenv; } // namespace std -#endif // _GLIBCXX_USE_C99_FENV_TR1 +#endif // _GLIBCXX_USE_C99_FENV #endif // C++11 diff --git a/libstdc++-v3/include/c_global/cinttypes b/libstdc++-v3/include/c_global/cinttypes index 8a9de63..06fc34d 100644 --- a/libstdc++-v3/include/c_global/cinttypes +++ b/libstdc++-v3/include/c_global/cinttypes @@ -50,7 +50,7 @@ # endif #endif -#ifdef _GLIBCXX_USE_C99_INTTYPES_TR1 +#ifdef _GLIBCXX_USE_C99_INTTYPES namespace std { @@ -68,13 +68,13 @@ namespace std using ::strtoimax; using ::strtoumax; -#if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1 +#if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_INTTYPES_WCHAR_T using ::wcstoimax; using ::wcstoumax; #endif } // namespace std -#endif // _GLIBCXX_USE_C99_INTTYPES_TR1 +#endif // _GLIBCXX_USE_C99_INTTYPES #endif // C++11 diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath index 568eb35..b0ba395 100644 --- a/libstdc++-v3/include/c_global/cmath +++ b/libstdc++-v3/include/c_global/cmath @@ -151,15 +151,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __builtin_atan2l(__y, __x); } #endif - template<typename _Tp, typename _Up> - inline _GLIBCXX_CONSTEXPR - typename __gnu_cxx::__promote_2<_Tp, _Up>::__type - atan2(_Tp __y, _Up __x) - { - typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; - return atan2(__type(__y), __type(__x)); - } - using ::ceil; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO @@ -286,15 +277,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __builtin_fmodl(__x, __y); } #endif - template<typename _Tp, typename _Up> - inline _GLIBCXX_CONSTEXPR - typename __gnu_cxx::__promote_2<_Tp, _Up>::__type - fmod(_Tp __x, _Up __y) - { - typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; - return fmod(__type(__x), __type(__y)); - } - using ::frexp; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO @@ -411,15 +393,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif #endif - template<typename _Tp, typename _Up> - inline _GLIBCXX_CONSTEXPR - typename __gnu_cxx::__promote_2<_Tp, _Up>::__type - pow(_Tp __x, _Up __y) - { - typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; - return pow(__type(__x), __type(__y)); - } - using ::sin; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO @@ -1073,6 +1046,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __gnu_cxx::__bfloat16_t(__builtin_tanhf(__x)); } #endif + template<typename _Tp, typename _Up> + inline _GLIBCXX_CONSTEXPR + typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + atan2(_Tp __y, _Up __x) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return atan2(__type(__y), __type(__x)); + } + + template<typename _Tp, typename _Up> + inline _GLIBCXX_CONSTEXPR + typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + fmod(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return fmod(__type(__x), __type(__y)); + } + + template<typename _Tp, typename _Up> + inline _GLIBCXX_CONSTEXPR + typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + pow(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return pow(__type(__x), __type(__y)); + } + #if _GLIBCXX_USE_C99_MATH #if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC @@ -1767,7 +1767,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L -#ifdef _GLIBCXX_USE_C99_MATH_TR1 +#ifdef _GLIBCXX_USE_C99_MATH_FUNCS #undef acosh #undef acoshf @@ -1877,9 +1877,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #undef truncf #undef truncl +#ifdef _GLIBCXX_HAVE_C99_FLT_EVAL_TYPES // types using ::double_t; using ::float_t; +#endif // functions using ::acosh; @@ -2107,16 +2109,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __builtin_copysignl(__x, __y); } #endif -#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT - template<typename _Tp, typename _Up> - constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type - copysign(_Tp __x, _Up __y) - { - typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; - return copysign(__type(__x), __type(__y)); - } -#endif - #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float erf(float __x) @@ -2199,16 +2191,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __builtin_fdiml(__x, __y); } #endif -#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT - template<typename _Tp, typename _Up> - constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type - fdim(_Tp __x, _Up __y) - { - typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; - return fdim(__type(__x), __type(__y)); - } -#endif - #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fma(float __x, float __y, float __z) @@ -2219,16 +2201,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __builtin_fmal(__x, __y, __z); } #endif -#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT - template<typename _Tp, typename _Up, typename _Vp> - constexpr typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type - fma(_Tp __x, _Up __y, _Vp __z) - { - typedef typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type __type; - return fma(__type(__x), __type(__y), __type(__z)); - } -#endif - #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fmax(float __x, float __y) @@ -2239,16 +2211,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __builtin_fmaxl(__x, __y); } #endif -#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT - template<typename _Tp, typename _Up> - constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type - fmax(_Tp __x, _Up __y) - { - typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; - return fmax(__type(__x), __type(__y)); - } -#endif - #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fmin(float __x, float __y) @@ -2259,16 +2221,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __builtin_fminl(__x, __y); } #endif -#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT - template<typename _Tp, typename _Up> - constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type - fmin(_Tp __x, _Up __y) - { - typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; - return fmin(__type(__x), __type(__y)); - } -#endif - #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float hypot(float __x, float __y) @@ -2279,16 +2231,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __builtin_hypotl(__x, __y); } #endif -#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT - template<typename _Tp, typename _Up> - constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type - hypot(_Tp __x, _Up __y) - { - typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; - return hypot(__type(__x), __type(__y)); - } -#endif - #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr int ilogb(float __x) @@ -2481,16 +2423,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __builtin_nextafterl(__x, __y); } #endif -#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT - template<typename _Tp, typename _Up> - constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type - nextafter(_Tp __x, _Up __y) - { - typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; - return nextafter(__type(__x), __type(__y)); - } -#endif - #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float nexttoward(float __x, long double __y) @@ -2519,16 +2451,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __builtin_remainderl(__x, __y); } #endif -#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT - template<typename _Tp, typename _Up> - constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type - remainder(_Tp __x, _Up __y) - { - typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; - return remainder(__type(__x), __type(__y)); - } -#endif - #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP inline float remquo(float __x, float __y, int* __pquo) @@ -2539,16 +2461,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __builtin_remquol(__x, __y, __pquo); } #endif -#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT - template<typename _Tp, typename _Up> - inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type - remquo(_Tp __x, _Up __y, int* __pquo) - { - typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; - return remquo(__type(__x), __type(__y), __pquo); - } -#endif - #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float rint(float __x) @@ -3555,8 +3467,81 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __gnu_cxx::__bfloat16_t(__builtin_truncf(__x)); } #endif +#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT + template<typename _Tp, typename _Up> + constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + copysign(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return copysign(__type(__x), __type(__y)); + } + + template<typename _Tp, typename _Up> + constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + fdim(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return fdim(__type(__x), __type(__y)); + } + + template<typename _Tp, typename _Up> + constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + fmax(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return fmax(__type(__x), __type(__y)); + } + + template<typename _Tp, typename _Up> + constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + fmin(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return fmin(__type(__x), __type(__y)); + } + + template<typename _Tp, typename _Up> + constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + hypot(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return hypot(__type(__x), __type(__y)); + } + + template<typename _Tp, typename _Up> + constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + nextafter(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return nextafter(__type(__x), __type(__y)); + } + + template<typename _Tp, typename _Up> + constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + remainder(_Tp __x, _Up __y) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return remainder(__type(__x), __type(__y)); + } + + template<typename _Tp, typename _Up> + inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type + remquo(_Tp __x, _Up __y, int* __pquo) + { + typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; + return remquo(__type(__x), __type(__y), __pquo); + } + + template<typename _Tp, typename _Up, typename _Vp> + constexpr typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type + fma(_Tp __x, _Up __y, _Vp __z) + { + typedef typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type __type; + return fma(__type(__x), __type(__y), __type(__z)); + } +#endif -#endif // _GLIBCXX_USE_C99_MATH_TR1 +#endif // _GLIBCXX_USE_C99_MATH_FUNCS #endif // C++11 #if __cplusplus >= 201703L diff --git a/libstdc++-v3/include/c_global/cstdint b/libstdc++-v3/include/c_global/cstdint index 64e8574..97a30d5 100644 --- a/libstdc++-v3/include/c_global/cstdint +++ b/libstdc++-v3/include/c_global/cstdint @@ -47,7 +47,7 @@ namespace std { -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 +#ifdef _GLIBCXX_USE_C99_STDINT using ::int8_t; using ::int16_t; using ::int32_t; @@ -83,7 +83,7 @@ namespace std using ::uintmax_t; using ::uintptr_t; -#else // !_GLIBCXX_USE_C99_STDINT_TR1 +#else // !_GLIBCXX_USE_C99_STDINT using intmax_t = __INTMAX_TYPE__; using uintmax_t = __UINTMAX_TYPE__; @@ -138,7 +138,7 @@ namespace std using uintptr_t = __UINTPTR_TYPE__; #endif -#endif // _GLIBCXX_USE_C99_STDINT_TR1 +#endif // _GLIBCXX_USE_C99_STDINT } // namespace std #endif // C++11 diff --git a/libstdc++-v3/include/experimental/bits/simd.h b/libstdc++-v3/include/experimental/bits/simd.h index 224153f..90523ea 100644 --- a/libstdc++-v3/include/experimental/bits/simd.h +++ b/libstdc++-v3/include/experimental/bits/simd.h @@ -1743,18 +1743,18 @@ template <typename _To, typename _From> return reinterpret_cast<_To>(__x); else if constexpr (__is_vector_type_v<_To> && __from_is_vectorizable) { - using _FV [[gnu::vector_size(sizeof(_From))]] = _From; + using _FV [[__gnu__::__vector_size__(sizeof(_From))]] = _From; return reinterpret_cast<_To>(_FV{__x}); } else if constexpr (__to_is_vectorizable && __from_is_vectorizable) { - using _TV [[gnu::vector_size(sizeof(_To))]] = _To; - using _FV [[gnu::vector_size(sizeof(_From))]] = _From; + using _TV [[__gnu__::__vector_size__(sizeof(_To))]] = _To; + using _FV [[__gnu__::__vector_size__(sizeof(_From))]] = _From; return reinterpret_cast<_TV>(_FV{__x})[0]; } else if constexpr (__to_is_vectorizable && __is_vector_type_v<_From>) { - using _TV [[gnu::vector_size(sizeof(_To))]] = _To; + using _TV [[__gnu__::__vector_size__(sizeof(_To))]] = _To; return reinterpret_cast<_TV>(__x)[0]; } else @@ -2369,15 +2369,21 @@ template <> struct __intrinsic_type<float, 16, void> { using type = float32x4_t; }; -#if _GLIBCXX_SIMD_HAVE_NEON_A64 template <> struct __intrinsic_type<double, 8, void> - { using type = float64x1_t; }; + { +#if _GLIBCXX_SIMD_HAVE_NEON_A64 + using type = float64x1_t; +#endif + }; template <> struct __intrinsic_type<double, 16, void> - { using type = float64x2_t; }; + { +#if _GLIBCXX_SIMD_HAVE_NEON_A64 + using type = float64x2_t; #endif + }; #define _GLIBCXX_SIMD_ARM_INTRIN(_Bits, _Np) \ template <> \ @@ -2460,11 +2466,40 @@ template <typename _Tp, size_t _Bytes> "no __intrinsic_type support for 64-bit floating point on PowerPC w/o VSX"); #endif - using type = - typename __intrinsic_type_impl< - conditional_t<is_floating_point_v<_Tp>, - conditional_t<_S_is_ldouble, double, _Tp>, - __int_for_sizeof_t<_Tp>>>::type; + static constexpr auto __element_type() + { + if constexpr (is_floating_point_v<_Tp>) + { + if constexpr (_S_is_ldouble) + return double {}; + else + return _Tp {}; + } + else if constexpr (is_signed_v<_Tp>) + { + if constexpr (sizeof(_Tp) == sizeof(_SChar)) + return _SChar {}; + else if constexpr (sizeof(_Tp) == sizeof(short)) + return short {}; + else if constexpr (sizeof(_Tp) == sizeof(int)) + return int {}; + else if constexpr (sizeof(_Tp) == sizeof(_LLong)) + return _LLong {}; + } + else + { + if constexpr (sizeof(_Tp) == sizeof(_UChar)) + return _UChar {}; + else if constexpr (sizeof(_Tp) == sizeof(_UShort)) + return _UShort {}; + else if constexpr (sizeof(_Tp) == sizeof(_UInt)) + return _UInt {}; + else if constexpr (sizeof(_Tp) == sizeof(_ULLong)) + return _ULLong {}; + } + } + + using type = typename __intrinsic_type_impl<decltype(__element_type())>::type; }; #endif // __ALTIVEC__ @@ -2675,7 +2710,14 @@ template <typename _Tp, size_t _Width> _GLIBCXX_SIMD_INTRINSIC constexpr void _M_set(size_t __i, _Tp __x) - { _M_data[__i] = __x; } + { + if (__builtin_is_constant_evaluated()) + _M_data = __generate_from_n_evaluations<_Width, _BuiltinType>([&](auto __j) { + return __j == __i ? __x : _M_data[__j()]; + }); + else + _M_data[__i] = __x; + } _GLIBCXX_SIMD_INTRINSIC constexpr bool @@ -2766,8 +2808,10 @@ template <typename _Tp> return 16; // ARM: - if constexpr (__have_neon_a64 - || (__have_neon_a32 && !is_same_v<_Tp, double>) ) + if constexpr (__have_neon_a64) + return 16; + if constexpr (__have_neon_a32 and (not is_floating_point_v<_Tp> + or is_same_v<_Tp, float>)) return 16; if constexpr (__have_neon && sizeof(_Tp) < 8 @@ -3186,6 +3230,10 @@ template <typename _Tp, typename _Up, typename _Ap> { if constexpr (is_same_v<typename _Tp::abi_type, _Ap>) return __x; + else if (__builtin_is_constant_evaluated()) + return _Tp([&](auto __i) constexpr { + return __i < simd_size_v<_Up, _Ap> ? __x[__i] : _Up(); + }); else if constexpr (simd_size_v<_Up, _Ap> == 1) { _Tp __r{}; @@ -3258,7 +3306,7 @@ template <typename _Tp, int _Np> return {__mem, vector_aligned}; } -template <typename _Tp, size_t _Np> +template <typename _Tp, int _Np> _GLIBCXX_SIMD_INTRINSIC enable_if_t<(_Np == native_simd_mask<_Tp>::size()), native_simd_mask<_Tp>> to_native(const fixed_size_simd_mask<_Tp, _Np>& __x) @@ -3269,7 +3317,7 @@ template <typename _Tp, size_t _Np> } // to_compatible {{{2 -template <typename _Tp, size_t _Np> +template <typename _Tp, int _Np> _GLIBCXX_SIMD_INTRINSIC enable_if_t<(_Np == simd<_Tp>::size()), simd<_Tp>> to_compatible(const simd<_Tp, simd_abi::fixed_size<_Np>>& __x) { @@ -3278,12 +3326,13 @@ template <typename _Tp, size_t _Np> return {__mem, vector_aligned}; } -template <typename _Tp, size_t _Np> +template <typename _Tp, int _Np> _GLIBCXX_SIMD_INTRINSIC enable_if_t<(_Np == simd_mask<_Tp>::size()), simd_mask<_Tp>> to_compatible(const simd_mask<_Tp, simd_abi::fixed_size<_Np>>& __x) { return simd_mask<_Tp>( + __private_init, [&](auto __i) constexpr _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { return __x[__i]; }); } @@ -3321,10 +3370,11 @@ template <typename _M, typename _Tp> const_where_expression& operator=(const const_where_expression&) = delete; - _GLIBCXX_SIMD_INTRINSIC const_where_expression(const _M& __kk, const _Tp& dd) - : _M_k(__kk), _M_value(const_cast<_Tp&>(dd)) {} + _GLIBCXX_SIMD_INTRINSIC constexpr + const_where_expression(const _M& __kk, const _Tp& dd) + : _M_k(__kk), _M_value(const_cast<_Tp&>(dd)) {} - _GLIBCXX_SIMD_INTRINSIC _V + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR _V operator-() const&& { return {__private_init, @@ -3333,7 +3383,7 @@ template <typename _M, typename _Tp> } template <typename _Up, typename _Flags> - [[nodiscard]] _GLIBCXX_SIMD_INTRINSIC _V + [[nodiscard]] _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR _V copy_from(const _LoadStorePtr<_Up, value_type>* __mem, _IsSimdFlagType<_Flags>) const&& { return {__private_init, @@ -3342,7 +3392,7 @@ template <typename _M, typename _Tp> } template <typename _Up, typename _Flags> - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void copy_to(_LoadStorePtr<_Up, value_type>* __mem, _IsSimdFlagType<_Flags>) const&& { _Impl::_S_masked_store(__data(_M_value), @@ -3381,19 +3431,21 @@ template <typename _Tp> const_where_expression(const const_where_expression&) = delete; const_where_expression& operator=(const const_where_expression&) = delete; - _GLIBCXX_SIMD_INTRINSIC const_where_expression(const bool __kk, const _Tp& dd) - : _M_k(__kk), _M_value(const_cast<_Tp&>(dd)) {} + _GLIBCXX_SIMD_INTRINSIC constexpr + const_where_expression(const bool __kk, const _Tp& dd) + : _M_k(__kk), _M_value(const_cast<_Tp&>(dd)) {} - _GLIBCXX_SIMD_INTRINSIC _V operator-() const&& + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR _V + operator-() const&& { return _M_k ? -_M_value : _M_value; } template <typename _Up, typename _Flags> - [[nodiscard]] _GLIBCXX_SIMD_INTRINSIC _V + [[nodiscard]] _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR _V copy_from(const _LoadStorePtr<_Up, value_type>* __mem, _IsSimdFlagType<_Flags>) const&& { return _M_k ? static_cast<_V>(__mem[0]) : _M_value; } template <typename _Up, typename _Flags> - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void copy_to(_LoadStorePtr<_Up, value_type>* __mem, _IsSimdFlagType<_Flags>) const&& { if (_M_k) @@ -3419,18 +3471,21 @@ template <typename _M, typename _Tp> is_same<typename _M::abi_type, typename _Tp::abi_type>::value, ""); static_assert(_M::size() == _Tp::size(), ""); - _GLIBCXX_SIMD_INTRINSIC friend _Tp& __get_lvalue(where_expression& __x) + _GLIBCXX_SIMD_INTRINSIC friend constexpr _Tp& + __get_lvalue(where_expression& __x) { return __x._M_value; } public: where_expression(const where_expression&) = delete; where_expression& operator=(const where_expression&) = delete; - _GLIBCXX_SIMD_INTRINSIC where_expression(const _M& __kk, _Tp& dd) - : const_where_expression<_M, _Tp>(__kk, dd) {} + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR + where_expression(const _M& __kk, _Tp& dd) + : const_where_expression<_M, _Tp>(__kk, dd) {} template <typename _Up> - _GLIBCXX_SIMD_INTRINSIC void operator=(_Up&& __x) && + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void + operator=(_Up&& __x) && { _Impl::_S_masked_assign(__data(_M_k), __data(_M_value), __to_value_type_or_member_type<_Tp>( @@ -3439,7 +3494,8 @@ template <typename _M, typename _Tp> #define _GLIBCXX_SIMD_OP_(__op, __name) \ template <typename _Up> \ - _GLIBCXX_SIMD_INTRINSIC void operator __op##=(_Up&& __x)&& \ + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void \ + operator __op##=(_Up&& __x)&& \ { \ _Impl::template _S_masked_cassign( \ __data(_M_k), __data(_M_value), \ @@ -3461,28 +3517,28 @@ template <typename _M, typename _Tp> _GLIBCXX_SIMD_OP_(>>, _S_shift_right); #undef _GLIBCXX_SIMD_OP_ - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void operator++() && { __data(_M_value) = _Impl::template _S_masked_unary<__increment>(__data(_M_k), __data(_M_value)); } - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void operator++(int) && { __data(_M_value) = _Impl::template _S_masked_unary<__increment>(__data(_M_k), __data(_M_value)); } - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void operator--() && { __data(_M_value) = _Impl::template _S_masked_unary<__decrement>(__data(_M_k), __data(_M_value)); } - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void operator--(int) && { __data(_M_value) @@ -3491,7 +3547,7 @@ template <typename _M, typename _Tp> // intentionally hides const_where_expression::copy_from template <typename _Up, typename _Flags> - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void copy_from(const _LoadStorePtr<_Up, value_type>* __mem, _IsSimdFlagType<_Flags>) && { __data(_M_value) = _Impl::_S_masked_load(__data(_M_value), __data(_M_k), @@ -3513,13 +3569,13 @@ template <typename _Tp> where_expression(const where_expression&) = delete; where_expression& operator=(const where_expression&) = delete; - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR where_expression(const _M& __kk, _Tp& dd) : const_where_expression<_M, _Tp>(__kk, dd) {} #define _GLIBCXX_SIMD_OP_(__op) \ template <typename _Up> \ - _GLIBCXX_SIMD_INTRINSIC void \ + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void \ operator __op(_Up&& __x)&& \ { if (_M_k) _M_value __op static_cast<_Up&&>(__x); } @@ -3536,68 +3592,71 @@ template <typename _Tp> _GLIBCXX_SIMD_OP_(>>=) #undef _GLIBCXX_SIMD_OP_ - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void operator++() && { if (_M_k) ++_M_value; } - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void operator++(int) && { if (_M_k) ++_M_value; } - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void operator--() && { if (_M_k) --_M_value; } - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void operator--(int) && { if (_M_k) --_M_value; } // intentionally hides const_where_expression::copy_from template <typename _Up, typename _Flags> - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR void copy_from(const _LoadStorePtr<_Up, value_type>* __mem, _IsSimdFlagType<_Flags>) && { if (_M_k) _M_value = __mem[0]; } }; // where {{{1 template <typename _Tp, typename _Ap> - _GLIBCXX_SIMD_INTRINSIC where_expression<simd_mask<_Tp, _Ap>, simd<_Tp, _Ap>> + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR + where_expression<simd_mask<_Tp, _Ap>, simd<_Tp, _Ap>> where(const typename simd<_Tp, _Ap>::mask_type& __k, simd<_Tp, _Ap>& __value) { return {__k, __value}; } template <typename _Tp, typename _Ap> - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR const_where_expression<simd_mask<_Tp, _Ap>, simd<_Tp, _Ap>> where(const typename simd<_Tp, _Ap>::mask_type& __k, const simd<_Tp, _Ap>& __value) { return {__k, __value}; } template <typename _Tp, typename _Ap> - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR where_expression<simd_mask<_Tp, _Ap>, simd_mask<_Tp, _Ap>> where(const remove_const_t<simd_mask<_Tp, _Ap>>& __k, simd_mask<_Tp, _Ap>& __value) { return {__k, __value}; } template <typename _Tp, typename _Ap> - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR const_where_expression<simd_mask<_Tp, _Ap>, simd_mask<_Tp, _Ap>> where(const remove_const_t<simd_mask<_Tp, _Ap>>& __k, const simd_mask<_Tp, _Ap>& __value) { return {__k, __value}; } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC where_expression<bool, _Tp> + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR where_expression<bool, _Tp> where(_ExactBool __k, _Tp& __value) { return {__k, __value}; } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC const_where_expression<bool, _Tp> + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR const_where_expression<bool, _Tp> where(_ExactBool __k, const _Tp& __value) { return {__k, __value}; } template <typename _Tp, typename _Ap> - void where(bool __k, simd<_Tp, _Ap>& __value) = delete; + _GLIBCXX_SIMD_CONSTEXPR void + where(bool __k, simd<_Tp, _Ap>& __value) = delete; template <typename _Tp, typename _Ap> - void where(bool __k, const simd<_Tp, _Ap>& __value) = delete; + _GLIBCXX_SIMD_CONSTEXPR void + where(bool __k, const simd<_Tp, _Ap>& __value) = delete; // proposed mask iterations {{{1 namespace __proposed { @@ -3820,12 +3879,12 @@ template <size_t... _Sizes, typename _Tp, typename _Ap, // __extract_part {{{ template <int _Index, int _Total, int _Combine = 1, typename _Tp, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_CONST + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_CONST constexpr _SimdWrapper<_Tp, _Np / _Total * _Combine> __extract_part(const _SimdWrapper<_Tp, _Np> __x); template <int _Index, int _Parts, int _Combine = 1, typename _Tp, typename _A0, typename... _As> - _GLIBCXX_SIMD_INTRINSIC auto + _GLIBCXX_SIMD_INTRINSIC constexpr auto __extract_part(const _SimdTuple<_Tp, _A0, _As...>& __x); // }}} @@ -4551,7 +4610,7 @@ template <typename _Tp, typename _Abi> // }}} // access to internal representation (optional feature) {{{ - _GLIBCXX_SIMD_ALWAYS_INLINE explicit + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR explicit simd_mask(typename _Traits::_MaskCastType __init) : _M_data{__init} {} // conversions to internal type is done in _MaskBase @@ -4562,11 +4621,11 @@ template <typename _Tp, typename _Abi> // Conversion of simd_mask to and from bitset makes it much easier to // interface with other facilities. I suggest adding `static // simd_mask::from_bitset` and `simd_mask::to_bitset`. - _GLIBCXX_SIMD_ALWAYS_INLINE static simd_mask + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR static simd_mask __from_bitset(bitset<size()> bs) { return {__bitset_init, bs}; } - _GLIBCXX_SIMD_ALWAYS_INLINE bitset<size()> + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR bitset<size()> __to_bitset() const { return _Impl::_S_to_bits(_M_data)._M_to_bitset(); } @@ -4591,7 +4650,7 @@ template <typename _Tp, typename _Abi> template <typename _Up, typename = enable_if_t<conjunction< is_same<abi_type, simd_abi::fixed_size<size()>>, is_same<_Up, _Up>>::value>> - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR simd_mask(const simd_mask<_Up, simd_abi::fixed_size<size()>>& __x) : _M_data(_Impl::_S_from_bitmask(__data(__x), _S_type_tag)) {} #endif @@ -4599,12 +4658,12 @@ template <typename _Tp, typename _Abi> // }}} // load constructor {{{ template <typename _Flags> - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR simd_mask(const value_type* __mem, _IsSimdFlagType<_Flags>) : _M_data(_Impl::template _S_load<_Ip>(_Flags::template _S_apply<simd_mask>(__mem))) {} template <typename _Flags> - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR simd_mask(const value_type* __mem, simd_mask __k, _IsSimdFlagType<_Flags>) : _M_data{} { @@ -4615,20 +4674,20 @@ template <typename _Tp, typename _Abi> // }}} // loads [simd_mask.load] {{{ template <typename _Flags> - _GLIBCXX_SIMD_ALWAYS_INLINE void + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR void copy_from(const value_type* __mem, _IsSimdFlagType<_Flags>) { _M_data = _Impl::template _S_load<_Ip>(_Flags::template _S_apply<simd_mask>(__mem)); } // }}} // stores [simd_mask.store] {{{ template <typename _Flags> - _GLIBCXX_SIMD_ALWAYS_INLINE void + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR void copy_to(value_type* __mem, _IsSimdFlagType<_Flags>) const { _Impl::_S_store(_M_data, _Flags::template _S_apply<simd_mask>(__mem)); } // }}} // scalar access {{{ - _GLIBCXX_SIMD_ALWAYS_INLINE reference + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR reference operator[](size_t __i) { if (__i >= size()) @@ -4636,7 +4695,7 @@ template <typename _Tp, typename _Abi> return {_M_data, int(__i)}; } - _GLIBCXX_SIMD_ALWAYS_INLINE value_type + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR value_type operator[](size_t __i) const { if (__i >= size()) @@ -4649,7 +4708,7 @@ template <typename _Tp, typename _Abi> // }}} // negation {{{ - _GLIBCXX_SIMD_ALWAYS_INLINE simd_mask + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR simd_mask operator!() const { return {__private_init, _Impl::_S_bit_not(_M_data)}; } @@ -4659,7 +4718,7 @@ template <typename _Tp, typename _Abi> // simd_mask<int> && simd_mask<uint> needs disambiguation template <typename _Up, typename _A2, typename = enable_if_t<is_convertible_v<simd_mask<_Up, _A2>, simd_mask>>> - _GLIBCXX_SIMD_ALWAYS_INLINE friend simd_mask + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR friend simd_mask operator&&(const simd_mask& __x, const simd_mask<_Up, _A2>& __y) { return {__private_init, @@ -4668,7 +4727,7 @@ template <typename _Tp, typename _Abi> template <typename _Up, typename _A2, typename = enable_if_t<is_convertible_v<simd_mask<_Up, _A2>, simd_mask>>> - _GLIBCXX_SIMD_ALWAYS_INLINE friend simd_mask + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR friend simd_mask operator||(const simd_mask& __x, const simd_mask<_Up, _A2>& __y) { return {__private_init, @@ -4676,41 +4735,41 @@ template <typename _Tp, typename _Abi> } #endif // _GLIBCXX_SIMD_ENABLE_IMPLICIT_MASK_CAST - _GLIBCXX_SIMD_ALWAYS_INLINE friend simd_mask + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR friend simd_mask operator&&(const simd_mask& __x, const simd_mask& __y) { return {__private_init, _Impl::_S_logical_and(__x._M_data, __y._M_data)}; } - _GLIBCXX_SIMD_ALWAYS_INLINE friend simd_mask + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR friend simd_mask operator||(const simd_mask& __x, const simd_mask& __y) { return {__private_init, _Impl::_S_logical_or(__x._M_data, __y._M_data)}; } - _GLIBCXX_SIMD_ALWAYS_INLINE friend simd_mask + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR friend simd_mask operator&(const simd_mask& __x, const simd_mask& __y) { return {__private_init, _Impl::_S_bit_and(__x._M_data, __y._M_data)}; } - _GLIBCXX_SIMD_ALWAYS_INLINE friend simd_mask + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR friend simd_mask operator|(const simd_mask& __x, const simd_mask& __y) { return {__private_init, _Impl::_S_bit_or(__x._M_data, __y._M_data)}; } - _GLIBCXX_SIMD_ALWAYS_INLINE friend simd_mask + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR friend simd_mask operator^(const simd_mask& __x, const simd_mask& __y) { return {__private_init, _Impl::_S_bit_xor(__x._M_data, __y._M_data)}; } - _GLIBCXX_SIMD_ALWAYS_INLINE friend simd_mask& + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR friend simd_mask& operator&=(simd_mask& __x, const simd_mask& __y) { __x._M_data = _Impl::_S_bit_and(__x._M_data, __y._M_data); return __x; } - _GLIBCXX_SIMD_ALWAYS_INLINE friend simd_mask& + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR friend simd_mask& operator|=(simd_mask& __x, const simd_mask& __y) { __x._M_data = _Impl::_S_bit_or(__x._M_data, __y._M_data); return __x; } - _GLIBCXX_SIMD_ALWAYS_INLINE friend simd_mask& + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR friend simd_mask& operator^=(simd_mask& __x, const simd_mask& __y) { __x._M_data = _Impl::_S_bit_xor(__x._M_data, __y._M_data); @@ -4747,7 +4806,8 @@ template <typename _Tp, typename _Abi> // }}} // bitset_init ctor {{{ - _GLIBCXX_SIMD_INTRINSIC simd_mask(_BitsetInit, bitset<size()> __init) + _GLIBCXX_SIMD_INTRINSIC constexpr + simd_mask(_BitsetInit, bitset<size()> __init) : _M_data(_Impl::_S_from_bitmask(_SanitizedBitMask<size()>(__init), _S_type_tag)) {} @@ -5015,7 +5075,8 @@ template <typename _V, typename _Tp, typename _Abi> { using _Impl = typename _SimdTraits<_Tp, _Abi>::_SimdImpl; - _GLIBCXX_SIMD_INTRINSIC const _V& __derived() const + _GLIBCXX_SIMD_INTRINSIC constexpr const _V& + __derived() const { return *static_cast<const _V*>(this); } template <typename _Up> @@ -5235,7 +5296,7 @@ template <typename _Tp, typename _Abi> // load constructor template <typename _Up, typename _Flags> - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR simd(const _Up* __mem, _IsSimdFlagType<_Flags>) : _M_data( _Impl::_S_load(_Flags::template _S_apply<simd>(__mem), _S_type_tag)) @@ -5243,7 +5304,7 @@ template <typename _Tp, typename _Abi> // loads [simd.load] template <typename _Up, typename _Flags> - _GLIBCXX_SIMD_ALWAYS_INLINE void + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR void copy_from(const _Vectorizable<_Up>* __mem, _IsSimdFlagType<_Flags>) { _M_data = static_cast<decltype(_M_data)>( @@ -5252,7 +5313,7 @@ template <typename _Tp, typename _Abi> // stores [simd.store] template <typename _Up, typename _Flags> - _GLIBCXX_SIMD_ALWAYS_INLINE void + _GLIBCXX_SIMD_ALWAYS_INLINE _GLIBCXX_SIMD_CONSTEXPR void copy_to(_Vectorizable<_Up>* __mem, _IsSimdFlagType<_Flags>) const { _Impl::_S_store(_M_data, _Flags::template _S_apply<simd>(__mem), @@ -5424,7 +5485,7 @@ template <typename _Tp, typename _Abi> } private: - _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR static mask_type + _GLIBCXX_SIMD_INTRINSIC static constexpr mask_type _S_make_mask(typename mask_type::_MemberType __k) { return {__private_init, __k}; } diff --git a/libstdc++-v3/include/experimental/bits/simd_builtin.h b/libstdc++-v3/include/experimental/bits/simd_builtin.h index 4c008da..6ccc2fc 100644 --- a/libstdc++-v3/include/experimental/bits/simd_builtin.h +++ b/libstdc++-v3/include/experimental/bits/simd_builtin.h @@ -52,7 +52,7 @@ template <typename _V, typename = _VectorTraits<_V>> // Index == -1 requests zeroing of the output element template <int... _Indices, typename _Tp, typename _TVT = _VectorTraits<_Tp>, typename = __detail::__odr_helper> - _Tp + constexpr _Tp __vector_permute(_Tp __x) { static_assert(sizeof...(_Indices) == _TVT::_S_full_size); @@ -65,7 +65,7 @@ template <int... _Indices, typename _Tp, typename _TVT = _VectorTraits<_Tp>, // Index == -1 requests zeroing of the output element template <int... _Indices, typename _Tp, typename _TVT = _VectorTraits<_Tp>, typename = __detail::__odr_helper> - _Tp + constexpr _Tp __vector_shuffle(_Tp __x, _Tp __y) { return _Tp{(_Indices == -1 ? 0 @@ -205,7 +205,7 @@ template <unsigned __shift, typename _Tp, typename _TVT = _VectorTraits<_Tp>> // }}} // __extract_part(_SimdWrapper<_Tp, _Np>) {{{ template <int _Index, int _Total, int _Combine, typename _Tp, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_CONST + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_CONST constexpr _SimdWrapper<_Tp, _Np / _Total * _Combine> __extract_part(const _SimdWrapper<_Tp, _Np> __x) { @@ -905,10 +905,10 @@ template <typename _Tp, typename _Mp, typename _Abi, size_t _Np> _SimdMember _M_data; public: - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE constexpr _SimdCastType1(_Ap __a) : _M_data(__vector_bitcast<_Tp>(__a)) {} - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE constexpr operator _SimdMember() const { return _M_data; } }; @@ -919,13 +919,13 @@ template <typename _Tp, typename _Mp, typename _Abi, size_t _Np> _SimdMember _M_data; public: - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE constexpr _SimdCastType2(_Ap __a) : _M_data(__vector_bitcast<_Tp>(__a)) {} - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE constexpr _SimdCastType2(_Bp __b) : _M_data(__b) {} - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE constexpr operator _SimdMember() const { return _M_data; } }; @@ -1295,6 +1295,18 @@ struct _CommonImplBuiltin // }}} // _S_store {{{ + template <size_t _Bytes> + _GLIBCXX_SIMD_INTRINSIC static void + _S_memcpy(char* __dst, const char* __src) + { + if constexpr (_Bytes > 0) + { + constexpr size_t _Ns = std::__bit_floor(_Bytes); + __builtin_memcpy(__dst, __src, _Ns); + _S_memcpy<_Bytes - _Ns>(__dst + _Ns, __src + _Ns); + } + } + template <size_t _ReqBytes = 0, typename _TV> _GLIBCXX_SIMD_INTRINSIC static void _S_store(_TV __x, void* __addr) @@ -1302,33 +1314,11 @@ struct _CommonImplBuiltin constexpr size_t _Bytes = _ReqBytes == 0 ? sizeof(__x) : _ReqBytes; static_assert(sizeof(__x) >= _Bytes); +#if !defined __clang__ && _GLIBCXX_SIMD_WORKAROUND_PR90424 if constexpr (__is_vector_type_v<_TV>) - { - using _Tp = typename _VectorTraits<_TV>::value_type; - constexpr size_t _Np = _Bytes / sizeof(_Tp); - static_assert(_Np * sizeof(_Tp) == _Bytes); - -#ifdef _GLIBCXX_SIMD_WORKAROUND_PR90424 - using _Up = conditional_t< - (is_integral_v<_Tp> || _Bytes < 4), - conditional_t<(sizeof(__x) > sizeof(long long)), long long, _Tp>, - float>; - const auto __v = __vector_bitcast<_Up>(__x); -#else // _GLIBCXX_SIMD_WORKAROUND_PR90424 - const __vector_type_t<_Tp, _Np> __v = __x; -#endif // _GLIBCXX_SIMD_WORKAROUND_PR90424 - - if constexpr ((_Bytes & (_Bytes - 1)) != 0) - { - constexpr size_t _MoreBytes = std::__bit_ceil(_Bytes); - alignas(decltype(__v)) char __tmp[_MoreBytes]; - __builtin_memcpy(__tmp, &__v, _MoreBytes); - __builtin_memcpy(__addr, __tmp, _Bytes); - } - else - __builtin_memcpy(__addr, &__v, _Bytes); - } + _S_memcpy<_Bytes>(reinterpret_cast<char*>(__addr), reinterpret_cast<const char*>(&__x)); else +#endif // _GLIBCXX_SIMD_WORKAROUND_PR90424 __builtin_memcpy(__addr, &__x, _Bytes); } @@ -1345,6 +1335,11 @@ struct _CommonImplBuiltin { if constexpr (_Np == 1) __mem[0] = __x[0]; + else if (__builtin_is_constant_evaluated()) + { + for (size_t __i = 0; __i < _Np; ++__i) + __mem[__i] = __x[__i]; + } else if constexpr (_Np == 2) { short __bool2 = (__x._M_to_bits() * 0x81) & 0x0101; @@ -1424,12 +1419,12 @@ template <typename _Abi, typename> // _M_make_simd(_SimdWrapper/__intrinsic_type_t) {{{2 template <typename _Tp, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static simd<_Tp, _Abi> + _GLIBCXX_SIMD_INTRINSIC static constexpr simd<_Tp, _Abi> _M_make_simd(_SimdWrapper<_Tp, _Np> __x) { return {__private_init, __x}; } template <typename _Tp, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static simd<_Tp, _Abi> + _GLIBCXX_SIMD_INTRINSIC static constexpr simd<_Tp, _Abi> _M_make_simd(__intrinsic_type_t<_Tp, _Np> __x) { return {__private_init, __vector_bitcast<_Tp>(__x)}; } @@ -1455,7 +1450,7 @@ template <typename _Abi, typename> // _S_load {{{2 template <typename _Tp, typename _Up> - _GLIBCXX_SIMD_INTRINSIC static _SimdMember<_Tp> + _GLIBCXX_SIMD_INTRINSIC static constexpr _SimdMember<_Tp> _S_load(const _Up* __mem, _TypeTag<_Tp>) noexcept { constexpr size_t _Np = _S_size<_Tp>; @@ -1464,7 +1459,12 @@ template <typename _Abi, typename> : (is_floating_point_v<_Up> && __have_avx) || __have_avx2 ? 32 : 16; constexpr size_t __bytes_to_load = sizeof(_Up) * _Np; - if constexpr (sizeof(_Up) > 8) + if (__builtin_is_constant_evaluated()) + return __generate_vector<_Tp, _S_full_size<_Tp>>( + [&](auto __i) constexpr { + return static_cast<_Tp>(__i < _Np ? __mem[__i] : 0); + }); + else if constexpr (sizeof(_Up) > 8) return __generate_vector<_Tp, _SimdMember<_Tp>::_S_full_size>( [&](auto __i) constexpr _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { return static_cast<_Tp>(__i < _Np ? __mem[__i] : 0); @@ -1511,7 +1511,7 @@ template <typename _Abi, typename> // _S_masked_load {{{2 template <typename _Tp, size_t _Np, typename _Up> - static inline _SimdWrapper<_Tp, _Np> + static constexpr inline _SimdWrapper<_Tp, _Np> _S_masked_load(_SimdWrapper<_Tp, _Np> __merge, _MaskMember<_Tp> __k, const _Up* __mem) noexcept { @@ -1524,14 +1524,19 @@ template <typename _Abi, typename> // _S_store {{{2 template <typename _Tp, typename _Up> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_store(_SimdMember<_Tp> __v, _Up* __mem, _TypeTag<_Tp>) noexcept { // TODO: converting int -> "smaller int" can be optimized with AVX512 constexpr size_t _Np = _S_size<_Tp>; constexpr size_t __max_store_size = _SuperImpl::template _S_max_store_size<_Up>; - if constexpr (sizeof(_Up) > 8) + if (__builtin_is_constant_evaluated()) + { + for (size_t __i = 0; __i < _Np; ++__i) + __mem[__i] = __v[__i]; + } + else if constexpr (sizeof(_Up) > 8) __execute_n_times<_Np>([&](auto __i) constexpr _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { __mem[__i] = __v[__i]; }); @@ -1562,7 +1567,7 @@ template <typename _Abi, typename> // _S_masked_store_nocvt {{{2 template <typename _Tp, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_store_nocvt(_SimdWrapper<_Tp, _Np> __v, _Tp* __mem, _MaskMember<_Tp> __k) { _BitOps::_S_bit_iteration( @@ -1575,7 +1580,7 @@ template <typename _Abi, typename> // _S_masked_store {{{2 template <typename _TW, typename _TVT = _VectorTraits<_TW>, typename _Tp = typename _TVT::value_type, typename _Up> - static inline void + static constexpr inline void _S_masked_store(const _TW __v, _Up* __mem, const _MaskMember<_Tp> __k) noexcept { constexpr size_t _TV_size = _S_size<_Tp>; @@ -1613,7 +1618,7 @@ template <typename _Abi, typename> if constexpr (_UW_size == _TV_size) // one convert+store { const _UW __converted = __convert<_UW>(__v); - _SuperImpl::_S_masked_store_nocvt( + _UAbi::_SimdImpl::_S_masked_store_nocvt( __converted, __mem, _UAbi::_MaskImpl::template _S_convert< __int_for_sizeof_t<_Up>>(__k)); @@ -1628,7 +1633,7 @@ template <typename _Abi, typename> const array<_UV, _NAllStores> __converted = __convert_all<_UV, _NAllStores>(__v); __execute_n_times<_NFullStores>([&](auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { - _SuperImpl::_S_masked_store_nocvt( + _UAbi::_SimdImpl::_S_masked_store_nocvt( _UW(__converted[__i]), __mem + __i * _UW_size, _UAbi::_MaskImpl::template _S_convert< __int_for_sizeof_t<_Up>>( @@ -1636,7 +1641,7 @@ template <typename _Abi, typename> }); if constexpr (_NAllStores > _NFullStores) // one partial at the end - _SuperImpl::_S_masked_store_nocvt( + _UAbi::_SimdImpl::_S_masked_store_nocvt( _UW(__converted[_NFullStores]), __mem + _NFullStores * _UW_size, _UAbi::_MaskImpl::template _S_convert< @@ -1803,7 +1808,7 @@ template <typename _Abi, typename> // reductions {{{2 template <size_t _Np, size_t... _Is, size_t... _Zeros, typename _Tp, typename _BinaryOperation> - _GLIBCXX_SIMD_INTRINSIC static _Tp + _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp _S_reduce_partial(index_sequence<_Is...>, index_sequence<_Zeros...>, simd<_Tp, _Abi> __x, _BinaryOperation&& __binary_op) { @@ -1833,6 +1838,13 @@ template <typename _Abi, typename> else if constexpr (_Np == 2) return __binary_op(simd<_Tp, simd_abi::scalar>(__x[0]), simd<_Tp, simd_abi::scalar>(__x[1]))[0]; + else if (__builtin_is_constant_evaluated()) + { + simd<_Tp, simd_abi::scalar> __acc = __x[0]; + for (size_t __i = 1; __i < _Np; ++__i) + __acc = __binary_op(__acc, simd<_Tp, simd_abi::scalar>(__x[__i])); + return __acc[0]; + } else if constexpr (_Abi::template _S_is_partial<_Tp>) //{{{ { [[maybe_unused]] constexpr auto __full_size @@ -2370,12 +2382,12 @@ template <typename _Abi, typename> constexpr size_t _NI = sizeof(__xn) / sizeof(_I); _GLIBCXX_SIMD_USE_CONSTEXPR auto __minn = __vector_bitcast<_I>(__vector_broadcast<_NI>(__norm_min_v<_Tp>)); - _GLIBCXX_SIMD_USE_CONSTEXPR auto __infn - = __vector_bitcast<_I>(__vector_broadcast<_NI>(__infinity_v<_Tp>)); _GLIBCXX_SIMD_USE_CONSTEXPR auto __fp_normal = __vector_broadcast<_NI, _I>(FP_NORMAL); #if !__FINITE_MATH_ONLY__ + _GLIBCXX_SIMD_USE_CONSTEXPR auto __infn + = __vector_bitcast<_I>(__vector_broadcast<_NI>(__infinity_v<_Tp>)); _GLIBCXX_SIMD_USE_CONSTEXPR auto __fp_nan = __vector_broadcast<_NI, _I>(FP_NAN); _GLIBCXX_SIMD_USE_CONSTEXPR auto __fp_infinite @@ -2445,24 +2457,24 @@ template <typename _Abi, typename> // _S_increment & _S_decrement{{{2 template <typename _Tp, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_increment(_SimdWrapper<_Tp, _Np>& __x) { __x = __x._M_data + 1; } template <typename _Tp, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_decrement(_SimdWrapper<_Tp, _Np>& __x) { __x = __x._M_data - 1; } // smart_reference access {{{2 template <typename _Tp, size_t _Np, typename _Up> - _GLIBCXX_SIMD_INTRINSIC constexpr static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_set(_SimdWrapper<_Tp, _Np>& __v, int __i, _Up&& __x) noexcept { __v._M_set(__i, static_cast<_Up&&>(__x)); } // _S_masked_assign{{{2 template <typename _Tp, typename _K, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_assign(_SimdWrapper<_K, _Np> __k, _SimdWrapper<_Tp, _Np>& __lhs, __type_identity_t<_SimdWrapper<_Tp, _Np>> __rhs) { @@ -2475,7 +2487,7 @@ template <typename _Abi, typename> } template <typename _Tp, typename _K, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_assign(_SimdWrapper<_K, _Np> __k, _SimdWrapper<_Tp, _Np>& __lhs, __type_identity_t<_Tp> __rhs) { @@ -2503,7 +2515,7 @@ template <typename _Abi, typename> // _S_masked_cassign {{{2 template <typename _Op, typename _Tp, typename _K, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_cassign(const _SimdWrapper<_K, _Np> __k, _SimdWrapper<_Tp, _Np>& __lhs, const __type_identity_t<_SimdWrapper<_Tp, _Np>> __rhs, @@ -2519,7 +2531,7 @@ template <typename _Abi, typename> } template <typename _Op, typename _Tp, typename _K, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_cassign(const _SimdWrapper<_K, _Np> __k, _SimdWrapper<_Tp, _Np>& __lhs, const __type_identity_t<_Tp> __rhs, _Op __op) @@ -2528,7 +2540,7 @@ template <typename _Abi, typename> // _S_masked_unary {{{2 template <template <typename> class _Op, typename _Tp, typename _K, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static _SimdWrapper<_Tp, _Np> + _GLIBCXX_SIMD_INTRINSIC static constexpr _SimdWrapper<_Tp, _Np> _S_masked_unary(const _SimdWrapper<_K, _Np> __k, const _SimdWrapper<_Tp, _Np> __v) { @@ -2704,18 +2716,18 @@ template <typename _Abi, typename> _S_load(const bool* __mem) { using _I = __int_for_sizeof_t<_Tp>; - if constexpr (sizeof(_Tp) == sizeof(bool)) - { - const auto __bools - = _CommonImpl::template _S_load<_I, _S_size<_Tp>>(__mem); - // bool is {0, 1}, everything else is UB - return __bools > 0; - } - else - return __generate_vector<_I, _S_size<_Tp>>( - [&](auto __i) constexpr _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { - return __mem[__i] ? ~_I() : _I(); - }); + if (not __builtin_is_constant_evaluated()) + if constexpr (sizeof(_Tp) == sizeof(bool)) + { + const auto __bools + = _CommonImpl::template _S_load<_I, _S_size<_Tp>>(__mem); + // bool is {0, 1}, everything else is UB + return __bools > 0; + } + return __generate_vector<_I, _S_size<_Tp>>( + [&](auto __i) constexpr _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { + return __mem[__i] ? ~_I() : _I(); + }); } // }}} @@ -2797,7 +2809,7 @@ template <typename _Abi, typename> // _S_store {{{2 template <typename _Tp, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_store(_SimdWrapper<_Tp, _Np> __v, bool* __mem) noexcept { __execute_n_times<_Np>([&](auto __i) constexpr _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { diff --git a/libstdc++-v3/include/experimental/bits/simd_fixed_size.h b/libstdc++-v3/include/experimental/bits/simd_fixed_size.h index 123e714..131fbd2 100644 --- a/libstdc++-v3/include/experimental/bits/simd_fixed_size.h +++ b/libstdc++-v3/include/experimental/bits/simd_fixed_size.h @@ -166,25 +166,25 @@ template <typename _Tp, typename _Abi, size_t _Offset> static constexpr _MaskImpl _S_mask_impl = {}; template <size_t _Np, bool _Sanitized> - _GLIBCXX_SIMD_INTRINSIC static auto + _GLIBCXX_SIMD_INTRINSIC static constexpr auto _S_submask(_BitMask<_Np, _Sanitized> __bits) { return __bits.template _M_extract<_Offset, _S_size()>(); } template <size_t _Np, bool _Sanitized> - _GLIBCXX_SIMD_INTRINSIC static _MaskMember + _GLIBCXX_SIMD_INTRINSIC static constexpr _MaskMember _S_make_mask(_BitMask<_Np, _Sanitized> __bits) { return _MaskImpl::template _S_convert<_Tp>( __bits.template _M_extract<_Offset, _S_size()>()._M_sanitized()); } - _GLIBCXX_SIMD_INTRINSIC static _ULLong + _GLIBCXX_SIMD_INTRINSIC static constexpr _ULLong _S_mask_to_shifted_ullong(_MaskMember __k) { return _MaskImpl::_S_to_bits(__k).to_ullong() << _Offset; } }; template <size_t _Offset, typename _Tp, typename _Abi, typename... _As> - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC constexpr __tuple_element_meta<_Tp, _Abi, _Offset> __make_meta(const _SimdTuple<_Tp, _Abi, _As...>&) { return {}; } @@ -535,7 +535,7 @@ template <typename _Tp, typename _Abi0, typename... _Abis> } template <typename _R = _Tp, typename _Fp, typename... _More> - _GLIBCXX_SIMD_INTRINSIC auto + _GLIBCXX_SIMD_INTRINSIC constexpr auto _M_apply_r(_Fp&& __fun, const _More&... __more) const { auto&& __first = __fun(__tuple_element_meta<_Tp, _Abi0, 0>(), first, @@ -573,50 +573,43 @@ template <typename _Tp, typename _Abi0, typename... _Abis> return second[integral_constant<_Up, _I - simd_size_v<_Tp, _Abi0>>()]; } - _GLIBCXX_SIMD_INTRINSIC _Tp + _GLIBCXX_SIMD_INTRINSIC constexpr _Tp operator[](size_t __i) const noexcept { if constexpr (_S_tuple_size == 1) return _M_subscript_read(__i); - else - { #ifdef _GLIBCXX_SIMD_USE_ALIASING_LOADS - return reinterpret_cast<const __may_alias<_Tp>*>(this)[__i]; -#else - if constexpr (__is_scalar_abi<_Abi0>()) - { - const _Tp* ptr = &first; - return ptr[__i]; - } - else - return __i < simd_size_v<_Tp, _Abi0> - ? _M_subscript_read(__i) - : second[__i - simd_size_v<_Tp, _Abi0>]; + else if (not __builtin_is_constant_evaluated()) + return reinterpret_cast<const __may_alias<_Tp>*>(this)[__i]; #endif + else if constexpr (__is_scalar_abi<_Abi0>()) + { + const _Tp* ptr = &first; + return ptr[__i]; } + else + return __i < simd_size_v<_Tp, _Abi0> ? _M_subscript_read(__i) + : second[__i - simd_size_v<_Tp, _Abi0>]; } - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC constexpr void _M_set(size_t __i, _Tp __val) noexcept { if constexpr (_S_tuple_size == 1) return _M_subscript_write(__i, __val); - else - { #ifdef _GLIBCXX_SIMD_USE_ALIASING_LOADS - reinterpret_cast<__may_alias<_Tp>*>(this)[__i] = __val; -#else - if (__i < simd_size_v<_Tp, _Abi0>) - _M_subscript_write(__i, __val); - else - second._M_set(__i - simd_size_v<_Tp, _Abi0>, __val); + else if (not __builtin_is_constant_evaluated()) + reinterpret_cast<__may_alias<_Tp>*>(this)[__i] = __val; #endif - } + else if (__i < simd_size_v<_Tp, _Abi0>) + _M_subscript_write(__i, __val); + else + second._M_set(__i - simd_size_v<_Tp, _Abi0>, __val); } private: // _M_subscript_read/_write {{{ - _GLIBCXX_SIMD_INTRINSIC _Tp + _GLIBCXX_SIMD_INTRINSIC constexpr _Tp _M_subscript_read([[maybe_unused]] size_t __i) const noexcept { if constexpr (__is_vectorizable_v<_FirstType>) @@ -625,7 +618,7 @@ template <typename _Tp, typename _Abi0, typename... _Abis> return first[__i]; } - _GLIBCXX_SIMD_INTRINSIC void + _GLIBCXX_SIMD_INTRINSIC constexpr void _M_subscript_write([[maybe_unused]] size_t __i, _Tp __y) noexcept { if constexpr (__is_vectorizable_v<_FirstType>) @@ -639,22 +632,22 @@ template <typename _Tp, typename _Abi0, typename... _Abis> // __make_simd_tuple {{{1 template <typename _Tp, typename _A0> - _GLIBCXX_SIMD_INTRINSIC _SimdTuple<_Tp, _A0> + _GLIBCXX_SIMD_INTRINSIC constexpr _SimdTuple<_Tp, _A0> __make_simd_tuple(simd<_Tp, _A0> __x0) { return {__data(__x0)}; } template <typename _Tp, typename _A0, typename... _As> - _GLIBCXX_SIMD_INTRINSIC _SimdTuple<_Tp, _A0, _As...> + _GLIBCXX_SIMD_INTRINSIC constexpr _SimdTuple<_Tp, _A0, _As...> __make_simd_tuple(const simd<_Tp, _A0>& __x0, const simd<_Tp, _As>&... __xs) { return {__data(__x0), __make_simd_tuple(__xs...)}; } template <typename _Tp, typename _A0> - _GLIBCXX_SIMD_INTRINSIC _SimdTuple<_Tp, _A0> + _GLIBCXX_SIMD_INTRINSIC constexpr _SimdTuple<_Tp, _A0> __make_simd_tuple(const typename _SimdTraits<_Tp, _A0>::_SimdMember& __arg0) { return {__arg0}; } template <typename _Tp, typename _A0, typename _A1, typename... _Abis> - _GLIBCXX_SIMD_INTRINSIC _SimdTuple<_Tp, _A0, _A1, _Abis...> + _GLIBCXX_SIMD_INTRINSIC constexpr _SimdTuple<_Tp, _A0, _A1, _Abis...> __make_simd_tuple( const typename _SimdTraits<_Tp, _A0>::_SimdMember& __arg0, const typename _SimdTraits<_Tp, _A1>::_SimdMember& __arg1, @@ -797,19 +790,19 @@ template <typename _Tp, typename _A0, size_t _NOut, size_t _Np, // __optimize_simd_tuple {{{1 template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC _SimdTuple<_Tp> + _GLIBCXX_SIMD_INTRINSIC constexpr _SimdTuple<_Tp> __optimize_simd_tuple(const _SimdTuple<_Tp>) { return {}; } template <typename _Tp, typename _Ap> - _GLIBCXX_SIMD_INTRINSIC const _SimdTuple<_Tp, _Ap>& + _GLIBCXX_SIMD_INTRINSIC constexpr const _SimdTuple<_Tp, _Ap>& __optimize_simd_tuple(const _SimdTuple<_Tp, _Ap>& __x) { return __x; } template <typename _Tp, typename _A0, typename _A1, typename... _Abis, typename _R = __fixed_size_storage_t< _Tp, _SimdTuple<_Tp, _A0, _A1, _Abis...>::_S_size()>> - _GLIBCXX_SIMD_INTRINSIC _R + _GLIBCXX_SIMD_INTRINSIC constexpr _R __optimize_simd_tuple(const _SimdTuple<_Tp, _A0, _A1, _Abis...>& __x) { using _Tup = _SimdTuple<_Tp, _A0, _A1, _Abis...>; @@ -916,7 +909,7 @@ template <size_t _Offset = 0, typename _Tp, typename _A0, typename _A1, // }}}1 // __extract_part(_SimdTuple) {{{ template <int _Index, int _Total, int _Combine, typename _Tp, typename _A0, typename... _As> - _GLIBCXX_SIMD_INTRINSIC auto // __vector_type_t or _SimdTuple + _GLIBCXX_SIMD_INTRINSIC constexpr auto // __vector_type_t or _SimdTuple __extract_part(const _SimdTuple<_Tp, _A0, _As...>& __x) { // worst cases: @@ -1017,11 +1010,11 @@ template <typename _Tp, bool = is_arithmetic_v<__remove_cvref_t<_Tp>>> _Tp _M_data; using _TT = __remove_cvref_t<_Tp>; - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC constexpr operator _TT() { return _M_data; } - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC constexpr operator _TT&() { static_assert(is_lvalue_reference<_Tp>::value, ""); @@ -1029,7 +1022,7 @@ template <typename _Tp, bool = is_arithmetic_v<__remove_cvref_t<_Tp>>> return _M_data; } - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC constexpr operator _TT*() { static_assert(is_lvalue_reference<_Tp>::value, ""); @@ -1041,17 +1034,17 @@ template <typename _Tp, bool = is_arithmetic_v<__remove_cvref_t<_Tp>>> __autocvt_to_simd(_Tp dd) : _M_data(dd) {} template <typename _Abi> - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC constexpr operator simd<typename _TT::value_type, _Abi>() { return {__private_init, _M_data}; } template <typename _Abi> - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC constexpr operator simd<typename _TT::value_type, _Abi>&() { return *reinterpret_cast<simd<typename _TT::value_type, _Abi>*>(&_M_data); } template <typename _Abi> - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC constexpr operator simd<typename _TT::value_type, _Abi>*() { return reinterpret_cast<simd<typename _TT::value_type, _Abi>*>(&_M_data); } }; @@ -1073,11 +1066,11 @@ template <typename _Tp> ~__autocvt_to_simd() { _M_data = __data(_M_fd).first; } - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC constexpr operator fixed_size_simd<_TT, 1>() { return _M_fd; } - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC constexpr operator fixed_size_simd<_TT, 1> &() { static_assert(is_lvalue_reference<_Tp>::value, ""); @@ -1085,7 +1078,7 @@ template <typename _Tp> return _M_fd; } - _GLIBCXX_SIMD_INTRINSIC + _GLIBCXX_SIMD_INTRINSIC constexpr operator fixed_size_simd<_TT, 1> *() { static_assert(is_lvalue_reference<_Tp>::value, ""); @@ -1162,15 +1155,16 @@ template <int _Np> { // The following ensures, function arguments are passed via the stack. // This is important for ABI compatibility across TU boundaries - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE constexpr _SimdBase(const _SimdBase&) {} + _SimdBase() = default; - _GLIBCXX_SIMD_ALWAYS_INLINE explicit + _GLIBCXX_SIMD_ALWAYS_INLINE constexpr explicit operator const _SimdMember &() const { return static_cast<const simd<_Tp, _Fixed>*>(this)->_M_data; } - _GLIBCXX_SIMD_ALWAYS_INLINE explicit + _GLIBCXX_SIMD_ALWAYS_INLINE constexpr explicit operator array<_Tp, _Np>() const { array<_Tp, _Np> __r; @@ -1191,13 +1185,13 @@ template <int _Np> // _SimdCastType {{{ struct _SimdCastType { - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE constexpr _SimdCastType(const array<_Tp, _Np>&); - _GLIBCXX_SIMD_ALWAYS_INLINE + _GLIBCXX_SIMD_ALWAYS_INLINE constexpr _SimdCastType(const _SimdMember& dd) : _M_data(dd) {} - _GLIBCXX_SIMD_ALWAYS_INLINE explicit + _GLIBCXX_SIMD_ALWAYS_INLINE constexpr explicit operator const _SimdMember &() const { return _M_data; } private: @@ -1282,7 +1276,7 @@ template <int _Np, typename> // _S_load {{{2 template <typename _Tp, typename _Up> - _GLIBCXX_SIMD_INTRINSIC static _SimdMember<_Tp> + _GLIBCXX_SIMD_INTRINSIC static constexpr _SimdMember<_Tp> _S_load(const _Up* __mem, _TypeTag<_Tp>) noexcept { return _SimdMember<_Tp>::_S_generate( @@ -1301,10 +1295,10 @@ template <int _Np, typename> __for_each(__merge, [&](auto __meta, auto& __native) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { if (__meta._S_submask(__bits).any()) #pragma GCC diagnostic push - // __mem + __mem._S_offset could be UB ([expr.add]/4.3, but it punts - // the responsibility for avoiding UB to the caller of the masked load - // via the mask. Consequently, the compiler may assume this branch is - // unreachable, if the pointer arithmetic is UB. + // Dereferencing __mem + __meta._S_offset could be UB ([expr.add]/4.3). + // It is the responsibility of the caller of the masked load (via the mask's value) to + // avoid UB. Consequently, the compiler may assume this branch is unreachable, if the + // pointer arithmetic is UB. #pragma GCC diagnostic ignored "-Warray-bounds" __native = __meta._S_masked_load(__native, __meta._S_make_mask(__bits), @@ -1316,7 +1310,7 @@ template <int _Np, typename> // _S_store {{{2 template <typename _Tp, typename _Up> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_store(const _SimdMember<_Tp>& __v, _Up* __mem, _TypeTag<_Tp>) noexcept { __for_each(__v, [&](auto __meta, auto __native) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { @@ -1346,7 +1340,7 @@ template <int _Np, typename> // negation {{{2 template <typename _Tp, typename... _As> - static inline _MaskMember + static constexpr inline _MaskMember _S_negate(const _SimdTuple<_Tp, _As...>& __x) noexcept { _MaskMember __bits = 0; @@ -1699,7 +1693,7 @@ template <int _Np, typename> // compares {{{2 #define _GLIBCXX_SIMD_CMP_OPERATIONS(__cmp) \ template <typename _Tp, typename... _As> \ - _GLIBCXX_SIMD_INTRINSIC constexpr static _MaskMember \ + _GLIBCXX_SIMD_INTRINSIC static constexpr _MaskMember \ __cmp(const _SimdTuple<_Tp, _As...>& __x, \ const _SimdTuple<_Tp, _As...>& __y) \ { \ @@ -1723,13 +1717,13 @@ template <int _Np, typename> // smart_reference access {{{2 template <typename _Tp, typename... _As, typename _Up> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_set(_SimdTuple<_Tp, _As...>& __v, int __i, _Up&& __x) noexcept { __v._M_set(__i, static_cast<_Up&&>(__x)); } // _S_masked_assign {{{2 template <typename _Tp, typename... _As> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_assign(const _MaskMember __bits, _SimdTuple<_Tp, _As...>& __lhs, const __type_identity_t<_SimdTuple<_Tp, _As...>>& __rhs) { @@ -1745,7 +1739,7 @@ template <int _Np, typename> // Optimization for the case where the RHS is a scalar. No need to broadcast // the scalar to a simd first. template <typename _Tp, typename... _As> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_assign(const _MaskMember __bits, _SimdTuple<_Tp, _As...>& __lhs, const __type_identity_t<_Tp> __rhs) { @@ -1758,7 +1752,7 @@ template <int _Np, typename> // _S_masked_cassign {{{2 template <typename _Op, typename _Tp, typename... _As> - static inline void + static constexpr inline void _S_masked_cassign(const _MaskMember __bits, _SimdTuple<_Tp, _As...>& __lhs, const _SimdTuple<_Tp, _As...>& __rhs, _Op __op) { @@ -1774,7 +1768,7 @@ template <int _Np, typename> // Optimization for the case where the RHS is a scalar. No need to broadcast // the scalar to a simd first. template <typename _Op, typename _Tp, typename... _As> - static inline void + static constexpr inline void _S_masked_cassign(const _MaskMember __bits, _SimdTuple<_Tp, _As...>& __lhs, const _Tp& __rhs, _Op __op) { @@ -1787,7 +1781,7 @@ template <int _Np, typename> // _S_masked_unary {{{2 template <template <typename> class _Op, typename _Tp, typename... _As> - static inline _SimdTuple<_Tp, _As...> + static constexpr inline _SimdTuple<_Tp, _As...> _S_masked_unary(const _MaskMember __bits, const _SimdTuple<_Tp, _As...>& __v) { return __v._M_apply_wrapped([&__bits](auto __meta, @@ -1834,6 +1828,13 @@ template <int _Np, typename> _GLIBCXX_SIMD_INTRINSIC static constexpr _MaskMember _S_load(const bool* __mem) { + if (__builtin_is_constant_evaluated()) + { + _MaskMember __r{}; + for (size_t __i = 0; __i < _Np; ++__i) + __r.set(__i, __mem[__i]); + return __r; + } using _Ip = __int_for_sizeof_t<bool>; // the following load uses element_aligned and relies on __mem already // carrying alignment information from when this load function was @@ -1869,12 +1870,12 @@ template <int _Np, typename> // }}} // _S_from_bitmask {{{2 template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC static _MaskMember + _GLIBCXX_SIMD_INTRINSIC static constexpr _MaskMember _S_from_bitmask(_MaskMember __bits, _TypeTag<_Tp>) noexcept { return __bits; } // _S_load {{{2 - static inline _MaskMember + static constexpr inline _MaskMember _S_load(const bool* __mem) noexcept { // TODO: _UChar is not necessarily the best type to use here. For smaller @@ -1890,7 +1891,7 @@ template <int _Np, typename> } // _S_masked_load {{{2 - static inline _MaskMember + static constexpr inline _MaskMember _S_masked_load(_MaskMember __merge, _MaskMember __mask, const bool* __mem) noexcept { _BitOps::_S_bit_iteration(__mask.to_ullong(), @@ -1901,7 +1902,7 @@ template <int _Np, typename> } // _S_store {{{2 - static inline void + static constexpr inline void _S_store(const _MaskMember __bitmask, bool* __mem) noexcept { if constexpr (_Np == 1) @@ -1911,7 +1912,7 @@ template <int _Np, typename> } // _S_masked_store {{{2 - static inline void + static constexpr inline void _S_masked_store(const _MaskMember __v, bool* __mem, const _MaskMember __k) noexcept { _BitOps::_S_bit_iteration( @@ -1919,11 +1920,11 @@ template <int _Np, typename> } // logical and bitwise operators {{{2 - _GLIBCXX_SIMD_INTRINSIC static _MaskMember + _GLIBCXX_SIMD_INTRINSIC static constexpr _MaskMember _S_logical_and(const _MaskMember& __x, const _MaskMember& __y) noexcept { return __x & __y; } - _GLIBCXX_SIMD_INTRINSIC static _MaskMember + _GLIBCXX_SIMD_INTRINSIC static constexpr _MaskMember _S_logical_or(const _MaskMember& __x, const _MaskMember& __y) noexcept { return __x | __y; } @@ -1931,30 +1932,30 @@ template <int _Np, typename> _S_bit_not(const _MaskMember& __x) noexcept { return ~__x; } - _GLIBCXX_SIMD_INTRINSIC static _MaskMember + _GLIBCXX_SIMD_INTRINSIC static constexpr _MaskMember _S_bit_and(const _MaskMember& __x, const _MaskMember& __y) noexcept { return __x & __y; } - _GLIBCXX_SIMD_INTRINSIC static _MaskMember + _GLIBCXX_SIMD_INTRINSIC static constexpr _MaskMember _S_bit_or(const _MaskMember& __x, const _MaskMember& __y) noexcept { return __x | __y; } - _GLIBCXX_SIMD_INTRINSIC static _MaskMember + _GLIBCXX_SIMD_INTRINSIC static constexpr _MaskMember _S_bit_xor(const _MaskMember& __x, const _MaskMember& __y) noexcept { return __x ^ __y; } // smart_reference access {{{2 - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_set(_MaskMember& __k, int __i, bool __x) noexcept { __k.set(__i, __x); } // _S_masked_assign {{{2 - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_assign(const _MaskMember __k, _MaskMember& __lhs, const _MaskMember __rhs) { __lhs = (__lhs & ~__k) | (__rhs & __k); } // Optimization for the case where the RHS is a scalar. - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_assign(const _MaskMember __k, _MaskMember& __lhs, const bool __rhs) { if (__rhs) @@ -1966,28 +1967,28 @@ template <int _Np, typename> // }}}2 // _S_all_of {{{ template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_all_of(simd_mask<_Tp, _Abi> __k) { return __data(__k).all(); } // }}} // _S_any_of {{{ template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_any_of(simd_mask<_Tp, _Abi> __k) { return __data(__k).any(); } // }}} // _S_none_of {{{ template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_none_of(simd_mask<_Tp, _Abi> __k) { return __data(__k).none(); } // }}} // _S_some_of {{{ template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_some_of([[maybe_unused]] simd_mask<_Tp, _Abi> __k) { if constexpr (_Np == 1) @@ -1999,21 +2000,21 @@ template <int _Np, typename> // }}} // _S_popcount {{{ template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC static int + _GLIBCXX_SIMD_INTRINSIC static constexpr int _S_popcount(simd_mask<_Tp, _Abi> __k) { return __data(__k).count(); } // }}} // _S_find_first_set {{{ template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC static int + _GLIBCXX_SIMD_INTRINSIC static constexpr int _S_find_first_set(simd_mask<_Tp, _Abi> __k) { return std::__countr_zero(__data(__k).to_ullong()); } // }}} // _S_find_last_set {{{ template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC static int + _GLIBCXX_SIMD_INTRINSIC static constexpr int _S_find_last_set(simd_mask<_Tp, _Abi> __k) { return std::__bit_width(__data(__k).to_ullong()) - 1; } diff --git a/libstdc++-v3/include/experimental/bits/simd_neon.h b/libstdc++-v3/include/experimental/bits/simd_neon.h index 637b121..8f732d7 100644 --- a/libstdc++-v3/include/experimental/bits/simd_neon.h +++ b/libstdc++-v3/include/experimental/bits/simd_neon.h @@ -84,50 +84,46 @@ template <typename _Abi, typename> // }}} // _S_reduce {{{ template <typename _Tp, typename _BinaryOperation> - _GLIBCXX_SIMD_INTRINSIC static _Tp + _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp _S_reduce(simd<_Tp, _Abi> __x, _BinaryOperation&& __binary_op) { - constexpr size_t _Np = __x.size(); - if constexpr (sizeof(__x) == 16 && _Np >= 4 - && !_Abi::template _S_is_partial<_Tp>) - { - const auto __halves = split<simd<_Tp, simd_abi::_Neon<8>>>(__x); - const auto __y = __binary_op(__halves[0], __halves[1]); - return _SimdImplNeon<simd_abi::_Neon<8>>::_S_reduce( - __y, static_cast<_BinaryOperation&&>(__binary_op)); - } - else if constexpr (_Np == 8) - { - __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( - __vector_permute<1, 0, 3, 2, 5, 4, 7, 6>( - __x._M_data))); - __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( - __vector_permute<3, 2, 1, 0, 7, 6, 5, 4>( - __x._M_data))); - __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( - __vector_permute<7, 6, 5, 4, 3, 2, 1, 0>( - __x._M_data))); - return __x[0]; - } - else if constexpr (_Np == 4) - { - __x - = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( - __vector_permute<1, 0, 3, 2>(__x._M_data))); - __x - = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( - __vector_permute<3, 2, 1, 0>(__x._M_data))); - return __x[0]; - } - else if constexpr (_Np == 2) + if (not __builtin_is_constant_evaluated()) { - __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( - __vector_permute<1, 0>(__x._M_data))); - return __x[0]; + constexpr size_t _Np = __x.size(); + if constexpr (sizeof(__x) == 16 && _Np >= 4 + && !_Abi::template _S_is_partial<_Tp>) + { + const auto __halves = split<simd<_Tp, simd_abi::_Neon<8>>>(__x); + const auto __y = __binary_op(__halves[0], __halves[1]); + return _SimdImplNeon<simd_abi::_Neon<8>>::_S_reduce( + __y, static_cast<_BinaryOperation&&>(__binary_op)); + } + else if constexpr (_Np == 8) + { + __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( + __vector_permute<1, 0, 3, 2, 5, 4, 7, 6>(__x._M_data))); + __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( + __vector_permute<3, 2, 1, 0, 7, 6, 5, 4>(__x._M_data))); + __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( + __vector_permute<7, 6, 5, 4, 3, 2, 1, 0>(__x._M_data))); + return __x[0]; + } + else if constexpr (_Np == 4) + { + __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( + __vector_permute<1, 0, 3, 2>(__x._M_data))); + __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( + __vector_permute<3, 2, 1, 0>(__x._M_data))); + return __x[0]; + } + else if constexpr (_Np == 2) + { + __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>( + __vector_permute<1, 0>(__x._M_data))); + return __x[0]; + } } - else - return _Base::_S_reduce(__x, - static_cast<_BinaryOperation&&>(__binary_op)); + return _Base::_S_reduce(__x, static_cast<_BinaryOperation&&>(__binary_op)); } // }}} diff --git a/libstdc++-v3/include/experimental/bits/simd_ppc.h b/libstdc++-v3/include/experimental/bits/simd_ppc.h index eca1b34..34daa53 100644 --- a/libstdc++-v3/include/experimental/bits/simd_ppc.h +++ b/libstdc++-v3/include/experimental/bits/simd_ppc.h @@ -64,7 +64,7 @@ template <typename _Abi, typename> __x = _Base::_S_bit_shift_left(__x, __y); if constexpr (sizeof(_Tp) < sizeof(int)) { - if (__y >= sizeof(_Tp) * __CHAR_BIT__) + if (__y >= int(sizeof(_Tp) * __CHAR_BIT__)) return {}; } return __x; @@ -130,7 +130,8 @@ template <typename _Abi, typename> const auto __kv = __as_vector(__k); if constexpr (__have_power10vec) { - return vec_cntm(__to_intrin(__kv), 1); + using _Intrin = __intrinsic_type16_t<make_unsigned_t<__int_for_sizeof_t<_Tp>>>; + return vec_cntm(reinterpret_cast<_Intrin>(__kv), 1); } else if constexpr (sizeof(_Tp) >= sizeof(int)) { diff --git a/libstdc++-v3/include/experimental/bits/simd_scalar.h b/libstdc++-v3/include/experimental/bits/simd_scalar.h index 1a1cc46..b88e13f 100644 --- a/libstdc++-v3/include/experimental/bits/simd_scalar.h +++ b/libstdc++-v3/include/experimental/bits/simd_scalar.h @@ -152,13 +152,13 @@ struct _SimdImplScalar // _S_load {{{2 template <typename _Tp, typename _Up> - _GLIBCXX_SIMD_INTRINSIC static _Tp + _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp _S_load(const _Up* __mem, _TypeTag<_Tp>) noexcept { return static_cast<_Tp>(__mem[0]); } // _S_masked_load {{{2 template <typename _Tp, typename _Up> - _GLIBCXX_SIMD_INTRINSIC static _Tp + _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp _S_masked_load(_Tp __merge, bool __k, const _Up* __mem) noexcept { if (__k) @@ -168,13 +168,13 @@ struct _SimdImplScalar // _S_store {{{2 template <typename _Tp, typename _Up> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_store(_Tp __v, _Up* __mem, _TypeTag<_Tp>) noexcept { __mem[0] = static_cast<_Up>(__v); } // _S_masked_store {{{2 template <typename _Tp, typename _Up> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_store(const _Tp __v, _Up* __mem, const bool __k) noexcept { if (__k) __mem[0] = __v; } @@ -572,101 +572,101 @@ struct _SimdImplScalar { return std::remquo(__x, __y, &__z->first); } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static _ST<int> + _GLIBCXX_SIMD_INTRINSIC static constexpr _ST<int> _S_fpclassify(_Tp __x) { return {std::fpclassify(__x)}; } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_isfinite(_Tp __x) { return std::isfinite(__x); } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_isinf(_Tp __x) { return std::isinf(__x); } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_isnan(_Tp __x) { return std::isnan(__x); } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_isnormal(_Tp __x) { return std::isnormal(__x); } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_signbit(_Tp __x) { return std::signbit(__x); } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_isgreater(_Tp __x, _Tp __y) { return std::isgreater(__x, __y); } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_isgreaterequal(_Tp __x, _Tp __y) { return std::isgreaterequal(__x, __y); } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_isless(_Tp __x, _Tp __y) { return std::isless(__x, __y); } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_islessequal(_Tp __x, _Tp __y) { return std::islessequal(__x, __y); } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_islessgreater(_Tp __x, _Tp __y) { return std::islessgreater(__x, __y); } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_isunordered(_Tp __x, _Tp __y) { return std::isunordered(__x, __y); } // _S_increment & _S_decrement{{{2 template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_increment(_Tp& __x) { ++__x; } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_decrement(_Tp& __x) { --__x; } // compares {{{2 template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_equal_to(_Tp __x, _Tp __y) { return __x == __y; } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_not_equal_to(_Tp __x, _Tp __y) { return __x != __y; } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_less(_Tp __x, _Tp __y) { return __x < __y; } template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_less_equal(_Tp __x, _Tp __y) { return __x <= __y; } // smart_reference access {{{2 template <typename _Tp, typename _Up> - _GLIBCXX_SIMD_INTRINSIC constexpr static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_set(_Tp& __v, [[maybe_unused]] int __i, _Up&& __x) noexcept { _GLIBCXX_DEBUG_ASSERT(__i == 0); @@ -675,19 +675,19 @@ struct _SimdImplScalar // _S_masked_assign {{{2 template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_assign(bool __k, _Tp& __lhs, _Tp __rhs) { if (__k) __lhs = __rhs; } // _S_masked_cassign {{{2 template <typename _Op, typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_cassign(const bool __k, _Tp& __lhs, const _Tp __rhs, _Op __op) { if (__k) __lhs = __op(_SimdImplScalar{}, __lhs, __rhs); } // _S_masked_unary {{{2 template <template <typename> class _Op, typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static _Tp + _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp _S_masked_unary(const bool __k, const _Tp __v) { return static_cast<_Tp>(__k ? _Op<_Tp>{}(__v) : __v); } @@ -737,12 +737,12 @@ struct _MaskImplScalar // }}} // _S_from_bitmask {{{2 template <typename _Tp> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_from_bitmask(_SanitizedBitMask<1> __bits, _TypeTag<_Tp>) noexcept { return __bits[0]; } // _S_masked_load {{{2 - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_masked_load(bool __merge, bool __mask, const bool* __mem) noexcept { if (__mask) @@ -751,12 +751,12 @@ struct _MaskImplScalar } // _S_store {{{2 - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_store(bool __v, bool* __mem) noexcept { __mem[0] = __v; } // _S_masked_store {{{2 - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_store(const bool __v, bool* __mem, const bool __k) noexcept { if (__k) @@ -789,7 +789,7 @@ struct _MaskImplScalar { return __x != __y; } // smart_reference access {{{2 - _GLIBCXX_SIMD_INTRINSIC constexpr static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_set(bool& __k, [[maybe_unused]] int __i, bool __x) noexcept { _GLIBCXX_DEBUG_ASSERT(__i == 0); @@ -797,7 +797,7 @@ struct _MaskImplScalar } // _S_masked_assign {{{2 - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_masked_assign(bool __k, bool& __lhs, bool __rhs) { if (__k) @@ -807,49 +807,49 @@ struct _MaskImplScalar // }}}2 // _S_all_of {{{ template <typename _Tp, typename _Abi> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_all_of(simd_mask<_Tp, _Abi> __k) { return __k._M_data; } // }}} // _S_any_of {{{ template <typename _Tp, typename _Abi> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_any_of(simd_mask<_Tp, _Abi> __k) { return __k._M_data; } // }}} // _S_none_of {{{ template <typename _Tp, typename _Abi> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_none_of(simd_mask<_Tp, _Abi> __k) { return !__k._M_data; } // }}} // _S_some_of {{{ template <typename _Tp, typename _Abi> - _GLIBCXX_SIMD_INTRINSIC constexpr static bool + _GLIBCXX_SIMD_INTRINSIC static constexpr bool _S_some_of(simd_mask<_Tp, _Abi>) { return false; } // }}} // _S_popcount {{{ template <typename _Tp, typename _Abi> - _GLIBCXX_SIMD_INTRINSIC constexpr static int + _GLIBCXX_SIMD_INTRINSIC static constexpr int _S_popcount(simd_mask<_Tp, _Abi> __k) { return __k._M_data; } // }}} // _S_find_first_set {{{ template <typename _Tp, typename _Abi> - _GLIBCXX_SIMD_INTRINSIC constexpr static int + _GLIBCXX_SIMD_INTRINSIC static constexpr int _S_find_first_set(simd_mask<_Tp, _Abi>) { return 0; } // }}} // _S_find_last_set {{{ template <typename _Tp, typename _Abi> - _GLIBCXX_SIMD_INTRINSIC constexpr static int + _GLIBCXX_SIMD_INTRINSIC static constexpr int _S_find_last_set(simd_mask<_Tp, _Abi>) { return 0; } diff --git a/libstdc++-v3/include/experimental/bits/simd_x86.h b/libstdc++-v3/include/experimental/bits/simd_x86.h index fc3e96d..2e301e4 100644 --- a/libstdc++-v3/include/experimental/bits/simd_x86.h +++ b/libstdc++-v3/include/experimental/bits/simd_x86.h @@ -510,12 +510,14 @@ struct _CommonImplX86 : _CommonImplBuiltin using _CommonImplBuiltin::_S_store; template <typename _Tp, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_store(_SimdWrapper<_Tp, _Np> __x, void* __addr) { constexpr size_t _Bytes = _Np * sizeof(_Tp); - if constexpr ((_Bytes & (_Bytes - 1)) != 0 && __have_avx512bw_vl) + if (__builtin_is_constant_evaluated()) + _CommonImplBuiltin::_S_store(__x, __addr); + else if constexpr ((_Bytes & (_Bytes - 1)) != 0 && __have_avx512bw_vl) { const auto __v = __to_intrin(__x); @@ -581,7 +583,9 @@ struct _CommonImplX86 : _CommonImplBuiltin _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_store_bool_array(const _BitMask<_Np, _Sanitized> __x, bool* __mem) { - if constexpr (__have_avx512bw_vl) // don't care for BW w/o VL + if (__builtin_is_constant_evaluated()) + _CommonImplBuiltin::_S_store_bool_array(__x, __mem); + else if constexpr (__have_avx512bw_vl) // don't care for BW w/o VL _S_store<_Np>(1 & __vector_bitcast<_UChar, _Np>( [=]() constexpr _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { if constexpr (_Np <= 16) @@ -1102,31 +1106,6 @@ template <typename _Abi, typename> else _mm512_mask_storeu_pd(__mem, __k, __vi); } -#if 0 // with KNL either sizeof(_Tp) >= 4 or sizeof(_vi) <= 32 - // with Skylake-AVX512, __have_avx512bw is true - else if constexpr (__have_sse2) - { - using _M = __vector_type_t<_Tp, _Np>; - using _MVT = _VectorTraits<_M>; - _mm_maskmoveu_si128(__auto_bitcast(__extract<0, 4>(__v._M_data)), - __auto_bitcast(_MaskImpl::template _S_convert<_Tp, _Np>(__k._M_data)), - reinterpret_cast<char*>(__mem)); - _mm_maskmoveu_si128(__auto_bitcast(__extract<1, 4>(__v._M_data)), - __auto_bitcast(_MaskImpl::template _S_convert<_Tp, _Np>( - __k._M_data >> 1 * _MVT::_S_full_size)), - reinterpret_cast<char*>(__mem) + 1 * 16); - _mm_maskmoveu_si128(__auto_bitcast(__extract<2, 4>(__v._M_data)), - __auto_bitcast(_MaskImpl::template _S_convert<_Tp, _Np>( - __k._M_data >> 2 * _MVT::_S_full_size)), - reinterpret_cast<char*>(__mem) + 2 * 16); - if constexpr (_Np > 48 / sizeof(_Tp)) - _mm_maskmoveu_si128( - __auto_bitcast(__extract<3, 4>(__v._M_data)), - __auto_bitcast(_MaskImpl::template _S_convert<_Tp, _Np>( - __k._M_data >> 3 * _MVT::_S_full_size)), - reinterpret_cast<char*>(__mem) + 3 * 16); - } -#endif else __assert_unreachable<_Tp>(); } @@ -1229,8 +1208,8 @@ template <typename _Abi, typename> else if constexpr (__have_avx && sizeof(_Tp) == 8) _mm_maskstore_pd(reinterpret_cast<double*>(__mem), __ki, __vector_bitcast<double>(__vi)); - else if constexpr (__have_sse2) - _mm_maskmoveu_si128(__vi, __ki, reinterpret_cast<char*>(__mem)); + else + _Base::_S_masked_store_nocvt(__v, __mem, __k); } else if constexpr (sizeof(__v) == 32) { @@ -1255,13 +1234,8 @@ template <typename _Abi, typename> else if constexpr (__have_avx && sizeof(_Tp) == 8) _mm256_maskstore_pd(reinterpret_cast<double*>(__mem), __ki, __vector_bitcast<double>(__v)); - else if constexpr (__have_sse2) - { - _mm_maskmoveu_si128(__lo128(__vi), __lo128(__ki), - reinterpret_cast<char*>(__mem)); - _mm_maskmoveu_si128(__hi128(__vi), __hi128(__ki), - reinterpret_cast<char*>(__mem) + 16); - } + else + _Base::_S_masked_store_nocvt(__v, __mem, __k); } else __assert_unreachable<_Tp>(); @@ -2319,14 +2293,14 @@ template <typename _Abi, typename> } // }}} else if (__builtin_is_constant_evaluated()) return _Base::_S_equal_to(__x, __y); - else if constexpr (sizeof(__x) == 8) // {{{ + else if constexpr (sizeof(__x) == 8) { const auto __r128 = __vector_bitcast<_Tp, 16 / sizeof(_Tp)>(__x) == __vector_bitcast<_Tp, 16 / sizeof(_Tp)>(__y); - _MaskMember<_Tp> __r64; + _MaskMember<_Tp> __r64{}; __builtin_memcpy(&__r64._M_data, &__r128, sizeof(__r64)); return __r64; - } // }}} + } else return _Base::_S_equal_to(__x, __y); } @@ -2397,7 +2371,7 @@ template <typename _Abi, typename> { const auto __r128 = __vector_bitcast<_Tp, 16 / sizeof(_Tp)>(__x) != __vector_bitcast<_Tp, 16 / sizeof(_Tp)>(__y); - _MaskMember<_Tp> __r64; + _MaskMember<_Tp> __r64{}; __builtin_memcpy(&__r64._M_data, &__r128, sizeof(__r64)); return __r64; } @@ -2505,7 +2479,7 @@ template <typename _Abi, typename> { const auto __r128 = __vector_bitcast<_Tp, 16 / sizeof(_Tp)>(__x) < __vector_bitcast<_Tp, 16 / sizeof(_Tp)>(__y); - _MaskMember<_Tp> __r64; + _MaskMember<_Tp> __r64{}; __builtin_memcpy(&__r64._M_data, &__r128, sizeof(__r64)); return __r64; } @@ -2613,7 +2587,7 @@ template <typename _Abi, typename> { const auto __r128 = __vector_bitcast<_Tp, 16 / sizeof(_Tp)>(__x) <= __vector_bitcast<_Tp, 16 / sizeof(_Tp)>(__y); - _MaskMember<_Tp> __r64; + _MaskMember<_Tp> __r64{}; __builtin_memcpy(&__r64._M_data, &__r128, sizeof(__r64)); return __r64; } @@ -4409,7 +4383,19 @@ template <typename _Abi, typename> _S_load(const bool* __mem) { static_assert(is_same_v<_Tp, __int_for_sizeof_t<_Tp>>); - if constexpr (__have_avx512bw) + if (__builtin_is_constant_evaluated()) + { + if constexpr (__is_avx512_abi<_Abi>()) + { + _MaskMember<_Tp> __r{}; + for (size_t __i = 0; __i < _S_size<_Tp>; ++__i) + __r._M_data |= _ULLong(__mem[__i]) << __i; + return __r; + } + else + return _Base::template _S_load<_Tp>(__mem); + } + else if constexpr (__have_avx512bw) { const auto __to_vec_or_bits = [](auto __bits) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA -> decltype(auto) { @@ -4677,10 +4663,12 @@ template <typename _Abi, typename> // _S_store {{{2 template <typename _Tp, size_t _Np> - _GLIBCXX_SIMD_INTRINSIC static void + _GLIBCXX_SIMD_INTRINSIC static constexpr void _S_store(_SimdWrapper<_Tp, _Np> __v, bool* __mem) noexcept { - if constexpr (__is_avx512_abi<_Abi>()) + if (__builtin_is_constant_evaluated()) + _Base::_S_store(__v, __mem); + else if constexpr (__is_avx512_abi<_Abi>()) { if constexpr (__have_avx512bw_vl) _CommonImplX86::_S_store<_Np>( @@ -4762,7 +4750,7 @@ template <typename _Abi, typename> if constexpr (_Np <= 4 && sizeof(_Tp) == 8) { auto __k = __intrin_bitcast<__m256i>(__to_intrin(__v)); - int __bool4; + int __bool4{}; if constexpr (__have_avx2) __bool4 = _mm256_movemask_epi8(__k); else @@ -4846,7 +4834,9 @@ template <typename _Abi, typename> { if constexpr (is_same_v<_Tp, bool>) { - if constexpr (__have_avx512dq && _Np <= 8) + if (__builtin_is_constant_evaluated()) + return __x._M_data & __y._M_data; + else if constexpr (__have_avx512dq && _Np <= 8) return _kand_mask8(__x._M_data, __y._M_data); else if constexpr (_Np <= 16) return _kand_mask16(__x._M_data, __y._M_data); @@ -4867,7 +4857,9 @@ template <typename _Abi, typename> { if constexpr (is_same_v<_Tp, bool>) { - if constexpr (__have_avx512dq && _Np <= 8) + if (__builtin_is_constant_evaluated()) + return __x._M_data | __y._M_data; + else if constexpr (__have_avx512dq && _Np <= 8) return _kor_mask8(__x._M_data, __y._M_data); else if constexpr (_Np <= 16) return _kor_mask16(__x._M_data, __y._M_data); @@ -4888,7 +4880,9 @@ template <typename _Abi, typename> { if constexpr (is_same_v<_Tp, bool>) { - if constexpr (__have_avx512dq && _Np <= 8) + if (__builtin_is_constant_evaluated()) + return __x._M_data ^ _Abi::template __implicit_mask_n<_Np>(); + else if constexpr (__have_avx512dq && _Np <= 8) return _kandn_mask8(__x._M_data, _Abi::template __implicit_mask_n<_Np>()); else if constexpr (_Np <= 16) @@ -4913,7 +4907,9 @@ template <typename _Abi, typename> { if constexpr (is_same_v<_Tp, bool>) { - if constexpr (__have_avx512dq && _Np <= 8) + if (__builtin_is_constant_evaluated()) + return __x._M_data & __y._M_data; + else if constexpr (__have_avx512dq && _Np <= 8) return _kand_mask8(__x._M_data, __y._M_data); else if constexpr (_Np <= 16) return _kand_mask16(__x._M_data, __y._M_data); @@ -4934,7 +4930,9 @@ template <typename _Abi, typename> { if constexpr (is_same_v<_Tp, bool>) { - if constexpr (__have_avx512dq && _Np <= 8) + if (__builtin_is_constant_evaluated()) + return __x._M_data | __y._M_data; + else if constexpr (__have_avx512dq && _Np <= 8) return _kor_mask8(__x._M_data, __y._M_data); else if constexpr (_Np <= 16) return _kor_mask16(__x._M_data, __y._M_data); @@ -4955,7 +4953,9 @@ template <typename _Abi, typename> { if constexpr (is_same_v<_Tp, bool>) { - if constexpr (__have_avx512dq && _Np <= 8) + if (__builtin_is_constant_evaluated()) + return __x._M_data ^ __y._M_data; + else if constexpr (__have_avx512dq && _Np <= 8) return _kxor_mask8(__x._M_data, __y._M_data); else if constexpr (_Np <= 16) return _kxor_mask16(__x._M_data, __y._M_data); diff --git a/libstdc++-v3/include/experimental/functional b/libstdc++-v3/include/experimental/functional index ce9d4e0..26b8dd5 100644 --- a/libstdc++-v3/include/experimental/functional +++ b/libstdc++-v3/include/experimental/functional @@ -42,10 +42,7 @@ #include <unordered_map> #include <vector> #include <array> -#include <bits/stl_algo.h> -#ifdef _GLIBCXX_PARALLEL -# include <parallel/algorithm> // For std::__parallel::search -#endif +#include <bits/stl_algobase.h> // std::max, std::search #include <experimental/bits/lfts_config.h> namespace std _GLIBCXX_VISIBILITY(default) diff --git a/libstdc++-v3/include/experimental/internet b/libstdc++-v3/include/experimental/internet index cae07f4..bd9a05f 100644 --- a/libstdc++-v3/include/experimental/internet +++ b/libstdc++-v3/include/experimental/internet @@ -977,7 +977,8 @@ namespace ip { return make_address(__str, __throw_on_error{"make_address"}); } inline address - make_address(const string& __str, error_code& __ec) noexcept; // TODO + make_address(const string& __str, error_code& __ec) noexcept + { return make_address(__str.c_str(), __ec); } inline address make_address(const string& __str) @@ -1275,7 +1276,12 @@ namespace ip constexpr address_v4 broadcast() const noexcept - { return address_v4{_M_addr.to_uint() | (0xFFFFFFFFu >> _M_prefix_len)}; } + { + auto __b = _M_addr.to_uint(); + if (_M_prefix_len < 32) + __b |= 0xFFFFFFFFu >> _M_prefix_len; + return address_v4{__b}; + } address_v4_range hosts() const noexcept @@ -1496,6 +1502,7 @@ namespace ip operator<<(basic_ostream<_CharT, _Traits>& __os, const network_v6& __net) { return __os << __net.to_string(); } +#if defined IPPROTO_TCP || defined IPPROTO_UDP /// An IP endpoint. template<typename _InternetProtocol> class basic_endpoint @@ -1506,23 +1513,45 @@ namespace ip // constructors: - constexpr + _GLIBCXX20_CONSTEXPR basic_endpoint() noexcept : _M_data() - { _M_data._M_v4.sin_family = protocol_type::v4().family(); } + { + _M_data._M_v4.sin_family = protocol_type::v4().family(); + // If in_addr contains a union, make the correct member active: + if (std::__is_constant_evaluated()) + std::_Construct(&_M_data._M_v4.sin_addr.s_addr); + } - constexpr + _GLIBCXX20_CONSTEXPR basic_endpoint(const protocol_type& __proto, port_type __port_num) noexcept : _M_data() { - __glibcxx_assert(__proto == protocol_type::v4() - || __proto == protocol_type::v6()); + if (__proto == protocol_type::v4()) + { + _M_data._M_v4.sin_family = protocol_type::v4().family(); + _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num); + if (std::__is_constant_evaluated()) + std::_Construct(&_M_data._M_v4.sin_addr.s_addr); + } + else if (__proto == protocol_type::v6()) + { + std::_Construct(&_M_data._M_v6); + _M_data._M_v6.sin6_family = __proto.family(); + _M_data._M_v6.sin6_port = address_v4::_S_hton_16(__port_num); + _M_data._M_v6.sin6_scope_id = 0; + if (std::__is_constant_evaluated()) + std::_Construct(&_M_data._M_v6.sin6_addr.s6_addr); + } + else + { + __glibcxx_assert(__proto == protocol_type::v4() + || __proto == protocol_type::v6()); - _M_data._M_v4.sin_family = __proto.family(); - _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num); + } } - constexpr + _GLIBCXX20_CONSTEXPR basic_endpoint(const ip::address& __addr, port_type __port_num) noexcept : _M_data() @@ -1531,20 +1560,25 @@ namespace ip { _M_data._M_v4.sin_family = protocol_type::v4().family(); _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num); - _M_data._M_v4.sin_addr.s_addr = __addr._M_v4._M_addr; + std::_Construct(&_M_data._M_v4.sin_addr.s_addr, + __addr._M_v4._M_addr); } else { - _M_data._M_v6 = {}; + std::_Construct(&_M_data._M_v6); _M_data._M_v6.sin6_family = protocol_type::v6().family(); _M_data._M_v6.sin6_port = address_v4::_S_hton_16(__port_num); - __builtin_memcpy(_M_data._M_v6.sin6_addr.s6_addr, - __addr._M_v6._M_bytes.data(), 16); + if (std::__is_constant_evaluated()) + std::_Construct(&_M_data._M_v6.sin6_addr.s6_addr); + uint8_t* __s6a = _M_data._M_v6.sin6_addr.s6_addr; + for (int __i = 0; __i < 16; ++__i) + __s6a[__i] = __addr._M_v6._M_bytes[__i]; _M_data._M_v6.sin6_scope_id = __addr._M_v6._M_scope_id; } } // members: + constexpr protocol_type protocol() const noexcept { return _M_is_v6() ? protocol_type::v6() : protocol_type::v4(); @@ -1553,19 +1587,21 @@ namespace ip constexpr ip::address address() const noexcept { - ip::address __addr; if (_M_is_v6()) { - __builtin_memcpy(&__addr._M_v6._M_bytes, - _M_data._M_v6.sin6_addr.s6_addr, 16); - __addr._M_is_v4 = false; + address_v6 __v6; + const uint8_t* __s6a = _M_data._M_v6.sin6_addr.s6_addr; + for (int __i = 0; __i < 16; ++__i) + __v6._M_bytes[__i] = __s6a[__i]; + __v6._M_scope_id = _M_data._M_v6.sin6_scope_id; + return __v6; } else { - __builtin_memcpy(&__addr._M_v4._M_addr, - &_M_data._M_v4.sin_addr.s_addr, 4); + address_v4 __v4; + __v4._M_addr = _M_data._M_v4.sin_addr.s_addr; + return __v4; } - return __addr; } void @@ -1573,7 +1609,7 @@ namespace ip { if (__addr.is_v6()) { - _M_data._M_v6 = {}; + std::_Construct(&_M_data._M_v6); _M_data._M_v6.sin6_family = protocol_type::v6().family(); __builtin_memcpy(_M_data._M_v6.sin6_addr.s6_addr, __addr._M_v6._M_bytes.data(), 16); @@ -1581,6 +1617,7 @@ namespace ip } else { + std::_Construct(&_M_data._M_v4); _M_data._M_v4.sin_family = protocol_type::v4().family(); _M_data._M_v4.sin_addr.s_addr = __addr._M_v4._M_addr; } @@ -1588,17 +1625,31 @@ namespace ip constexpr port_type port() const noexcept - { return address_v4::_S_ntoh_16(_M_data._M_v4.sin_port); } + { + port_type __p = 0; + if (_M_is_v6()) + __p = _M_data._M_v6.sin6_port; + else + __p = _M_data._M_v4.sin_port; + return address_v4::_S_ntoh_16(__p); + } void port(port_type __port_num) noexcept - { _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num); } + { + __port_num = address_v4::_S_hton_16(__port_num); + if (_M_is_v6()) + _M_data._M_v6.sin6_port = __port_num; + else + _M_data._M_v4.sin_port = __port_num; + } void* data() noexcept { return &_M_data; } const void* data() const noexcept { return &_M_data; } - constexpr size_t size() const noexcept + constexpr size_t + size() const noexcept { return _M_is_v6() ? sizeof(sockaddr_in6) : sizeof(sockaddr_in); } void @@ -1617,8 +1668,15 @@ namespace ip sockaddr_in6 _M_v6; } _M_data; - constexpr bool _M_is_v6() const noexcept - { return _M_data._M_v4.sin_family == AF_INET6; } + constexpr bool + _M_is_v6() const noexcept + { + // For constexpr eval we can just detect which union member is active. + // i.e. emulate P2641R1's std::is_active_member(&_M_data._M_v6)). + if (std::__is_constant_evaluated()) + return __builtin_constant_p(_M_data._M_v6.sin6_family); + return _M_data._M_v6.sin6_family == AF_INET6; + } }; /** basic_endpoint comparisons @@ -2130,6 +2188,7 @@ namespace ip __ec = std::make_error_code(errc::operation_not_supported); #endif } +#endif // IPPROTO_TCP || IPPROTO_UDP /** The name of the local host. * @{ diff --git a/libstdc++-v3/include/experimental/memory_resource b/libstdc++-v3/include/experimental/memory_resource index 070cf79..9f1cb42 100644 --- a/libstdc++-v3/include/experimental/memory_resource +++ b/libstdc++-v3/include/experimental/memory_resource @@ -45,14 +45,12 @@ #include <bits/new_allocator.h> #include <debug/assertions.h> -/// @cond namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> class malloc_allocator; _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx -/// @endcond namespace std { _GLIBCXX_BEGIN_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/experimental/source_location b/libstdc++-v3/include/experimental/source_location index 1dfce73..ee94a36 100644 --- a/libstdc++-v3/include/experimental/source_location +++ b/libstdc++-v3/include/experimental/source_location @@ -44,12 +44,6 @@ inline namespace fundamentals_v2 { struct source_location { -#ifndef _GLIBCXX_USE_C99_STDINT_TR1 - private: - using uint_least32_t = unsigned; - public: -#endif - // 14.1.2, source_location creation static constexpr source_location current(const char* __file = __builtin_FILE(), diff --git a/libstdc++-v3/include/ext/random b/libstdc++-v3/include/ext/random index 795c3c5..5ae085a 100644 --- a/libstdc++-v3/include/ext/random +++ b/libstdc++-v3/include/ext/random @@ -45,7 +45,7 @@ # include <emmintrin.h> #endif -#if defined(_GLIBCXX_USE_C99_STDINT_TR1) && defined(UINT32_C) +#ifdef UINT32_C namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { @@ -1116,7 +1116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { result_type __x = this->_M_ndx(__urng); result_type __y = this->_M_ndy(__urng); -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS return std::hypot(__x, __y); #else return std::sqrt(__x * __x + __y * __y); @@ -1132,7 +1132,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma()); result_type __x = this->_M_ndx(__px, __urng); result_type __y = this->_M_ndy(__py, __urng); -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS return std::hypot(__x, __y); #else return std::sqrt(__x * __x + __y * __y); @@ -3923,7 +3923,7 @@ _GLIBCXX_END_NAMESPACE_VERSION #include <ext/opt_random.h> #include <ext/random.tcc> -#endif // _GLIBCXX_USE_C99_STDINT_TR1 && UINT32_C +#endif // UINT32_C #endif // C++11 diff --git a/libstdc++-v3/include/ext/random.tcc b/libstdc++-v3/include/ext/random.tcc index df80422..87ecce7 100644 --- a/libstdc++-v3/include/ext/random.tcc +++ b/libstdc++-v3/include/ext/random.tcc @@ -740,7 +740,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma()); result_type __x = this->_M_ndx(__px, __urng); result_type __y = this->_M_ndy(__py, __urng); -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS *__f++ = std::hypot(__x, __y); #else *__f++ = std::sqrt(__x * __x + __y * __y); @@ -1287,7 +1287,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } result_type __res = std::acos(__f); -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS __res = std::copysign(__res, __aurng() - result_type(0.5)); #else if (__aurng() < result_type(0.5)) @@ -1623,7 +1623,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } while (__sq == _RealType(0) || __sq > _RealType(1)); -#if _GLIBCXX_USE_C99_MATH_TR1 +#if _GLIBCXX_USE_C99_MATH_FUNCS // Yes, we do not just use sqrt(__sq) because hypot() is more // accurate. auto __norm = std::hypot(__ret[0], __ret[1]); diff --git a/libstdc++-v3/include/ext/throw_allocator.h b/libstdc++-v3/include/ext/throw_allocator.h index 0dbf001..71b7198 100644 --- a/libstdc++-v3/include/ext/throw_allocator.h +++ b/libstdc++-v3/include/ext/throw_allocator.h @@ -495,7 +495,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 /** * @brief Base class for random probability control and throw. */ @@ -613,7 +612,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _S_e; } }; -#endif // _GLIBCXX_USE_C99_STDINT_TR1 /** * @brief Class with exception generation control. Intended to be @@ -769,7 +767,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif }; -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 /// Type throwing via random condition. struct throw_value_random : public throw_value_base<random_condition> { @@ -800,7 +797,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator=(throw_value_random&&) = default; #endif }; -#endif // _GLIBCXX_USE_C99_STDINT_TR1 /** * @brief Allocator class with logging and exception generation control. @@ -947,7 +943,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif }; -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 /// Allocator throwing via random condition. template<typename _Tp> struct throw_allocator_random @@ -973,7 +968,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator=(const throw_allocator_random&) = default; #endif }; -#endif // _GLIBCXX_USE_C99_STDINT_TR1 _GLIBCXX_END_NAMESPACE_VERSION } // namespace @@ -1002,7 +996,6 @@ namespace std _GLIBCXX_VISIBILITY(default) } }; -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random. template<> struct hash<__gnu_cxx::throw_value_random> @@ -1017,7 +1010,6 @@ namespace std _GLIBCXX_VISIBILITY(default) return __result; } }; -#endif #pragma GCC diagnostic pop } // end namespace std diff --git a/libstdc++-v3/include/parallel/algo.h b/libstdc++-v3/include/parallel/algo.h index 43ed6c5..13ae762 100644 --- a/libstdc++-v3/include/parallel/algo.h +++ b/libstdc++-v3/include/parallel/algo.h @@ -996,59 +996,6 @@ namespace __parallel std::__iterator_category(__begin2)); } - // Public interface. - template<typename _FIterator1, typename _FIterator2, - typename _BinaryPredicate> - inline _FIterator1 - search(_FIterator1 __begin1, _FIterator1 __end1, - _FIterator2 __begin2, _FIterator2 __end2, - _BinaryPredicate __pred, __gnu_parallel::sequential_tag) - { return _GLIBCXX_STD_A::search( - __begin1, __end1, __begin2, __end2, __pred); } - - // Parallel algorithm for random access iterator. - template<typename _RAIter1, typename _RAIter2, - typename _BinaryPredicate> - _RAIter1 - __search_switch(_RAIter1 __begin1, _RAIter1 __end1, - _RAIter2 __begin2, _RAIter2 __end2, - _BinaryPredicate __pred, - random_access_iterator_tag, random_access_iterator_tag) - { - if (_GLIBCXX_PARALLEL_CONDITION( - static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) - >= __gnu_parallel::_Settings::get().search_minimal_n)) - return __gnu_parallel::__search_template(__begin1, __end1, - __begin2, __end2, __pred); - else - return search(__begin1, __end1, __begin2, __end2, __pred, - __gnu_parallel::sequential_tag()); - } - - // Sequential fallback for input iterator case - template<typename _FIterator1, typename _FIterator2, - typename _BinaryPredicate, typename _IteratorTag1, - typename _IteratorTag2> - inline _FIterator1 - __search_switch(_FIterator1 __begin1, _FIterator1 __end1, - _FIterator2 __begin2, _FIterator2 __end2, - _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2) - { return search(__begin1, __end1, __begin2, __end2, __pred, - __gnu_parallel::sequential_tag()); } - - // Public interface - template<typename _FIterator1, typename _FIterator2, - typename _BinaryPredicate> - inline _FIterator1 - search(_FIterator1 __begin1, _FIterator1 __end1, - _FIterator2 __begin2, _FIterator2 __end2, - _BinaryPredicate __pred) - { - return __search_switch(__begin1, __end1, __begin2, __end2, __pred, - std::__iterator_category(__begin1), - std::__iterator_category(__begin2)); - } - #if __cplusplus >= 201703L /** @brief Search a sequence using a Searcher object. * diff --git a/libstdc++-v3/include/parallel/algobase.h b/libstdc++-v3/include/parallel/algobase.h index 0bc25a6..9e5b865 100644 --- a/libstdc++-v3/include/parallel/algobase.h +++ b/libstdc++-v3/include/parallel/algobase.h @@ -41,6 +41,7 @@ #include <parallel/algorithmfwd.h> #include <parallel/find.h> #include <parallel/find_selectors.h> +#include <parallel/search.h> namespace std _GLIBCXX_VISIBILITY(default) { @@ -470,7 +471,60 @@ namespace __parallel #if __cpp_lib_three_way_comparison using _GLIBCXX_STD_A::lexicographical_compare_three_way; #endif -} // end namespace -} // end namespace + + // Public interface. + template<typename _FIterator1, typename _FIterator2, + typename _BinaryPredicate> + inline _FIterator1 + search(_FIterator1 __begin1, _FIterator1 __end1, + _FIterator2 __begin2, _FIterator2 __end2, + _BinaryPredicate __pred, __gnu_parallel::sequential_tag) + { return _GLIBCXX_STD_A::search( + __begin1, __end1, __begin2, __end2, __pred); } + + // Parallel algorithm for random access iterator. + template<typename _RAIter1, typename _RAIter2, + typename _BinaryPredicate> + _RAIter1 + __search_switch(_RAIter1 __begin1, _RAIter1 __end1, + _RAIter2 __begin2, _RAIter2 __end2, + _BinaryPredicate __pred, + random_access_iterator_tag, random_access_iterator_tag) + { + if (_GLIBCXX_PARALLEL_CONDITION( + static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) + >= __gnu_parallel::_Settings::get().search_minimal_n)) + return __gnu_parallel::__search_template(__begin1, __end1, + __begin2, __end2, __pred); + else + return search(__begin1, __end1, __begin2, __end2, __pred, + __gnu_parallel::sequential_tag()); + } + + // Sequential fallback for input iterator case + template<typename _FIterator1, typename _FIterator2, + typename _BinaryPredicate, typename _IteratorTag1, + typename _IteratorTag2> + inline _FIterator1 + __search_switch(_FIterator1 __begin1, _FIterator1 __end1, + _FIterator2 __begin2, _FIterator2 __end2, + _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2) + { return search(__begin1, __end1, __begin2, __end2, __pred, + __gnu_parallel::sequential_tag()); } + + // Public interface + template<typename _FIterator1, typename _FIterator2, + typename _BinaryPredicate> + inline _FIterator1 + search(_FIterator1 __begin1, _FIterator1 __end1, + _FIterator2 __begin2, _FIterator2 __end2, + _BinaryPredicate __pred) + { + return __search_switch(__begin1, __end1, __begin2, __end2, __pred, + std::__iterator_category(__begin1), + std::__iterator_category(__begin2)); + } +} // end namespace __parallel +} // end namespace std #endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */ diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h index bc01198..176ad79 100644 --- a/libstdc++-v3/include/precompiled/stdc++.h +++ b/libstdc++-v3/include/precompiled/stdc++.h @@ -75,7 +75,6 @@ #if __cplusplus >= 201703L #include <any> -#include <charconv> // #include <execution> #include <optional> #include <variant> diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 27354d9..ad36cda 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -69,7 +69,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Conversion to a pointer produces a null pointer. __attribute__((__always_inline__)) - constexpr operator _Tp*() const noexcept { return nullptr; } + constexpr explicit operator _Tp*() const noexcept { return nullptr; } }; using _Is_swappable = true_type; @@ -240,7 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION front() noexcept { __glibcxx_requires_nonempty(); - return _M_elems[0]; + return _M_elems[(size_type)0]; } [[__nodiscard__]] @@ -250,7 +250,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201402L __glibcxx_requires_nonempty(); #endif - return _M_elems[0]; + return _M_elems[(size_type)0]; } [[__nodiscard__]] @@ -274,12 +274,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]] _GLIBCXX17_CONSTEXPR pointer data() noexcept - { return _M_elems; } + { return static_cast<pointer>(_M_elems); } [[__nodiscard__]] _GLIBCXX17_CONSTEXPR const_pointer data() const noexcept - { return _M_elems; } + { return static_cast<const_pointer>(_M_elems); } }; #if __cpp_deduction_guides >= 201606 @@ -414,19 +414,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return std::move(std::get<_Int>(__arr)); } -#if __cplusplus > 201703L +#if __cplusplus >= 202002L && __cpp_generic_lambdas >= 201707L #define __cpp_lib_to_array 201907L - - template<bool _Move = false, typename _Tp, size_t... _Idx> - constexpr array<remove_cv_t<_Tp>, sizeof...(_Idx)> - __to_array(_Tp (&__a)[sizeof...(_Idx)], index_sequence<_Idx...>) - { - if constexpr (_Move) - return {{std::move(__a[_Idx])...}}; - else - return {{__a[_Idx]...}}; - } - template<typename _Tp, size_t _Nm> [[nodiscard]] constexpr array<remove_cv_t<_Tp>, _Nm> @@ -436,8 +425,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_assert(!is_array_v<_Tp>); static_assert(is_constructible_v<_Tp, _Tp&>); if constexpr (is_constructible_v<_Tp, _Tp&>) - return __to_array(__a, make_index_sequence<_Nm>{}); - __builtin_unreachable(); // FIXME: see PR c++/91388 + { + if constexpr (is_trivial_v<_Tp>) + { + array<remove_cv_t<_Tp>, _Nm> __arr; + if (!__is_constant_evaluated() && _Nm != 0) + __builtin_memcpy(__arr.data(), __a, sizeof(__a)); + else + for (size_t __i = 0; __i < _Nm; ++__i) + __arr._M_elems[__i] = __a[__i]; + return __arr; + } + else + return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) { + return array<remove_cv_t<_Tp>, _Nm>{{ __a[_Idx]... }}; + }(make_index_sequence<_Nm>{}); + } + else + __builtin_unreachable(); // FIXME: see PR c++/91388 } template<typename _Tp, size_t _Nm> @@ -449,8 +454,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_assert(!is_array_v<_Tp>); static_assert(is_move_constructible_v<_Tp>); if constexpr (is_move_constructible_v<_Tp>) - return __to_array<1>(__a, make_index_sequence<_Nm>{}); - __builtin_unreachable(); // FIXME: see PR c++/91388 + { + if constexpr (is_trivial_v<_Tp>) + { + array<remove_cv_t<_Tp>, _Nm> __arr; + if (!__is_constant_evaluated() && _Nm != 0) + __builtin_memcpy(__arr.data(), __a, sizeof(__a)); + else + for (size_t __i = 0; __i < _Nm; ++__i) + __arr._M_elems[__i] = __a[__i]; + return __arr; + } + else + return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) { + return array<remove_cv_t<_Tp>, _Nm>{{ std::move(__a[_Idx])... }}; + }(make_index_sequence<_Nm>{}); + } + else + __builtin_unreachable(); // FIXME: see PR c++/91388 } #endif // C++20 diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic index 96e87de..111df2a 100644 --- a/libstdc++-v3/include/std/atomic +++ b/libstdc++-v3/include/std/atomic @@ -1103,7 +1103,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// atomic_char32_t typedef atomic<char32_t> atomic_char32_t; -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 +#ifdef _GLIBCXX_USE_C99_STDINT // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2441. Exact-width atomic typedefs should be provided @@ -1130,7 +1130,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// atomic_uint64_t typedef atomic<uint64_t> atomic_uint64_t; - +#endif /// atomic_int_least8_t typedef atomic<int_least8_t> atomic_int_least8_t; @@ -1180,7 +1180,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// atomic_uint_fast64_t typedef atomic<uint_fast64_t> atomic_uint_fast64_t; -#endif /// atomic_intptr_t @@ -1195,13 +1194,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// atomic_ptrdiff_t typedef atomic<ptrdiff_t> atomic_ptrdiff_t; -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 /// atomic_intmax_t typedef atomic<intmax_t> atomic_intmax_t; /// atomic_uintmax_t typedef atomic<uintmax_t> atomic_uintmax_t; -#endif // Function definitions, atomic_flag operations. inline bool diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit index 0c58971..5eb4021 100644 --- a/libstdc++-v3/include/std/bit +++ b/libstdc++-v3/include/std/bit @@ -144,7 +144,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif - /// @cond undoc + /// @cond undocumented template<typename _Tp> constexpr _Tp @@ -374,7 +374,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define __cpp_lib_bitops 201907L - /// @cond undoc + /// @cond undocumented template<typename _Tp, typename _Up = _Tp> using _If_is_unsigned_integer = enable_if_t<__is_unsigned_integer<_Tp>::value, _Up>; diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index 7bfc9b79..660e8d2 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -2398,17 +2398,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return {}; } }; - // True if the maximum constructor argument can be represented in _Tp. - template<typename _Tp> - static constexpr bool __fits - = duration_values<typename _Duration::rep>::max() - <= duration_values<_Tp>::max(); - template<typename _Rep, typename _Period> requires (!treat_as_floating_point_v<_Rep>) && ratio_less_v<_Period, ratio<1, 1>> - && (ratio_greater_equal_v<_Period, ratio<1, 250>> - || __fits<unsigned char>) + && ratio_greater_equal_v<_Period, ratio<1, 250>> struct __subseconds<duration<_Rep, _Period>> { unsigned char _M_r{}; @@ -2421,8 +2414,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Rep, typename _Period> requires (!treat_as_floating_point_v<_Rep>) && ratio_less_v<_Period, ratio<1, 250>> - && (ratio_greater_equal_v<_Period, ratio<1, 4000000000>> - || __fits<uint_least32_t>) + && ratio_greater_equal_v<_Period, ratio<1, 4000000000>> struct __subseconds<duration<_Rep, _Period>> { uint_least32_t _M_r{}; diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex index 0f5f14c..f01a3af 100644 --- a/libstdc++-v3/include/std/complex +++ b/libstdc++-v3/include/std/complex @@ -2021,7 +2021,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); } -#if _GLIBCXX_USE_C99_COMPLEX_TR1 +#if _GLIBCXX_USE_C99_COMPLEX_ARC #if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) inline __complex__ _Float16 __complex_acos(__complex__ _Float16 __z) @@ -2177,7 +2177,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif #endif -#if _GLIBCXX_USE_C99_COMPLEX_TR1 +#if _GLIBCXX_USE_C99_COMPLEX_ARC inline __complex__ float __complex_acos(__complex__ float __z) { return __builtin_cacosf(__z); } @@ -2213,7 +2213,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return std::complex<_Tp>(__t.imag(), -__t.real()); } -#if _GLIBCXX_USE_C99_COMPLEX_TR1 +#if _GLIBCXX_USE_C99_COMPLEX_ARC inline __complex__ float __complex_asin(__complex__ float __z) { return __builtin_casinf(__z); } @@ -2257,7 +2257,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Tp(0.25) * log(__num / __den)); } -#if _GLIBCXX_USE_C99_COMPLEX_TR1 +#if _GLIBCXX_USE_C99_COMPLEX_ARC inline __complex__ float __complex_atan(__complex__ float __z) { return __builtin_catanf(__z); } @@ -2293,7 +2293,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0)))); } -#if _GLIBCXX_USE_C99_COMPLEX_TR1 +#if _GLIBCXX_USE_C99_COMPLEX_ARC inline __complex__ float __complex_acosh(__complex__ float __z) { return __builtin_cacoshf(__z); } @@ -2332,7 +2332,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return std::log(__t + __z); } -#if _GLIBCXX_USE_C99_COMPLEX_TR1 +#if _GLIBCXX_USE_C99_COMPLEX_ARC inline __complex__ float __complex_asinh(__complex__ float __z) { return __builtin_casinhf(__z); } @@ -2376,7 +2376,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); } -#if _GLIBCXX_USE_C99_COMPLEX_TR1 +#if _GLIBCXX_USE_C99_COMPLEX_ARC inline __complex__ float __complex_atanh(__complex__ float __z) { return __builtin_catanhf(__z); } @@ -2534,7 +2534,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __complex_proj(__z.__rep()); } #endif -#elif defined _GLIBCXX_USE_C99_MATH_TR1 +#elif defined _GLIBCXX_USE_C99_MATH_FUNCS inline complex<float> __complex_proj(const complex<float>& __z) { diff --git a/libstdc++-v3/include/std/expected b/libstdc++-v3/include/std/expected index 567a519..a635574 100644 --- a/libstdc++-v3/include/std/expected +++ b/libstdc++-v3/include/std/expected @@ -139,7 +139,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ inline constexpr unexpect_t unexpect{}; -/// @cond undoc +/// @cond undocumented namespace __expected { template<typename _Tp> @@ -154,8 +154,12 @@ namespace __expected template<typename _Fn, typename _Tp> using __result = remove_cvref_t<invoke_result_t<_Fn&&, _Tp&&>>; + template<typename _Fn, typename _Tp> + using __result_xform = remove_cv_t<invoke_result_t<_Fn&&, _Tp&&>>; template<typename _Fn> using __result0 = remove_cvref_t<invoke_result_t<_Fn&&>>; + template<typename _Fn> + using __result0_xform = remove_cv_t<invoke_result_t<_Fn&&>>; template<typename _Er> concept __can_be_unexpected @@ -250,7 +254,7 @@ namespace __expected template<typename _Er> unexpected(_Er) -> unexpected<_Er>; -/// @cond undoc +/// @cond undocumented namespace __expected { template<typename _Tp> @@ -732,7 +736,8 @@ namespace __expected { if (_M_has_value) [[likely]] return _M_val; - _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex)); + const auto& __unex = _M_unex; + _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(__unex)); } constexpr const _Tp&& @@ -740,8 +745,7 @@ namespace __expected { if (_M_has_value) [[likely]] return std::move(_M_val); - _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>( - std::move(_M_unex))); + _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex))); } constexpr _Tp&& @@ -749,8 +753,7 @@ namespace __expected { if (_M_has_value) [[likely]] return std::move(_M_val); - _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>( - std::move(_M_unex))); + _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex))); } constexpr const _Er& @@ -835,7 +838,7 @@ namespace __expected // monadic operations - template<typename _Fn> requires is_copy_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, _Er&> constexpr auto and_then(_Fn&& __f) & { @@ -844,12 +847,12 @@ namespace __expected static_assert(is_same_v<typename _Up::error_type, _Er>); if (has_value()) - return std::__invoke(std::forward<_Fn>(__f), value()); + return std::__invoke(std::forward<_Fn>(__f), _M_val); else - return _Up(unexpect, error()); + return _Up(unexpect, _M_unex); } - template<typename _Fn> requires is_copy_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, const _Er&> constexpr auto and_then(_Fn&& __f) const & { @@ -858,12 +861,12 @@ namespace __expected static_assert(is_same_v<typename _Up::error_type, _Er>); if (has_value()) - return std::__invoke(std::forward<_Fn>(__f), value()); + return std::__invoke(std::forward<_Fn>(__f), _M_val); else - return _Up(unexpect, error()); + return _Up(unexpect, _M_unex); } - template<typename _Fn> requires is_move_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, _Er> constexpr auto and_then(_Fn&& __f) && { @@ -872,13 +875,13 @@ namespace __expected static_assert(is_same_v<typename _Up::error_type, _Er>); if (has_value()) - return std::__invoke(std::forward<_Fn>(__f), std::move(value())); + return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val)); else - return _Up(unexpect, std::move(error())); + return _Up(unexpect, std::move(_M_unex)); } - template<typename _Fn> requires is_move_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, const _Er> constexpr auto and_then(_Fn&& __f) const && { @@ -887,12 +890,12 @@ namespace __expected static_assert(is_same_v<typename _Up::error_type, _Er>); if (has_value()) - return std::__invoke(std::forward<_Fn>(__f), std::move(value())); + return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val)); else - return _Up(unexpect, std::move(error())); + return _Up(unexpect, std::move(_M_unex)); } - template<typename _Fn> requires is_copy_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Tp, _Tp&> constexpr auto or_else(_Fn&& __f) & { @@ -901,12 +904,12 @@ namespace __expected static_assert(is_same_v<typename _Gr::value_type, _Tp>); if (has_value()) - return _Gr(in_place, value()); + return _Gr(in_place, _M_val); else - return std::__invoke(std::forward<_Fn>(__f), error()); + return std::__invoke(std::forward<_Fn>(__f), _M_unex); } - template<typename _Fn> requires is_copy_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&> constexpr auto or_else(_Fn&& __f) const & { @@ -915,13 +918,13 @@ namespace __expected static_assert(is_same_v<typename _Gr::value_type, _Tp>); if (has_value()) - return _Gr(in_place, value()); + return _Gr(in_place, _M_val); else - return std::__invoke(std::forward<_Fn>(__f), error()); + return std::__invoke(std::forward<_Fn>(__f), _M_unex); } - template<typename _Fn> requires is_move_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Tp, _Tp> constexpr auto or_else(_Fn&& __f) && { @@ -930,12 +933,12 @@ namespace __expected static_assert(is_same_v<typename _Gr::value_type, _Tp>); if (has_value()) - return _Gr(in_place, std::move(value())); + return _Gr(in_place, std::move(_M_val)); else - return std::__invoke(std::forward<_Fn>(__f), std::move(error())); + return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex)); } - template<typename _Fn> requires is_move_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Tp, const _Tp> constexpr auto or_else(_Fn&& __f) const && { @@ -944,16 +947,16 @@ namespace __expected static_assert(is_same_v<typename _Gr::value_type, _Tp>); if (has_value()) - return _Gr(in_place, std::move(value())); + return _Gr(in_place, std::move(_M_val)); else - return std::__invoke(std::forward<_Fn>(__f), std::move(error())); + return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex)); } - template<typename _Fn> requires is_copy_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, _Er&> constexpr auto transform(_Fn&& __f) & { - using _Up = __expected::__result<_Fn, _Tp&>; + using _Up = __expected::__result_xform<_Fn, _Tp&>; using _Res = expected<_Up, _Er>; if (has_value()) @@ -962,14 +965,14 @@ namespace __expected _M_val); }); else - return _Res(unexpect, std::move(error())); + return _Res(unexpect, _M_unex); } - template<typename _Fn> requires is_copy_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, const _Er&> constexpr auto transform(_Fn&& __f) const & { - using _Up = __expected::__result<_Fn, const _Tp&>; + using _Up = __expected::__result_xform<_Fn, const _Tp&>; using _Res = expected<_Up, _Er>; if (has_value()) @@ -978,14 +981,14 @@ namespace __expected _M_val); }); else - return _Res(unexpect, std::move(error())); + return _Res(unexpect, _M_unex); } - template<typename _Fn> requires is_move_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, _Er> constexpr auto transform(_Fn&& __f) && { - using _Up = __expected::__result<_Fn, _Tp>; + using _Up = __expected::__result_xform<_Fn, _Tp>; using _Res = expected<_Up, _Er>; if (has_value()) @@ -994,14 +997,14 @@ namespace __expected std::move(_M_val)); }); else - return _Res(unexpect, std::move(error())); + return _Res(unexpect, std::move(_M_unex)); } - template<typename _Fn> requires is_move_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, const _Er> constexpr auto transform(_Fn&& __f) const && { - using _Up = __expected::__result<_Fn, const _Tp>; + using _Up = __expected::__result_xform<_Fn, const _Tp>; using _Res = expected<_Up, _Er>; if (has_value()) @@ -1010,18 +1013,18 @@ namespace __expected std::move(_M_val)); }); else - return _Res(unexpect, std::move(error())); + return _Res(unexpect, std::move(_M_unex)); } - template<typename _Fn> requires is_copy_constructible_v<_Tp> + template<typename _Fn> requires is_constructible_v<_Tp, _Tp&> constexpr auto transform_error(_Fn&& __f) & { - using _Gr = __expected::__result<_Fn, _Er&>; + using _Gr = __expected::__result_xform<_Fn, _Er&>; using _Res = expected<_Tp, _Gr>; if (has_value()) - return _Res(in_place, value()); + return _Res(in_place, _M_val); else return _Res(__unexpect_inv{}, [&]() { return std::__invoke(std::forward<_Fn>(__f), @@ -1029,15 +1032,15 @@ namespace __expected }); } - template<typename _Fn> requires is_copy_constructible_v<_Tp> + template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&> constexpr auto transform_error(_Fn&& __f) const & { - using _Gr = __expected::__result<_Fn, const _Er&>; + using _Gr = __expected::__result_xform<_Fn, const _Er&>; using _Res = expected<_Tp, _Gr>; if (has_value()) - return _Res(in_place, value()); + return _Res(in_place, _M_val); else return _Res(__unexpect_inv{}, [&]() { return std::__invoke(std::forward<_Fn>(__f), @@ -1045,15 +1048,15 @@ namespace __expected }); } - template<typename _Fn> requires is_move_constructible_v<_Tp> + template<typename _Fn> requires is_constructible_v<_Tp, _Tp> constexpr auto transform_error(_Fn&& __f) && { - using _Gr = __expected::__result<_Fn, _Er&&>; + using _Gr = __expected::__result_xform<_Fn, _Er&&>; using _Res = expected<_Tp, _Gr>; if (has_value()) - return _Res(in_place, std::move(value())); + return _Res(in_place, std::move(_M_val)); else return _Res(__unexpect_inv{}, [&]() { return std::__invoke(std::forward<_Fn>(__f), @@ -1061,15 +1064,15 @@ namespace __expected }); } - template<typename _Fn> requires is_move_constructible_v<_Tp> + template<typename _Fn> requires is_constructible_v<_Tp, const _Tp> constexpr auto transform_error(_Fn&& __f) const && { - using _Gr = __expected::__result<_Fn, const _Er&&>; + using _Gr = __expected::__result_xform<_Fn, const _Er&&>; using _Res = expected<_Tp, _Gr>; if (has_value()) - return _Res(in_place, std::move(value())); + return _Res(in_place, std::move(_M_val)); else return _Res(__unexpect_inv{}, [&]() { return std::__invoke(std::forward<_Fn>(__f), @@ -1514,7 +1517,7 @@ namespace __expected // monadic operations - template<typename _Fn> requires is_copy_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, _Er&> constexpr auto and_then(_Fn&& __f) & { @@ -1525,10 +1528,10 @@ namespace __expected if (has_value()) return std::__invoke(std::forward<_Fn>(__f)); else - return _Up(unexpect, error()); + return _Up(unexpect, _M_unex); } - template<typename _Fn> requires is_copy_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, const _Er&> constexpr auto and_then(_Fn&& __f) const & { @@ -1539,10 +1542,10 @@ namespace __expected if (has_value()) return std::__invoke(std::forward<_Fn>(__f)); else - return _Up(unexpect, error()); + return _Up(unexpect, _M_unex); } - template<typename _Fn> requires is_move_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, _Er> constexpr auto and_then(_Fn&& __f) && { @@ -1553,10 +1556,10 @@ namespace __expected if (has_value()) return std::__invoke(std::forward<_Fn>(__f)); else - return _Up(unexpect, std::move(error())); + return _Up(unexpect, std::move(_M_unex)); } - template<typename _Fn> requires is_move_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, const _Er> constexpr auto and_then(_Fn&& __f) const && { @@ -1567,7 +1570,7 @@ namespace __expected if (has_value()) return std::__invoke(std::forward<_Fn>(__f)); else - return _Up(unexpect, std::move(error())); + return _Up(unexpect, std::move(_M_unex)); } template<typename _Fn> @@ -1581,7 +1584,7 @@ namespace __expected if (has_value()) return _Gr(); else - return std::__invoke(std::forward<_Fn>(__f), error()); + return std::__invoke(std::forward<_Fn>(__f), _M_unex); } template<typename _Fn> @@ -1595,7 +1598,7 @@ namespace __expected if (has_value()) return _Gr(); else - return std::__invoke(std::forward<_Fn>(__f), error()); + return std::__invoke(std::forward<_Fn>(__f), _M_unex); } template<typename _Fn> @@ -1609,7 +1612,7 @@ namespace __expected if (has_value()) return _Gr(); else - return std::__invoke(std::forward<_Fn>(__f), std::move(error())); + return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex)); } template<typename _Fn> @@ -1623,66 +1626,66 @@ namespace __expected if (has_value()) return _Gr(); else - return std::__invoke(std::forward<_Fn>(__f), std::move(error())); + return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex)); } - template<typename _Fn> requires is_copy_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, _Er&> constexpr auto transform(_Fn&& __f) & { - using _Up = __expected::__result0<_Fn>; + using _Up = __expected::__result0_xform<_Fn>; using _Res = expected<_Up, _Er>; if (has_value()) return _Res(__in_place_inv{}, std::forward<_Fn>(__f)); else - return _Res(unexpect, error()); + return _Res(unexpect, _M_unex); } - template<typename _Fn> requires is_copy_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, const _Er&> constexpr auto transform(_Fn&& __f) const & { - using _Up = __expected::__result0<_Fn>; + using _Up = __expected::__result0_xform<_Fn>; using _Res = expected<_Up, _Er>; if (has_value()) return _Res(__in_place_inv{}, std::forward<_Fn>(__f)); else - return _Res(unexpect, error()); + return _Res(unexpect, _M_unex); } - template<typename _Fn> requires is_move_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, _Er> constexpr auto transform(_Fn&& __f) && { - using _Up = __expected::__result0<_Fn>; + using _Up = __expected::__result0_xform<_Fn>; using _Res = expected<_Up, _Er>; if (has_value()) return _Res(__in_place_inv{}, std::forward<_Fn>(__f)); else - return _Res(unexpect, std::move(error())); + return _Res(unexpect, std::move(_M_unex)); } - template<typename _Fn> requires is_move_constructible_v<_Er> + template<typename _Fn> requires is_constructible_v<_Er, const _Er> constexpr auto transform(_Fn&& __f) const && { - using _Up = __expected::__result0<_Fn>; + using _Up = __expected::__result0_xform<_Fn>; using _Res = expected<_Up, _Er>; if (has_value()) return _Res(__in_place_inv{}, std::forward<_Fn>(__f)); else - return _Res(unexpect, std::move(error())); + return _Res(unexpect, std::move(_M_unex)); } template<typename _Fn> constexpr auto transform_error(_Fn&& __f) & { - using _Gr = __expected::__result<_Fn, _Er&>; + using _Gr = __expected::__result_xform<_Fn, _Er&>; using _Res = expected<_Tp, _Gr>; if (has_value()) @@ -1698,7 +1701,7 @@ namespace __expected constexpr auto transform_error(_Fn&& __f) const & { - using _Gr = __expected::__result<_Fn, const _Er&>; + using _Gr = __expected::__result_xform<_Fn, const _Er&>; using _Res = expected<_Tp, _Gr>; if (has_value()) @@ -1714,7 +1717,7 @@ namespace __expected constexpr auto transform_error(_Fn&& __f) && { - using _Gr = __expected::__result<_Fn, _Er&&>; + using _Gr = __expected::__result_xform<_Fn, _Er&&>; using _Res = expected<_Tp, _Gr>; if (has_value()) @@ -1730,7 +1733,7 @@ namespace __expected constexpr auto transform_error(_Fn&& __f) const && { - using _Gr = __expected::__result<_Fn, const _Er&&>; + using _Gr = __expected::__result_xform<_Fn, const _Er&&>; using _Res = expected<_Tp, _Gr>; if (has_value()) diff --git a/libstdc++-v3/include/std/filesystem b/libstdc++-v3/include/std/filesystem index eff2b93..d46e842 100644 --- a/libstdc++-v3/include/std/filesystem +++ b/libstdc++-v3/include/std/filesystem @@ -41,6 +41,8 @@ * * Utilities for performing operations on file systems and their components, * such as paths, regular files, and directories. + * + * @since C++17 */ #include <bits/fs_fwd.h> diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index 72b6b45..96a1e62 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -137,7 +137,7 @@ namespace __format template<typename _Tp, typename _CharT = char> struct formatter { - formatter() = delete; + formatter() = delete; // No std::formatter specialization for this type. formatter(const formatter&) = delete; formatter& operator=(const formatter&) = delete; }; @@ -185,7 +185,7 @@ namespace __format __failed_to_parse_format_spec() { __throw_format_error("format error: failed to parse format-spec"); } } // namespace __format -/// @endcond + /// @endcond // [format.parse.ctx], class template basic_format_parse_context template<typename _CharT> class basic_format_parse_context; @@ -830,7 +830,7 @@ namespace __format { if (_M_spec._M_type == _Pres_esc) { - // TODO: C++20 escaped string presentation + // TODO: C++23 escaped string presentation } if (_M_spec._M_width_kind == _WP_none @@ -2081,19 +2081,31 @@ namespace __format if (__finished()) return __first; - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // P2519R3 Formatting pointers +// _GLIBCXX_RESOLVE_LIB_DEFECTS +// P2510R3 Formatting pointers +#define _GLIBCXX_P2518R3 (__cplusplus > 202302L || ! defined __STRICT_ANSI__) + +#if _GLIBCXX_P2518R3 __first = __spec._M_parse_zero_fill(__first, __last); if (__finished()) return __first; +#endif __first = __spec._M_parse_width(__first, __last, __pc); - if (__first != __last && (*__first == 'p' || *__first == 'P')) + if (__first != __last) { - if (*__first == 'P') + if (*__first == 'p') + ++__first; +#if _GLIBCXX_P2518R3 + else if (*__first == 'P') + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // P2510R3 Formatting pointers __spec._M_type = __format::_Pres_P; - ++__first; + ++__first; + } +#endif } if (__finished()) @@ -2110,9 +2122,21 @@ namespace __format char __buf[2 + sizeof(__v) * 2]; auto [__ptr, __ec] = std::to_chars(__buf + 2, std::end(__buf), __u, 16); - const int __n = __ptr - __buf; + int __n = __ptr - __buf; __buf[0] = '0'; __buf[1] = 'x'; +#if _GLIBCXX_P2518R3 + if (_M_spec._M_type == __format::_Pres_P) + { + __buf[1] = 'X'; + for (auto __p = __buf + 2; __p != __ptr; ++__p) +#if __has_builtin(__builtin_toupper) + *__p = __builtin_toupper(*__p); +#else + *__p = std::toupper(*__p); +#endif + } +#endif basic_string_view<_CharT> __str; if constexpr (is_same_v<_CharT, char>) @@ -2126,6 +2150,24 @@ namespace __format __str = wstring_view(__p, __n); } +#if _GLIBCXX_P2518R3 + if (_M_spec._M_zero_fill) + { + size_t __width = _M_spec._M_get_width(__fc); + if (__width <= __str.size()) + return __format::__write(__fc.out(), __str); + + auto __out = __fc.out(); + // Write "0x" or "0X" prefix before zero-filling. + __out = __format::__write(std::move(__out), __str.substr(0, 2)); + __str.remove_prefix(2); + size_t __nfill = __width - __n; + return __format::__write_padded(std::move(__out), __str, + __format::_Align_right, + __nfill, _CharT('0')); + } +#endif + return __format::__write_padded_as_spec(__str, __n, __fc, _M_spec, __format::_Align_right); } @@ -3560,6 +3602,10 @@ namespace __format template<typename _CharT, typename... _Args> class _Checking_scanner : public _Scanner<_CharT> { + static_assert( + (is_default_constructible_v<formatter<_Args, _CharT>> && ...), + "std::formatter must be specialized for each type being formatted"); + public: constexpr _Checking_scanner(basic_string_view<_CharT> __str) @@ -3581,17 +3627,17 @@ namespace __format __builtin_unreachable(); } - template<typename _Head, typename... _Tail> + template<typename _Tp, typename... _OtherArgs> constexpr void _M_parse_format_spec(size_t __id) { if (__id == 0) { - formatter<_Head, _CharT> __f; + formatter<_Tp, _CharT> __f; this->_M_pc.advance_to(__f.parse(this->_M_pc)); } - else if constexpr (sizeof...(_Tail) != 0) - _M_parse_format_spec<_Tail...>(__id - 1); + else if constexpr (sizeof...(_OtherArgs) != 0) + _M_parse_format_spec<_OtherArgs...>(__id - 1); else __builtin_unreachable(); } @@ -3866,7 +3912,7 @@ namespace __format }; #endif } // namespace __format -/// @@endcond +/// @endcond template<typename... _Args> [[nodiscard]] diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index c7c6a5a..4a4b8b2 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -64,7 +64,7 @@ # include <vector> # include <array> # endif -# include <bits/stl_algo.h> // std::search +# include <bits/stl_algobase.h> // std::search #endif #if __cplusplus >= 202002L # include <bits/ranges_cmp.h> // std::identity, ranges::equal_to etc. diff --git a/libstdc++-v3/include/std/iomanip b/libstdc++-v3/include/std/iomanip index a5366655..eb82fc5 100644 --- a/libstdc++-v3/include/std/iomanip +++ b/libstdc++-v3/include/std/iomanip @@ -168,6 +168,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return { __c }; } template<typename _CharT, typename _Traits> + __attribute__((__deprecated__("'std::setfill' should only be used with " + "output streams"))) inline basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, _Setfill<_CharT> __f) { @@ -457,6 +459,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __string String to quote. * @param __delim Character to quote string with. * @param __escape Escape character to escape itself or quote character. + * @since C++14 */ template<typename _CharT> inline auto diff --git a/libstdc++-v3/include/std/iostream b/libstdc++-v3/include/std/iostream index 7653002..cfd124d 100644 --- a/libstdc++-v3/include/std/iostream +++ b/libstdc++-v3/include/std/iostream @@ -77,6 +77,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // in the compiled library instead (src/c++98/globals_io.cc). #if !__has_attribute(__init_priority__) static ios_base::Init __ioinit; +#elif defined(_GLIBCXX_SYMVER_GNU) + __extension__ __asm (".globl _ZSt21ios_base_library_initv"); #endif _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits index 8bafd6f..52b19ef 100644 --- a/libstdc++-v3/include/std/limits +++ b/libstdc++-v3/include/std/limits @@ -2071,7 +2071,145 @@ __glibcxx_float_n(128) }; #endif +#endif // C++23 + +#if defined(_GLIBCXX_USE_FLOAT128) +// We either need Q literal suffixes, or IEEE double. +#if ! defined(__STRICT_ANSI__) || defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64) + __extension__ + template<> + struct numeric_limits<__float128> + { + static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; + + static _GLIBCXX_CONSTEXPR __float128 + min() _GLIBCXX_USE_NOEXCEPT + { +#ifdef __STRICT_ANSI__ + // 0x1.0p-30 * 0x1.0p-16352 + return double(9.3132257461547852e-10) * _S_1pm16352(); +#else + return __extension__ 0x1.0p-16382Q; +#endif + } + + static _GLIBCXX_CONSTEXPR __float128 + max() _GLIBCXX_USE_NOEXCEPT + { +#ifdef __STRICT_ANSI__ + // (0x1.fffffffffffffp+127 + 0x0.fffffffffffffp+75 + 0x0.ffp+23) + // * 0x1.0p16256 + return (__float128(double(3.4028236692093843e+38)) + + double(3.7778931862957153e+22) + double(8.35584e+6)) + * _S_1p16256(); +#else + return __extension__ 0x1.ffffffffffffffffffffffffffffp+16383Q; +#endif + } + + static _GLIBCXX_CONSTEXPR __float128 + lowest() _GLIBCXX_USE_NOEXCEPT + { return -max(); } + + static _GLIBCXX_USE_CONSTEXPR int digits = 113; + static _GLIBCXX_USE_CONSTEXPR int digits10 = 33; +#if __cplusplus >= 201103L + static constexpr int max_digits10 = 35; +#endif + static _GLIBCXX_USE_CONSTEXPR bool is_signed = true; + static _GLIBCXX_USE_CONSTEXPR bool is_integer = false; + static _GLIBCXX_USE_CONSTEXPR bool is_exact = false; + static _GLIBCXX_USE_CONSTEXPR int radix = __FLT_RADIX__; + + static _GLIBCXX_CONSTEXPR __float128 + epsilon() _GLIBCXX_USE_NOEXCEPT + { return double(1.9259299443872359e-34); } + + static _GLIBCXX_CONSTEXPR __float128 + round_error() _GLIBCXX_USE_NOEXCEPT { return 0.5; } + + static _GLIBCXX_USE_CONSTEXPR int min_exponent = -16381; + static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = -4931; + static _GLIBCXX_USE_CONSTEXPR int max_exponent = 16384; + static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 4932; + + static _GLIBCXX_USE_CONSTEXPR bool has_infinity = 1; + static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = 1; +#if __has_builtin(__builtin_nansq) \ + || (__has_builtin(__builtin_bit_cast) && __has_builtin(__builtin_nansf128)) + static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = true; +#else + static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; +#endif + static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm + = denorm_present; + static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; + + static _GLIBCXX_CONSTEXPR __float128 + infinity() _GLIBCXX_USE_NOEXCEPT + { return __builtin_huge_val(); } + + static _GLIBCXX_CONSTEXPR __float128 + quiet_NaN() _GLIBCXX_USE_NOEXCEPT + { return __builtin_nan(""); } + + static _GLIBCXX_CONSTEXPR __float128 + signaling_NaN() _GLIBCXX_USE_NOEXCEPT + { +#if __has_builtin(__builtin_nansq) + return __builtin_nansq(""); +#elif __has_builtin(__builtin_bit_cast) && __has_builtin(__builtin_nansf128) + return __builtin_bit_cast(__float128, __builtin_nansf128("")); +#else + return quiet_NaN(); +#endif + } + + static _GLIBCXX_CONSTEXPR __float128 + denorm_min() _GLIBCXX_USE_NOEXCEPT + { +#if defined(__STRICT_ANSI__) || defined(__INTEL_COMPILER) + // 0x1.0p-142 * 0x1.0p-16352 + return double(1.7936620343357659e-43) * _S_1pm16352(); +#else + return __extension__ 0x1.0p-16494Q; #endif + } + + static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = has_signaling_NaN; + static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; + static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; + + static _GLIBCXX_USE_CONSTEXPR bool traps = false; + static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; + static _GLIBCXX_USE_CONSTEXPR float_round_style round_style + = round_to_nearest; + +#if defined(__STRICT_ANSI__) || defined(__INTEL_COMPILER) + private: + static _GLIBCXX_CONSTEXPR __float128 + _S_4p(__float128 __v) _GLIBCXX_USE_NOEXCEPT + { return __v * __v * __v * __v; } + + static _GLIBCXX_CONSTEXPR __float128 + _S_1pm4088() _GLIBCXX_USE_NOEXCEPT + { return _S_4p(/* 0x1.0p-1022 */ double(2.2250738585072014e-308)); } + + static _GLIBCXX_CONSTEXPR __float128 + _S_1pm16352() _GLIBCXX_USE_NOEXCEPT + { return _S_4p(_S_1pm4088()); } + + static _GLIBCXX_CONSTEXPR __float128 + _S_1p4064() _GLIBCXX_USE_NOEXCEPT + { return _S_4p(/* 0x1.0p+1016 */ double(7.0222388080559215e+305)); } + + static _GLIBCXX_CONSTEXPR __float128 + _S_1p16256() _GLIBCXX_USE_NOEXCEPT + { return _S_4p(_S_1p4064()); } +#endif + }; +#endif // !__STRICT_ANSI__ || DOUBLE_IS_IEEE_BINARY64 +#endif // _GLIBCXX_USE_FLOAT128 _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory index 341f985..85c36d6 100644 --- a/libstdc++-v3/include/std/memory +++ b/libstdc++-v3/include/std/memory @@ -91,6 +91,12 @@ # include <bits/uses_allocator_args.h> #endif +/* As a hack, we declare __cpp_lib_atomic_value_initialization here even though + we don't include the bit that actually declares it, for consistency. */ +#if !defined(__cpp_lib_atomic_value_initialization) && __cplusplus >= 202002L +# define __cpp_lib_atomic_value_initialization 201911L +#endif + #if __cplusplus >= 201103L && __cplusplus <= 202002L && _GLIBCXX_HOSTED namespace std _GLIBCXX_VISIBILITY(default) { diff --git a/libstdc++-v3/include/std/memory_resource b/libstdc++-v3/include/std/memory_resource index 0085926..fdfc23c 100644 --- a/libstdc++-v3/include/std/memory_resource +++ b/libstdc++-v3/include/std/memory_resource @@ -24,6 +24,9 @@ /** @file include/memory_resource * This is a Standard C++ Library header. + * + * This header declares the @ref pmr (std::pmr) memory resources. + * @ingroup pmr */ #ifndef _GLIBCXX_MEMORY_RESOURCE @@ -35,6 +38,25 @@ #if __cplusplus >= 201703L +/** + * @defgroup pmr Polymorphic memory resources + * + * @anchor pmr + * @ingroup memory + * @since C++17 + * + * Memory resources are classes that implement the `std::pmr::memory_resource` + * interface for allocating and deallocating memory. Unlike traditional C++ + * allocators, memory resources are not value types and are used via pointers + * to the abstract base class. They are only responsible for allocating and + * deallocating, not for construction and destruction of objects. As a result, + * memory resources just allocate raw memory as type `void*` and are not + * templates that allocate/deallocate and construct/destroy a specific type. + * + * The class template `std::pmr::polymorphic_allocator` is an allocator that + * uses a memory resource for its allocations. + */ + #include <bits/memory_resource.h> #include <vector> // vector #include <shared_mutex> // shared_mutex @@ -63,6 +85,11 @@ namespace pmr // Global memory resources /// A pmr::memory_resource that uses `new` to allocate memory + /** + * @ingroup pmr + * @headerfile memory_resource + * @since C++17 + */ [[nodiscard, __gnu__::__returns_nonnull__, __gnu__::__const__]] memory_resource* new_delete_resource() noexcept; @@ -91,6 +118,11 @@ namespace pmr class monotonic_buffer_resource; /// Parameters for tuning a pool resource's behaviour. + /** + * @ingroup pmr + * @headerfile memory_resource + * @since C++17 + */ struct pool_options { /** @brief Upper limit on number of blocks in a chunk. @@ -152,6 +184,11 @@ namespace pmr #ifdef _GLIBCXX_HAS_GTHREADS /// A thread-safe memory resource that manages pools of fixed-size blocks. + /** + * @ingroup pmr + * @headerfile memory_resource + * @since C++17 + */ class synchronized_pool_resource : public memory_resource { public: @@ -218,6 +255,11 @@ namespace pmr #endif /// A non-thread-safe memory resource that manages pools of fixed-size blocks. + /** + * @ingroup pmr + * @headerfile memory_resource + * @since C++17 + */ class unsynchronized_pool_resource : public memory_resource { public: @@ -275,6 +317,27 @@ namespace pmr _Pool* _M_pools = nullptr; }; + /// A memory resource that allocates from a fixed-size buffer. + /** + * The main feature of a `pmr::monotonic_buffer_resource` is that its + * `do_deallocate` does nothing. This makes it very fast because there is no + * need to manage a free list, and every allocation simply returns a new + * block of memory, rather than searching for a suitably-sized free block. + * Because deallocating is a no-op, the amount of memory used by the resource + * only grows until `release()` (or the destructor) is called to return all + * memory to upstream. + * + * A `monotonic_buffer_resource` can be initialized with a buffer that + * will be used to satisfy all allocation requests, until the buffer is full. + * After that a new buffer will be allocated from the upstream resource. + * By using a stack buffer and `pmr::null_memory_resource()` as the upstream + * you can get a memory resource that only uses the stack and never + * dynamically allocates. + * + * @ingroup pmr + * @headerfile memory_resource + * @since C++17 + */ class monotonic_buffer_resource : public memory_resource { public: diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex index 7942038..2b0059f 100644 --- a/libstdc++-v3/include/std/mutex +++ b/libstdc++-v3/include/std/mutex @@ -37,11 +37,13 @@ # include <bits/c++0x_warning.h> #else -#include <tuple> -#include <exception> -#include <type_traits> -#include <bits/chrono.h> -#include <bits/error_constants.h> +#include <tuple> // std::tuple +#include <type_traits> // is_same_v +#include <errno.h> // EAGAIN, EDEADLK +#include <bits/chrono.h> // duration, time_point, is_clock_v +#include <bits/functexcept.h> // __throw_system_error +#include <bits/invoke.h> // __invoke +#include <bits/move.h> // std::forward #include <bits/std_mutex.h> #include <bits/unique_lock.h> #if ! _GTHREAD_USE_MUTEX_TIMEDLOCK diff --git a/libstdc++-v3/include/std/numbers b/libstdc++-v3/include/std/numbers index d9d202f..d7d9e81 100644 --- a/libstdc++-v3/include/std/numbers +++ b/libstdc++-v3/include/std/numbers @@ -49,7 +49,7 @@ namespace numbers { #define __cpp_lib_math_constants 201907L - /// @cond undoc + /// @cond undocumented template<typename _Tp> using _Enable_if_floating = enable_if_t<is_floating_point_v<_Tp>, _Tp>; /// @endcond diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional index 62ff87a..bcac152 100644 --- a/libstdc++-v3/include/std/optional +++ b/libstdc++-v3/include/std/optional @@ -718,7 +718,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>); static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>); - static_assert(!is_reference_v<_Tp>); + static_assert(is_object_v<_Tp> && !is_array_v<_Tp>); private: using _Base = _Optional_base<_Tp>; @@ -1100,7 +1100,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr auto transform(_Fn&& __f) & { - using _Up = invoke_result_t<_Fn, _Tp&>; + using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp&>>; if (has_value()) return optional<_Up>(_Optional_func<_Fn>{__f}, **this); else @@ -1111,7 +1111,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr auto transform(_Fn&& __f) const & { - using _Up = invoke_result_t<_Fn, const _Tp&>; + using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp&>>; if (has_value()) return optional<_Up>(_Optional_func<_Fn>{__f}, **this); else @@ -1122,7 +1122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr auto transform(_Fn&& __f) && { - using _Up = invoke_result_t<_Fn, _Tp>; + using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp>>; if (has_value()) return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(**this)); else @@ -1133,7 +1133,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr auto transform(_Fn&& __f) const && { - using _Up = invoke_result_t<_Fn, const _Tp>; + using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp>>; if (has_value()) return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(**this)); else diff --git a/libstdc++-v3/include/std/random b/libstdc++-v3/include/std/random index e6591bc..a0785a4 100644 --- a/libstdc++-v3/include/std/random +++ b/libstdc++-v3/include/std/random @@ -38,22 +38,17 @@ #else #include <cmath> +#include <cstdint> // For uint_fast32_t, uint_fast64_t, uint_least32_t #include <cstdlib> #include <string> #include <iosfwd> #include <limits> #include <debug/debug.h> #include <type_traits> - -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - -#include <cstdint> // For uint_fast32_t, uint_fast64_t, uint_least32_t #include <bits/random.h> #include <bits/opt_random.h> #include <bits/random.tcc> -#endif // _GLIBCXX_USE_C99_STDINT_TR1 - #endif // C++11 #endif // _GLIBCXX_RANDOM diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index b230ebe..c4d4d85 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -1122,6 +1122,14 @@ namespace views::__adaptor }; } // namespace views::__adaptor +#if __cplusplus > 202002L + template<typename _Derived> + requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> + class range_adaptor_closure + : public views::__adaptor::_RangeAdaptorClosure + { }; +#endif + template<range _Range> requires is_object_v<_Range> class ref_view : public view_interface<ref_view<_Range>> { @@ -3209,7 +3217,8 @@ namespace views::__adaptor _OuterIter(_OuterIter<!_Const> __i) requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> - : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)) + : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)), + _M_trailing_empty(__i._M_trailing_empty) { } constexpr value_type @@ -6742,8 +6751,8 @@ namespace views::__adaptor _M_find_next(iterator_t<_Vp> __current) { __glibcxx_assert(_M_pred.has_value()); - auto __pred = [this]<typename _Tp>(_Tp&& __x, _Tp&& __y) { - return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Tp>(__y))); + auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) { + return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y))); }; auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred); return ranges::next(__it, 1, ranges::end(_M_base)); @@ -6753,8 +6762,8 @@ namespace views::__adaptor _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp> { __glibcxx_assert(_M_pred.has_value()); - auto __pred = [this]<typename _Tp>(_Tp&& __x, _Tp&& __y) { - return !bool((*_M_pred)(std::forward<_Tp>(__y), std::forward<_Tp>(__x))); + auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) { + return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x))); }; auto __rbegin = std::make_reverse_iterator(__current); auto __rend = std::make_reverse_iterator(ranges::begin(_M_base)); @@ -8625,6 +8634,415 @@ namespace views::__adaptor inline constexpr _AsRvalue as_rvalue; } + +#define __cpp_lib_ranges_enumerate 202302L + + namespace __detail + { + template<typename _Range> + concept __range_with_movable_reference = input_range<_Range> + && move_constructible<range_reference_t<_Range>> + && move_constructible<range_rvalue_reference_t<_Range>>; + } + + template<view _Vp> + requires __detail::__range_with_movable_reference<_Vp> + class enumerate_view : public view_interface<enumerate_view<_Vp>> + { + _Vp _M_base = _Vp(); + + template<bool _Const> class _Iterator; + template<bool _Const> class _Sentinel; + + public: + enumerate_view() requires default_initializable<_Vp> = default; + + constexpr explicit + enumerate_view(_Vp __base) + : _M_base(std::move(__base)) + { } + + constexpr auto + begin() requires (!__detail::__simple_view<_Vp>) + { return _Iterator<false>(ranges::begin(_M_base), 0); } + + constexpr auto + begin() const requires __detail::__range_with_movable_reference<const _Vp> + { return _Iterator<true>(ranges::begin(_M_base), 0); } + + constexpr auto + end() requires (!__detail::__simple_view<_Vp>) + { + if constexpr (common_range<_Vp> && sized_range<_Vp>) + return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base)); + else + return _Sentinel<false>(ranges::end(_M_base)); + } + + constexpr auto + end() const requires __detail::__range_with_movable_reference<const _Vp> + { + if constexpr (common_range<const _Vp> && sized_range<const _Vp>) + return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base)); + else + return _Sentinel<true>(ranges::end(_M_base)); + } + + constexpr auto + size() requires sized_range<_Vp> + { return ranges::size(_M_base); } + + constexpr auto + size() const requires sized_range<const _Vp> + { return ranges::size(_M_base); } + + constexpr _Vp + base() const & requires copy_constructible<_Vp> + { return _M_base; } + + constexpr _Vp + base() && + { return std::move(_M_base); } + }; + + template<typename _Range> + enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>; + + template<typename _Tp> + inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>> + = enable_borrowed_range<_Tp>; + + template<view _Vp> + requires __detail::__range_with_movable_reference<_Vp> + template<bool _Const> + class enumerate_view<_Vp>::_Iterator + { + using _Base = __maybe_const_t<_Const, _Vp>; + + static auto + _S_iter_concept() + { + if constexpr (random_access_range<_Base>) + return random_access_iterator_tag{}; + else if constexpr (bidirectional_range<_Base>) + return bidirectional_iterator_tag{}; + else if constexpr (forward_range<_Base>) + return forward_iterator_tag{}; + else + return input_iterator_tag{}; + } + + friend enumerate_view; + + public: + using iterator_category = input_iterator_tag; + using iterator_concept = decltype(_S_iter_concept()); + using difference_type = range_difference_t<_Base>; + using value_type = tuple<difference_type, range_value_t<_Base>>; + + private: + using __reference_type = tuple<difference_type, range_reference_t<_Base>>; + + iterator_t<_Base> _M_current = iterator_t<_Base>(); + difference_type _M_pos = 0; + + constexpr explicit + _Iterator(iterator_t<_Base> __current, difference_type __pos) + : _M_current(std::move(__current)), _M_pos(__pos) + { } + + public: + _Iterator() requires default_initializable<iterator_t<_Base>> = default; + + constexpr + _Iterator(_Iterator<!_Const> __i) + requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> + : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos) + { } + + constexpr const iterator_t<_Base> & + base() const & noexcept + { return _M_current; } + + constexpr iterator_t<_Base> + base() && + { return std::move(_M_current); } + + constexpr difference_type + index() const noexcept + { return _M_pos; } + + constexpr auto + operator*() const + { return __reference_type(_M_pos, *_M_current); } + + constexpr _Iterator& + operator++() + { + ++_M_current; + ++_M_pos; + return *this; + } + + constexpr void + operator++(int) + { ++*this; } + + constexpr _Iterator + operator++(int) requires forward_range<_Base> + { + auto __tmp = *this; + ++*this; + return __tmp; + } + + constexpr _Iterator& + operator--() requires bidirectional_range<_Base> + { + --_M_current; + --_M_pos; + return *this; + } + + constexpr _Iterator + operator--(int) requires bidirectional_range<_Base> + { + auto __tmp = *this; + --*this; + return __tmp; + } + + constexpr _Iterator& + operator+=(difference_type __n) requires random_access_range<_Base> + { + _M_current += __n; + _M_pos += __n; + return *this; + } + + constexpr _Iterator& + operator-=(difference_type __n) requires random_access_range<_Base> + { + _M_current -= __n; + _M_pos -= __n; + return *this; + } + + constexpr auto + operator[](difference_type __n) const requires random_access_range<_Base> + { return __reference_type(_M_pos + __n, _M_current[__n]); } + + friend constexpr bool + operator==(const _Iterator& __x, const _Iterator& __y) noexcept + { return __x._M_pos == __y._M_pos; } + + friend constexpr strong_ordering + operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept + { return __x._M_pos <=> __y._M_pos; } + + friend constexpr _Iterator + operator+(const _Iterator& __x, difference_type __y) + requires random_access_range<_Base> + { return (auto(__x) += __y); } + + friend constexpr _Iterator + operator+(difference_type __x, const _Iterator& __y) + requires random_access_range<_Base> + { return auto(__y) += __x; } + + friend constexpr _Iterator + operator-(const _Iterator& __x, difference_type __y) + requires random_access_range<_Base> + { return auto(__x) -= __y; } + + friend constexpr difference_type + operator-(const _Iterator& __x, const _Iterator& __y) + { return __x._M_pos - __y._M_pos; } + + friend constexpr auto + iter_move(const _Iterator& __i) + noexcept(noexcept(ranges::iter_move(__i._M_current)) + && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>) + { + return tuple<difference_type, range_rvalue_reference_t<_Base>> + (__i._M_pos, ranges::iter_move(__i._M_current)); + } + }; + + template<view _Vp> + requires __detail::__range_with_movable_reference<_Vp> + template<bool _Const> + class enumerate_view<_Vp>::_Sentinel + { + using _Base = __maybe_const_t<_Const, _Vp>; + + sentinel_t<_Base> _M_end = sentinel_t<_Base>(); + + constexpr explicit + _Sentinel(sentinel_t<_Base> __end) + : _M_end(std::move(__end)) + { } + + friend enumerate_view; + + public: + _Sentinel() = default; + + constexpr + _Sentinel(_Sentinel<!_Const> __other) + requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> + : _M_end(std::move(__other._M_end)) + { } + + constexpr sentinel_t<_Base> + base() const + { return _M_end; } + + template<bool _OtherConst> + requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>> + friend constexpr bool + operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) + { return __x._M_current == __y._M_end; } + + template<bool _OtherConst> + requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>> + friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>> + operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) + { return __x._M_current - __y._M_end; } + + template<bool _OtherConst> + requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>> + friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>> + operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y) + { return __x._M_end - __y._M_current; } + }; + + namespace views + { + namespace __detail + { + template<typename _Tp> + concept __can_enumerate_view + = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); }; + } + + struct _Enumerate : __adaptor::_RangeAdaptorClosure + { + template<viewable_range _Range> + requires __detail::__can_enumerate_view<_Range> + constexpr auto + operator() [[nodiscard]] (_Range&& __r) const + { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); } + }; + + inline constexpr _Enumerate enumerate; + } + +#define __cpp_lib_ranges_as_const 202207L + + template<view _Vp> + requires input_range<_Vp> + class as_const_view : public view_interface<as_const_view<_Vp>> + { + _Vp _M_base = _Vp(); + + public: + as_const_view() requires default_initializable<_Vp> = default; + + constexpr explicit + as_const_view(_Vp __base) + noexcept(is_nothrow_move_constructible_v<_Vp>) + : _M_base(std::move(__base)) + { } + + constexpr _Vp + base() const & + noexcept(is_nothrow_copy_constructible_v<_Vp>) + requires copy_constructible<_Vp> + { return _M_base; } + + constexpr _Vp + base() && + noexcept(is_nothrow_move_constructible_v<_Vp>) + { return std::move(_M_base); } + + constexpr auto + begin() requires (!__detail::__simple_view<_Vp>) + { return ranges::cbegin(_M_base); } + + constexpr auto + begin() const requires range<const _Vp> + { return ranges::cbegin(_M_base); } + + constexpr auto + end() requires (!__detail::__simple_view<_Vp>) + { return ranges::cend(_M_base); } + + constexpr auto + end() const requires range<const _Vp> + { return ranges::cend(_M_base); } + + constexpr auto + size() requires sized_range<_Vp> + { return ranges::size(_M_base); } + + constexpr auto + size() const requires sized_range<const _Vp> + { return ranges::size(_M_base); } + }; + + template<typename _Range> + as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>; + + template<typename _Tp> + inline constexpr bool enable_borrowed_range<as_const_view<_Tp>> + = enable_borrowed_range<_Tp>; + + namespace views + { + namespace __detail + { + template<typename _Tp> + inline constexpr bool __is_ref_view = false; + + template<typename _Range> + inline constexpr bool __is_ref_view<ref_view<_Range>> = true; + + template<typename _Range> + concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); }; + } + + struct _AsConst : __adaptor::_RangeAdaptorClosure + { + template<viewable_range _Range> + constexpr auto + operator()(_Range&& __r) const + noexcept(noexcept(as_const_view(std::declval<_Range>()))) + requires __detail::__can_as_const_view<_Range> + { + using _Tp = remove_cvref_t<_Range>; + using element_type = remove_reference_t<range_reference_t<_Range>>; + if constexpr (constant_range<views::all_t<_Range>>) + return views::all(std::forward<_Range>(__r)); + else if constexpr (__detail::__is_empty_view<_Tp>) + return views::empty<const element_type>; + else if constexpr (std::__detail::__is_span<_Tp>) + return span<const element_type, _Tp::extent>(std::forward<_Range>(__r)); + else if constexpr (__detail::__is_ref_view<_Tp> + && constant_range<const element_type>) + return ref_view(static_cast<const element_type&> + (std::forward<_Range>(__r).base())); + else if constexpr (is_lvalue_reference_v<_Range> + && constant_range<const _Tp> + && !view<_Tp>) + return ref_view(static_cast<const _Tp&>(__r)); + else + return as_const_view(std::forward<_Range>(__r)); + } + }; + + inline constexpr _AsConst as_const; + } #endif // C++23 } // namespace ranges diff --git a/libstdc++-v3/include/std/scoped_allocator b/libstdc++-v3/include/std/scoped_allocator index 68e6afb..a115450 100644 --- a/libstdc++-v3/include/std/scoped_allocator +++ b/libstdc++-v3/include/std/scoped_allocator @@ -65,7 +65,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __outermost_type { using type = _Alloc; - static type& _S_outermost(_Alloc& __a) { return __a; } + static type& _S_outermost(_Alloc& __a) noexcept { return __a; } }; template<typename _Alloc> @@ -79,7 +79,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >; static typename __base::type& - _S_outermost(_Alloc& __a) + _S_outermost(_Alloc& __a) noexcept { return __base::_S_outermost(__a.outer_allocator()); } }; @@ -104,11 +104,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __inner_type_impl& operator=(__inner_type_impl&&) = default; template<typename _Alloc> - __inner_type_impl(const __inner_type_impl<_Alloc>& __other) + __inner_type_impl(const __inner_type_impl<_Alloc>& __other) noexcept { } template<typename _Alloc> - __inner_type_impl(__inner_type_impl<_Alloc>&& __other) + __inner_type_impl(__inner_type_impl<_Alloc>&& __other) noexcept { } __type& @@ -137,16 +137,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __inner_type_impl& operator=(__inner_type_impl&&) = default; template<typename... _Allocs> - __inner_type_impl(const __inner_type_impl<_Allocs...>& __other) + __inner_type_impl(const __inner_type_impl<_Allocs...>& __other) noexcept : _M_inner(__other._M_inner) { } template<typename... _Allocs> - __inner_type_impl(__inner_type_impl<_Allocs...>&& __other) + __inner_type_impl(__inner_type_impl<_Allocs...>&& __other) noexcept : _M_inner(std::move(__other._M_inner)) { } template<typename... _Args> explicit - __inner_type_impl(_Args&&... __args) + __inner_type_impl(_Args&&... __args) noexcept : _M_inner(std::forward<_Args>(__args)...) { } __type& @@ -307,31 +307,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Outer2, typename = _Constructible<_Outer2>> scoped_allocator_adaptor(_Outer2&& __outer, - const _InnerAllocs&... __inner) + const _InnerAllocs&... __inner) noexcept : _OuterAlloc(std::forward<_Outer2>(__outer)), _M_inner(__inner...) { } - scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) + scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) noexcept : _OuterAlloc(__other.outer_allocator()), _M_inner(__other._M_inner) { } - scoped_allocator_adaptor(scoped_allocator_adaptor&& __other) + scoped_allocator_adaptor(scoped_allocator_adaptor&& __other) noexcept : _OuterAlloc(std::move(__other.outer_allocator())), _M_inner(std::move(__other._M_inner)) { } template<typename _Outer2, typename = _Constructible<const _Outer2&>> scoped_allocator_adaptor( - const scoped_allocator_adaptor<_Outer2, _InnerAllocs...>& __other) + const scoped_allocator_adaptor<_Outer2, _InnerAllocs...>& __other + ) noexcept : _OuterAlloc(__other.outer_allocator()), _M_inner(__other._M_inner) { } template<typename _Outer2, typename = _Constructible<_Outer2>> scoped_allocator_adaptor( - scoped_allocator_adaptor<_Outer2, _InnerAllocs...>&& __other) + scoped_allocator_adaptor<_Outer2, _InnerAllocs...>&& __other) noexcept : _OuterAlloc(std::move(__other.outer_allocator())), _M_inner(std::move(__other._M_inner)) { } @@ -342,25 +343,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default; - inner_allocator_type& inner_allocator() noexcept + inner_allocator_type& + inner_allocator() noexcept { return _M_inner._M_get(this); } - const inner_allocator_type& inner_allocator() const noexcept + const inner_allocator_type& + inner_allocator() const noexcept { return _M_inner._M_get(this); } - outer_allocator_type& outer_allocator() noexcept + outer_allocator_type& + outer_allocator() noexcept { return static_cast<_OuterAlloc&>(*this); } - const outer_allocator_type& outer_allocator() const noexcept + const outer_allocator_type& + outer_allocator() const noexcept { return static_cast<const _OuterAlloc&>(*this); } - _GLIBCXX_NODISCARD pointer allocate(size_type __n) + _GLIBCXX_NODISCARD pointer + allocate(size_type __n) { return __traits::allocate(outer_allocator(), __n); } - _GLIBCXX_NODISCARD pointer allocate(size_type __n, const_void_pointer __hint) + _GLIBCXX_NODISCARD pointer + allocate(size_type __n, const_void_pointer __hint) { return __traits::allocate(outer_allocator(), __n, __hint); } - void deallocate(pointer __p, size_type __n) + void deallocate(pointer __p, size_type __n) noexcept { return __traits::deallocate(outer_allocator(), __p, __n); } size_type max_size() const diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index 06d5c18..6763389 100644 --- a/libstdc++-v3/include/std/span +++ b/libstdc++-v3/include/std/span @@ -137,6 +137,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using const_reference = const element_type&; using iterator = __gnu_cxx::__normal_iterator<pointer, span>; using reverse_iterator = std::reverse_iterator<iterator>; +#if __cplusplus > 202002L + using const_iterator = std::const_iterator<iterator>; + using const_reverse_iterator = std::const_iterator<reverse_iterator>; +#endif // member constants static constexpr size_t extent = _Extent; @@ -301,6 +305,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION rend() const noexcept { return reverse_iterator(this->begin()); } +#if __cplusplus > 202002L + constexpr const_iterator + cbegin() const noexcept + { return begin(); } + + constexpr const_iterator + cend() const noexcept + { return end(); } + + constexpr const_reverse_iterator + crbegin() const noexcept + { return rbegin(); } + + constexpr const_reverse_iterator + crend() const noexcept + { return rend(); } +#endif + // subviews template<size_t _Count> diff --git a/libstdc++-v3/include/std/stop_token b/libstdc++-v3/include/std/stop_token index 76aef78..c90fc78 100644 --- a/libstdc++-v3/include/std/stop_token +++ b/libstdc++-v3/include/std/stop_token @@ -395,6 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _Stop_state_ref() = default; + [[__gnu__::__access__(__none__, 2)]] explicit _Stop_state_ref(const stop_source&) : _M_ptr(new _Stop_state_t()) diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 2bd607a..0e7a9c9 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -61,9 +61,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp, _Tp __v> struct integral_constant { - static constexpr _Tp value = __v; - typedef _Tp value_type; - typedef integral_constant<_Tp, __v> type; + static constexpr _Tp value = __v; + using value_type = _Tp; + using type = integral_constant<_Tp, __v>; constexpr operator value_type() const noexcept { return value; } #if __cplusplus > 201103L @@ -109,7 +109,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Partial specialization for true. template<typename _Tp> struct enable_if<true, _Tp> - { typedef _Tp type; }; + { using type = _Tp; }; // __enable_if_t (std::enable_if_t for C++11) template<bool _Cond, typename _Tp = void> @@ -578,19 +578,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// is_enum template<typename _Tp> struct is_enum - : public integral_constant<bool, __is_enum(_Tp)> + : public __bool_constant<__is_enum(_Tp)> { }; /// is_union template<typename _Tp> struct is_union - : public integral_constant<bool, __is_union(_Tp)> + : public __bool_constant<__is_union(_Tp)> { }; /// is_class template<typename _Tp> struct is_class - : public integral_constant<bool, __is_class(_Tp)> + : public __bool_constant<__is_class(_Tp)> { }; /// is_function @@ -784,7 +784,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// is_trivial template<typename _Tp> struct is_trivial - : public integral_constant<bool, __is_trivial(_Tp)> + : public __bool_constant<__is_trivial(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -793,7 +793,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// is_trivially_copyable template<typename _Tp> struct is_trivially_copyable - : public integral_constant<bool, __is_trivially_copyable(_Tp)> + : public __bool_constant<__is_trivially_copyable(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -802,7 +802,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// is_standard_layout template<typename _Tp> struct is_standard_layout - : public integral_constant<bool, __is_standard_layout(_Tp)> + : public __bool_constant<__is_standard_layout(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -817,7 +817,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout && is_trivial") is_pod - : public integral_constant<bool, __is_pod(_Tp)> + : public __bool_constant<__is_pod(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -831,7 +831,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _GLIBCXX17_DEPRECATED is_literal_type - : public integral_constant<bool, __is_literal_type(_Tp)> + : public __bool_constant<__is_literal_type(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -840,13 +840,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// is_empty template<typename _Tp> struct is_empty - : public integral_constant<bool, __is_empty(_Tp)> + : public __bool_constant<__is_empty(_Tp)> { }; /// is_polymorphic template<typename _Tp> struct is_polymorphic - : public integral_constant<bool, __is_polymorphic(_Tp)> + : public __bool_constant<__is_polymorphic(_Tp)> { }; #if __cplusplus >= 201402L @@ -855,14 +855,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @since C++14 template<typename _Tp> struct is_final - : public integral_constant<bool, __is_final(_Tp)> + : public __bool_constant<__is_final(_Tp)> { }; #endif /// is_abstract template<typename _Tp> struct is_abstract - : public integral_constant<bool, __is_abstract(_Tp)> + : public __bool_constant<__is_abstract(_Tp)> { }; /// @cond undocumented @@ -873,7 +873,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_signed_helper<_Tp, true> - : public integral_constant<bool, _Tp(-1) < _Tp(0)> + : public __bool_constant<_Tp(-1) < _Tp(0)> { }; /// @endcond @@ -946,7 +946,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_destructible_impl : public __do_is_destructible_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template<typename _Tp, @@ -1000,7 +1000,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_nt_destructible_impl : public __do_is_nt_destructible_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template<typename _Tp, @@ -1252,7 +1252,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_implicitly_default_constructible_impl : public __do_is_implicitly_default_constructible_impl { - typedef decltype(__test(declval<_Tp>())) type; + using type = decltype(__test(declval<_Tp>())); }; template<typename _Tp> @@ -1333,7 +1333,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// has_virtual_destructor template<typename _Tp> struct has_virtual_destructor - : public integral_constant<bool, __has_virtual_destructor(_Tp)> + : public __bool_constant<__has_virtual_destructor(_Tp)> { static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), "template argument must be a complete class or an unbounded array"); @@ -1392,7 +1392,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp, typename _Up> struct is_same #ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME - : public integral_constant<bool, __is_same(_Tp, _Up)> + : public __bool_constant<__is_same(_Tp, _Up)> #else : public false_type #endif @@ -1408,7 +1408,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// is_base_of template<typename _Base, typename _Derived> struct is_base_of - : public integral_constant<bool, __is_base_of(_Base, _Derived)> + : public __bool_constant<__is_base_of(_Base, _Derived)> { }; #if __has_builtin(__is_convertible) @@ -1422,7 +1422,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION is_array<_To>>::value> struct __is_convertible_helper { - typedef typename is_void<_To>::type type; + using type = typename is_void<_To>::type; }; #pragma GCC diagnostic push @@ -1443,7 +1443,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __test(...); public: - typedef decltype(__test<_From, _To>(0)) type; + using type = decltype(__test<_From, _To>(0)); }; #pragma GCC diagnostic pop @@ -1521,20 +1521,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// remove_const template<typename _Tp> struct remove_const - { typedef _Tp type; }; + { using type = _Tp; }; template<typename _Tp> struct remove_const<_Tp const> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_volatile template<typename _Tp> struct remove_volatile - { typedef _Tp type; }; + { using type = _Tp; }; template<typename _Tp> struct remove_volatile<_Tp volatile> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_cv #if __has_builtin(__remove_cv) @@ -1658,83 +1658,83 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Unqualified> struct __cv_selector<_Unqualified, false, false> - { typedef _Unqualified __type; }; + { using __type = _Unqualified; }; template<typename _Unqualified> struct __cv_selector<_Unqualified, false, true> - { typedef volatile _Unqualified __type; }; + { using __type = volatile _Unqualified; }; template<typename _Unqualified> struct __cv_selector<_Unqualified, true, false> - { typedef const _Unqualified __type; }; + { using __type = const _Unqualified; }; template<typename _Unqualified> struct __cv_selector<_Unqualified, true, true> - { typedef const volatile _Unqualified __type; }; + { using __type = const volatile _Unqualified; }; template<typename _Qualified, typename _Unqualified, bool _IsConst = is_const<_Qualified>::value, bool _IsVol = is_volatile<_Qualified>::value> class __match_cv_qualifiers { - typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match; + using __match = __cv_selector<_Unqualified, _IsConst, _IsVol>; public: - typedef typename __match::__type __type; + using __type = typename __match::__type; }; // Utility for finding the unsigned versions of signed integral types. template<typename _Tp> struct __make_unsigned - { typedef _Tp __type; }; + { using __type = _Tp; }; template<> struct __make_unsigned<char> - { typedef unsigned char __type; }; + { using __type = unsigned char; }; template<> struct __make_unsigned<signed char> - { typedef unsigned char __type; }; + { using __type = unsigned char; }; template<> struct __make_unsigned<short> - { typedef unsigned short __type; }; + { using __type = unsigned short; }; template<> struct __make_unsigned<int> - { typedef unsigned int __type; }; + { using __type = unsigned int; }; template<> struct __make_unsigned<long> - { typedef unsigned long __type; }; + { using __type = unsigned long; }; template<> struct __make_unsigned<long long> - { typedef unsigned long long __type; }; + { using __type = unsigned long long; }; #if defined(__GLIBCXX_TYPE_INT_N_0) __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0> - { typedef unsigned __GLIBCXX_TYPE_INT_N_0 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_0; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1> - { typedef unsigned __GLIBCXX_TYPE_INT_N_1 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_1; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2> - { typedef unsigned __GLIBCXX_TYPE_INT_N_2 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_2; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) __extension__ template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3> - { typedef unsigned __GLIBCXX_TYPE_INT_N_3 __type; }; + { using __type = unsigned __GLIBCXX_TYPE_INT_N_3; }; #endif // Select between integral and enum: not possible to be both. @@ -1833,7 +1833,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// make_unsigned template<typename _Tp> struct make_unsigned - { typedef typename __make_unsigned_selector<_Tp>::__type type; }; + { using type = typename __make_unsigned_selector<_Tp>::__type; }; // Integral, but don't define. template<> struct make_unsigned<bool>; @@ -1846,55 +1846,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Utility for finding the signed versions of unsigned integral types. template<typename _Tp> struct __make_signed - { typedef _Tp __type; }; + { using __type = _Tp; }; template<> struct __make_signed<char> - { typedef signed char __type; }; + { using __type = signed char; }; template<> struct __make_signed<unsigned char> - { typedef signed char __type; }; + { using __type = signed char; }; template<> struct __make_signed<unsigned short> - { typedef signed short __type; }; + { using __type = signed short; }; template<> struct __make_signed<unsigned int> - { typedef signed int __type; }; + { using __type = signed int; }; template<> struct __make_signed<unsigned long> - { typedef signed long __type; }; + { using __type = signed long; }; template<> struct __make_signed<unsigned long long> - { typedef signed long long __type; }; + { using __type = signed long long; }; #if defined(__GLIBCXX_TYPE_INT_N_0) __extension__ template<> struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_0> - { typedef __GLIBCXX_TYPE_INT_N_0 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_0; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) __extension__ template<> struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_1> - { typedef __GLIBCXX_TYPE_INT_N_1 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_1; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) __extension__ template<> struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_2> - { typedef __GLIBCXX_TYPE_INT_N_2 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_2; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) __extension__ template<> struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_3> - { typedef __GLIBCXX_TYPE_INT_N_3 __type; }; + { using __type = __GLIBCXX_TYPE_INT_N_3; }; #endif // Select between integral and enum: not possible to be both. @@ -1918,10 +1918,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> class __make_signed_selector<_Tp, false, true> { - typedef typename __make_unsigned_selector<_Tp>::__type __unsigned_type; + using __unsigned_type = typename __make_unsigned_selector<_Tp>::__type; public: - typedef typename __make_signed_selector<__unsigned_type>::__type __type; + using __type = typename __make_signed_selector<__unsigned_type>::__type; }; // wchar_t, char16_t and char32_t are integral types but are neither @@ -1965,7 +1965,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// make_signed template<typename _Tp> struct make_signed - { typedef typename __make_signed_selector<_Tp>::__type type; }; + { using type = typename __make_signed_selector<_Tp>::__type; }; // Integral, but don't define. template<> struct make_signed<bool>; @@ -1988,28 +1988,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// remove_extent template<typename _Tp> struct remove_extent - { typedef _Tp type; }; + { using type = _Tp; }; template<typename _Tp, std::size_t _Size> struct remove_extent<_Tp[_Size]> - { typedef _Tp type; }; + { using type = _Tp; }; template<typename _Tp> struct remove_extent<_Tp[]> - { typedef _Tp type; }; + { using type = _Tp; }; /// remove_all_extents template<typename _Tp> struct remove_all_extents - { typedef _Tp type; }; + { using type = _Tp; }; template<typename _Tp, std::size_t _Size> struct remove_all_extents<_Tp[_Size]> - { typedef typename remove_all_extents<_Tp>::type type; }; + { using type = typename remove_all_extents<_Tp>::type; }; template<typename _Tp> struct remove_all_extents<_Tp[]> - { typedef typename remove_all_extents<_Tp>::type type; }; + { using type = typename remove_all_extents<_Tp>::type; }; #if __cplusplus > 201103L /// Alias template for remove_extent @@ -2025,11 +2025,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp, typename> struct __remove_pointer_helper - { typedef _Tp type; }; + { using type = _Tp; }; template<typename _Tp, typename _Up> struct __remove_pointer_helper<_Tp, _Up*> - { typedef _Up type; }; + { using type = _Up; }; /// remove_pointer template<typename _Tp> @@ -2153,7 +2153,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// The value of the strictest alignment of _Types. static const size_t alignment_value = __strictest::_S_alignment; /// The storage. - typedef typename aligned_storage<_S_len, alignment_value>::type type; + using type = typename aligned_storage<_S_len, alignment_value>::type; }; template <size_t _Len, typename... _Types> @@ -2200,13 +2200,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __strip_reference_wrapper { - typedef _Tp __type; + using __type = _Tp; }; template<typename _Tp> struct __strip_reference_wrapper<reference_wrapper<_Tp> > { - typedef _Tp& __type; + using __type = _Tp&; }; // __decay_t (std::decay_t for C++11). @@ -2233,12 +2233,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Define a member typedef @c type to one of two argument types. template<bool _Cond, typename _Iftrue, typename _Iffalse> struct conditional - { typedef _Iftrue type; }; + { using type = _Iftrue; }; // Partial specialization for false. template<typename _Iftrue, typename _Iffalse> struct conditional<false, _Iftrue, _Iffalse> - { typedef _Iffalse type; }; + { using type = _Iffalse; }; /// common_type template<typename... _Tp> @@ -2255,7 +2255,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __success_type - { typedef _Tp type; }; + { using type = _Tp; }; struct __failure_type { }; @@ -2426,7 +2426,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __result_of_memfun_ref : private __result_of_memfun_ref_impl { - typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0)); }; // [func.require] paragraph 1 bullet 2: @@ -2445,7 +2445,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __result_of_memfun_deref : private __result_of_memfun_deref_impl { - typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0)); }; // [func.require] paragraph 1 bullet 3: @@ -2464,7 +2464,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __result_of_memobj_ref : private __result_of_memobj_ref_impl { - typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg>(0)); }; // [func.require] paragraph 1 bullet 4: @@ -2483,7 +2483,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __result_of_memobj_deref : private __result_of_memobj_deref_impl { - typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; + using type = decltype(_S_test<_MemPtr, _Arg>(0)); }; template<typename _MemPtr, typename _Arg> @@ -2492,13 +2492,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Res, typename _Class, typename _Arg> struct __result_of_memobj<_Res _Class::*, _Arg> { - typedef __remove_cvref_t<_Arg> _Argval; - typedef _Res _Class::* _MemPtr; - typedef typename __conditional_t<__or_<is_same<_Argval, _Class>, + using _Argval = __remove_cvref_t<_Arg>; + using _MemPtr = _Res _Class::*; + using type = typename __conditional_t<__or_<is_same<_Argval, _Class>, is_base_of<_Class, _Argval>>::value, __result_of_memobj_ref<_MemPtr, _Arg>, __result_of_memobj_deref<_MemPtr, _Arg> - >::type type; + >::type; }; template<typename _MemPtr, typename _Arg, typename... _Args> @@ -2507,12 +2507,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Res, typename _Class, typename _Arg, typename... _Args> struct __result_of_memfun<_Res _Class::*, _Arg, _Args...> { - typedef typename remove_reference<_Arg>::type _Argval; - typedef _Res _Class::* _MemPtr; - typedef typename __conditional_t<is_base_of<_Class, _Argval>::value, + using _Argval = typename remove_reference<_Arg>::type; + using _MemPtr = _Res _Class::*; + using type = typename __conditional_t<is_base_of<_Class, _Argval>::value, __result_of_memfun_ref<_MemPtr, _Arg, _Args...>, __result_of_memfun_deref<_MemPtr, _Arg, _Args...> - >::type type; + >::type; }; // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -2535,7 +2535,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<bool, bool, typename _Functor, typename... _ArgTypes> struct __result_of_impl { - typedef __failure_type type; + using type = __failure_type; }; template<typename _MemPtr, typename _Arg> @@ -2566,7 +2566,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __result_of_impl<false, false, _Functor, _ArgTypes...> : private __result_of_other_impl { - typedef decltype(_S_test<_Functor, _ArgTypes...>(0)) type; + using type = decltype(_S_test<_Functor, _ArgTypes...>(0)); }; // __invoke_result (std::invoke_result for C++11) @@ -2763,14 +2763,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_swappable_impl : public __swappable_details::__do_is_swappable_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template<typename _Tp> struct __is_nothrow_swappable_impl : public __swappable_details::__do_is_nothrow_swappable_impl { - typedef decltype(__test<_Tp>(0)) type; + using type = decltype(__test<_Tp>(0)); }; template<typename _Tp> @@ -2853,7 +2853,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_swappable_with_impl : public __swappable_with_details::__do_is_swappable_with_impl { - typedef decltype(__test<_Tp, _Up>(0)) type; + using type = decltype(__test<_Tp, _Up>(0)); }; // Optimization for the homogenous lvalue case, not required: @@ -2861,14 +2861,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_swappable_impl { - typedef decltype(__test<_Tp&>(0)) type; + using type = decltype(__test<_Tp&>(0)); }; template<typename _Tp, typename _Up> struct __is_nothrow_swappable_with_impl : public __swappable_with_details::__do_is_nothrow_swappable_with_impl { - typedef decltype(__test<_Tp, _Up>(0)) type; + using type = decltype(__test<_Tp, _Up>(0)); }; // Optimization for the homogenous lvalue case, not required: @@ -2876,7 +2876,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_nothrow_swappable_impl { - typedef decltype(__test<_Tp&>(0)) type; + using type = decltype(__test<_Tp&>(0)); }; /// @endcond diff --git a/libstdc++-v3/include/std/valarray b/libstdc++-v3/include/std/valarray index 504d02b..6bd23e0 100644 --- a/libstdc++-v3/include/std/valarray +++ b/libstdc++-v3/include/std/valarray @@ -1080,6 +1080,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _Expr<_Closure, _Tp>(_Closure(*this, __func)); } + /// @cond undocumented #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ template<typename _Tp> \ inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \ @@ -1206,6 +1207,7 @@ _DEFINE_BINARY_OPERATOR(<=, __less_equal) _DEFINE_BINARY_OPERATOR(>=, __greater_equal) #undef _DEFINE_BINARY_OPERATOR + /// @endcond #if __cplusplus >= 201103L /** diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version index a19c39c..02ead8f 100644 --- a/libstdc++-v3/include/std/version +++ b/libstdc++-v3/include/std/version @@ -30,7 +30,10 @@ #ifndef _GLIBCXX_VERSION_INCLUDED #define _GLIBCXX_VERSION_INCLUDED -#pragma GCC system_header +// To facilitate testsuite/17_intro/versionconflict.cc +#ifndef _GLIBCXX_TESTING_SYSHDR +# pragma GCC system_header +#endif #include <bits/c++config.h> @@ -81,18 +84,23 @@ #ifndef _GLIBCXX_DEBUG // PR libstdc++/70303 # define __cpp_lib_null_iterators 201304L #endif +#define __cpp_lib_robust_nonmodifying_seq_ops 201304L #define __cpp_lib_transformation_trait_aliases 201304L #define __cpp_lib_transparent_operators 201510L #define __cpp_lib_tuple_element_t 201402L #define __cpp_lib_tuples_by_type 201304L +#if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 \ + && __SIZE_WIDTH__ >= 32 +# define __cpp_lib_to_chars 201611L +#endif + #if _GLIBCXX_HOSTED # define __cpp_lib_chrono_udls 201304L # define __cpp_lib_complex_udls 201309L # define __cpp_lib_generic_associative_lookup 201304L # define __cpp_lib_make_unique 201304L # define __cpp_lib_quoted_string_io 201304L -# define __cpp_lib_robust_nonmodifying_seq_ops 201304L # ifdef _GLIBCXX_HAS_GTHREADS # define __cpp_lib_shared_timed_mutex 201402L # endif @@ -108,6 +116,9 @@ #define __cpp_lib_atomic_is_always_lock_free 201603L #define __cpp_lib_bool_constant 201505L #define __cpp_lib_byte 201603L +#define __cpp_lib_clamp 201603L +#define __cpp_lib_gcd 201606L +#define __cpp_lib_gcd_lcm 201606L #ifdef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP # define __cpp_lib_has_unique_object_representations 201606L #endif @@ -123,12 +134,16 @@ #ifdef _GLIBCXX_HAVE_BUILTIN_LAUNDER # define __cpp_lib_launder 201606L #endif +#define __cpp_lib_lcm 201606L #define __cpp_lib_logical_traits 201510L #define __cpp_lib_make_from_tuple 201606L +#define __cpp_lib_nonmember_container_access 201411L #define __cpp_lib_not_fn 201603L #if __cplusplus == 201703L // N.B. updated value in C++20 # define __cpp_lib_optional 201606L #endif +#define __cpp_lib_raw_memory_algorithms 201606L +#define __cpp_lib_sample 201603L #define __cpp_lib_type_trait_variable_templates 201510L #define __cpp_lib_uncaught_exceptions 201411L #if !(__cpp_concepts >= 202002L && __cpp_constexpr >= 201811L) @@ -136,27 +151,23 @@ # define __cpp_lib_variant 202102L #endif #define __cpp_lib_void_t 201411L - -#if _GLIBCXX_HOSTED #if __cplusplus == 201703L // N.B. updated value in C++20 # define __cpp_lib_array_constexpr 201803L #endif -#define __cpp_lib_boyer_moore_searcher 201603L -#define __cpp_lib_chrono 201611L -#define __cpp_lib_clamp 201603L #if __cplusplus == 201703L // N.B. updated value in C++20 # if _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED # define __cpp_lib_constexpr_char_traits 201611L # define __cpp_lib_constexpr_string 201611L # endif #endif + +#if _GLIBCXX_HOSTED +#define __cpp_lib_boyer_moore_searcher 201603L +#define __cpp_lib_chrono 201611L #define __cpp_lib_enable_shared_from_this 201603L #define __cpp_lib_execution 201902L // FIXME: should be 201603L #define __cpp_lib_filesystem 201703L -#define __cpp_lib_gcd 201606L -#define __cpp_lib_gcd_lcm 201606L #define __cpp_lib_hypot 201603L -#define __cpp_lib_lcm 201606L #define __cpp_lib_map_try_emplace 201411L #define __cpp_lib_math_special_functions 201603L #ifdef _GLIBCXX_HAS_GTHREADS @@ -165,20 +176,13 @@ # define __cpp_lib_memory_resource 1 #endif #define __cpp_lib_node_extract 201606L -#define __cpp_lib_nonmember_container_access 201411L #define __cpp_lib_parallel_algorithm 201603L -#define __cpp_lib_raw_memory_algorithms 201606L -#define __cpp_lib_sample 201603L #ifdef _GLIBCXX_HAS_GTHREADS # define __cpp_lib_scoped_lock 201703L # define __cpp_lib_shared_mutex 201505L #endif #define __cpp_lib_shared_ptr_weak_type 201606L #define __cpp_lib_string_view 201803L -#if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 \ - && __SIZE_WIDTH__ >= 32 -# define __cpp_lib_to_chars 201611L -#endif #define __cpp_lib_unordered_map_try_emplace 201411L #endif @@ -224,7 +228,9 @@ #if __cpp_lib_concepts # define __cpp_lib_make_obj_using_allocator 201811L #endif -#define __cpp_lib_optional 202106L +#if __cplusplus <= 202002L // N.B. updated value in C++23 +# define __cpp_lib_optional 202106L +#endif #define __cpp_lib_remove_cvref 201711L #if __has_builtin(__builtin_source_location) # define __cpp_lib_source_location 201907L @@ -243,9 +249,29 @@ #if __cpp_concepts >= 202002L && __cpp_constexpr >= 201811L # define __cpp_lib_variant 202106L #endif +#define __cpp_lib_constexpr_algorithms 201806L +#define __cpp_lib_constexpr_functional 201907L +#if __cplusplus <= 202002L // N.B. updated value in C++23 +# define __cpp_lib_constexpr_memory 201811L +#endif // C++20 +#define __cpp_lib_constexpr_numeric 201911L +#define __cpp_lib_constexpr_tuple 201811L +#define __cpp_lib_array_constexpr 201811L +#ifdef __cpp_lib_is_constant_evaluated +# define __cpp_lib_constexpr_char_traits 201811L +#endif +#define __cpp_lib_constexpr_iterator 201811L +#define __cpp_lib_constexpr_utility 201811L +#define __cpp_lib_interpolate 201902L +#if __cpp_lib_concepts +# define __cpp_lib_move_iterator_concept 202207L +#if __cplusplus <= 202002L // N.B. updated value in C++23 +# define __cpp_lib_ranges 202110L +#endif +#endif +#define __cpp_lib_shift 201806L #if _GLIBCXX_HOSTED -#define __cpp_lib_array_constexpr 201811L #define __cpp_lib_atomic_shared_ptr 201711L #if defined _GLIBCXX_HAS_GTHREADS || defined _GLIBCXX_HAVE_LINUX_FUTEX # define __cpp_lib_atomic_wait 201907L @@ -256,16 +282,9 @@ // #undef __cpp_lib_chrono // #define __cpp_lib_chrono 201907L // FIXME: #define __cpp_lib_execution 201902L -#define __cpp_lib_constexpr_algorithms 201806L -#ifdef __cpp_lib_is_constant_evaluated -# define __cpp_lib_constexpr_char_traits 201811L -#endif #define __cpp_lib_constexpr_complex 201711L #define __cpp_lib_constexpr_dynamic_alloc 201907L -#define __cpp_lib_constexpr_functional 201907L -#define __cpp_lib_constexpr_iterator 201811L -#define __cpp_lib_constexpr_memory 201811L -#define __cpp_lib_constexpr_numeric 201911L +#define __cpp_lib_constexpr_tuple 201811L #ifdef __cpp_lib_is_constant_evaluated # if _GLIBCXX_USE_CXX11_ABI # define __cpp_lib_constexpr_string 201907L @@ -273,13 +292,10 @@ # define __cpp_lib_constexpr_string 201811L # endif #endif -#define __cpp_lib_constexpr_tuple 201811L -#define __cpp_lib_constexpr_utility 201811L #define __cpp_lib_constexpr_vector 201907L #define __cpp_lib_erase_if 202002L #define __cpp_lib_format 202106L #define __cpp_lib_generic_unordered_lookup 201811L -#define __cpp_lib_interpolate 201902L #ifdef _GLIBCXX_HAS_GTHREADS # define __cpp_lib_jthread 201911L #endif @@ -288,15 +304,10 @@ #endif #define __cpp_lib_list_remove_return_type 201806L #define __cpp_lib_polymorphic_allocator 201902L -#if __cpp_lib_concepts -# define __cpp_lib_ranges 202110L -# define __cpp_lib_move_iterator_concept 202207L -#endif #if __cpp_lib_atomic_wait || _GLIBCXX_HAVE_POSIX_SEMAPHORE # define __cpp_lib_semaphore 201907L #endif #define __cpp_lib_shared_ptr_arrays 201707L -#define __cpp_lib_shift 201806L #define __cpp_lib_smart_ptr_for_overwrite 202002L # if _GLIBCXX_USE_CXX11_ABI // Only supported with cxx11-abi @@ -321,6 +332,7 @@ #define __cpp_lib_reference_from_temporary 202202L #define __cpp_lib_to_underlying 202102L #define __cpp_lib_unreachable 202202L +#define __cpp_lib_ranges 202202L #define __cpp_lib_ranges_zip 202110L #define __cpp_lib_ranges_chunk 202202L #define __cpp_lib_ranges_slide 202202L @@ -330,14 +342,23 @@ #define __cpp_lib_ranges_stride 202207L #define __cpp_lib_ranges_cartesian_product 202207L #define __cpp_lib_ranges_as_rvalue 202207L - -#if _GLIBCXX_HOSTED -#define __cpp_lib_adaptor_iterator_pair_constructor 202106L +#define __cpp_lib_ranges_as_const 202207L +#define __cpp_lib_ranges_enumerate 202302L +#define __cpp_lib_ranges_contains 202207L +#define __cpp_lib_ranges_iota 202202L +#define __cpp_lib_ranges_find_last 202207L +#define __cpp_lib_ranges_fold 202207L #if __cpp_constexpr_dynamic_alloc -# define __cpp_lib_constexpr_bitset 202202L +# if _GLIBCXX_HOSTED +# define __cpp_lib_constexpr_bitset 202202L +# endif # undef __cpp_lib_constexpr_memory # define __cpp_lib_constexpr_memory 202202L #endif +#define __cpp_lib_stdatomic_h 202011L + +#if _GLIBCXX_HOSTED +#define __cpp_lib_adaptor_iterator_pair_constructor 202106L #define __cpp_lib_ios_noreplace 202207L #define __cpp_lib_move_only_function 202110L #if __cpp_lib_span |