diff options
Diffstat (limited to 'libstdc++-v3/include')
79 files changed, 3031 insertions, 751 deletions
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 886e7e6..a087e63 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -51,6 +51,11 @@ # include <string_view> #endif +#if __glibcxx_containers_ranges // C++ >= 23 +# include <bits/ranges_algobase.h> // ranges::copy +# include <bits/ranges_util.h> // ranges::subrange +#endif + #if __cplusplus > 202302L # include <charconv> #endif @@ -468,6 +473,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 traits_type::assign(__d, __n, __c); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // _S_copy_chars is a separate template to permit specialization // to optimize for the common case of pointers as iterators. template<class _Iterator> @@ -475,31 +482,69 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 static void _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) { +#if __cplusplus >= 201103L + using _IterBase = decltype(std::__niter_base(__k1)); + if constexpr (__or_<is_same<_IterBase, _CharT*>, + is_same<_IterBase, const _CharT*>>::value) + _S_copy(__p, std::__niter_base(__k1), __k2 - __k1); +#if __cpp_lib_concepts + else if constexpr (requires { + requires contiguous_iterator<_Iterator>; + { std::to_address(__k1) } + -> convertible_to<const _CharT*>; + }) + { + const auto __d = __k2 - __k1; + (void) (__k1 + __d); // See P3349R1 + _S_copy(__p, std::to_address(__k1), static_cast<size_type>(__d)); + } +#endif + else +#endif for (; __k1 != __k2; ++__k1, (void)++__p) - traits_type::assign(*__p, *__k1); // These types are off. + traits_type::assign(*__p, static_cast<_CharT>(*__k1)); } +#pragma GCC diagnostic pop - _GLIBCXX20_CONSTEXPR +#if __cplusplus < 201103L || defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS static void - _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT + _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } - _GLIBCXX20_CONSTEXPR static void _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) - _GLIBCXX_NOEXCEPT { _S_copy_chars(__p, __k1.base(), __k2.base()); } - _GLIBCXX20_CONSTEXPR static void - _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) { _S_copy(__p, __k1, __k2 - __k1); } - _GLIBCXX20_CONSTEXPR static void _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) - _GLIBCXX_NOEXCEPT { _S_copy(__p, __k1, __k2 - __k1); } +#endif + +#if __glibcxx_containers_ranges // C++ >= 23 + // pre: __n == ranges::distance(__rg). __p+[0,__n) is a valid range. + template<typename _Rg> + static constexpr void + _S_copy_range(pointer __p, _Rg&& __rg, size_type __n) + { + if constexpr (requires { + requires ranges::contiguous_range<_Rg>; + { ranges::data(std::forward<_Rg>(__rg)) } + -> convertible_to<const _CharT*>; + }) + _S_copy(__p, ranges::data(std::forward<_Rg>(__rg)), __n); + else + { + auto __first = ranges::begin(__rg); + const auto __last = ranges::end(__rg); + for (; __first != __last; ++__first) + traits_type::assign(*__p++, static_cast<_CharT>(*__first)); + } + } +#endif _GLIBCXX20_CONSTEXPR static int @@ -717,6 +762,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 __str._M_set_length(0); } +#if __glibcxx_containers_ranges // C++ >= 23 + /** + * @brief Construct a string from a range. + * @since C++23 + */ + template<__detail::__container_compatible_range<_CharT> _Rg> + constexpr + basic_string(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc()) + : basic_string(__a) + { + if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>) + { + const auto __n = static_cast<size_type>(ranges::distance(__rg)); + reserve(__n); + _S_copy_range(_M_data(), std::forward<_Rg>(__rg), __n); + _M_set_length(__n); + } + else + { + auto __first = ranges::begin(__rg); + const auto __last = ranges::end(__rg); + for (; __first != __last; ++__first) + push_back(*__first); + } + } +#endif + /** * @brief Construct string from an initializer %list. * @param __l std::initializer_list of characters. @@ -1526,6 +1598,58 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 append(size_type __n, _CharT __c) { return _M_replace_aux(this->size(), size_type(0), __n, __c); } +#if __glibcxx_containers_ranges // C++ >= 23 + /** + * @brief Append a range to the string. + * @param __rg A range of values that are convertible to `value_type`. + * @since C++23 + * + * The range `__rg` is allowed to overlap with `*this`. + */ + template<__detail::__container_compatible_range<_CharT> _Rg> + constexpr basic_string& + append_range(_Rg&& __rg) + { + // N.B. __rg may overlap with *this, so we must copy from __rg before + // existing elements or iterators referring to *this are invalidated. + // e.g. in s.append_range(views::concat(s, str)), rg overlaps s. + if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>) + { + const auto __len = size_type(ranges::distance(__rg)); + + // Don't care if this addition wraps around, we check it below: + const size_type __newlen = size() + __len; + + if ((capacity() - size()) >= __len) + _S_copy_range(_M_data() + size(), std::forward<_Rg>(__rg), + __len); + else + { + _M_check_length(0, __len, "basic_string::append_range"); + basic_string __s(_M_get_allocator()); + __s.reserve(__newlen); + _S_copy_range(__s._M_data() + size(), std::forward<_Rg>(__rg), + __len); + _S_copy(__s._M_data(), _M_data(), size()); + if (!_M_is_local()) + _M_destroy(_M_allocated_capacity); + _M_data(__s._M_data()); + _M_capacity(__s._M_allocated_capacity); + __s._M_data(__s._M_local_data()); + __s._M_length(0); + } + _M_set_length(__newlen); // adds null-terminator + } + else + { + basic_string __s(from_range, std::forward<_Rg>(__rg), + _M_get_allocator()); + append(__s); + } + return *this; + } +#endif + #if __cplusplus >= 201103L /** * @brief Append an initializer_list of characters. @@ -1785,6 +1909,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { return this->replace(begin(), end(), __first, __last); } #endif +#if __glibcxx_containers_ranges // C++ >= 23 + /** + * @brief Assign a range to the string. + * @param __rg A range of values that are convertible to `value_type`. + * @since C++23 + * + * The range `__rg` is allowed to overlap with `*this`. + */ + template<__detail::__container_compatible_range<_CharT> _Rg> + constexpr basic_string& + assign_range(_Rg&& __rg) + { + basic_string __s(from_range, std::forward<_Rg>(__rg), + _M_get_allocator()); + assign(std::move(__s)); + return *this; + } +#endif + #if __cplusplus >= 201103L /** * @brief Set value to an initializer_list of characters. @@ -1934,6 +2077,37 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { this->replace(__p, __p, __beg, __end); } #endif +#if __glibcxx_containers_ranges // C++ >= 23 + /** + * @brief Insert a range into the string. + * @param __rg A range of values that are convertible to `value_type`. + * @since C++23 + * + * The range `__rg` is allowed to overlap with `*this`. + */ + template<__detail::__container_compatible_range<_CharT> _Rg> + constexpr iterator + insert_range(const_iterator __p, _Rg&& __rg) + { + auto __pos = __p - cbegin(); + + if constexpr (ranges::forward_range<_Rg>) + if (ranges::empty(__rg)) + return begin() + __pos; + + + if (__p == cend()) + append_range(std::forward<_Rg>(__rg)); + else + { + basic_string __s(from_range, std::forward<_Rg>(__rg), + _M_get_allocator()); + insert(__pos, __s); + } + return begin() + __pos; + } +#endif + #if __cplusplus >= 201103L /** * @brief Insert an initializer_list of characters. @@ -2522,6 +2696,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 __k1.base(), __k2 - __k1); } +#if __glibcxx_containers_ranges // C++ >= 23 + /** + * @brief Replace part of the string with a range. + * @param __rg A range of values that are convertible to `value_type`. + * @since C++23 + * + * The range `__rg` is allowed to overlap with `*this`. + */ + template<__detail::__container_compatible_range<_CharT> _Rg> + constexpr basic_string& + replace_with_range(const_iterator __i1, const_iterator __i2, _Rg&& __rg) + { + if (__i1 == cend()) + append_range(std::forward<_Rg>(__rg)); + else + { + basic_string __s(from_range, std::forward<_Rg>(__rg), + _M_get_allocator()); + replace(__i1, __i2, __s); + } + return *this; + } +#endif + #if __cplusplus >= 201103L /** * @brief Replace range of characters with initializer_list. @@ -3599,6 +3797,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 typename basic_string<_CharT, _Traits, _Allocator>::size_type, const _Allocator& = _Allocator()) -> basic_string<_CharT, _Traits, _Allocator>; + +#if __glibcxx_containers_ranges // C++ >= 23 + template<ranges::input_range _Rg, + typename _Allocator = allocator<ranges::range_value_t<_Rg>>> + basic_string(from_range_t, _Rg&&, _Allocator = _Allocator()) + -> basic_string<ranges::range_value_t<_Rg>, + char_traits<ranges::range_value_t<_Rg>>, + _Allocator>; +#endif _GLIBCXX_END_NAMESPACE_CXX11 #endif @@ -3731,21 +3938,23 @@ _GLIBCXX_END_NAMESPACE_CXX11 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs, basic_string<_CharT, _Traits, _Alloc>&& __rhs) { -#if _GLIBCXX_USE_CXX11_ABI - using _Alloc_traits = allocator_traits<_Alloc>; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + // Return value must use __lhs.get_allocator(), but if __rhs has equal + // allocator then we can choose which parameter to modify in-place. bool __use_rhs = false; - if _GLIBCXX17_CONSTEXPR (typename _Alloc_traits::is_always_equal{}) + if constexpr (allocator_traits<_Alloc>::is_always_equal::value) __use_rhs = true; else if (__lhs.get_allocator() == __rhs.get_allocator()) __use_rhs = true; if (__use_rhs) -#endif { const auto __size = __lhs.size() + __rhs.size(); if (__size > __lhs.capacity() && __size <= __rhs.capacity()) return std::move(__rhs.insert(0, __lhs)); } return std::move(__lhs.append(__rhs)); +#pragma GCC diagnostic pop } template<typename _CharT, typename _Traits, typename _Alloc> diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 02230ac..bca55bc 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -210,7 +210,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_data(__another); _M_capacity(__capacity); } - traits_type::assign(_M_data()[__len++], *__beg); + traits_type::assign(_M_data()[__len++], + static_cast<_CharT>(*__beg)); ++__beg; } diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h index 67e18e8..5ca3466 100644 --- a/libstdc++-v3/include/bits/char_traits.h +++ b/libstdc++-v3/include/bits/char_traits.h @@ -284,7 +284,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif - if _GLIBCXX17_CONSTEXPR (sizeof(_CharT) == 1 && __is_trivial(_CharT)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + if _GLIBCXX_CONSTEXPR (sizeof(_CharT) == 1 && __is_trivial(_CharT)) { if (__n) { @@ -298,6 +300,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION for (std::size_t __i = 0; __i < __n; ++__i) __s[__i] = __a; } +#pragma GCC diagnostic pop return __s; } diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index d872109..b7f6f5f 100644 --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -57,21 +57,7 @@ namespace chrono /// @cond undocumented namespace __detail { - // STATICALLY-WIDEN, see C++20 [time.general] - // It doesn't matter for format strings (which can only be char or wchar_t) - // but this returns the narrow string for anything that isn't wchar_t. This - // is done because const char* can be inserted into any ostream type, and - // will be widened at runtime if necessary. - template<typename _CharT> - consteval auto - _Widen(const char* __narrow, const wchar_t* __wide) - { - if constexpr (is_same_v<_CharT, wchar_t>) - return __wide; - else - return __narrow; - } -#define _GLIBCXX_WIDEN_(C, S) ::std::chrono::__detail::_Widen<C>(S, L##S) +#define _GLIBCXX_WIDEN_(C, S) ::std::__format::_Widen<C>(S, L##S) #define _GLIBCXX_WIDEN(S) _GLIBCXX_WIDEN_(_CharT, S) template<typename _Period, typename _CharT> diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h index d5b3979..f9df2be 100644 --- a/libstdc++-v3/include/bits/cow_string.h +++ b/libstdc++-v3/include/bits/cow_string.h @@ -423,7 +423,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) { for (; __k1 != __k2; ++__k1, (void)++__p) - traits_type::assign(*__p, *__k1); // These types are off. + traits_type::assign(*__p, static_cast<_CharT>(*__k1)); } static void @@ -639,6 +639,48 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif } +#if __glibcxx_containers_ranges // C++ >= 23 + /** + * @brief Construct a string from a range. + * @since C++23 + */ + template<__detail::__container_compatible_range<_CharT> _Rg> + basic_string(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc()) + : basic_string(__a) + { + if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>) + { + const auto __n = static_cast<size_type>(ranges::distance(__rg)); + if (__n == 0) + return; + + reserve(__n); + pointer __p = _M_data(); + if constexpr (requires { + requires ranges::contiguous_range<_Rg>; + { ranges::data(std::forward<_Rg>(__rg)) } + -> convertible_to<const _CharT*>; + }) + _M_copy(__p, ranges::data(std::forward<_Rg>(__rg)), __n); + else + { + auto __first = ranges::begin(__rg); + const auto __last = ranges::end(__rg); + for (; __first != __last; ++__first) + traits_type::assign(*__p++, static_cast<_CharT>(*__first)); + } + _M_rep()->_M_set_length_and_sharable(__n); + } + else + { + auto __first = ranges::begin(__rg); + const auto __last = ranges::end(__rg); + for (; __first != __last; ++__first) + push_back(*__first); + } + } +#endif + /** * @brief Construct string from an initializer %list. * @param __l std::initializer_list of characters. @@ -1314,6 +1356,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_string& append(size_type __n, _CharT __c); +#if __glibcxx_containers_ranges // C++ >= 23 + /** + * @brief Append a range to the string. + * @since C++23 + */ + template<__detail::__container_compatible_range<_CharT> _Rg> + basic_string& + append_range(_Rg&& __rg) + { + basic_string __s(from_range, std::forward<_Rg>(__rg), + get_allocator()); + append(__s); + return *this; + } +#endif + #if __cplusplus >= 201103L /** * @brief Append an initializer_list of characters. @@ -1485,6 +1543,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION assign(_InputIterator __first, _InputIterator __last) { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } +#if __glibcxx_containers_ranges // C++ >= 23 + /** + * @brief Set value to a range of characters. + * @since C++23 + */ + template<__detail::__container_compatible_range<_CharT> _Rg> + basic_string& + assign_range(_Rg&& __rg) + { + basic_string __s(from_range, std::forward<_Rg>(__rg), + get_allocator()); + assign(std::move(__s)); + return *this; + } +#endif + #if __cplusplus >= 201103L /** * @brief Set value to an initializer_list of characters. @@ -1562,6 +1636,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION insert(iterator __p, _InputIterator __beg, _InputIterator __end) { this->replace(__p, __p, __beg, __end); } +#if __glibcxx_containers_ranges // C++ >= 23 + /** + * @brief Insert a range into the string. + * @since C++23 + */ + template<__detail::__container_compatible_range<_CharT> _Rg> + iterator + insert_range(const_iterator __p, _Rg&& __rg) + { + auto __pos = __p - cbegin(); + + if constexpr (ranges::forward_range<_Rg>) + if (ranges::empty(__rg)) + return begin() + __pos; + + if (__p == cend()) + append_range(std::forward<_Rg>(__rg)); + else + { + basic_string __s(from_range, std::forward<_Rg>(__rg), + get_allocator()); + insert(__pos, __s); + } + return begin() + __pos; + } +#endif + #if __cplusplus >= 201103L /** * @brief Insert an initializer_list of characters. @@ -2072,6 +2173,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __k1.base(), __k2 - __k1); } +#if __glibcxx_containers_ranges // C++ >= 23 + /** + * @brief Replace part of the string with a range. + * @since C++23 + */ + template<__detail::__container_compatible_range<_CharT> _Rg> + basic_string& + replace_with_range(const_iterator __i1, const_iterator __i2, _Rg&& __rg) + { + if (__i1 == cend()) + append_range(std::forward<_Rg>(__rg)); + else + { + basic_string __s(from_range, std::forward<_Rg>(__rg), + get_allocator()); + replace(__i1 - cbegin(), __i2 - __i1, __s); + } + return *this; + } +#endif + #if __cplusplus >= 201103L /** * @brief Replace range of characters with initializer_list. diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index 87ea1ce..dabb6ec 100644 --- a/libstdc++-v3/include/bits/deque.tcc +++ b/libstdc++-v3/include/bits/deque.tcc @@ -873,7 +873,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::forward_range _Rg> auto __advance_dist(_Rg& __rg) { @@ -1022,7 +1022,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER __guard.__n = size(); } } -#endif // ranges_to_container +#endif // containers_ranges template<typename _Tp, typename _Alloc> void diff --git a/libstdc++-v3/include/bits/formatfwd.h b/libstdc++-v3/include/bits/formatfwd.h index a6b5ac8..3fa01ad 100644 --- a/libstdc++-v3/include/bits/formatfwd.h +++ b/libstdc++-v3/include/bits/formatfwd.h @@ -37,6 +37,12 @@ // <bits/version.h> must have been included before this header: #ifdef __glibcxx_format // C++ >= 20 && HOSTED +#include <concepts> +#include <type_traits> +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED +# include <bits/ranges_base.h> // input_range, range_reference_t +#endif + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -50,6 +56,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // [format.formatter], formatter template<typename _Tp, typename _CharT = char> struct formatter; +/// @cond undocumented + [[noreturn]] + inline void + __throw_format_error(const char* __what); + namespace __format { #ifdef _GLIBCXX_USE_WCHAR_T @@ -60,9 +71,97 @@ namespace __format concept __char = same_as<_CharT, char>; #endif - template<__char _CharT> - struct __formatter_int; + enum _Align { + _Align_default, + _Align_left, + _Align_right, + _Align_centre, + }; + + template<typename _CharT> struct _Spec; + + template<__char _CharT> struct __formatter_str; + template<__char _CharT> struct __formatter_int; + template<__char _CharT> struct __formatter_ptr; + + template<typename _Tp, typename _Context, + typename _Formatter + = typename _Context::template formatter_type<remove_const_t<_Tp>>, + typename _ParseContext + = basic_format_parse_context<typename _Context::char_type>> + concept __parsable_with + = semiregular<_Formatter> + && requires (_Formatter __f, _ParseContext __pc) + { + { __f.parse(__pc) } -> same_as<typename _ParseContext::iterator>; + }; + + template<typename _Tp, typename _Context, + typename _Formatter + = typename _Context::template formatter_type<remove_const_t<_Tp>>, + typename _ParseContext + = basic_format_parse_context<typename _Context::char_type>> + concept __formattable_with + = semiregular<_Formatter> + && requires (const _Formatter __cf, _Tp&& __t, _Context __fc) + { + { __cf.format(__t, __fc) } -> same_as<typename _Context::iterator>; + }; + + // An unspecified output iterator type used in the `formattable` concept. + template<typename _CharT> + struct _Iter_for; + template<typename _CharT> + using _Iter_for_t = typename _Iter_for<_CharT>::type; + + template<typename _Tp, typename _CharT, + typename _Context = basic_format_context<_Iter_for_t<_CharT>, _CharT>> + concept __formattable_impl + = __parsable_with<_Tp, _Context> && __formattable_with<_Tp, _Context>; + + template<typename _Formatter> + concept __has_debug_format = requires(_Formatter __f) + { + __f.set_debug_format(); + }; +} // namespace __format +/// @endcond + +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED + // [format.formattable], concept formattable + template<typename _Tp, typename _CharT> + concept formattable + = __format::__formattable_impl<remove_reference_t<_Tp>, _CharT>; + + template<typename _Tp, __format::__char _CharT = char> + requires same_as<remove_cvref_t<_Tp>, _Tp> && formattable<_Tp, _CharT> + class range_formatter; + +/// @cond undocumented +namespace __format +{ + template<typename _Rg, typename _CharT> + concept __const_formattable_range + = ranges::input_range<const _Rg> + && formattable<ranges::range_reference_t<const _Rg>, _CharT>; + + // _Rg& and const _Rg& are both formattable and use same formatter + // specialization for their references. + template<typename _Rg, typename _CharT> + concept __simply_formattable_range + = __const_formattable_range<_Rg, _CharT> + && same_as<remove_cvref_t<ranges::range_reference_t<_Rg>>, + remove_cvref_t<ranges::range_reference_t<const _Rg>>>; + + template<typename _Rg, typename _CharT> + using __maybe_const_range + = __conditional_t<__const_formattable_range<_Rg, _CharT>, const _Rg, _Rg>; + + template<typename _Tp, typename _CharT> + using __maybe_const + = __conditional_t<formattable<const _Tp, _CharT>, const _Tp, _Tp>; } +#endif // format_ranges _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index 84882a5..8bcfb80 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -46,7 +46,7 @@ #include <ext/alloc_traits.h> #include <ext/aligned_buffer.h> #include <debug/assertions.h> -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <bits/ranges_base.h> // ranges::begin, ranges::distance etc. # include <bits/ranges_util.h> // ranges::subrange #endif @@ -896,7 +896,7 @@ namespace __fwdlist : _Base(_Node_alloc_type(__al)) { _M_range_initialize(__first, __last); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a forward_list from a range. * @param __rg An input range with elements that are convertible to @@ -918,7 +918,7 @@ namespace __fwdlist __to = __to->_M_next; } } -#endif // ranges_to_container +#endif // containers_ranges /** * @brief The %forward_list copy constructor. @@ -1071,7 +1071,7 @@ namespace __fwdlist } #pragma GCC diagnostic pop -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Assign a range to a forward_list. * @since C++23 @@ -1102,7 +1102,7 @@ namespace __fwdlist insert_range_after(__prev, ranges::subrange(std::move(__first), __last)); } -#endif // ranges_to_container +#endif // containers_ranges #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr @@ -1345,7 +1345,7 @@ namespace __fwdlist push_front(_Tp&& __val) { this->_M_insert_after(cbefore_begin(), std::move(__val)); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Insert a range at the beginning of a forward_list. * @param __rg An input range with elements that are convertible to @@ -1370,7 +1370,7 @@ namespace __fwdlist if (!__tmp.empty()) splice_after(before_begin(), __tmp); } -#endif // ranges_to_container +#endif // containers_ranges /** * @brief Removes first element. @@ -1491,7 +1491,7 @@ namespace __fwdlist insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) { return insert_after(__pos, __il.begin(), __il.end()); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Insert a rangeinto a forward_list. * @param __position An iterator. @@ -1515,7 +1515,7 @@ namespace __fwdlist get_allocator()); return _M_splice_after(__position, __tmp.before_begin(), __tmp.end()); } -#endif // ranges_to_container +#endif // containers_ranges /** * @brief Removes the element pointed to by the iterator following @@ -1953,7 +1953,7 @@ namespace __fwdlist forward_list(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> forward_list<_ValT, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, typename _Allocator = allocator<ranges::range_value_t<_Rg>>> forward_list(from_range_t, _Rg&&, _Allocator = _Allocator()) diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index e36556d..3b73ff9 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -829,11 +829,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using __projected_Proj = _Proj; }; }; - - // Optimize the common case of the projection being std::identity. - template<typename _Iter> - struct __projected<_Iter, identity> - { using __type = _Iter; }; } // namespace __detail /// [projected], projected diff --git a/libstdc++-v3/include/bits/locale_conv.h b/libstdc++-v3/include/bits/locale_conv.h index 076e14f..b08795d 100644 --- a/libstdc++-v3/include/bits/locale_conv.h +++ b/libstdc++-v3/include/bits/locale_conv.h @@ -85,16 +85,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return false; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr // The codecvt facet will only return noconv when the types are // the same, so avoid instantiating basic_string::assign otherwise - if _GLIBCXX17_CONSTEXPR (is_same<typename _Codecvt::intern_type, - typename _Codecvt::extern_type>()) + if constexpr (is_same<typename _Codecvt::intern_type, + typename _Codecvt::extern_type>::value) if (__result == codecvt_base::noconv) { __outstr.assign(__first, __last); __count = __last - __first; return true; } +#pragma GCC diagnostic pop __outstr.resize(__outchars); __count = __next - __first; diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h index e91b003..085ca07 100644 --- a/libstdc++-v3/include/bits/move.h +++ b/libstdc++-v3/include/bits/move.h @@ -174,7 +174,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION [[__nodiscard__,__gnu__::__always_inline__]] inline _GLIBCXX17_CONSTEXPR _Tp* addressof(_Tp& __r) noexcept - { return std::__addressof(__r); } + { return __builtin_addressof(__r); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2598. addressof works on temporaries diff --git a/libstdc++-v3/include/bits/ostream.h b/libstdc++-v3/include/bits/ostream.h index d19a76a..caa47be 100644 --- a/libstdc++-v3/include/bits/ostream.h +++ b/libstdc++-v3/include/bits/ostream.h @@ -499,9 +499,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif __sign = __builtin_signbit(__f) ? _To(-1.0) : _To(+1.0); - if _GLIBCXX17_CONSTEXPR (__is_same(_To, double)) + if _GLIBCXX_CONSTEXPR (__is_same(_To, double)) __d = __builtin_copysign(__d, __sign); - else if _GLIBCXX17_CONSTEXPR (__is_same(_To, long double)) + else if _GLIBCXX_CONSTEXPR (__is_same(_To, long double)) __d = __builtin_copysignl(__d, __sign); #endif return __d; diff --git a/libstdc++-v3/include/bits/ptr_traits.h b/libstdc++-v3/include/bits/ptr_traits.h index d3c1765..4308669 100644 --- a/libstdc++-v3/include/bits/ptr_traits.h +++ b/libstdc++-v3/include/bits/ptr_traits.h @@ -223,7 +223,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Obtain address referenced by a pointer to an object * @param __ptr A pointer to an object - * @return @c __ptr + * @return `__ptr` * @ingroup pointer_abstractions */ template<typename _Tp> @@ -239,8 +239,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Obtain address referenced by a pointer to an object * @param __ptr A pointer to an object - * @return @c pointer_traits<_Ptr>::to_address(__ptr) if that expression is - well-formed, otherwise @c to_address(__ptr.operator->()) + * @return `pointer_traits<_Ptr>::to_address(__ptr)` if that expression is + * well-formed, otherwise `to_address(__ptr.operator->())`. * @ingroup pointer_abstractions */ template<typename _Ptr> diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc index 752d707..53ccacb 100644 --- a/libstdc++-v3/include/bits/random.tcc +++ b/libstdc++-v3/include/bits/random.tcc @@ -849,11 +849,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr result_type __range = max() - min(); size_t __j = __k; const result_type __y = _M_y - min(); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr // Avoid using slower long double arithmetic if possible. - if _GLIBCXX17_CONSTEXPR (__detail::__p1_representable_as_double(__range)) + if constexpr (__detail::__p1_representable_as_double(__range)) __j *= __y / (__range + 1.0); else __j *= __y / (__range + 1.0L); +#pragma GCC diagnostic pop _M_y = _M_v[__j]; _M_v[__j] = _M_b(); @@ -3244,8 +3247,11 @@ namespace __detail template<typename _InputIterator> seed_seq::seed_seq(_InputIterator __begin, _InputIterator __end) { - if _GLIBCXX17_CONSTEXPR (__is_random_access_iter<_InputIterator>::value) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + if constexpr (__is_random_access_iter<_InputIterator>::value) _M_v.reserve(std::distance(__begin, __end)); +#pragma GCC diagnostic pop for (_InputIterator __iter = __begin; __iter != __end; ++__iter) _M_v.push_back(__detail::__mod<result_type, diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index 13bfbb3..dde1649 100644 --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -41,7 +41,7 @@ #include <bits/max_size_type.h> #include <bits/version.h> -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <bits/utility.h> // for tuple_element_t #endif @@ -1085,7 +1085,9 @@ namespace ranges #if __glibcxx_ranges_to_container // C++ >= 23 struct from_range_t { explicit from_range_t() = default; }; inline constexpr from_range_t from_range{}; +#endif +#if __glibcxx_containers_ranges // C++ >= 23 /// @cond undocumented template<typename _T1, typename _T2> struct pair; @@ -1101,11 +1103,11 @@ namespace __detail // 4223. Deduction guides for maps are mishandling tuples and references template<ranges::input_range _Range> using __range_key_type - = remove_const_t<tuple_element_t<0, ranges::range_value_t<_Range>>>; + = remove_cvref_t<tuple_element_t<0, ranges::range_value_t<_Range>>>; template<ranges::input_range _Range> using __range_mapped_type - = tuple_element_t<1, ranges::range_value_t<_Range>>; + = remove_cvref_t<tuple_element_t<1, ranges::range_value_t<_Range>>>; // The allocator's value_type for map-like containers. template<ranges::input_range _Range> diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h index f24c7e3..21e7065 100644 --- a/libstdc++-v3/include/bits/regex_compiler.h +++ b/libstdc++-v3/include/bits/regex_compiler.h @@ -38,6 +38,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_CXX11 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr namespace __detail { /** @@ -221,9 +223,9 @@ namespace __detail _CharT _M_translate(_CharT __ch) const { - if _GLIBCXX17_CONSTEXPR (__icase) + if constexpr (__icase) return _M_traits.translate_nocase(__ch); - else if _GLIBCXX17_CONSTEXPR (__collate) + else if constexpr (__collate) return _M_traits.translate(__ch); else return __ch; @@ -285,7 +287,7 @@ namespace __detail bool _M_match_range(_CharT __first, _CharT __last, _CharT __ch) const { - if _GLIBCXX17_CONSTEXPR (!__icase) + if constexpr (!__icase) return __first <= __ch && __ch <= __last; else return this->_M_in_range_icase(__first, __last, __ch); @@ -376,26 +378,20 @@ namespace __detail bool operator()(_CharT __ch) const - { return _M_apply(__ch, typename is_same<_CharT, char>::type()); } - - bool - _M_apply(_CharT __ch, true_type) const { - auto __c = _M_translator._M_translate(__ch); - auto __n = _M_translator._M_translate('\n'); - auto __r = _M_translator._M_translate('\r'); - return __c != __n && __c != __r; - } - - bool - _M_apply(_CharT __ch, false_type) const - { - auto __c = _M_translator._M_translate(__ch); - auto __n = _M_translator._M_translate('\n'); - auto __r = _M_translator._M_translate('\r'); - auto __u2028 = _M_translator._M_translate(u'\u2028'); - auto __u2029 = _M_translator._M_translate(u'\u2029'); - return __c != __n && __c != __r && __c != __u2028 && __c != __u2029; + const auto __c = _M_translator._M_translate(__ch); + if (__c == _M_translator._M_translate('\n')) + return false; + if (__c == _M_translator._M_translate('\r')) + return false; + if constexpr (!is_same<_CharT, char>::value) + { + if (__c == _M_translator._M_translate(u'\u2028')) // line sep + return false; + if (__c == _M_translator._M_translate(u'\u2029')) // para sep + return false; + } + return true; } _TransT _M_translator; @@ -441,7 +437,10 @@ namespace __detail operator()(_CharT __ch) const { _GLIBCXX_DEBUG_ASSERT(_M_is_ready); - return _M_apply(__ch, _UseCache()); + if constexpr (_UseCache::value) + if (!(__ch & 0x80)) [[__likely__]] + return _M_cache[static_cast<_UnsignedCharT>(__ch)]; + return _M_apply(__ch); } void @@ -512,7 +511,9 @@ namespace __detail std::sort(_M_char_set.begin(), _M_char_set.end()); auto __end = std::unique(_M_char_set.begin(), _M_char_set.end()); _M_char_set.erase(__end, _M_char_set.end()); - _M_make_cache(_UseCache()); + if constexpr (_UseCache::value) + for (unsigned __i = 0; __i < 128; __i++) // Only cache 7-bit chars + _M_cache[__i] = _M_apply(static_cast<_CharT>(__i)); _GLIBCXX_DEBUG_ONLY(_M_is_ready = true); } @@ -531,22 +532,7 @@ namespace __detail using _UnsignedCharT = typename std::make_unsigned<_CharT>::type; bool - _M_apply(_CharT __ch, false_type) const; - - bool - _M_apply(_CharT __ch, true_type) const - { return _M_cache[static_cast<_UnsignedCharT>(__ch)]; } - - void - _M_make_cache(true_type) - { - for (unsigned __i = 0; __i < _M_cache.size(); __i++) - _M_cache[__i] = _M_apply(static_cast<_CharT>(__i), false_type()); - } - - void - _M_make_cache(false_type) - { } + _M_apply(_CharT __ch) const; private: _GLIBCXX_STD_C::vector<_CharT> _M_char_set; @@ -565,6 +551,7 @@ namespace __detail ///@} regex-detail } // namespace __detail +#pragma GCC diagnostic pop _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc index cd0db27..59b79fd 100644 --- a/libstdc++-v3/include/bits/regex_compiler.tcc +++ b/libstdc++-v3/include/bits/regex_compiler.tcc @@ -598,7 +598,7 @@ namespace __detail template<typename _TraitsT, bool __icase, bool __collate> bool _BracketMatcher<_TraitsT, __icase, __collate>:: - _M_apply(_CharT __ch, false_type) const + _M_apply(_CharT __ch) const { return [this, __ch] { diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc index e887e28..8f0f756 100644 --- a/libstdc++-v3/include/bits/regex_executor.tcc +++ b/libstdc++-v3/include/bits/regex_executor.tcc @@ -32,6 +32,8 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr namespace __detail { template<typename _BiIter, typename _Alloc, typename _TraitsT, @@ -217,7 +219,7 @@ namespace __detail } else // Non-greedy mode { - if (__dfs_mode) + if constexpr (__dfs_mode) { // vice-versa. _M_dfs(__match_mode, __state._M_next); @@ -322,7 +324,7 @@ namespace __detail if (_M_current == _M_end) return; - if (__dfs_mode) + if constexpr (__dfs_mode) { if (__state._M_matches(*_M_current)) { @@ -393,7 +395,7 @@ namespace __detail void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_backref(_Match_mode __match_mode, _StateIdT __i) { - __glibcxx_assert(__dfs_mode); + static_assert(__dfs_mode, "this should never be instantiated"); const auto& __state = _M_nfa[__i]; auto& __submatch = _M_cur_results[__state._M_backref_index]; @@ -426,7 +428,7 @@ namespace __detail void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_accept(_Match_mode __match_mode, _StateIdT) { - if _GLIBCXX17_CONSTEXPR (__dfs_mode) + if constexpr (__dfs_mode) { __glibcxx_assert(!_M_has_sol); if (__match_mode == _Match_mode::_Exact) @@ -529,7 +531,11 @@ namespace __detail case _S_opcode_match: _M_handle_match(__match_mode, __i); break; case _S_opcode_backref: - _M_handle_backref(__match_mode, __i); break; + if constexpr (__dfs_mode) + _M_handle_backref(__match_mode, __i); + else + __builtin_unreachable(); + break; case _S_opcode_accept: _M_handle_accept(__match_mode, __i); break; case _S_opcode_alternative: @@ -564,6 +570,7 @@ namespace __detail return __left_is_word != __right_is_word; } } // namespace __detail +#pragma GCC diagnostic pop _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 3622e02..b4be1b4 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -315,6 +315,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline void _Sp_counted_base<_S_atomic>::_M_release() noexcept { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); #if ! _GLIBCXX_TSAN constexpr bool __lock_free @@ -325,7 +327,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // The ref-count members follow the vptr, so are aligned to // alignof(void*). constexpr bool __aligned = __alignof(long long) <= alignof(void*); - if _GLIBCXX17_CONSTEXPR (__lock_free && __double_word && __aligned) + if constexpr (__lock_free && __double_word && __aligned) { constexpr int __wordbits = __CHAR_BIT__ * sizeof(_Atomic_word); constexpr int __shiftbits = __double_word ? __wordbits : 0; @@ -359,6 +361,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _M_release_last_use(); } +#pragma GCC diagnostic pop } template<> diff --git a/libstdc++-v3/include/bits/std_function.h b/libstdc++-v3/include/bits/std_function.h index 1bf8b9a..3bfbe82 100644 --- a/libstdc++-v3/include/bits/std_function.h +++ b/libstdc++-v3/include/bits/std_function.h @@ -135,13 +135,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _Functor* _M_get_pointer(const _Any_data& __source) noexcept { - if _GLIBCXX17_CONSTEXPR (__stored_locally) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + if constexpr (__stored_locally) { const _Functor& __f = __source._M_access<_Functor>(); return const_cast<_Functor*>(std::__addressof(__f)); } else // have stored a pointer return __source._M_access<_Functor*>(); +#pragma GCC diagnostic pop } private: @@ -312,21 +315,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return false; } }; - // Avoids instantiating ill-formed specializations of _Function_handler - // in std::function<_Signature>::target<_Functor>(). - // e.g. _Function_handler<Sig, void()> and _Function_handler<Sig, void> - // would be ill-formed. - template<typename _Signature, typename _Functor, - bool __valid = is_object<_Functor>::value> - struct _Target_handler - : _Function_handler<_Signature, typename remove_cv<_Functor>::type> - { }; - - template<typename _Signature, typename _Functor> - struct _Target_handler<_Signature, _Functor, false> - : _Function_handler<void, void> - { }; - /** * @brief Polymorphic function wrapper. * @ingroup functors @@ -644,13 +632,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const _Functor* target() const noexcept { - if _GLIBCXX17_CONSTEXPR (is_object<_Functor>::value) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + if constexpr (is_object<_Functor>::value) { - // For C++11 and C++14 if-constexpr is not used above, so - // _Target_handler avoids ill-formed _Function_handler types. - using _Handler = _Target_handler<_Res(_ArgTypes...), _Functor>; - - if (_M_manager == &_Handler::_M_manager + if (_M_manager == &_Handler<_Functor>::_M_manager #if __cpp_rtti || (_M_manager && typeid(_Functor) == target_type()) #endif @@ -661,6 +647,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __ptr._M_access<const _Functor*>(); } } +#pragma GCC diagnostic pop return nullptr; } /// @} diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index 03f6434..8cc2920 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -896,7 +896,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a vector from a range. * @param __rg A range of values that are convertible to `value_type`. @@ -1026,7 +1026,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Assign a range to the vector. * @param __rg A range of values that are convertible to `value_type`. @@ -1347,7 +1347,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { return this->insert(__p, __l.begin(), __l.end()); } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Insert a range into the vector. * @param __rg A range of values that are convertible to `bool`. @@ -1458,7 +1458,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(end(), __tmp.begin(), __tmp.end()); } } -#endif // ranges_to_container +#endif // containers_ranges _GLIBCXX20_CONSTEXPR void diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 94e0886..8d8ee57 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -1022,7 +1022,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a deque from a range. * @param __rg A range of values that are convertible to `value_type`. @@ -1150,7 +1150,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Assign a range to the deque. * @param __rg A range of values that are convertible to `value_type`. @@ -1194,7 +1194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER emplace_back(*__first); } } -#endif // ranges_to_container +#endif // containers_ranges /// Get a copy of the memory allocation object. @@ -1824,7 +1824,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Insert a range into the deque. * @param __rg A range of values that are convertible to `value_type`. @@ -1854,7 +1854,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<__detail::__container_compatible_range<_Tp> _Rg> void append_range(_Rg&& __rg); -#endif // ranges_to_container +#endif // containers_ranges /** * @brief Remove element at given position. @@ -2386,7 +2386,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER deque(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> deque<_ValT, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, typename _Alloc = allocator<ranges::range_value_t<_Rg>>> deque(from_range_t, _Rg&&, _Alloc = _Alloc()) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 33732b1..bed7295 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -2933,10 +2933,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(noexcept(_M_current - __y)) { return _M_current - __y; } - template<__detail::__not_a_const_iterator _Sent> + template<__detail::__not_a_const_iterator _Sent, same_as<_It> _It2> requires sized_sentinel_for<_Sent, _It> friend constexpr difference_type - operator-(const _Sent& __x, const basic_const_iterator& __y) + operator-(const _Sent& __x, const basic_const_iterator<_It2>& __y) noexcept(noexcept(__x - __y._M_current)) { return __x - __y._M_current; } @@ -3086,8 +3086,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cpp_deduction_guides >= 201606 // These helper traits are used for deduction guides // of associative containers. + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4223. Deduction guides for maps are mishandling tuples and references template<typename _InputIterator> - using __iter_key_t = remove_const_t< + using __iter_key_t = __remove_cvref_t< #ifdef __glibcxx_tuple_like // >= C++23 tuple_element_t<0, typename iterator_traits<_InputIterator>::value_type>>; #else @@ -3095,11 +3098,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif template<typename _InputIterator> - using __iter_val_t + using __iter_val_t = __remove_cvref_t< #ifdef __glibcxx_tuple_like // >= C++23 - = tuple_element_t<1, typename iterator_traits<_InputIterator>::value_type>; + tuple_element_t<1, typename iterator_traits<_InputIterator>::value_type>>; #else - = typename iterator_traits<_InputIterator>::value_type::second_type; + typename iterator_traits<_InputIterator>::value_type::second_type>; #endif template<typename _T1, typename _T2> diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index 82ccb50..d27824c 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -66,7 +66,7 @@ #include <bits/ptr_traits.h> #include <ext/aligned_buffer.h> #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <bits/ranges_base.h> // ranges::begin, ranges::distance etc. # include <bits/ranges_util.h> // ranges::subrange #endif @@ -1263,7 +1263,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a list from a range. * @since C++23 @@ -1360,7 +1360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Assign a range to a list. * @since C++23 @@ -1726,7 +1726,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Insert a range at the beginning of a list. * @param __rg An input range of elements that can be converted to @@ -1964,7 +1964,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Insert a range into a list. * @param __position An iterator. @@ -2594,7 +2594,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 list(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> list<_ValT, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, typename _Allocator = allocator<ranges::range_value_t<_Rg>>> list(from_range_t, _Rg&&, _Allocator = _Allocator()) diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h index 9381a79..68c23b8 100644 --- a/libstdc++-v3/include/bits/stl_map.h +++ b/libstdc++-v3/include/bits/stl_map.h @@ -62,7 +62,7 @@ #include <initializer_list> #include <tuple> #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <bits/ranges_base.h> // ranges::begin, ranges::distance etc. #endif @@ -308,7 +308,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_t(__comp, _Pair_alloc_type(__a)) { _M_t._M_insert_range_unique(__first, __last); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Builds a %map from a range. * @since C++23 @@ -903,7 +903,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { insert(__list.begin(), __list.end()); } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Inserts a range of elements. * @since C++23 @@ -1156,7 +1156,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ size_type erase(const key_type& __x) - { return _M_t.erase(__x); } + { return _M_t._M_erase_unique(__x); } #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -1536,7 +1536,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER map(initializer_list<pair<_Key, _Tp>>, _Allocator) -> map<_Key, _Tp, less<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Compare = less<__detail::__range_key_type<_Rg>>, __allocator_like _Alloc = diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h index 8fca3a4..4ee4a84 100644 --- a/libstdc++-v3/include/bits/stl_multimap.h +++ b/libstdc++-v3/include/bits/stl_multimap.h @@ -60,7 +60,7 @@ #if __cplusplus >= 201103L #include <initializer_list> #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <bits/ranges_base.h> // ranges::begin, ranges::distance etc. #endif @@ -297,7 +297,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_t(__comp, _Pair_alloc_type(__a)) { _M_t._M_insert_range_equal(__first, __last); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Builds a %multimap from a range. * @since C++23 @@ -655,7 +655,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { this->insert(__l.begin(), __l.end()); } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Inserts a range of elements. * @since C++23 @@ -1159,7 +1159,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER multimap(initializer_list<pair<_Key, _Tp>>, _Allocator) -> multimap<_Key, _Tp, less<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Compare = less<__detail::__range_key_type<_Rg>>, __allocator_like _Alloc = diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h index 7030f28..31451ab 100644 --- a/libstdc++-v3/include/bits/stl_multiset.h +++ b/libstdc++-v3/include/bits/stl_multiset.h @@ -60,7 +60,7 @@ #if __cplusplus >= 201103L #include <initializer_list> #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <bits/ranges_base.h> // ranges::begin, ranges::distance etc. #endif @@ -274,7 +274,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_t(_Key_alloc_type(__a)) { _M_t._M_insert_range_equal(__first, __last); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Builds a %multiset from a range. * @since C++23 @@ -588,7 +588,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { this->insert(__l.begin(), __l.end()); } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Inserts a range of elements. * @since C++23 @@ -996,7 +996,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER multiset(initializer_list<_Key>, _Allocator) -> multiset<_Key, less<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Compare = less<ranges::range_value_t<_Rg>>, __allocator_like _Alloc = std::allocator<ranges::range_value_t<_Rg>>> diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h index 2a4b629..a3a8bc1 100644 --- a/libstdc++-v3/include/bits/stl_queue.h +++ b/libstdc++-v3/include/bits/stl_queue.h @@ -61,7 +61,7 @@ #if __cplusplus >= 201103L # include <bits/uses_allocator.h> #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <ranges> // ranges::to # include <bits/ranges_algobase.h> // ranges::copy #endif @@ -70,6 +70,10 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if __glibcxx_format_ranges + template<typename, typename> class formatter; +#endif + /** * @brief A standard container giving FIFO behavior. * @@ -213,7 +217,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : c(__first, __last, __a) { } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a queue from a range. * @since C++23 @@ -326,7 +330,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<_Tp> _Rg> void push_range(_Rg&& __rg) @@ -369,6 +373,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION swap(c, __q.c); } #endif // __cplusplus >= 201103L + +#if __glibcxx_format_ranges + friend class formatter<queue<_Tp, _Sequence>, char>; + friend class formatter<queue<_Tp, _Sequence>, wchar_t>; +#endif }; #if __cpp_deduction_guides >= 201606 @@ -397,7 +406,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION -> queue<_ValT, deque<_ValT, _Allocator>>; #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg> queue(from_range_t, _Rg&&) -> queue<ranges::range_value_t<_Rg>>; @@ -766,7 +775,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a priority_queue from a range. * @since C++23 @@ -849,7 +858,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<_Tp> _Rg> void push_range(_Rg&& __rg) @@ -898,6 +907,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION swap(comp, __pq.comp); } #endif // __cplusplus >= 201103L + +#if __glibcxx_format_ranges + friend class formatter<priority_queue<_Tp, _Sequence, _Compare>, char>; + friend class formatter<priority_queue<_Tp, _Sequence, _Compare>, wchar_t>; +#endif }; #if __cpp_deduction_guides >= 201606 @@ -924,7 +938,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION priority_queue(_Compare, _Container, _Allocator) -> priority_queue<typename _Container::value_type, _Container, _Compare>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Compare = less<ranges::range_value_t<_Rg>>, __allocator_like _Alloc = std::allocator<ranges::range_value_t<_Rg>>> diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h index 124237e..b65d631 100644 --- a/libstdc++-v3/include/bits/stl_set.h +++ b/libstdc++-v3/include/bits/stl_set.h @@ -60,7 +60,7 @@ #if __cplusplus >= 201103L #include <initializer_list> #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <bits/ranges_base.h> // ranges::begin, ranges::distance etc. #endif @@ -278,7 +278,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_t(_Key_alloc_type(__a)) { _M_t._M_insert_range_unique(__first, __last); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Builds a %set from a range. * @since C++23 @@ -603,7 +603,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { this->insert(__l.begin(), __l.end()); } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Inserts a range of elements. * @since C++23 @@ -728,7 +728,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ size_type erase(const key_type& __x) - { return _M_t.erase(__x); } + { return _M_t._M_erase_unique(__x); } #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -1014,7 +1014,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER set(initializer_list<_Key>, _Allocator) -> set<_Key, less<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Compare = less<ranges::range_value_t<_Rg>>, __allocator_like _Alloc = std::allocator<ranges::range_value_t<_Rg>>> diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h index 2a274bf..27c79d6 100644 --- a/libstdc++-v3/include/bits/stl_stack.h +++ b/libstdc++-v3/include/bits/stl_stack.h @@ -61,7 +61,7 @@ #if __cplusplus >= 201103L # include <bits/uses_allocator.h> #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <ranges> // ranges::to # include <bits/ranges_algobase.h> // ranges::copy #endif @@ -70,6 +70,10 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if __glibcxx_format_ranges + template<typename, typename> class formatter; +#endif + /** * @brief A standard container giving FILO behavior. * @@ -181,7 +185,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : c(__first, __last) { } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a stack from a range. * @since C++23 @@ -300,7 +304,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<_Tp> _Rg> void push_range(_Rg&& __rg) @@ -343,6 +347,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION swap(c, __s.c); } #endif // __cplusplus >= 201103L + +#if __glibcxx_format_ranges + friend class formatter<stack<_Tp, _Sequence>, char>; + friend class formatter<stack<_Tp, _Sequence>, wchar_t>; +#endif }; #if __cpp_deduction_guides >= 201606 @@ -371,7 +380,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION -> stack<_ValT, deque<_ValT, _Allocator>>; #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg> stack(from_range_t, _Rg&&) -> stack<ranges::range_value_t<_Rg>>; diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index 6b35f99..4b7f482 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -1390,27 +1390,25 @@ namespace __rb_tree _M_end() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_base_ptr(); } - static const _Key& - _S_key(const _Node& __node) - { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2542. Missing const requirements for associative containers + template<typename _Key1, typename _Key2> + bool + _M_key_compare(const _Key1& __k1, const _Key2& __k2) const + { #if __cplusplus >= 201103L - // If we're asking for the key we're presumably using the comparison - // object, and so this is a good place to sanity check it. - static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{}, - "comparison object must be invocable " - "with two arguments of key type"); -# if __cplusplus >= 201703L - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 2542. Missing const requirements for associative containers - if constexpr (__is_invocable<_Compare&, const _Key&, const _Key&>{}) + // Enforce this here with a user-friendly message. static_assert( - is_invocable_v<const _Compare&, const _Key&, const _Key&>, - "comparison object must be invocable as const"); -# endif // C++17 -#endif // C++11 + __is_invocable<const _Compare&, const _Key&, const _Key&>::value, + "comparison object must be invocable with two arguments of key type" + ); +#endif + return _M_impl._M_key_compare(__k1, __k2); + } - return _KeyOfValue()(*__node._M_valptr()); - } + static const _Key& + _S_key(const _Node& __node) + { return _KeyOfValue()(*__node._M_valptr()); } static const _Key& _S_key(_Base_ptr __x) @@ -1852,6 +1850,9 @@ namespace __rb_tree size_type erase(const key_type& __x); + size_type + _M_erase_unique(const key_type& __x); + #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. @@ -1933,7 +1934,7 @@ namespace __rb_tree _M_find_tr(const _Kt& __k) const { const_iterator __j(_M_lower_bound_tr(__k)); - if (__j != end() && _M_impl._M_key_compare(__k, _S_key(__j._M_node))) + if (__j != end() && _M_key_compare(__k, _S_key(__j._M_node))) __j = end(); return __j; } @@ -1955,7 +1956,7 @@ namespace __rb_tree auto __x = _M_begin(); auto __y = _M_end(); while (__x) - if (!_M_impl._M_key_compare(_S_key(__x), __k)) + if (!_M_key_compare(_S_key(__x), __k)) { __y = __x; __x = _S_left(__x); @@ -1973,7 +1974,7 @@ namespace __rb_tree auto __x = _M_begin(); auto __y = _M_end(); while (__x) - if (_M_impl._M_key_compare(__k, _S_key(__x))) + if (_M_key_compare(__k, _S_key(__x))) { __y = __x; __x = _S_left(__x); @@ -2342,8 +2343,11 @@ namespace __rb_tree constexpr bool __move = !__move_if_noexcept_cond<value_type>::value; _Alloc_node __an(*this); _M_root() = _M_copy<__move>(__x, __an); - if _GLIBCXX17_CONSTEXPR (__move) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + if constexpr (__move) __x.clear(); +#pragma GCC diagnostic pop } } @@ -2474,8 +2478,8 @@ namespace __rb_tree _NodeGen& __node_gen) { bool __insert_left = (__x || __p == _M_end() - || _M_impl._M_key_compare(_KeyOfValue()(__v), - _S_key(__p))); + || _M_key_compare(_KeyOfValue()(__v), + _S_key(__p))); _Base_ptr __z = __node_gen(_GLIBCXX_FORWARD(_Arg, __v))->_M_base_ptr(); @@ -2500,8 +2504,8 @@ namespace __rb_tree #endif { bool __insert_left = (__p == _M_end() - || !_M_impl._M_key_compare(_S_key(__p), - _KeyOfValue()(__v))); + || !_M_key_compare(_S_key(__p), + _KeyOfValue()(__v))); _Base_ptr __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v))->_M_base_ptr(); @@ -2529,7 +2533,7 @@ namespace __rb_tree while (__x) { __y = __x; - __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ? + __x = !_M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ? _S_left(__x) : _S_right(__x); } return _M_insert_lower(__y, _GLIBCXX_FORWARD(_Arg, __v)); @@ -2601,7 +2605,7 @@ namespace __rb_tree const _Key& __k) const { while (__x) - if (!_M_impl._M_key_compare(_S_key(__x), __k)) + if (!_M_key_compare(_S_key(__x), __k)) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); @@ -2617,7 +2621,7 @@ namespace __rb_tree const _Key& __k) const { while (__x) - if (_M_impl._M_key_compare(__k, _S_key(__x))) + if (_M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); @@ -2639,9 +2643,9 @@ namespace __rb_tree _Base_ptr __y = _M_end(); while (__x) { - if (_M_impl._M_key_compare(_S_key(__x), __k)) + if (_M_key_compare(_S_key(__x), __k)) __x = _S_right(__x); - else if (_M_impl._M_key_compare(__k, _S_key(__x))) + else if (_M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else { @@ -2671,9 +2675,9 @@ namespace __rb_tree _Base_ptr __y = _M_end(); while (__x) { - if (_M_impl._M_key_compare(_S_key(__x), __k)) + if (_M_key_compare(_S_key(__x), __k)) __x = _S_right(__x); - else if (_M_impl._M_key_compare(__k, _S_key(__x))) + else if (_M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else { @@ -2737,7 +2741,7 @@ namespace __rb_tree while (__x) { __y = __x; - __comp = _M_impl._M_key_compare(__k, _S_key(__x)); + __comp = _M_key_compare(__k, _S_key(__x)); __x = __comp ? _S_left(__x) : _S_right(__x); } iterator __j = iterator(__y); @@ -2748,7 +2752,7 @@ namespace __rb_tree else --__j; } - if (_M_impl._M_key_compare(_S_key(__j._M_node), __k)) + if (_M_key_compare(_S_key(__j._M_node), __k)) return _Res(__x, __y); return _Res(__j._M_node, _Base_ptr()); } @@ -2768,8 +2772,7 @@ namespace __rb_tree while (__x) { __y = __x; - __x = _M_impl._M_key_compare(__k, _S_key(__x)) ? - _S_left(__x) : _S_right(__x); + __x = _M_key_compare(__k, _S_key(__x)) ? _S_left(__x) : _S_right(__x); } return _Res(__x, __y); } @@ -2838,19 +2841,18 @@ namespace __rb_tree // end() if (__position._M_node == _M_end()) { - if (size() > 0 - && _M_impl._M_key_compare(_S_key(_M_rightmost()), __k)) + if (size() > 0 && _M_key_compare(_S_key(_M_rightmost()), __k)) return _Res(_Base_ptr(), _M_rightmost()); else return _M_get_insert_unique_pos(__k); } - else if (_M_impl._M_key_compare(__k, _S_key(__position._M_node))) + else if (_M_key_compare(__k, _S_key(__position._M_node))) { // First, try before... iterator __before(__position._M_node); if (__position._M_node == _M_leftmost()) // begin() return _Res(_M_leftmost(), _M_leftmost()); - else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k)) + else if (_M_key_compare(_S_key((--__before)._M_node), __k)) { if (!_S_right(__before._M_node)) return _Res(_Base_ptr(), __before._M_node); @@ -2860,13 +2862,13 @@ namespace __rb_tree else return _M_get_insert_unique_pos(__k); } - else if (_M_impl._M_key_compare(_S_key(__position._M_node), __k)) + else if (_M_key_compare(_S_key(__position._M_node), __k)) { // ... then try after. iterator __after(__position._M_node); if (__position._M_node == _M_rightmost()) return _Res(_Base_ptr(), _M_rightmost()); - else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node))) + else if (_M_key_compare(__k, _S_key((++__after)._M_node))) { if (!_S_right(__position._M_node)) return _Res(_Base_ptr(), __position._M_node); @@ -2923,18 +2925,18 @@ namespace __rb_tree if (__position._M_node == _M_end()) { if (size() > 0 - && !_M_impl._M_key_compare(__k, _S_key(_M_rightmost()))) + && !_M_key_compare(__k, _S_key(_M_rightmost()))) return _Res(_Base_ptr(), _M_rightmost()); else return _M_get_insert_equal_pos(__k); } - else if (!_M_impl._M_key_compare(_S_key(__position._M_node), __k)) + else if (!_M_key_compare(_S_key(__position._M_node), __k)) { // First, try before... iterator __before(__position._M_node); if (__position._M_node == _M_leftmost()) // begin() return _Res(_M_leftmost(), _M_leftmost()); - else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node))) + else if (!_M_key_compare(__k, _S_key((--__before)._M_node))) { if (!_S_right(__before._M_node)) return _Res(_Base_ptr(), __before._M_node); @@ -2950,7 +2952,7 @@ namespace __rb_tree iterator __after(__position._M_node); if (__position._M_node == _M_rightmost()) return _Res(_Base_ptr(), _M_rightmost()); - else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k)) + else if (!_M_key_compare(_S_key((++__after)._M_node), __k)) { if (!_S_right(__position._M_node)) return _Res(_Base_ptr(), __position._M_node); @@ -2999,8 +3001,7 @@ namespace __rb_tree -> iterator { bool __insert_left = (__x || __p == _M_end() - || _M_impl._M_key_compare(_S_key(__z), - _S_key(__p))); + || _M_key_compare(_S_key(__z), _S_key(__p))); _Base_ptr __base_z = __z->_M_base_ptr(); _Node_traits::_S_insert_and_rebalance @@ -3017,8 +3018,7 @@ namespace __rb_tree -> iterator { bool __insert_left = (__p == _M_end() - || !_M_impl._M_key_compare(_S_key(__p), - _S_key(__z))); + || !_M_key_compare(_S_key(__p), _S_key(__z))); _Base_ptr __base_z = __z->_M_base_ptr(); _Node_traits::_S_insert_and_rebalance @@ -3039,7 +3039,7 @@ namespace __rb_tree while (__x) { __y = __x; - __x = !_M_impl._M_key_compare(_S_key(__x), _S_key(__z)) ? + __x = !_M_key_compare(_S_key(__x), _S_key(__z)) ? _S_left(__x) : _S_right(__x); } return _M_insert_lower_node(__y, __z); @@ -3144,6 +3144,20 @@ namespace __rb_tree template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_erase_unique(const _Key& __x) + { + iterator __it = find(__x); + if (__it == end()) + return 0; + + _M_erase_aux(__it); + return 1; + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: @@ -3151,8 +3165,7 @@ namespace __rb_tree { iterator __j(_M_lower_bound(_M_begin(), _M_end(), __k)); return (__j == end() - || _M_impl._M_key_compare(__k, - _S_key(__j._M_node))) ? end() : __j; + || _M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; } template<typename _Key, typename _Val, typename _KeyOfValue, @@ -3164,8 +3177,7 @@ namespace __rb_tree { const_iterator __j(_M_lower_bound(_M_begin(), _M_end(), __k)); return (__j == end() - || _M_impl._M_key_compare(__k, - _S_key(__j._M_node))) ? end() : __j; + || _M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; } template<typename _Key, typename _Val, typename _KeyOfValue, @@ -3205,9 +3217,9 @@ namespace __rb_tree || (__R && __R->_M_color == _S_red)) return false; - if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L))) + if (__L && _M_key_compare(_S_key(__x), _S_key(__L))) return false; - if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x))) + if (__R && _M_key_compare(_S_key(__R), _S_key(__x))) return false; if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len) diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 458adc9..57680b7 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -68,7 +68,7 @@ #if __glibcxx_concepts // C++ >= C++20 # include <bits/ranges_base.h> // ranges::distance #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <bits/ranges_algobase.h> // ranges::copy # include <bits/ranges_util.h> // ranges::subrange #endif @@ -407,7 +407,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 // Called by insert_range, and indirectly by assign_range, append_range. // Initializes new elements in storage at __ptr and updates __ptr to // point after the last new element. @@ -518,29 +518,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER return _S_nothrow_relocate(__is_move_insertable<_Tp_alloc_type>{}); } - static pointer - _S_do_relocate(pointer __first, pointer __last, pointer __result, - _Tp_alloc_type& __alloc, true_type) noexcept - { - return std::__relocate_a(__first, __last, __result, __alloc); - } - - static pointer - _S_do_relocate(pointer, pointer, pointer __result, - _Tp_alloc_type&, false_type) noexcept - { return __result; } - static _GLIBCXX20_CONSTEXPR pointer _S_relocate(pointer __first, pointer __last, pointer __result, _Tp_alloc_type& __alloc) noexcept { -#if __cpp_if_constexpr - // All callers have already checked _S_use_relocate() so just do it. - return std::__relocate_a(__first, __last, __result, __alloc); -#else - using __do_it = __bool_constant<_S_use_relocate()>; - return _S_do_relocate(__first, __last, __result, __alloc, __do_it{}); -#endif +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + if constexpr (_S_use_relocate()) + return std::__relocate_a(__first, __last, __result, __alloc); + else + return __result; +#pragma GCC diagnostic pop } #endif // C++11 @@ -763,7 +751,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a vector from a range. * @param __rg A range of values that are convertible to `bool`. @@ -926,7 +914,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Assign a range to the vector. * @param __rg A range of values that are convertible to `value_type`. @@ -982,7 +970,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } } } -#endif // ranges_to_container +#endif // containers_ranges /// Get a copy of the memory allocation object. using _Base::get_allocator; @@ -1648,7 +1636,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Insert a range into the vector. * @param __rg A range of values that are convertible to `value_type`. @@ -1769,7 +1757,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER append_range(__r); // This will take the fast path above. } } -#endif // ranges_to_container +#endif // containers_ranges /** * @brief Remove element at given position. @@ -2313,7 +2301,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER vector(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> vector<_ValT, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, typename _Alloc = allocator<ranges::range_value_t<_Rg>>> vector(from_range_t, _Rg&&, _Alloc = _Alloc()) diff --git a/libstdc++-v3/include/bits/unicode-data.h b/libstdc++-v3/include/bits/unicode-data.h index fc0a4b3..0ab5ecb 100644 --- a/libstdc++-v3/include/bits/unicode-data.h +++ b/libstdc++-v3/include/bits/unicode-data.h @@ -33,7 +33,7 @@ # error "Version mismatch for Unicode static data" #endif - // Table generated by contrib/unicode/gen_std_format_width.py, + // Table generated by contrib/unicode/gen_libstdcxx_unicode_data.py, // from EastAsianWidth.txt from the Unicode standard. inline constexpr char32_t __width_edges[] = { 0x1100, 0x1160, 0x231a, 0x231c, 0x2329, 0x232b, 0x23e9, 0x23ed, @@ -64,6 +64,258 @@ 0x1faf0, 0x1faf9, 0x20000, 0x2fffe, 0x30000, 0x3fffe, }; + // Values generated by contrib/unicode/gen_libstdcxx_unicode_data.py, + // from DerivedGeneralCategory.txt from the Unicode standard. + // Entries are (code_point << 1) + escape. + inline constexpr uint32_t __escape_edges[] = { + 0x1, 0x42, 0xff, 0x142, 0x15b, 0x15c, + 0x6f1, 0x6f4, 0x701, 0x708, 0x717, 0x718, + 0x71b, 0x71c, 0x745, 0x746, 0xa61, 0xa62, + 0xaaf, 0xab2, 0xb17, 0xb1a, 0xb21, 0xb22, + 0xb91, 0xba0, 0xbd7, 0xbde, 0xbeb, 0xc0c, + 0xc39, 0xc3a, 0xdbb, 0xdbc, 0xe1d, 0xe20, + 0xe97, 0xe9a, 0xf65, 0xf80, 0xff7, 0xffa, + 0x105d, 0x1060, 0x107f, 0x1080, 0x10b9, 0x10bc, + 0x10bf, 0x10c0, 0x10d7, 0x10e0, 0x111f, 0x112e, + 0x11c5, 0x11c6, 0x1309, 0x130a, 0x131b, 0x131e, + 0x1323, 0x1326, 0x1353, 0x1354, 0x1363, 0x1364, + 0x1367, 0x136c, 0x1375, 0x1378, 0x138b, 0x138e, + 0x1393, 0x1396, 0x139f, 0x13ae, 0x13b1, 0x13b8, + 0x13bd, 0x13be, 0x13c9, 0x13cc, 0x13ff, 0x1402, + 0x1409, 0x140a, 0x1417, 0x141e, 0x1423, 0x1426, + 0x1453, 0x1454, 0x1463, 0x1464, 0x1469, 0x146a, + 0x146f, 0x1470, 0x1475, 0x1478, 0x147b, 0x147c, + 0x1487, 0x148e, 0x1493, 0x1496, 0x149d, 0x14a2, + 0x14a5, 0x14b2, 0x14bb, 0x14bc, 0x14bf, 0x14cc, + 0x14ef, 0x1502, 0x1509, 0x150a, 0x151d, 0x151e, + 0x1525, 0x1526, 0x1553, 0x1554, 0x1563, 0x1564, + 0x1569, 0x156a, 0x1575, 0x1578, 0x158d, 0x158e, + 0x1595, 0x1596, 0x159d, 0x15a0, 0x15a3, 0x15c0, + 0x15c9, 0x15cc, 0x15e5, 0x15f2, 0x1601, 0x1602, + 0x1609, 0x160a, 0x161b, 0x161e, 0x1623, 0x1626, + 0x1653, 0x1654, 0x1663, 0x1664, 0x1669, 0x166a, + 0x1675, 0x1678, 0x168b, 0x168e, 0x1693, 0x1696, + 0x169d, 0x16aa, 0x16b1, 0x16b8, 0x16bd, 0x16be, + 0x16c9, 0x16cc, 0x16f1, 0x1704, 0x1709, 0x170a, + 0x1717, 0x171c, 0x1723, 0x1724, 0x172d, 0x1732, + 0x1737, 0x1738, 0x173b, 0x173c, 0x1741, 0x1746, + 0x174b, 0x1750, 0x1757, 0x175c, 0x1775, 0x177c, + 0x1787, 0x178c, 0x1793, 0x1794, 0x179d, 0x17a0, + 0x17a3, 0x17ae, 0x17b1, 0x17cc, 0x17f7, 0x1800, + 0x181b, 0x181c, 0x1823, 0x1824, 0x1853, 0x1854, + 0x1875, 0x1878, 0x188b, 0x188c, 0x1893, 0x1894, + 0x189d, 0x18aa, 0x18af, 0x18b0, 0x18b7, 0x18ba, + 0x18bd, 0x18c0, 0x18c9, 0x18cc, 0x18e1, 0x18ee, + 0x191b, 0x191c, 0x1923, 0x1924, 0x1953, 0x1954, + 0x1969, 0x196a, 0x1975, 0x1978, 0x198b, 0x198c, + 0x1993, 0x1994, 0x199d, 0x19aa, 0x19af, 0x19ba, + 0x19bf, 0x19c0, 0x19c9, 0x19cc, 0x19e1, 0x19e2, + 0x19e9, 0x1a00, 0x1a1b, 0x1a1c, 0x1a23, 0x1a24, + 0x1a8b, 0x1a8c, 0x1a93, 0x1a94, 0x1aa1, 0x1aa8, + 0x1ac9, 0x1acc, 0x1b01, 0x1b02, 0x1b09, 0x1b0a, + 0x1b2f, 0x1b34, 0x1b65, 0x1b66, 0x1b79, 0x1b7a, + 0x1b7d, 0x1b80, 0x1b8f, 0x1b94, 0x1b97, 0x1b9e, + 0x1bab, 0x1bac, 0x1baf, 0x1bb0, 0x1bc1, 0x1bcc, + 0x1be1, 0x1be4, 0x1beb, 0x1c02, 0x1c77, 0x1c7e, + 0x1cb9, 0x1d02, 0x1d07, 0x1d08, 0x1d0b, 0x1d0c, + 0x1d17, 0x1d18, 0x1d49, 0x1d4a, 0x1d4d, 0x1d4e, + 0x1d7d, 0x1d80, 0x1d8b, 0x1d8c, 0x1d8f, 0x1d90, + 0x1d9f, 0x1da0, 0x1db5, 0x1db8, 0x1dc1, 0x1e00, + 0x1e91, 0x1e92, 0x1edb, 0x1ee2, 0x1f31, 0x1f32, + 0x1f7b, 0x1f7c, 0x1f9b, 0x1f9c, 0x1fb7, 0x2000, + 0x218d, 0x218e, 0x2191, 0x219a, 0x219d, 0x21a0, + 0x2493, 0x2494, 0x249d, 0x24a0, 0x24af, 0x24b0, + 0x24b3, 0x24b4, 0x24bd, 0x24c0, 0x2513, 0x2514, + 0x251d, 0x2520, 0x2563, 0x2564, 0x256d, 0x2570, + 0x257f, 0x2580, 0x2583, 0x2584, 0x258d, 0x2590, + 0x25af, 0x25b0, 0x2623, 0x2624, 0x262d, 0x2630, + 0x26b7, 0x26ba, 0x26fb, 0x2700, 0x2735, 0x2740, + 0x27ed, 0x27f0, 0x27fd, 0x2800, 0x2d01, 0x2d02, + 0x2d3b, 0x2d40, 0x2df3, 0x2e00, 0x2e2d, 0x2e3e, + 0x2e6f, 0x2e80, 0x2ea9, 0x2ec0, 0x2edb, 0x2edc, + 0x2ee3, 0x2ee4, 0x2ee9, 0x2f00, 0x2fbd, 0x2fc0, + 0x2fd5, 0x2fe0, 0x2ff5, 0x3000, 0x301d, 0x301e, + 0x3035, 0x3040, 0x30f3, 0x3100, 0x3157, 0x3160, + 0x31ed, 0x3200, 0x323f, 0x3240, 0x3259, 0x3260, + 0x3279, 0x3280, 0x3283, 0x3288, 0x32dd, 0x32e0, + 0x32eb, 0x3300, 0x3359, 0x3360, 0x3395, 0x33a0, + 0x33b7, 0x33bc, 0x3439, 0x343c, 0x34bf, 0x34c0, + 0x34fb, 0x34fe, 0x3515, 0x3520, 0x3535, 0x3540, + 0x355d, 0x3560, 0x359f, 0x3600, 0x369b, 0x369c, + 0x37e9, 0x37f8, 0x3871, 0x3876, 0x3895, 0x389a, + 0x3917, 0x3920, 0x3977, 0x397a, 0x3991, 0x39a0, + 0x39f7, 0x3a00, 0x3e2d, 0x3e30, 0x3e3d, 0x3e40, + 0x3e8d, 0x3e90, 0x3e9d, 0x3ea0, 0x3eb1, 0x3eb2, + 0x3eb5, 0x3eb6, 0x3eb9, 0x3eba, 0x3ebd, 0x3ebe, + 0x3efd, 0x3f00, 0x3f6b, 0x3f6c, 0x3f8b, 0x3f8c, + 0x3fa9, 0x3fac, 0x3fb9, 0x3fba, 0x3fe1, 0x3fe4, + 0x3feb, 0x3fec, 0x3fff, 0x4020, 0x4051, 0x4060, + 0x40bf, 0x40e0, 0x40e5, 0x40e8, 0x411f, 0x4120, + 0x413b, 0x4140, 0x4183, 0x41a0, 0x41e3, 0x4200, + 0x4319, 0x4320, 0x4855, 0x4880, 0x4897, 0x48c0, + 0x56e9, 0x56ec, 0x572d, 0x572e, 0x59e9, 0x59f2, + 0x5a4d, 0x5a4e, 0x5a51, 0x5a5a, 0x5a5d, 0x5a60, + 0x5ad1, 0x5ade, 0x5ae3, 0x5afe, 0x5b2f, 0x5b40, + 0x5b4f, 0x5b50, 0x5b5f, 0x5b60, 0x5b6f, 0x5b70, + 0x5b7f, 0x5b80, 0x5b8f, 0x5b90, 0x5b9f, 0x5ba0, + 0x5baf, 0x5bb0, 0x5bbf, 0x5bc0, 0x5cbd, 0x5d00, + 0x5d35, 0x5d36, 0x5de9, 0x5e00, 0x5fad, 0x5fe0, + 0x6001, 0x6002, 0x6081, 0x6082, 0x612f, 0x6132, + 0x6201, 0x620a, 0x6261, 0x6262, 0x631f, 0x6320, + 0x63cd, 0x63de, 0x643f, 0x6440, 0x1491b, 0x14920, + 0x1498f, 0x149a0, 0x14c59, 0x14c80, 0x14df1, 0x14e00, + 0x14f9d, 0x14fa0, 0x14fa5, 0x14fa6, 0x14fa9, 0x14faa, + 0x14fbb, 0x14fe4, 0x1505b, 0x15060, 0x15075, 0x15080, + 0x150f1, 0x15100, 0x1518d, 0x1519c, 0x151b5, 0x151c0, + 0x152a9, 0x152be, 0x152fb, 0x15300, 0x1539d, 0x1539e, + 0x153b5, 0x153bc, 0x153ff, 0x15400, 0x1546f, 0x15480, + 0x1549d, 0x154a0, 0x154b5, 0x154b8, 0x15587, 0x155b6, + 0x155ef, 0x15602, 0x1560f, 0x15612, 0x1561f, 0x15622, + 0x1562f, 0x15640, 0x1564f, 0x15650, 0x1565f, 0x15660, + 0x156d9, 0x156e0, 0x157dd, 0x157e0, 0x157f5, 0x15800, + 0x1af49, 0x1af60, 0x1af8f, 0x1af96, 0x1aff9, 0x1f200, + 0x1f4dd, 0x1f4e0, 0x1f5b5, 0x1f600, 0x1f60f, 0x1f626, + 0x1f631, 0x1f63a, 0x1f66f, 0x1f670, 0x1f67b, 0x1f67c, + 0x1f67f, 0x1f680, 0x1f685, 0x1f686, 0x1f68b, 0x1f68c, + 0x1f787, 0x1f7a6, 0x1fb21, 0x1fb24, 0x1fb91, 0x1fb9e, + 0x1fba1, 0x1fbe0, 0x1fc35, 0x1fc40, 0x1fca7, 0x1fca8, + 0x1fccf, 0x1fcd0, 0x1fcd9, 0x1fce0, 0x1fceb, 0x1fcec, + 0x1fdfb, 0x1fe02, 0x1ff7f, 0x1ff84, 0x1ff91, 0x1ff94, + 0x1ffa1, 0x1ffa4, 0x1ffb1, 0x1ffb4, 0x1ffbb, 0x1ffc0, + 0x1ffcf, 0x1ffd0, 0x1ffdf, 0x1fff8, 0x1fffd, 0x20000, + 0x20019, 0x2001a, 0x2004f, 0x20050, 0x20077, 0x20078, + 0x2007d, 0x2007e, 0x2009d, 0x200a0, 0x200bd, 0x20100, + 0x201f7, 0x20200, 0x20207, 0x2020e, 0x20269, 0x2026e, + 0x2031f, 0x20320, 0x2033b, 0x20340, 0x20343, 0x203a0, + 0x203fd, 0x20500, 0x2053b, 0x20540, 0x205a3, 0x205c0, + 0x205f9, 0x20600, 0x20649, 0x2065a, 0x20697, 0x206a0, + 0x206f7, 0x20700, 0x2073d, 0x2073e, 0x20789, 0x20790, + 0x207ad, 0x20800, 0x2093d, 0x20940, 0x20955, 0x20960, + 0x209a9, 0x209b0, 0x209f9, 0x20a00, 0x20a51, 0x20a60, + 0x20ac9, 0x20ade, 0x20af7, 0x20af8, 0x20b17, 0x20b18, + 0x20b27, 0x20b28, 0x20b2d, 0x20b2e, 0x20b45, 0x20b46, + 0x20b65, 0x20b66, 0x20b75, 0x20b76, 0x20b7b, 0x20b80, + 0x20be9, 0x20c00, 0x20e6f, 0x20e80, 0x20ead, 0x20ec0, + 0x20ed1, 0x20f00, 0x20f0d, 0x20f0e, 0x20f63, 0x20f64, + 0x20f77, 0x21000, 0x2100d, 0x21010, 0x21013, 0x21014, + 0x2106d, 0x2106e, 0x21073, 0x21078, 0x2107b, 0x2107e, + 0x210ad, 0x210ae, 0x2113f, 0x2114e, 0x21161, 0x211c0, + 0x211e7, 0x211e8, 0x211ed, 0x211f6, 0x21239, 0x2123e, + 0x21275, 0x2127e, 0x21281, 0x21300, 0x21371, 0x21378, + 0x213a1, 0x213a4, 0x21409, 0x2140a, 0x2140f, 0x21418, + 0x21429, 0x2142a, 0x21431, 0x21432, 0x2146d, 0x21470, + 0x21477, 0x2147e, 0x21493, 0x214a0, 0x214b3, 0x214c0, + 0x21541, 0x21580, 0x215cf, 0x215d6, 0x215ef, 0x21600, + 0x2166d, 0x21672, 0x216ad, 0x216b0, 0x216e7, 0x216f0, + 0x21725, 0x21732, 0x2173b, 0x21752, 0x21761, 0x21800, + 0x21893, 0x21900, 0x21967, 0x21980, 0x219e7, 0x219f4, + 0x21a51, 0x21a60, 0x21a75, 0x21a80, 0x21acd, 0x21ad2, + 0x21b0d, 0x21b1c, 0x21b21, 0x21cc0, 0x21cff, 0x21d00, + 0x21d55, 0x21d56, 0x21d5d, 0x21d60, 0x21d65, 0x21d84, + 0x21d8b, 0x21df8, 0x21e51, 0x21e60, 0x21eb5, 0x21ee0, + 0x21f15, 0x21f60, 0x21f99, 0x21fc0, 0x21fef, 0x22000, + 0x2209d, 0x220a4, 0x220ed, 0x220fe, 0x2217b, 0x2217c, + 0x22187, 0x221a0, 0x221d3, 0x221e0, 0x221f5, 0x22200, + 0x2226b, 0x2226c, 0x22291, 0x222a0, 0x222ef, 0x22300, + 0x223c1, 0x223c2, 0x223eb, 0x22400, 0x22425, 0x22426, + 0x22485, 0x22500, 0x2250f, 0x22510, 0x22513, 0x22514, + 0x2251d, 0x2251e, 0x2253d, 0x2253e, 0x22555, 0x22560, + 0x225d7, 0x225e0, 0x225f5, 0x22600, 0x22609, 0x2260a, + 0x2261b, 0x2261e, 0x22623, 0x22626, 0x22653, 0x22654, + 0x22663, 0x22664, 0x22669, 0x2266a, 0x22675, 0x22676, + 0x2268b, 0x2268e, 0x22693, 0x22696, 0x2269d, 0x226a0, + 0x226a3, 0x226ae, 0x226b1, 0x226ba, 0x226c9, 0x226cc, + 0x226db, 0x226e0, 0x226eb, 0x22700, 0x22715, 0x22716, + 0x22719, 0x2271c, 0x2271f, 0x22720, 0x2276d, 0x2276e, + 0x22783, 0x22784, 0x22787, 0x2278a, 0x2278d, 0x2278e, + 0x22797, 0x22798, 0x227ad, 0x227ae, 0x227b3, 0x227c2, + 0x227c7, 0x22800, 0x228b9, 0x228ba, 0x228c5, 0x22900, + 0x22991, 0x229a0, 0x229b5, 0x22b00, 0x22b6d, 0x22b70, + 0x22bbd, 0x22c00, 0x22c8b, 0x22ca0, 0x22cb5, 0x22cc0, + 0x22cdb, 0x22d00, 0x22d75, 0x22d80, 0x22d95, 0x22da0, + 0x22dc9, 0x22e00, 0x22e37, 0x22e3a, 0x22e59, 0x22e60, + 0x22e8f, 0x23000, 0x23079, 0x23140, 0x231e7, 0x231fe, + 0x2320f, 0x23212, 0x23215, 0x23218, 0x23229, 0x2322a, + 0x2322f, 0x23230, 0x2326d, 0x2326e, 0x23273, 0x23276, + 0x2328f, 0x232a0, 0x232b5, 0x23340, 0x23351, 0x23354, + 0x233b1, 0x233b4, 0x233cb, 0x23400, 0x23491, 0x234a0, + 0x23547, 0x23560, 0x235f3, 0x23600, 0x23615, 0x23780, + 0x237c5, 0x237e0, 0x237f5, 0x23800, 0x23813, 0x23814, + 0x2386f, 0x23870, 0x2388d, 0x238a0, 0x238db, 0x238e0, + 0x23921, 0x23924, 0x23951, 0x23952, 0x2396f, 0x23a00, + 0x23a0f, 0x23a10, 0x23a15, 0x23a16, 0x23a6f, 0x23a74, + 0x23a77, 0x23a78, 0x23a7d, 0x23a7e, 0x23a91, 0x23aa0, + 0x23ab5, 0x23ac0, 0x23acd, 0x23ace, 0x23ad3, 0x23ad4, + 0x23b1f, 0x23b20, 0x23b25, 0x23b26, 0x23b33, 0x23b40, + 0x23b55, 0x23dc0, 0x23df3, 0x23e00, 0x23e23, 0x23e24, + 0x23e77, 0x23e7c, 0x23eb7, 0x23f60, 0x23f63, 0x23f80, + 0x23fe5, 0x23ffe, 0x24735, 0x24800, 0x248df, 0x248e0, + 0x248eb, 0x24900, 0x24a89, 0x25f20, 0x25fe7, 0x26000, + 0x26861, 0x26880, 0x268ad, 0x268c0, 0x287f7, 0x28800, + 0x28c8f, 0x2c200, 0x2c275, 0x2d000, 0x2d473, 0x2d480, + 0x2d4bf, 0x2d4c0, 0x2d4d5, 0x2d4dc, 0x2d57f, 0x2d580, + 0x2d595, 0x2d5a0, 0x2d5dd, 0x2d5e0, 0x2d5ed, 0x2d600, + 0x2d68d, 0x2d6a0, 0x2d6b5, 0x2d6b6, 0x2d6c5, 0x2d6c6, + 0x2d6f1, 0x2d6fa, 0x2d721, 0x2da80, 0x2daf5, 0x2dc80, + 0x2dd37, 0x2de00, 0x2de97, 0x2de9e, 0x2df11, 0x2df1e, + 0x2df41, 0x2dfc0, 0x2dfcb, 0x2dfe0, 0x2dfe5, 0x2e000, + 0x30ff1, 0x31000, 0x319ad, 0x319fe, 0x31a13, 0x35fe0, + 0x35fe9, 0x35fea, 0x35ff9, 0x35ffa, 0x35fff, 0x36000, + 0x36247, 0x36264, 0x36267, 0x362a0, 0x362a7, 0x362aa, + 0x362ad, 0x362c8, 0x362d1, 0x362e0, 0x365f9, 0x37800, + 0x378d7, 0x378e0, 0x378fb, 0x37900, 0x37913, 0x37920, + 0x37935, 0x37938, 0x37941, 0x39800, 0x399f5, 0x39a00, + 0x39d69, 0x39e00, 0x39e5d, 0x39e60, 0x39e8f, 0x39ea0, + 0x39f89, 0x3a000, 0x3a1ed, 0x3a200, 0x3a24f, 0x3a252, + 0x3a2e7, 0x3a2f6, 0x3a3d7, 0x3a400, 0x3a48d, 0x3a580, + 0x3a5a9, 0x3a5c0, 0x3a5e9, 0x3a600, 0x3a6af, 0x3a6c0, + 0x3a6f3, 0x3a800, 0x3a8ab, 0x3a8ac, 0x3a93b, 0x3a93c, + 0x3a941, 0x3a944, 0x3a947, 0x3a94a, 0x3a94f, 0x3a952, + 0x3a95b, 0x3a95c, 0x3a975, 0x3a976, 0x3a979, 0x3a97a, + 0x3a989, 0x3a98a, 0x3aa0d, 0x3aa0e, 0x3aa17, 0x3aa1a, + 0x3aa2b, 0x3aa2c, 0x3aa3b, 0x3aa3c, 0x3aa75, 0x3aa76, + 0x3aa7f, 0x3aa80, 0x3aa8b, 0x3aa8c, 0x3aa8f, 0x3aa94, + 0x3aaa3, 0x3aaa4, 0x3ad4d, 0x3ad50, 0x3af99, 0x3af9c, + 0x3b519, 0x3b536, 0x3b541, 0x3b542, 0x3b561, 0x3be00, + 0x3be3f, 0x3be4a, 0x3be57, 0x3c000, 0x3c00f, 0x3c010, + 0x3c033, 0x3c036, 0x3c045, 0x3c046, 0x3c04b, 0x3c04c, + 0x3c057, 0x3c060, 0x3c0dd, 0x3c11e, 0x3c121, 0x3c200, + 0x3c25b, 0x3c260, 0x3c27d, 0x3c280, 0x3c295, 0x3c29c, + 0x3c2a1, 0x3c520, 0x3c55f, 0x3c580, 0x3c5f5, 0x3c5fe, + 0x3c601, 0x3c9a0, 0x3c9f5, 0x3cba0, 0x3cbf7, 0x3cbfe, + 0x3cc01, 0x3cfc0, 0x3cfcf, 0x3cfd0, 0x3cfd9, 0x3cfda, + 0x3cfdf, 0x3cfe0, 0x3cfff, 0x3d000, 0x3d18b, 0x3d18e, + 0x3d1af, 0x3d200, 0x3d299, 0x3d2a0, 0x3d2b5, 0x3d2bc, + 0x3d2c1, 0x3d8e2, 0x3d96b, 0x3da02, 0x3da7d, 0x3dc00, + 0x3dc09, 0x3dc0a, 0x3dc41, 0x3dc42, 0x3dc47, 0x3dc48, + 0x3dc4b, 0x3dc4e, 0x3dc51, 0x3dc52, 0x3dc67, 0x3dc68, + 0x3dc71, 0x3dc72, 0x3dc75, 0x3dc76, 0x3dc79, 0x3dc84, + 0x3dc87, 0x3dc8e, 0x3dc91, 0x3dc92, 0x3dc95, 0x3dc96, + 0x3dc99, 0x3dc9a, 0x3dca1, 0x3dca2, 0x3dca7, 0x3dca8, + 0x3dcab, 0x3dcae, 0x3dcb1, 0x3dcb2, 0x3dcb5, 0x3dcb6, + 0x3dcb9, 0x3dcba, 0x3dcbd, 0x3dcbe, 0x3dcc1, 0x3dcc2, + 0x3dcc7, 0x3dcc8, 0x3dccb, 0x3dcce, 0x3dcd7, 0x3dcd8, + 0x3dce7, 0x3dce8, 0x3dcf1, 0x3dcf2, 0x3dcfb, 0x3dcfc, + 0x3dcff, 0x3dd00, 0x3dd15, 0x3dd16, 0x3dd39, 0x3dd42, + 0x3dd49, 0x3dd4a, 0x3dd55, 0x3dd56, 0x3dd79, 0x3dde0, + 0x3dde5, 0x3e000, 0x3e059, 0x3e060, 0x3e129, 0x3e140, + 0x3e15f, 0x3e162, 0x3e181, 0x3e182, 0x3e1a1, 0x3e1a2, + 0x3e1ed, 0x3e200, 0x3e35d, 0x3e3cc, 0x3e407, 0x3e420, + 0x3e479, 0x3e480, 0x3e493, 0x3e4a0, 0x3e4a5, 0x3e4c0, + 0x3e4cd, 0x3e600, 0x3edb1, 0x3edb8, 0x3eddb, 0x3ede0, + 0x3edfb, 0x3ee00, 0x3eeef, 0x3eef6, 0x3efb5, 0x3efc0, + 0x3efd9, 0x3efe0, 0x3efe3, 0x3f000, 0x3f019, 0x3f020, + 0x3f091, 0x3f0a0, 0x3f0b5, 0x3f0c0, 0x3f111, 0x3f120, + 0x3f15d, 0x3f160, 0x3f179, 0x3f180, 0x3f185, 0x3f200, + 0x3f4a9, 0x3f4c0, 0x3f4dd, 0x3f4e0, 0x3f4fb, 0x3f500, + 0x3f515, 0x3f51e, 0x3f58f, 0x3f59c, 0x3f5bb, 0x3f5be, + 0x3f5d5, 0x3f5e0, 0x3f5f3, 0x3f600, 0x3f727, 0x3f728, + 0x3f7f5, 0x40000, 0x54dc1, 0x54e00, 0x56e75, 0x56e80, + 0x5703d, 0x57040, 0x59d45, 0x59d60, 0x5d7c3, 0x5d7e0, + 0x5dcbd, 0x5f000, 0x5f43d, 0x60000, 0x62697, 0x626a0, + 0x64761, 0x1c0200, 0x1c03e1, + }; + enum class _Gcb_property { _Gcb_Other = 0, _Gcb_Control = 1, @@ -81,7 +333,7 @@ _Gcb_Regional_Indicator = 13, }; - // Values generated by contrib/unicode/gen_std_format_width.py, + // Values generated by contrib/unicode/gen_libstdcxx_unicode_data.py, // from GraphemeBreakProperty.txt from the Unicode standard. // Entries are (code_point << shift_bits) + property. inline constexpr int __gcb_shift_bits = 0x4; @@ -381,7 +633,7 @@ enum class _InCB { _Consonant = 1, _Extend = 2 }; - // Values generated by contrib/unicode/gen_std_format_width.py, + // Values generated by contrib/unicode/gen_libstdcxx_unicode_data.py, // from DerivedCoreProperties.txt from the Unicode standard. // Entries are (code_point << 2) + property. inline constexpr uint32_t __incb_edges[] = { @@ -519,7 +771,7 @@ 0x380082, 0x380200, 0x380402, 0x3807c0, }; - // Table generated by contrib/unicode/gen_std_format_width.py, + // Table generated by contrib/unicode/gen_libstdcxx_unicode_data.py, // from emoji-data.txt from the Unicode standard. inline constexpr char32_t __xpicto_edges[] = { 0xa9, 0xaa, 0xae, 0xaf, 0x203c, 0x203d, 0x2049, 0x204a, diff --git a/libstdc++-v3/include/bits/unicode.h b/libstdc++-v3/include/bits/unicode.h index 99d972e..f1b6bf4 100644 --- a/libstdc++-v3/include/bits/unicode.h +++ b/libstdc++-v3/include/bits/unicode.h @@ -151,6 +151,11 @@ namespace __unicode { return _M_curr(); } [[nodiscard]] + constexpr iter_difference_t<_Iter> + _M_units() const requires forward_iterator<_Iter> + { return _M_to_increment; } + + [[nodiscard]] constexpr value_type operator*() const { return _M_buf[_M_buf_index]; } @@ -610,6 +615,18 @@ inline namespace __v16_0_0 } // @pre c <= 0x10FFFF + constexpr bool + __should_escape_category(char32_t __c) noexcept + { + constexpr uint32_t __mask = 0x01; + auto* __end = std::end(__escape_edges); + auto* __p = std::lower_bound(__escape_edges, __end, + (__c << 1u) + 2); + return __p[-1] & __mask; + } + + + // @pre c <= 0x10FFFF constexpr _Gcb_property __grapheme_cluster_break_property(char32_t __c) noexcept { diff --git a/libstdc++-v3/include/bits/uniform_int_dist.h b/libstdc++-v3/include/bits/uniform_int_dist.h index d96dcbd..77b1e96 100644 --- a/libstdc++-v3/include/bits/uniform_int_dist.h +++ b/libstdc++-v3/include/bits/uniform_int_dist.h @@ -308,9 +308,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const __uctype __uerange = __urange + 1; // __urange can be zero +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr #if defined __UINT64_TYPE__ && defined __UINT32_TYPE__ #if __SIZEOF_INT128__ - if _GLIBCXX17_CONSTEXPR (__urngrange == __UINT64_MAX__) + if constexpr (__urngrange == __UINT64_MAX__) { // __urng produces values that use exactly 64-bits, // so use 128-bit integers to downscale to desired range. @@ -320,7 +322,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } else #endif - if _GLIBCXX17_CONSTEXPR (__urngrange == __UINT32_MAX__) + if constexpr (__urngrange == __UINT32_MAX__) { // __urng produces values that use exactly 32-bits, // so use 64-bit integers to downscale to desired range. @@ -338,6 +340,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION while (__ret >= __past); __ret /= __scaling; } +#pragma GCC diagnostic pop } else if (__urngrange < __urange) { diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h index 49e97e2..fc07ffc 100644 --- a/libstdc++-v3/include/bits/unordered_map.h +++ b/libstdc++-v3/include/bits/unordered_map.h @@ -34,7 +34,7 @@ #include <bits/allocator.h> #include <bits/functional_hash.h> // hash #include <bits/stl_function.h> // equal_to -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <bits/ranges_base.h> // ranges::begin, ranges::distance etc. #endif @@ -251,6 +251,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_map(__n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered containers + template<typename _InputIterator> + unordered_map(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_map(__first, __last, 0, hasher(), key_equal(), __a) + { } + template<typename _InputIterator> unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, @@ -271,13 +279,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_map(__l, __n, hasher(), key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered containers + unordered_map(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_map(__l, 0, hasher(), key_equal(), __a) + { } + unordered_map(initializer_list<value_type> __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__l, __n, __hf, key_equal(), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Builds an %unordered_map from a range. * @since C++23 @@ -681,7 +696,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(initializer_list<value_type> __l) { _M_h.insert(__l); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Inserts a range of elements. * @since C++23 @@ -1291,7 +1306,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Hash, _Allocator) -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>, __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>, @@ -1504,6 +1519,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_multimap(__n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered containers + template<typename _InputIterator> + unordered_multimap(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_multimap(__first, __last, 0, hasher(), key_equal(), __a) + { } + template<typename _InputIterator> unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, @@ -1518,6 +1541,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered containers + unordered_multimap(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_multimap(__l, 0, hasher(), key_equal(), __a) + { } + unordered_multimap(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) @@ -1530,7 +1560,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_multimap(__l, __n, __hf, key_equal(), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Builds an %unordered_multimap from a range. * @since C++23 @@ -1802,7 +1832,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(initializer_list<value_type> __l) { _M_h.insert(__l); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Inserts a range of elements. * @since C++23 @@ -2311,7 +2341,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Hash, _Allocator) -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>, __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>, diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h index 4bc256c..5649dd7 100644 --- a/libstdc++-v3/include/bits/unordered_set.h +++ b/libstdc++-v3/include/bits/unordered_set.h @@ -34,7 +34,7 @@ #include <bits/allocator.h> #include <bits/functional_hash.h> // hash #include <bits/stl_function.h> // equal_to -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 # include <bits/ranges_base.h> // ranges::begin, ranges::distance etc. #endif @@ -245,6 +245,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_set(__n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _InputIterator> + unordered_set(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_set(__first, __last, 0, hasher(), key_equal(), __a) + { } + template<typename _InputIterator> unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, @@ -259,6 +267,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_set(__first, __last, __n, __hf, key_equal(), __a) { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + unordered_set(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_set(__l, 0, hasher(), key_equal(), __a) + { } + unordered_set(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) @@ -271,7 +287,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_set(__l, __n, __hf, key_equal(), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Builds an %unordered_set from a range. * @since C++23 @@ -533,7 +549,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(initializer_list<value_type> __l) { _M_h.insert(__l); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Inserts a range of elements. * @since C++23 @@ -987,6 +1003,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typename iterator_traits<_InputIterator>::value_type>, _Allocator>; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _InputIterator, typename _Allocator, + typename = _RequireInputIter<_InputIterator>, + typename = _RequireAllocator<_Allocator>> + unordered_set(_InputIterator, _InputIterator, _Allocator) + -> unordered_set<typename iterator_traits<_InputIterator>::value_type, + hash< + typename iterator_traits<_InputIterator>::value_type>, + equal_to< + typename iterator_traits<_InputIterator>::value_type>, + _Allocator>; + template<typename _InputIterator, typename _Hash, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireNotAllocatorOrIntegral<_Hash>, @@ -1006,6 +1035,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER unordered_set<int>::size_type, _Allocator) -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _Tp, typename _Allocator, + typename = _RequireAllocator<_Allocator>> + unordered_set(initializer_list<_Tp>, _Allocator) + -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + template<typename _Tp, typename _Hash, typename _Allocator, typename = _RequireNotAllocatorOrIntegral<_Hash>, typename = _RequireAllocator<_Allocator>> @@ -1013,7 +1049,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER unordered_set<int>::size_type, _Hash, _Allocator) -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>, __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>, @@ -1223,6 +1259,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_multiset(__n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _InputIterator> + unordered_multiset(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_multiset(__first, __last, 0, hasher(), key_equal(), __a) + { } + template<typename _InputIterator> unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, @@ -1237,6 +1281,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + unordered_multiset(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_multiset(__l, 0, hasher(), key_equal(), __a) + { } + unordered_multiset(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) @@ -1249,7 +1300,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_multiset(__l, __n, __hf, key_equal(), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Builds an %unordered_multiset from a range. * @since C++23 @@ -1483,7 +1534,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(initializer_list<value_type> __l) { _M_h.insert(__l); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Inserts a range of elements. * @since C++23 @@ -1949,6 +2000,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER iterator_traits<_InputIterator>::value_type>, _Allocator>; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _InputIterator, typename _Allocator, + typename = _RequireInputIter<_InputIterator>, + typename = _RequireAllocator<_Allocator>> + unordered_multiset(_InputIterator, _InputIterator, _Allocator) + -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type, + hash<typename + iterator_traits<_InputIterator>::value_type>, + equal_to<typename + iterator_traits<_InputIterator>::value_type>, + _Allocator>; + template<typename _InputIterator, typename _Hash, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireNotAllocatorOrIntegral<_Hash>, @@ -1970,6 +2034,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER unordered_multiset<int>::size_type, _Allocator) -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _Tp, typename _Allocator, + typename = _RequireAllocator<_Allocator>> + unordered_multiset(initializer_list<_Tp>, _Allocator) + -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + template<typename _Tp, typename _Hash, typename _Allocator, typename = _RequireNotAllocatorOrIntegral<_Hash>, typename = _RequireAllocator<_Allocator>> @@ -1977,7 +2048,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER unordered_multiset<int>::size_type, _Hash, _Allocator) -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>, __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>, diff --git a/libstdc++-v3/include/bits/valarray_array.h b/libstdc++-v3/include/bits/valarray_array.h index 03b6f1e..b5c02b7 100644 --- a/libstdc++-v3/include/bits/valarray_array.h +++ b/libstdc++-v3/include/bits/valarray_array.h @@ -64,13 +64,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __valarray_release_memory(void* __p) { operator delete(__p); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + // Turn raw-memory into an array of _Tp filled with _Tp(). // This is used in `valarray<T> v(n);` and in `valarray<T>::shift(n)`. template<typename _Tp> inline void __valarray_default_construct(_Tp* __b, _Tp* __e) { - if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) + if _GLIBCXX_CONSTEXPR (__is_trivial(_Tp)) __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); else while (__b != __e) @@ -94,7 +97,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __valarray_copy_construct(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) { - if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) + if _GLIBCXX_CONSTEXPR (__is_trivial(_Tp)) { if (__b) __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); @@ -110,7 +113,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, size_t __s, _Tp* __restrict__ __o) { - if _GLIBCXX17_CONSTEXPR (__is_trivial(_Tp)) + if _GLIBCXX_CONSTEXPR (__is_trivial(_Tp)) while (__n--) { *__o++ = *__a; @@ -131,7 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const size_t* __restrict__ __i, _Tp* __restrict__ __o, size_t __n) { - if (__is_trivial(_Tp)) + if _GLIBCXX_CONSTEXPR (__is_trivial(_Tp)) while (__n--) *__o++ = __a[*__i++]; else @@ -144,7 +147,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline void __valarray_destroy_elements(_Tp* __b, _Tp* __e) { - if (!__is_trivial(_Tp)) + if _GLIBCXX_CONSTEXPR (!__is_trivial(_Tp)) while (__b != __e) { __b->~_Tp(); @@ -152,6 +155,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +#pragma GCC diagnostic pop + // Fill a plain array __a[<__n>] with __t template<typename _Tp> inline void diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 66d73b4..e18f01a 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -61,6 +61,9 @@ namespace std _GLIBCXX_VISIBILITY(default) _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + template<typename _Tp, typename _Alloc> _GLIBCXX20_CONSTEXPR void @@ -74,11 +77,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const size_type __old_size = size(); pointer __tmp; #if __cplusplus >= 201103L - if _GLIBCXX17_CONSTEXPR (_S_use_relocate()) + if constexpr (_S_use_relocate()) { __tmp = this->_M_allocate(__n); - _S_relocate(this->_M_impl._M_start, this->_M_impl._M_finish, - __tmp, _M_get_Tp_allocator()); + std::__relocate_a(this->_M_impl._M_start, this->_M_impl._M_finish, + __tmp, _M_get_Tp_allocator()); } else #endif @@ -98,6 +101,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; } } +#pragma GCC diagnostic pop #if __cplusplus >= 201103L template<typename _Tp, typename _Alloc> @@ -444,6 +448,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #endif } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr #if __cplusplus >= 201103L template<typename _Tp, typename _Alloc> template<typename... _Args> @@ -488,14 +494,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #endif #if __cplusplus >= 201103L - if _GLIBCXX17_CONSTEXPR (_S_use_relocate()) + if constexpr (_S_use_relocate()) { // Relocation cannot throw. - __new_finish = _S_relocate(__old_start, __position.base(), - __new_start, _M_get_Tp_allocator()); + __new_finish = std::__relocate_a(__old_start, __position.base(), + __new_start, + _M_get_Tp_allocator()); ++__new_finish; - __new_finish = _S_relocate(__position.base(), __old_finish, - __new_finish, _M_get_Tp_allocator()); + __new_finish = std::__relocate_a(__position.base(), __old_finish, + __new_finish, + _M_get_Tp_allocator()); } else #endif @@ -593,11 +601,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #endif #if __cplusplus >= 201103L - if _GLIBCXX17_CONSTEXPR (_S_use_relocate()) + if constexpr (_S_use_relocate()) { // Relocation cannot throw. - __new_finish = _S_relocate(__old_start, __old_finish, - __new_start, _M_get_Tp_allocator()); + __new_finish = std::__relocate_a(__old_start, __old_finish, + __new_start, + _M_get_Tp_allocator()); ++__new_finish; } else @@ -645,6 +654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_finish = __new_finish; this->_M_impl._M_end_of_storage = __new_start + __len; } +#pragma GCC diagnostic pop template<typename _Tp, typename _Alloc> _GLIBCXX20_CONSTEXPR @@ -751,6 +761,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } #if __cplusplus >= 201103L +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr template<typename _Tp, typename _Alloc> _GLIBCXX20_CONSTEXPR void @@ -794,10 +806,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER std::__uninitialized_default_n_a(__new_start + __size, __n, _M_get_Tp_allocator()); - if _GLIBCXX17_CONSTEXPR (_S_use_relocate()) + if constexpr (_S_use_relocate()) { - _S_relocate(__old_start, __old_finish, - __new_start, _M_get_Tp_allocator()); + std::__relocate_a(__old_start, __old_finish, + __new_start, _M_get_Tp_allocator()); } else { @@ -842,6 +854,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } } } +#pragma GCC diagnostic pop template<typename _Tp, typename _Alloc> _GLIBCXX20_CONSTEXPR @@ -977,7 +990,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<typename _Tp, typename _Alloc> template<__detail::__container_compatible_range<_Tp> _Rg> constexpr auto @@ -1100,7 +1113,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER return insert_range(__pos, vector(from_range, std::forward<_Rg>(__rg), _M_get_Tp_allocator())); } -#endif // ranges_to_container +#endif // containers_ranges // vector<bool> template<typename _Alloc> diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index 8f609b4..282667e 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -959,6 +959,7 @@ ftms = { ftms = { name = make_obj_using_allocator; + no_stdname = true; values = { // Not specified by C++20, used internally v = 201811; @@ -1273,7 +1274,12 @@ ftms = { ftms = { name = constrained_equality; values = { - v = 202411; // FIXME: 202403 for P2944R3, ??? for P3379R0 + v = 202411; + cxxmin = 23; + extra_cond = "__glibcxx_three_way_comparison"; + }; + values = { + v = 202403; cxxmin = 20; extra_cond = "__glibcxx_three_way_comparison"; }; @@ -1411,9 +1417,8 @@ ftms = { // 202207 P2286R8 Formatting Ranges // 202207 P2585R1 Improving default container formatting // LWG3750 Too many papers bump __cpp_lib_format - no_stdname = true; // TODO remove values = { - v = 1; // TODO 202207 + v = 202207; cxxmin = 23; hosted = yes; }; @@ -1510,14 +1515,14 @@ ftms = { }; }; -//ftms = { -// name = containers_ranges; -// values = { -// v = 202202; -// cxxmin = 23; -// hosted = yes; -// }; -//}; +ftms = { + name = containers_ranges; + values = { + v = 202202; + cxxmin = 23; + hosted = yes; + }; +}; ftms = { name = ranges_to_container; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index f05c3fd..bb7c047 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -1074,7 +1074,6 @@ # if (__cplusplus >= 202002L) && (__cpp_concepts) # define __glibcxx_make_obj_using_allocator 201811L # if defined(__glibcxx_want_all) || defined(__glibcxx_want_make_obj_using_allocator) -# define __cpp_lib_make_obj_using_allocator 201811L # endif # endif #endif /* !defined(__cpp_lib_make_obj_using_allocator) && defined(__glibcxx_want_make_obj_using_allocator) */ @@ -1406,11 +1405,16 @@ #undef __glibcxx_want_constexpr_vector #if !defined(__cpp_lib_constrained_equality) -# if (__cplusplus >= 202002L) && (__glibcxx_three_way_comparison) +# if (__cplusplus >= 202100L) && (__glibcxx_three_way_comparison) # define __glibcxx_constrained_equality 202411L # if defined(__glibcxx_want_all) || defined(__glibcxx_want_constrained_equality) # define __cpp_lib_constrained_equality 202411L # endif +# elif (__cplusplus >= 202002L) && (__glibcxx_three_way_comparison) +# define __glibcxx_constrained_equality 202403L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_constrained_equality) +# define __cpp_lib_constrained_equality 202403L +# endif # endif #endif /* !defined(__cpp_lib_constrained_equality) && defined(__glibcxx_want_constrained_equality) */ #undef __glibcxx_want_constrained_equality @@ -1557,8 +1561,9 @@ #if !defined(__cpp_lib_format_ranges) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED -# define __glibcxx_format_ranges 1L +# define __glibcxx_format_ranges 202207L # if defined(__glibcxx_want_all) || defined(__glibcxx_want_format_ranges) +# define __cpp_lib_format_ranges 202207L # endif # endif #endif /* !defined(__cpp_lib_format_ranges) && defined(__glibcxx_want_format_ranges) */ @@ -1664,6 +1669,16 @@ #endif /* !defined(__cpp_lib_reference_from_temporary) && defined(__glibcxx_want_reference_from_temporary) */ #undef __glibcxx_want_reference_from_temporary +#if !defined(__cpp_lib_containers_ranges) +# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED +# define __glibcxx_containers_ranges 202202L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_containers_ranges) +# define __cpp_lib_containers_ranges 202202L +# endif +# endif +#endif /* !defined(__cpp_lib_containers_ranges) && defined(__glibcxx_want_containers_ranges) */ +#undef __glibcxx_want_containers_ranges + #if !defined(__cpp_lib_ranges_to_container) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED # define __glibcxx_ranges_to_container 202202L diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque index 9715721..59d60b2 100644 --- a/libstdc++-v3/include/debug/deque +++ b/libstdc++-v3/include/debug/deque @@ -155,7 +155,7 @@ namespace __debug __gnu_debug::__base(__last), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<_Tp> _Rg> deque(from_range_t, _Rg&& __rg, const _Allocator& __a = _Allocator()) : _Base(from_range, std::forward<_Rg>(__rg), __a) @@ -217,7 +217,7 @@ namespace __debug } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<std::__detail::__container_compatible_range<_Tp> _Rg> void assign_range(_Rg&& __rg) @@ -561,7 +561,7 @@ namespace __debug } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<_Tp> _Rg> iterator insert_range(const_iterator __pos, _Rg&& __rg) @@ -712,7 +712,7 @@ namespace __debug deque(size_t, _Tp, _Allocator = _Allocator()) -> deque<_Tp, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, typename _Alloc = allocator<ranges::range_value_t<_Rg>>> deque(from_range_t, _Rg&&, _Alloc = _Alloc()) diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list index 00b96d6..60a2542 100644 --- a/libstdc++-v3/include/debug/forward_list +++ b/libstdc++-v3/include/debug/forward_list @@ -267,7 +267,7 @@ namespace __debug __gnu_debug::__base(__last), __al) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<_Tp> _Rg> forward_list(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc()) : _Base(std::from_range, std::forward<_Rg>(__rg), __a) @@ -318,7 +318,7 @@ namespace __debug this->_M_invalidate_all(); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<_Tp> _Rg> void assign_range(_Rg&& __rg) @@ -440,7 +440,7 @@ namespace __debug using _Base::emplace_front; using _Base::push_front; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 using _Base::prepend_range; #endif @@ -512,7 +512,7 @@ namespace __debug return { _Base::insert_after(__pos.base(), __il), this }; } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<_Tp> _Rg> iterator insert_range_after(const_iterator __position, _Rg&& __rg) @@ -917,7 +917,7 @@ namespace __debug forward_list(size_t, _Tp, _Allocator = _Allocator()) -> forward_list<_Tp, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, typename _Allocator = allocator<ranges::range_value_t<_Rg>>> forward_list(from_range_t, _Rg&&, _Allocator = _Allocator()) diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list index 344fc98..a9d974c 100644 --- a/libstdc++-v3/include/debug/list +++ b/libstdc++-v3/include/debug/list @@ -160,7 +160,7 @@ namespace __debug __gnu_debug::__base(__last), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<_Tp> _Rg> list(from_range_t, _Rg&& __rg, const _Allocator& __a = _Allocator()) : _Base(std::from_range, std::forward<_Rg>(__rg), __a) @@ -214,7 +214,7 @@ namespace __debug this->_M_invalidate_all(); } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<_Tp> _Rg> void assign_range(_Rg&& __rg) @@ -434,7 +434,7 @@ namespace __debug using _Base::emplace_front; #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 using _Base::prepend_range; using _Base::append_range; #endif @@ -549,7 +549,7 @@ namespace __debug } #endif -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<_Tp> _Rg> iterator insert_range(const_iterator __position, _Rg&& __rg) @@ -970,7 +970,7 @@ namespace __debug list(size_t, _Tp, _Allocator = _Allocator()) -> list<_Tp, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, typename _Allocator = allocator<ranges::range_value_t<_Rg>>> list(from_range_t, _Rg&&, _Allocator = _Allocator()) diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h index aa1c1db..985a7ac 100644 --- a/libstdc++-v3/include/debug/map.h +++ b/libstdc++-v3/include/debug/map.h @@ -133,7 +133,7 @@ namespace __debug __gnu_debug::__base(__last), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a map from a range. * @since C++23 @@ -759,7 +759,7 @@ namespace __debug map(initializer_list<pair<_Key, _Tp>>, _Allocator) -> map<_Key, _Tp, less<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Compare = less<__detail::__range_key_type<_Rg>>, __allocator_like _Alloc = diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h index bef1f17..c187e51 100644 --- a/libstdc++-v3/include/debug/multimap.h +++ b/libstdc++-v3/include/debug/multimap.h @@ -133,7 +133,7 @@ namespace __debug __glibcxx_check_valid_constructor_range(__first, __last)), __gnu_debug::__base(__last), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a multimap from a range. * @since C++23 @@ -641,7 +641,7 @@ namespace __debug multimap(initializer_list<pair<_Key, _Tp>>, _Allocator) -> multimap<_Key, _Tp, less<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Compare = less<__detail::__range_key_type<_Rg>>, __allocator_like _Alloc = diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h index bddcd28..41bf78d 100644 --- a/libstdc++-v3/include/debug/multiset.h +++ b/libstdc++-v3/include/debug/multiset.h @@ -133,7 +133,7 @@ namespace __debug __glibcxx_check_valid_constructor_range(__first, __last)), __gnu_debug::__base(__last), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a multiset from a range. * @since C++23 @@ -613,7 +613,7 @@ namespace __debug multiset(initializer_list<_Key>, _Allocator) -> multiset<_Key, less<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Compare = less<ranges::range_value_t<_Rg>>, __allocator_like _Alloc = std::allocator<ranges::range_value_t<_Rg>>> diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h index 9555555..6ec8338 100644 --- a/libstdc++-v3/include/debug/set.h +++ b/libstdc++-v3/include/debug/set.h @@ -131,7 +131,7 @@ namespace __debug __glibcxx_check_valid_constructor_range(__first, __last)), __gnu_debug::__base(__last), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a set from a range. * @since C++23 @@ -623,7 +623,7 @@ namespace __debug set(initializer_list<_Key>, _Allocator) -> set<_Key, less<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Compare = less<ranges::range_value_t<_Rg>>, __allocator_like _Alloc = std::allocator<ranges::range_value_t<_Rg>>> diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map index 16d4a4a..7673db1 100644 --- a/libstdc++-v3/include/debug/unordered_map +++ b/libstdc++-v3/include/debug/unordered_map @@ -175,6 +175,12 @@ namespace __debug template<typename _InputIterator> unordered_map(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_map(__first, __last, 0, hasher(), key_equal(), __a) + { } + + template<typename _InputIterator> + unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) @@ -189,6 +195,11 @@ namespace __debug { } unordered_map(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_map(__l, 0, hasher(), key_equal(), __a) + { } + + unordered_map(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) : unordered_map(__l, __n, hasher(), key_equal(), __a) @@ -201,7 +212,7 @@ namespace __debug : unordered_map(__l, __n, __hf, key_equal(), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<value_type> _Rg> unordered_map(from_range_t, _Rg&& __rg, size_type __n = 0, @@ -869,7 +880,7 @@ namespace __debug _Hash, _Allocator) -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>, __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>, @@ -1053,6 +1064,12 @@ namespace __debug template<typename _InputIterator> unordered_multimap(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_multimap(__first, __last, 0, hasher(), key_equal(), __a) + { } + + template<typename _InputIterator> + unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) @@ -1066,6 +1083,11 @@ namespace __debug { } unordered_multimap(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_multimap(__l, 0, hasher(), key_equal(), __a) + { } + + unordered_multimap(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) : unordered_multimap(__l, __n, hasher(), key_equal(), __a) @@ -1077,7 +1099,7 @@ namespace __debug : unordered_multimap(__l, __n, __hf, key_equal(), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<value_type> _Rg> unordered_multimap(from_range_t, _Rg&& __rg, size_type __n = 0, @@ -1655,7 +1677,7 @@ namespace __debug _Hash, _Allocator) -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>, __not_allocator_like _Pred = equal_to<__detail::__range_key_type<_Rg>>, diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set index 2e342cc..932600d 100644 --- a/libstdc++-v3/include/debug/unordered_set +++ b/libstdc++-v3/include/debug/unordered_set @@ -170,6 +170,12 @@ namespace __debug template<typename _InputIterator> unordered_set(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_set(__first, __last, 0, hasher(), key_equal(), __a) + { } + + template<typename _InputIterator> + unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) @@ -183,6 +189,11 @@ namespace __debug { } unordered_set(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_set(__l, 0, hasher(), key_equal(), __a) + { } + + unordered_set(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) : unordered_set(__l, __n, hasher(), key_equal(), __a) @@ -194,7 +205,7 @@ namespace __debug : unordered_set(__l, __n, __hf, key_equal(), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<value_type> _Rg> unordered_set(from_range_t, _Rg&& __rg, size_type __n = 0, @@ -713,6 +724,17 @@ namespace __debug typename iterator_traits<_InputIterator>::value_type>, _Allocator>; + template<typename _InputIterator, typename _Allocator, + typename = _RequireInputIter<_InputIterator>, + typename = _RequireAllocator<_Allocator>> + unordered_set(_InputIterator, _InputIterator, _Allocator) + -> unordered_set<typename iterator_traits<_InputIterator>::value_type, + hash< + typename iterator_traits<_InputIterator>::value_type>, + equal_to< + typename iterator_traits<_InputIterator>::value_type>, + _Allocator>; + template<typename _InputIterator, typename _Hash, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireNotAllocatorOrIntegral<_Hash>, @@ -732,6 +754,11 @@ namespace __debug unordered_set<int>::size_type, _Allocator) -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + template<typename _Tp, typename _Allocator, + typename = _RequireAllocator<_Allocator>> + unordered_set(initializer_list<_Tp>, _Allocator) + -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + template<typename _Tp, typename _Hash, typename _Allocator, typename = _RequireNotAllocatorOrIntegral<_Hash>, typename = _RequireAllocator<_Allocator>> @@ -878,6 +905,12 @@ namespace __debug template<typename _InputIterator> unordered_multiset(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_multiset(__first, __last, 0, hasher(), key_equal(), __a) + { } + + template<typename _InputIterator> + unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) @@ -891,6 +924,11 @@ namespace __debug { } unordered_multiset(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_multiset(__l, 0, hasher(), key_equal(), __a) + { } + + unordered_multiset(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) : unordered_multiset(__l, __n, hasher(), key_equal(), __a) @@ -902,7 +940,7 @@ namespace __debug : unordered_multiset(__l, __n, __hf, key_equal(), __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<__detail::__container_compatible_range<value_type> _Rg> unordered_multiset(from_range_t, _Rg&& __rg, size_type __n = 0, @@ -1416,6 +1454,17 @@ namespace __debug iterator_traits<_InputIterator>::value_type>, _Allocator>; + template<typename _InputIterator, typename _Allocator, + typename = _RequireInputIter<_InputIterator>, + typename = _RequireAllocator<_Allocator>> + unordered_multiset(_InputIterator, _InputIterator, _Allocator) + -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type, + hash<typename + iterator_traits<_InputIterator>::value_type>, + equal_to<typename + iterator_traits<_InputIterator>::value_type>, + _Allocator>; + template<typename _InputIterator, typename _Hash, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireNotAllocatorOrIntegral<_Hash>, @@ -1437,6 +1486,11 @@ namespace __debug unordered_multiset<int>::size_type, _Allocator) -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + template<typename _Tp, typename _Allocator, + typename = _RequireAllocator<_Allocator>> + unordered_multiset(initializer_list<_Tp>, _Allocator) + -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + template<typename _Tp, typename _Hash, typename _Allocator, typename = _RequireNotAllocatorOrIntegral<_Hash>, typename = _RequireAllocator<_Allocator>> @@ -1444,7 +1498,7 @@ namespace __debug unordered_multiset<int>::size_type, _Hash, _Allocator) -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>, __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>, @@ -1479,7 +1533,7 @@ namespace __debug equal_to<ranges::range_value_t<_Rg>>, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>, __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>, diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector index b49766c..1b3486b 100644 --- a/libstdc++-v3/include/debug/vector +++ b/libstdc++-v3/include/debug/vector @@ -244,7 +244,7 @@ namespace __debug const allocator_type& __a = allocator_type()) : _Base(__l, __a) { } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 /** * @brief Construct a vector from a range. * @since C++23 @@ -871,7 +871,7 @@ namespace __debug const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<std::__detail::__container_compatible_range<_Tp> _Rg> constexpr void assign_range(_Rg&& __rg) @@ -999,7 +999,7 @@ namespace __debug vector(size_t, _Tp, _Allocator = _Allocator()) -> vector<_Tp, _Allocator>; -#if __glibcxx_ranges_to_container // C++ >= 23 +#if __glibcxx_containers_ranges // C++ >= 23 template<ranges::input_range _Rg, typename _Alloc = allocator<ranges::range_value_t<_Rg>>> vector(from_range_t, _Rg&&, _Alloc = _Alloc()) diff --git a/libstdc++-v3/include/experimental/numeric b/libstdc++-v3/include/experimental/numeric index 381ecf3..33e9731 100644 --- a/libstdc++-v3/include/experimental/numeric +++ b/libstdc++-v3/include/experimental/numeric @@ -88,9 +88,12 @@ inline namespace fundamentals_v2 return 0; _Ct __r = __m2 / __detail::__gcd<make_unsigned_t<_Ct>>(__m2, __n2); - if _GLIBCXX17_CONSTEXPR (is_signed_v<_Ct>) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + if constexpr (is_signed_v<_Ct>) if (__is_constant_evaluated()) return __r * __n2; // constant evaluation can detect overflow here. +#pragma GCC diagnostic pop bool __overflow = __builtin_mul_overflow(__r, __n2, &__r); __glibcxx_assert(!__overflow); diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit index a481781..5187c96 100644 --- a/libstdc++-v3/include/std/bit +++ b/libstdc++-v3/include/std/bit @@ -153,13 +153,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // __cpp_lib_byteswap /// @cond undocumented +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr template<typename _Tp> constexpr _Tp __rotl(_Tp __x, int __s) noexcept { constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits; - if _GLIBCXX17_CONSTEXPR ((_Nd & (_Nd - 1)) == 0) + if constexpr ((_Nd & (_Nd - 1)) == 0) { // Variant for power of two _Nd which the compiler can // easily pattern match. @@ -181,7 +183,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __rotr(_Tp __x, int __s) noexcept { constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits; - if _GLIBCXX17_CONSTEXPR ((_Nd & (_Nd - 1)) == 0) + if constexpr ((_Nd & (_Nd - 1)) == 0) { // Variant for power of two _Nd which the compiler can // easily pattern match. @@ -215,17 +217,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits; constexpr auto _Nd_u = __int_traits<unsigned>::__digits; - if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u) + if constexpr (_Nd <= _Nd_u) { constexpr int __diff = _Nd_u - _Nd; return __builtin_clz(__x) - __diff; } - else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul) + else if constexpr (_Nd <= _Nd_ul) { constexpr int __diff = _Nd_ul - _Nd; return __builtin_clzl(__x) - __diff; } - else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull) + else if constexpr (_Nd <= _Nd_ull) { constexpr int __diff = _Nd_ull - _Nd; return __builtin_clzll(__x) - __diff; @@ -272,11 +274,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits; constexpr auto _Nd_u = __int_traits<unsigned>::__digits; - if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u) + if constexpr (_Nd <= _Nd_u) return __builtin_ctz(__x); - else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul) + else if constexpr (_Nd <= _Nd_ul) return __builtin_ctzl(__x); - else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull) + else if constexpr (_Nd <= _Nd_ull) return __builtin_ctzll(__x); else // (_Nd > _Nd_ull) { @@ -314,11 +316,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits; constexpr auto _Nd_u = __int_traits<unsigned>::__digits; - if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u) + if constexpr (_Nd <= _Nd_u) return __builtin_popcount(__x); - else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul) + else if constexpr (_Nd <= _Nd_ul) return __builtin_popcountl(__x); - else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull) + else if constexpr (_Nd <= _Nd_ull) return __builtin_popcountll(__x); else // (_Nd > _Nd_ull) { @@ -357,7 +359,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } using __promoted_type = decltype(__x << 1); - if _GLIBCXX17_CONSTEXPR (!is_same<__promoted_type, _Tp>::value) + if constexpr (!is_same<__promoted_type, _Tp>::value) { // If __x undergoes integral promotion then shifting by _Nd is // not undefined. In order to make the shift undefined, so that @@ -388,6 +390,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _Nd - std::__countl_zero(__x); } +#pragma GCC diagnostic pop /// @endcond #ifdef __cpp_lib_bitops // C++ >= 20 diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset index c07117a..8b5d270 100644 --- a/libstdc++-v3/include/std/bitset +++ b/libstdc++-v3/include/std/bitset @@ -1605,6 +1605,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr struct _Buffer { static _GLIBCXX_CONSTEXPR bool _S_use_alloca() { return _Nb <= 256; } @@ -1613,18 +1615,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ~_Buffer() { - if _GLIBCXX17_CONSTEXPR (!_S_use_alloca()) + if _GLIBCXX_CONSTEXPR (!_S_use_alloca()) delete[] _M_ptr; } _CharT* const _M_ptr; }; _CharT* __ptr; - if _GLIBCXX17_CONSTEXPR (_Buffer::_S_use_alloca()) + if _GLIBCXX_CONSTEXPR (_Buffer::_S_use_alloca()) __ptr = (_CharT*)__builtin_alloca(_Nb); else __ptr = new _CharT[_Nb]; const _Buffer __buf(__ptr); +#pragma GCC diagnostic pop // _GLIBCXX_RESOLVE_LIB_DEFECTS // 303. Bitset input operator underspecified @@ -1673,7 +1676,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { __is._M_setstate(__ios_base::badbit); } } - if _GLIBCXX17_CONSTEXPR (_Nb) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + if _GLIBCXX_CONSTEXPR (_Nb) { if (size_t __len = __ptr - __buf._M_ptr) __x.template _M_copy_from_ptr<_CharT, _Traits>(__buf._M_ptr, __len, @@ -1682,6 +1687,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER else __state |= __ios_base::failbit; } +#pragma GCC diagnostic pop if (__state) __is.setstate(__state); return __is; diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv index 75fcb71..dda49ce 100644 --- a/libstdc++-v3/include/std/charconv +++ b/libstdc++-v3/include/std/charconv @@ -35,6 +35,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" // __int128 +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr #include <bits/requires_hosted.h> // for error codes @@ -239,7 +240,7 @@ namespace __detail to_chars_result __res; unsigned __len = 0; - if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Tp>::__digits <= 16) + if constexpr (__gnu_cxx::__int_traits<_Tp>::__digits <= 16) { __len = __val > 077777u ? 6u : __val > 07777u ? 5u @@ -336,7 +337,7 @@ namespace __detail *__first = '0'; return { __first + 1, errc{} }; } - else if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) + else if constexpr (std::is_signed<_Tp>::value) if (__value < 0) { *__first++ = '-'; @@ -452,7 +453,7 @@ namespace __detail _GLIBCXX20_CONSTEXPR unsigned char __from_chars_alnum_to_val(unsigned char __c) { - if _GLIBCXX17_CONSTEXPR (_DecOnly) + if constexpr (_DecOnly) return static_cast<unsigned char>(__c - '0'); else return __from_chars_alnum_to_val_table<_DecOnly>::value.__data[__c]; @@ -562,7 +563,7 @@ namespace __detail from_chars_result __res{__first, {}}; int __sign = 1; - if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) + if constexpr (std::is_signed<_Tp>::value) if (__first != __last && *__first == '-') { __sign = -1; @@ -595,7 +596,7 @@ namespace __detail __res.ec = errc::result_out_of_range; else { - if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) + if constexpr (std::is_signed<_Tp>::value) { _Tp __tmp; if (__builtin_mul_overflow(__val, __sign, &__tmp)) @@ -605,8 +606,8 @@ namespace __detail } else { - if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Up>::__max - > __gnu_cxx::__int_traits<_Tp>::__max) + if constexpr (__gnu_cxx::__int_traits<_Up>::__max + > __gnu_cxx::__int_traits<_Tp>::__max) { if (__val > __gnu_cxx::__int_traits<_Tp>::__max) __res.ec = errc::result_out_of_range; diff --git a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque index 8fd7300..2badab8 100644 --- a/libstdc++-v3/include/std/deque +++ b/libstdc++-v3/include/std/deque @@ -72,6 +72,7 @@ #define __glibcxx_want_algorithm_default_value_type #define __glibcxx_want_allocator_traits_is_always_equal +#define __glibcxx_want_containers_ranges #define __glibcxx_want_erase_if #define __glibcxx_want_nonmember_container_access #include <bits/version.h> diff --git a/libstdc++-v3/include/std/flat_map b/libstdc++-v3/include/std/flat_map index 405caa8..6593988 100644 --- a/libstdc++-v3/include/std/flat_map +++ b/libstdc++-v3/include/std/flat_map @@ -890,14 +890,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __x.swap(__y); } template<typename _Predicate> - friend size_type - erase_if(_Derived& __c, _Predicate __pred) + size_type + _M_erase_if(_Predicate __pred) { - auto __guard = __c._M_make_clear_guard(); - auto __zv = views::zip(__c._M_cont.keys, __c._M_cont.values); + auto __guard = _M_make_clear_guard(); + auto __zv = views::zip(_M_cont.keys, _M_cont.values); auto __sr = ranges::remove_if(__zv, __pred); auto __erased = __sr.size(); - __c.erase(__c.end() - __erased, __c.end()); + erase(end() - __erased, end()); __guard._M_disable(); return __erased; } @@ -1329,6 +1329,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using _Impl::lower_bound; using _Impl::upper_bound; using _Impl::equal_range; + + using _Impl::_M_erase_if; }; template<typename _KeyContainer, typename _MappedContainer, @@ -1412,6 +1414,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && uses_allocator_v<_MappedContainer, _Alloc>> { }; + template<typename _Key, typename _Tp, typename _Compare, + typename _KeyContainer, typename _MappedContainer, typename _Predicate> + typename flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type + erase_if(flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __c, + _Predicate __pred) + { return __c._M_erase_if(std::move(__pred)); } + /* Class template flat_multimap - container adaptor * * @ingroup @@ -1487,6 +1496,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using _Impl::lower_bound; using _Impl::upper_bound; using _Impl::equal_range; + + using _Impl::_M_erase_if; }; template<typename _KeyContainer, typename _MappedContainer, @@ -1571,6 +1582,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && uses_allocator_v<_MappedContainer, _Alloc>> { }; + template<typename _Key, typename _Tp, typename _Compare, + typename _KeyContainer, typename _MappedContainer, typename _Predicate> + typename flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type + erase_if(flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __c, + _Predicate __pred) + { return __c._M_erase_if(std::move(__pred)); } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // __cpp_lib_flat_map diff --git a/libstdc++-v3/include/std/flat_set b/libstdc++-v3/include/std/flat_set index 3e15d1a..c48340d 100644 --- a/libstdc++-v3/include/std/flat_set +++ b/libstdc++-v3/include/std/flat_set @@ -745,15 +745,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __x.swap(__y); } template<typename _Predicate> - friend size_type - erase_if(_Derived& __c, _Predicate __pred) + size_type + _M_erase_if(_Predicate __pred) { - auto __guard = __c._M_make_clear_guard(); - auto __first = __c._M_cont.begin(); - auto __last = __c._M_cont.end(); + auto __guard = _M_make_clear_guard(); + auto __first = _M_cont.begin(); + auto __last = _M_cont.end(); __first = std::remove_if(__first, __last, __pred); auto __n = __last - __first; - __c.erase(__first, __last); + erase(__first, __last); __guard._M_disable(); return __n; } @@ -860,6 +860,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using _Impl::lower_bound; using _Impl::upper_bound; using _Impl::equal_range; + + using _Impl::_M_erase_if; }; template<typename _KeyContainer, @@ -930,6 +932,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : bool_constant<uses_allocator_v<_KeyContainer, _Alloc>> { }; + template<typename _Key, typename _Compare, typename _KeyContainer, + typename _Predicate> + typename flat_set<_Key, _Compare, _KeyContainer>::size_type + erase_if(flat_set<_Key, _Compare, _KeyContainer>& __c, _Predicate __pred) + { return __c._M_erase_if(std::move(__pred)); } + /* Class template flat_multiset - container adaptor * * @ingroup @@ -999,6 +1007,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using _Impl::lower_bound; using _Impl::upper_bound; using _Impl::equal_range; + + using _Impl::_M_erase_if; }; template<typename _KeyContainer, @@ -1069,6 +1079,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : bool_constant<uses_allocator_v<_KeyContainer, _Alloc>> { }; + template<typename _Key, typename _Compare, typename _KeyContainer, + typename _Predicate> + typename flat_multiset<_Key, _Compare, _KeyContainer>::size_type + erase_if(flat_multiset<_Key, _Compare, _KeyContainer>& __c, _Predicate __pred) + { return __c._M_erase_if(std::move(__pred)); } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // __cpp_lib_flat_set diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index 2e9319c..054ce35 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -56,7 +56,7 @@ #include <bits/ranges_base.h> // input_range, range_reference_t #include <bits/ranges_util.h> // subrange #include <bits/ranges_algobase.h> // ranges::copy -#include <bits/stl_iterator.h> // back_insert_iterator +#include <bits/stl_iterator.h> // back_insert_iterator, counted_iterator #include <bits/stl_pair.h> // __is_pair #include <bits/unicode.h> // __is_scalar_value, _Utf_view, etc. #include <bits/utility.h> // tuple_size_v @@ -80,12 +80,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @cond undocumented namespace __format { - // Type-erased character sink. + // STATICALLY-WIDEN, see C++20 [time.general] + // It doesn't matter for format strings (which can only be char or wchar_t) + // but this returns the narrow string for anything that isn't wchar_t. This + // is done because const char* can be inserted into any ostream type, and + // will be widened at runtime if necessary. + template<typename _CharT> + consteval auto + _Widen(const char* __narrow, const wchar_t* __wide) + { + if constexpr (is_same_v<_CharT, wchar_t>) + return __wide; + else + return __narrow; + } +#define _GLIBCXX_WIDEN_(C, S) ::std::__format::_Widen<C>(S, L##S) +#define _GLIBCXX_WIDEN(S) _GLIBCXX_WIDEN_(_CharT, S) + + // Size for stack located buffer + template<typename _CharT> + constexpr size_t __stackbuf_size = 32 * sizeof(void*) / sizeof(_CharT); + + // Type-erased character sinks. template<typename _CharT> class _Sink; + template<typename _CharT> class _Fixedbuf_sink; + template<typename _Out, typename _CharT> class _Padding_sink; + // Output iterator that writes to a type-erase character sink. template<typename _CharT> class _Sink_iter; + // An unspecified output iterator type used in the `formattable` concept. + template<typename _CharT> + struct _Iter_for + { using type = back_insert_iterator<basic_string<_CharT>>; }; + template<typename _CharT> using __format_context = basic_format_context<_Sink_iter<_CharT>, _CharT>; @@ -104,6 +133,7 @@ namespace __format template<typename, typename...> friend struct std::basic_format_string; }; + } // namespace __format /// @endcond @@ -448,16 +478,10 @@ namespace __format _Pres_d = 1, _Pres_b, _Pres_B, _Pres_o, _Pres_x, _Pres_X, _Pres_c, // Presentation types for floating-point types. _Pres_a = 1, _Pres_A, _Pres_e, _Pres_E, _Pres_f, _Pres_F, _Pres_g, _Pres_G, - _Pres_p = 0, _Pres_P, // For pointers. - _Pres_s = 0, // For strings and bool. - _Pres_esc = 0xf, // For strings and charT. - }; - - enum _Align { - _Align_default, - _Align_left, - _Align_right, - _Align_centre, + _Pres_p = 0, _Pres_P, // For pointers. + _Pres_s = 0, // For strings, bool + _Pres_seq = 0, _Pres_str, // For ranges + _Pres_esc = 0xf, // For strings, charT and ranges }; enum _Sign { @@ -517,42 +541,48 @@ namespace __format // pre: __first != __last constexpr iterator _M_parse_fill_and_align(iterator __first, iterator __last) noexcept + { return _M_parse_fill_and_align(__first, __last, "{"); } + + // pre: __first != __last + constexpr iterator + _M_parse_fill_and_align(iterator __first, iterator __last, string_view __not_fill) noexcept { - if (*__first != '{') + for (char __c : __not_fill) + if (*__first == static_cast<_CharT>(__c)) + return __first; + + using namespace __unicode; + if constexpr (__literal_encoding_is_unicode<_CharT>()) { - using namespace __unicode; - if constexpr (__literal_encoding_is_unicode<_CharT>()) - { - // Accept any UCS scalar value as fill character. - _Utf32_view<ranges::subrange<iterator>> __uv({__first, __last}); - if (!__uv.empty()) - { - auto __beg = __uv.begin(); - char32_t __c = *__beg++; - if (__is_scalar_value(__c)) - if (auto __next = __beg.base(); __next != __last) - if (_Align __align = _S_align(*__next)) - { - _M_fill = __c; - _M_align = __align; - return ++__next; - } - } - } - else if (__last - __first >= 2) - if (_Align __align = _S_align(__first[1])) - { - _M_fill = *__first; - _M_align = __align; - return __first + 2; - } + // Accept any UCS scalar value as fill character. + _Utf32_view<ranges::subrange<iterator>> __uv({__first, __last}); + if (!__uv.empty()) + { + auto __beg = __uv.begin(); + char32_t __c = *__beg++; + if (__is_scalar_value(__c)) + if (auto __next = __beg.base(); __next != __last) + if (_Align __align = _S_align(*__next)) + { + _M_fill = __c; + _M_align = __align; + return ++__next; + } + } + } + else if (__last - __first >= 2) + if (_Align __align = _S_align(__first[1])) + { + _M_fill = *__first; + _M_align = __align; + return __first + 2; + } - if (_Align __align = _S_align(__first[0])) - { - _M_fill = ' '; - _M_align = __align; - return __first + 1; - } + if (_Align __align = _S_align(__first[0])) + { + _M_fill = ' '; + _M_align = __align; + return __first + 1; } return __first; } @@ -848,6 +878,321 @@ namespace __format __spec._M_fill); } + template<typename _CharT> + size_t + __truncate(basic_string_view<_CharT>& __s, size_t __prec) + { + if constexpr (__unicode::__literal_encoding_is_unicode<_CharT>()) + { + if (__prec != (size_t)-1) + return __unicode::__truncate(__s, __prec); + else + return __unicode::__field_width(__s); + } + else + { + __s = __s.substr(0, __prec); + return __s.size(); + } + } + + + // Values are indices into _Escapes::all. + enum class _Term_char : unsigned char { + _Tc_quote = 12, + _Tc_apos = 15 + }; + + template<typename _CharT> + struct _Escapes + { + using _Str_view = basic_string_view<_CharT>; + + static consteval + _Str_view _S_all() + { return _GLIBCXX_WIDEN("\t\\t\n\\n\r\\r\\\\\\\"\\\"'\\'\\u\\x"); } + + static constexpr + _CharT _S_term(_Term_char __term) + { return _S_all()[static_cast<unsigned char>(__term)]; } + + static consteval + _Str_view _S_tab() + { return _S_all().substr(0, 3); } + + static consteval + _Str_view _S_newline() + { return _S_all().substr(3, 3); } + + static consteval + _Str_view _S_return() + { return _S_all().substr(6, 3); } + + static consteval + _Str_view _S_bslash() + { return _S_all().substr(9, 3); } + + static consteval + _Str_view _S_quote() + { return _S_all().substr(12, 3); } + + static consteval + _Str_view _S_apos() + { return _S_all().substr(15, 3); } + + static consteval + _Str_view _S_u() + { return _S_all().substr(18, 2); } + + static consteval + _Str_view _S_x() + { return _S_all().substr(20, 2); } + }; + + template<typename _CharT> + struct _Separators + { + using _Str_view = basic_string_view<_CharT>; + + static consteval + _Str_view _S_all() + { return _GLIBCXX_WIDEN("[]{}(), : "); } + + static consteval + _Str_view _S_squares() + { return _S_all().substr(0, 2); } + + static consteval + _Str_view _S_braces() + { return _S_all().substr(2, 2); } + + static consteval + _Str_view _S_parens() + { return _S_all().substr(4, 2); } + + static consteval + _Str_view _S_comma() + { return _S_all().substr(6, 2); } + + static consteval + _Str_view _S_colon() + { return _S_all().substr(8, 2); } + }; + + template<typename _CharT> + constexpr bool __should_escape_ascii(_CharT __c, _Term_char __term) + { + using _Esc = _Escapes<_CharT>; + switch (__c) + { + case _Esc::_S_tab()[0]: + case _Esc::_S_newline()[0]: + case _Esc::_S_return()[0]: + case _Esc::_S_bslash()[0]: + return true; + case _Esc::_S_quote()[0]: + return __term == _Term_char::_Tc_quote; + case _Esc::_S_apos()[0]: + return __term == _Term_char::_Tc_apos; + default: + return (__c >= 0 && __c < 0x20) || __c == 0x7f; + }; + } + + // @pre __c <= 0x10FFFF + constexpr bool __should_escape_unicode(char32_t __c, bool __prev_esc) + { + if (__unicode::__should_escape_category(__c)) + return __c != U' '; + if (!__prev_esc) + return false; + return __unicode::__grapheme_cluster_break_property(__c) + == __unicode::_Gcb_property::_Gcb_Extend; + } + + using uint_least32_t = __UINT_LEAST32_TYPE__; + template<typename _Out, typename _CharT> + _Out + __write_escape_seq(_Out __out, uint_least32_t __val, + basic_string_view<_CharT> __prefix) + { + using _Str_view = basic_string_view<_CharT>; + constexpr size_t __max = 8; + char __buf[__max]; + const string_view __narrow( + __buf, + std::__to_chars_i<uint_least32_t>(__buf, __buf + __max, __val, 16).ptr); + + __out = __format::__write(__out, __prefix); + *__out = _Separators<_CharT>::_S_braces()[0]; + ++__out; + if constexpr (is_same_v<char, _CharT>) + __out = __format::__write(__out, __narrow); +#ifdef _GLIBCXX_USE_WCHAR_T + else + { + _CharT __wbuf[__max]; + const size_t __n = __narrow.size(); + std::__to_wstring_numeric(__narrow.data(), __n, __wbuf); + __out = __format::__write(__out, _Str_view(__wbuf, __n)); + } +#endif + *__out = _Separators<_CharT>::_S_braces()[1]; + return ++__out; + } + + template<typename _Out, typename _CharT> + _Out + __write_escaped_char(_Out __out, _CharT __c) + { + using _UChar = make_unsigned_t<_CharT>; + using _Esc = _Escapes<_CharT>; + switch (__c) + { + case _Esc::_S_tab()[0]: + return __format::__write(__out, _Esc::_S_tab().substr(1, 2)); + case _Esc::_S_newline()[0]: + return __format::__write(__out, _Esc::_S_newline().substr(1, 2)); + case _Esc::_S_return()[0]: + return __format::__write(__out, _Esc::_S_return().substr(1, 2)); + case _Esc::_S_bslash()[0]: + return __format::__write(__out, _Esc::_S_bslash().substr(1, 2)); + case _Esc::_S_quote()[0]: + return __format::__write(__out, _Esc::_S_quote().substr(1, 2)); + case _Esc::_S_apos()[0]: + return __format::__write(__out, _Esc::_S_apos().substr(1, 2)); + default: + return __format::__write_escape_seq(__out, + static_cast<_UChar>(__c), + _Esc::_S_u()); + } + } + + template<typename _CharT, typename _Out> + _Out + __write_escaped_ascii(_Out __out, + basic_string_view<_CharT> __str, + _Term_char __term) + { + using _Str_view = basic_string_view<_CharT>; + auto __first = __str.begin(); + auto const __last = __str.end(); + while (__first != __last) + { + auto __print = __first; + // assume anything outside ASCII is printable + while (__print != __last + && !__format::__should_escape_ascii(*__print, __term)) + ++__print; + + if (__print != __first) + __out = __format::__write(__out, _Str_view(__first, __print)); + + if (__print == __last) + return __out; + + __first = __print; + __out = __format::__write_escaped_char(__out, *__first); + ++__first; + } + return __out; + } + + template<typename _CharT, typename _Out> + _Out + __write_escaped_unicode(_Out __out, + basic_string_view<_CharT> __str, + _Term_char __term) + { + using _Str_view = basic_string_view<_CharT>; + using _UChar = make_unsigned_t<_CharT>; + using _Esc = _Escapes<_CharT>; + + static constexpr char32_t __replace = U'\uFFFD'; + static constexpr _Str_view __replace_rep = [] + { + // N.B. "\uFFFD" is ill-formed if encoding is not unicode. + if constexpr (is_same_v<char, _CharT>) + return "\xEF\xBF\xBD"; + else + return L"\xFFFD"; + }(); + + __unicode::_Utf_view<char32_t, _Str_view> __v(std::move(__str)); + auto __first = __v.begin(); + auto const __last = __v.end(); + + bool __prev_esc = true; + while (__first != __last) + { + bool __esc_ascii = false; + bool __esc_unicode = false; + bool __esc_replace = false; + auto __should_escape = [&](auto const& __it) + { + if (*__it <= 0x7f) + return __esc_ascii + = __format::__should_escape_ascii(*__it.base(), __term); + if (__format::__should_escape_unicode(*__it, __prev_esc)) + return __esc_unicode = true; + if (*__it == __replace) + { + _Str_view __units(__it.base(), __it._M_units()); + return __esc_replace = (__units != __replace_rep); + } + return false; + }; + + auto __print = __first; + while (__print != __last && !__should_escape(__print)) + { + __prev_esc = false; + ++__print; + } + + if (__print != __first) + __out = __format::__write(__out, _Str_view(__first.base(), __print.base())); + + if (__print == __last) + return __out; + + __first = __print; + if (__esc_ascii) + __out = __format::__write_escaped_char(__out, *__first.base()); + else if (__esc_unicode) + __out = __format::__write_escape_seq(__out, *__first, _Esc::_S_u()); + else // __esc_replace + for (_CharT __c : _Str_view(__first.base(), __first._M_units())) + __out = __format::__write_escape_seq(__out, + static_cast<_UChar>(__c), + _Esc::_S_x()); + __prev_esc = true; + ++__first; + + } + return __out; + } + + template<typename _CharT, typename _Out> + _Out + __write_escaped(_Out __out, basic_string_view<_CharT> __str, _Term_char __term) + { + *__out = _Escapes<_CharT>::_S_term(__term); + ++__out; + + if constexpr (__unicode::__literal_encoding_is_unicode<_CharT>()) + __out = __format::__write_escaped_unicode(__out, __str, __term); + else if constexpr (is_same_v<char, _CharT> + && __unicode::__literal_encoding_is_extended_ascii()) + __out = __format::__write_escaped_ascii(__out, __str, __term); + else + // TODO Handle non-ascii extended encoding + __out = __format::__write_escaped_ascii(__out, __str, __term); + + *__out = _Escapes<_CharT>::_S_term(__term); + return ++__out; + } + // A lightweight optional<locale>. struct _Optional_locale { @@ -924,6 +1269,13 @@ namespace __format template<__char _CharT> struct __formatter_str { + __formatter_str() = default; + + constexpr + __formatter_str(_Spec<_CharT> __spec) noexcept + : _M_spec(__spec) + { } + constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) { @@ -961,7 +1313,7 @@ namespace __format if (*__first == 's') ++__first; -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED else if (*__first == '?') { __spec._M_type = _Pres_esc; @@ -981,36 +1333,112 @@ namespace __format basic_format_context<_Out, _CharT>& __fc) const { if (_M_spec._M_type == _Pres_esc) - { - // TODO: C++23 escaped string presentation - } + return _M_format_escaped(__s, __fc); if (_M_spec._M_width_kind == _WP_none && _M_spec._M_prec_kind == _WP_none) return __format::__write(__fc.out(), __s); - size_t __estimated_width; - if constexpr (__unicode::__literal_encoding_is_unicode<_CharT>()) + const size_t __maxwidth = _M_spec._M_get_precision(__fc); + const size_t __width = __format::__truncate(__s, __maxwidth); + return __format::__write_padded_as_spec(__s, __width, __fc, _M_spec); + } + + template<typename _Out> + _Out + _M_format_escaped(basic_string_view<_CharT> __s, + basic_format_context<_Out, _CharT>& __fc) const + { + constexpr auto __term = __format::_Term_char::_Tc_quote; + const size_t __padwidth = _M_spec._M_get_width(__fc); + if (__padwidth == 0 && _M_spec._M_prec_kind == _WP_none) + return __format::__write_escaped(__fc.out(), __s, __term); + + const size_t __maxwidth = _M_spec._M_get_precision(__fc); + const size_t __width = __truncate(__s, __maxwidth); + // N.B. Escaping only increases width + if (__padwidth <= __width && _M_spec._M_prec_kind == _WP_none) + return __format::__write_escaped(__fc.out(), __s, __term); + + // N.B. [tab:format.type.string] defines '?' as + // Copies the escaped string ([format.string.escaped]) to the output, + // so precision seem to appy to escaped string. + _Padding_sink<_Out, _CharT> __sink(__fc.out(), __padwidth, __maxwidth); + __format::__write_escaped(__sink.out(), __s, __term); + return __sink._M_finish(_M_spec._M_align, _M_spec._M_fill); + } + +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED + template<ranges::input_range _Rg, typename _Out> + requires same_as<remove_cvref_t<ranges::range_reference_t<_Rg>>, _CharT> + _Out + _M_format_range(_Rg&& __rg, basic_format_context<_Out, _CharT>& __fc) const + { + using _Range = remove_reference_t<_Rg>; + using _String = basic_string<_CharT>; + using _String_view = basic_string_view<_CharT>; + if constexpr (!is_lvalue_reference_v<_Rg>) + return _M_format_range<_Range&>(__rg, __fc); + else if constexpr (!is_const_v<_Range> + && __simply_formattable_range<_Range, _CharT>) + return _M_format_range<const _Range&>(__rg, __fc); + else if constexpr (ranges::contiguous_range<_Rg>) { - if (_M_spec._M_prec_kind != _WP_none) + _String_view __str(ranges::data(__rg), + size_t(ranges::distance(__rg))); + return format(__str, __fc); + } + else if (_M_spec._M_type != _Pres_esc) + { + const size_t __padwidth = _M_spec._M_get_width(__fc); + if (__padwidth == 0 && _M_spec._M_prec_kind == _WP_none) + return ranges::copy(__rg, __fc.out()).out; + + _Padding_sink<_Out, _CharT> __sink(__fc.out(), __padwidth, + _M_spec._M_get_precision(__fc)); + ranges::copy(__rg, __sink.out()); + return __sink._M_finish(_M_spec._M_align, _M_spec._M_fill); + } + else if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>) + { + const size_t __n(ranges::distance(__rg)); + size_t __w = __n; + if constexpr (!__unicode::__literal_encoding_is_unicode<_CharT>()) + if (size_t __max = _M_spec._M_get_precision(__fc); __n > __max) + __w == __max; + + if (__w <= __format::__stackbuf_size<_CharT>) + { + _CharT __buf[__format::__stackbuf_size<_CharT>]; + ranges::copy_n(ranges::begin(__rg), __w, __buf); + return _M_format_escaped(_String_view(__buf, __n), __fc); + } + else if constexpr (ranges::random_access_range<_Rg>) { - size_t __prec = _M_spec._M_get_precision(__fc); - __estimated_width = __unicode::__truncate(__s, __prec); + ranges::iterator_t<_Rg> __first = ranges::begin(__rg); + ranges::subrange __sub(__first, __first + __w); + return _M_format_escaped(_String(from_range, __sub), __fc); } + else if (__w <= __n) + { + ranges::subrange __sub( + counted_iterator(ranges::begin(__rg), __w), + default_sentinel); + return _M_format_escaped(_String(from_range, __sub), __fc); + } + else if constexpr (ranges::sized_range<_Rg>) + return _M_format_escaped(_String(from_range, __rg), __fc); else - __estimated_width = __unicode::__field_width(__s); + { + // N.B. preserve the computed size + ranges::subrange __sub(__rg, __n); + return _M_format_escaped(_String(from_range, __sub), __fc); + } } else - { - __s = __s.substr(0, _M_spec._M_get_precision(__fc)); - __estimated_width = __s.size(); - } - - return __format::__write_padded_as_spec(__s, __estimated_width, - __fc, _M_spec); + return _M_format_escaped(_String(from_range, __rg), __fc); } -#if __cpp_lib_format_ranges constexpr void set_debug_format() noexcept { _M_spec._M_type = _Pres_esc; } @@ -1029,6 +1457,13 @@ namespace __format static constexpr _Pres_type _AsBool = _Pres_s; static constexpr _Pres_type _AsChar = _Pres_c; + __formatter_int() = default; + + constexpr + __formatter_int(_Spec<_CharT> __spec) noexcept + : _M_spec(__spec) + { } + constexpr typename basic_format_parse_context<_CharT>::iterator _M_do_parse(basic_format_parse_context<_CharT>& __pc, _Pres_type __type) { @@ -1120,7 +1555,7 @@ namespace __format ++__first; } break; -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED case '?': if (__type == _AsChar) { @@ -1272,7 +1707,7 @@ namespace __format _S_character_width(_CharT __c) { // N.B. single byte cannot encode charcter of width greater than 1 - if constexpr (sizeof(_CharT) > 1u && + if constexpr (sizeof(_CharT) > 1u && __unicode::__literal_encoding_is_unicode<_CharT>()) return __unicode::__field_width(__c); else @@ -1286,7 +1721,33 @@ namespace __format { return __format::__write_padded_as_spec({&__c, 1u}, _S_character_width(__c), - __fc, _M_spec); + __fc, _M_spec); + } + + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + _M_format_character_escaped(_CharT __c, + basic_format_context<_Out, _CharT>& __fc) const + { + using _Esc = _Escapes<_CharT>; + constexpr auto __term = __format::_Term_char::_Tc_apos; + const basic_string_view<_CharT> __in(&__c, 1u); + if (_M_spec._M_get_width(__fc) <= 3u) + return __format::__write_escaped(__fc.out(), __in, __term); + + _CharT __buf[12]; + __format::_Fixedbuf_sink<_CharT> __sink(__buf); + __format::__write_escaped(__sink.out(), __in, __term); + + const basic_string_view<_CharT> __escaped = __sink.view(); + size_t __estimated_width; + if (__escaped[1] == _Esc::_S_bslash()[0]) // escape sequence + __estimated_width = __escaped.size(); + else + __estimated_width = 2 + _S_character_width(__c); + return __format::__write_padded_as_spec(__escaped, + __estimated_width, + __fc, _M_spec); } template<typename _Int> @@ -1950,6 +2411,134 @@ namespace __format _Spec<_CharT> _M_spec{}; }; + template<__format::__char _CharT> + struct __formatter_ptr + { + __formatter_ptr() = default; + + constexpr + __formatter_ptr(_Spec<_CharT> __spec) noexcept + : _M_spec(__spec) + { } + + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { + __format::_Spec<_CharT> __spec{}; + const auto __last = __pc.end(); + auto __first = __pc.begin(); + + auto __finalize = [this, &__spec] { + _M_spec = __spec; + }; + + auto __finished = [&] { + if (__first == __last || *__first == '}') + { + __finalize(); + return true; + } + return false; + }; + + if (__finished()) + return __first; + + __first = __spec._M_parse_fill_and_align(__first, __last); + if (__finished()) + return __first; + +// _GLIBCXX_RESOLVE_LIB_DEFECTS +// P2510R3 Formatting pointers +#if __glibcxx_format >= 202304L + __first = __spec._M_parse_zero_fill(__first, __last); + if (__finished()) + return __first; +#endif + + __first = __spec._M_parse_width(__first, __last, __pc); + + if (__first != __last) + { + if (*__first == 'p') + ++__first; +#if __glibcxx_format >= 202304L + else if (*__first == 'P') + { + __spec._M_type = __format::_Pres_P; + ++__first; + } +#endif + } + + if (__finished()) + return __first; + + __format::__failed_to_parse_format_spec(); + } + + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const void* __v, basic_format_context<_Out, _CharT>& __fc) const + { + auto __u = reinterpret_cast<__UINTPTR_TYPE__>(__v); + char __buf[2 + sizeof(__v) * 2]; + auto [__ptr, __ec] = std::to_chars(__buf + 2, std::end(__buf), + __u, 16); + int __n = __ptr - __buf; + __buf[0] = '0'; + __buf[1] = 'x'; +#if __glibcxx_format >= 202304L + 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>) + __str = string_view(__buf, __n); +#ifdef _GLIBCXX_USE_WCHAR_T + else + { + auto __p = (_CharT*)__builtin_alloca(__n * sizeof(_CharT)); + std::__to_wstring_numeric(__buf, __n, __p); + __str = wstring_view(__p, __n); + } +#endif + +#if __glibcxx_format >= 202304L + 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); + } + + private: + __format::_Spec<_CharT> _M_spec{}; + }; + } // namespace __format /// @endcond @@ -1973,15 +2562,12 @@ namespace __format || _M_f._M_spec._M_type == __format::_Pres_c) return _M_f._M_format_character(__u, __fc); else if (_M_f._M_spec._M_type == __format::_Pres_esc) - { - // TODO - return __fc.out(); - } + return _M_f._M_format_character_escaped(__u, __fc); else return _M_f.format(static_cast<make_unsigned_t<_CharT>>(__u), __fc); } -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED constexpr void set_debug_format() noexcept { _M_f._M_spec._M_type = __format::_Pres_esc; } @@ -2012,15 +2598,12 @@ namespace __format || _M_f._M_spec._M_type == __format::_Pres_c) return _M_f._M_format_character(__u, __fc); else if (_M_f._M_spec._M_type == __format::_Pres_esc) - { - // TODO - return __fc.out(); - } + return _M_f._M_format_character_escaped(__u, __fc); else return _M_f.format(static_cast<unsigned char>(__u), __fc); } -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED constexpr void set_debug_format() noexcept { _M_f._M_spec._M_type = __format::_Pres_esc; } @@ -2050,7 +2633,7 @@ namespace __format format(_CharT* __u, basic_format_context<_Out, _CharT>& __fc) const { return _M_f.format(__u, __fc); } -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED constexpr void set_debug_format() noexcept { _M_f.set_debug_format(); } #endif @@ -2075,7 +2658,7 @@ namespace __format basic_format_context<_Out, _CharT>& __fc) const { return _M_f.format(__u, __fc); } -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED constexpr void set_debug_format() noexcept { _M_f.set_debug_format(); } #endif @@ -2099,7 +2682,7 @@ namespace __format basic_format_context<_Out, _CharT>& __fc) const { return _M_f.format({__u, _Nm}, __fc); } -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED constexpr void set_debug_format() noexcept { _M_f.set_debug_format(); } #endif @@ -2123,7 +2706,7 @@ namespace __format basic_format_context<_Out, char>& __fc) const { return _M_f.format(__u, __fc); } -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED constexpr void set_debug_format() noexcept { _M_f.set_debug_format(); } #endif @@ -2148,7 +2731,7 @@ namespace __format basic_format_context<_Out, wchar_t>& __fc) const { return _M_f.format(__u, __fc); } -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED constexpr void set_debug_format() noexcept { _M_f.set_debug_format(); } #endif @@ -2173,7 +2756,7 @@ namespace __format basic_format_context<_Out, char>& __fc) const { return _M_f.format(__u, __fc); } -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED constexpr void set_debug_format() noexcept { _M_f.set_debug_format(); } #endif @@ -2198,7 +2781,7 @@ namespace __format basic_format_context<_Out, wchar_t>& __fc) const { return _M_f.format(__u, __fc); } -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED constexpr void set_debug_format() noexcept { _M_f.set_debug_format(); } #endif @@ -2420,120 +3003,15 @@ namespace __format constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { - __format::_Spec<_CharT> __spec{}; - const auto __last = __pc.end(); - auto __first = __pc.begin(); - - auto __finalize = [this, &__spec] { - _M_spec = __spec; - }; - - auto __finished = [&] { - if (__first == __last || *__first == '}') - { - __finalize(); - return true; - } - return false; - }; - - if (__finished()) - return __first; - - __first = __spec._M_parse_fill_and_align(__first, __last); - if (__finished()) - return __first; - -// _GLIBCXX_RESOLVE_LIB_DEFECTS -// P2510R3 Formatting pointers -#if __glibcxx_format >= 202304L - __first = __spec._M_parse_zero_fill(__first, __last); - if (__finished()) - return __first; -#endif - - __first = __spec._M_parse_width(__first, __last, __pc); - - if (__first != __last) - { - if (*__first == 'p') - ++__first; -#if __glibcxx_format >= 202304L - else if (*__first == 'P') - { - __spec._M_type = __format::_Pres_P; - ++__first; - } -#endif - } - - if (__finished()) - return __first; - - __format::__failed_to_parse_format_spec(); - } + { return _M_f.parse(__pc); } template<typename _Out> typename basic_format_context<_Out, _CharT>::iterator format(const void* __v, basic_format_context<_Out, _CharT>& __fc) const - { - auto __u = reinterpret_cast<__UINTPTR_TYPE__>(__v); - char __buf[2 + sizeof(__v) * 2]; - auto [__ptr, __ec] = std::to_chars(__buf + 2, std::end(__buf), - __u, 16); - int __n = __ptr - __buf; - __buf[0] = '0'; - __buf[1] = 'x'; -#if __glibcxx_format >= 202304L - 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>) - __str = string_view(__buf, __n); -#ifdef _GLIBCXX_USE_WCHAR_T - else - { - auto __p = (_CharT*)__builtin_alloca(__n * sizeof(_CharT)); - std::__to_wstring_numeric(__buf, __n, __p); - __str = wstring_view(__p, __n); - } -#endif - -#if __glibcxx_format >= 202304L - 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); - } + { return _M_f.format(__v, __fc); } private: - __format::_Spec<_CharT> _M_spec{}; + __format::__formatter_ptr<_CharT> _M_f; }; template<__format::__char _CharT> @@ -2552,7 +3030,7 @@ namespace __format { return _M_f.format(__v, __fc); } private: - formatter<const void*, _CharT> _M_f; + __format::__formatter_ptr<_CharT> _M_f; }; template<__format::__char _CharT> @@ -2571,11 +3049,11 @@ namespace __format { return _M_f.format(nullptr, __fc); } private: - formatter<const void*, _CharT> _M_f; + __format::__formatter_ptr<_CharT> _M_f; }; /// @} -#if defined _GLIBCXX_USE_WCHAR_T && __cpp_lib_format_ranges +#if defined _GLIBCXX_USE_WCHAR_T && __glibcxx_format_ranges // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3944. Formatters converting sequences of char to sequences of wchar_t @@ -2599,70 +3077,6 @@ namespace __format : private formatter<__format::__disabled, wchar_t> { }; #endif -/// @cond undocumented -namespace __format -{ - template<typename _Tp, typename _Context, - typename _Formatter - = typename _Context::template formatter_type<remove_const_t<_Tp>>, - typename _ParseContext - = basic_format_parse_context<typename _Context::char_type>> - concept __parsable_with - = semiregular<_Formatter> - && requires (_Formatter __f, _ParseContext __pc) - { - { __f.parse(__pc) } -> same_as<typename _ParseContext::iterator>; - }; - - template<typename _Tp, typename _Context, - typename _Formatter - = typename _Context::template formatter_type<remove_const_t<_Tp>>, - typename _ParseContext - = basic_format_parse_context<typename _Context::char_type>> - concept __formattable_with - = semiregular<_Formatter> - && requires (const _Formatter __cf, _Tp&& __t, _Context __fc) - { - { __cf.format(__t, __fc) } -> same_as<typename _Context::iterator>; - }; - - // An unspecified output iterator type used in the `formattable` concept. - template<typename _CharT> - using _Iter_for = back_insert_iterator<basic_string<_CharT>>; - - template<typename _Tp, typename _CharT, - typename _Context = basic_format_context<_Iter_for<_CharT>, _CharT>> - concept __formattable_impl - = __parsable_with<_Tp, _Context> && __formattable_with<_Tp, _Context>; - -} // namespace __format -/// @endcond - -// Concept std::formattable was introduced by P2286R8 "Formatting Ranges", -// but we can't guard it with __cpp_lib_format_ranges until we define that! -#if __cplusplus > 202002L - // [format.formattable], concept formattable - template<typename _Tp, typename _CharT> - concept formattable - = __format::__formattable_impl<remove_reference_t<_Tp>, _CharT>; -#endif - -#if __cpp_lib_format_ranges - /// @cond undocumented -namespace __format -{ - template<typename _Rg, typename _CharT> - concept __const_formattable_range - = ranges::input_range<const _Rg> - && formattable<ranges::range_reference_t<const _Rg>, _CharT>; - - template<typename _Rg, typename _CharT> - using __maybe_const_range - = conditional_t<__const_formattable_range<_Rg, _CharT>, const _Rg, _Rg>; -} // namespace __format - /// @endcond -#endif // format_ranges - /// An iterator after the last character written, and the number of /// characters that would have been written. template<typename _Out> @@ -2859,12 +3273,38 @@ namespace __format { return _Sink_iter<_CharT>(*this); } }; + + template<typename _CharT> + class _Fixedbuf_sink final : public _Sink<_CharT> + { + void + _M_overflow() override + { + __glibcxx_assert(false); + this->_M_rewind(); + } + + public: + [[__gnu__::__always_inline__]] + constexpr explicit + _Fixedbuf_sink(span<_CharT> __buf) + : _Sink<_CharT>(__buf) + { } + + constexpr basic_string_view<_CharT> + view() const + { + auto __s = this->_M_used(); + return basic_string_view<_CharT>(__s.data(), __s.size()); + } + }; + // A sink with an internal buffer. This is used to implement concrete sinks. template<typename _CharT> class _Buf_sink : public _Sink<_CharT> { protected: - _CharT _M_buf[32 * sizeof(void*) / sizeof(_CharT)]; + _CharT _M_buf[__stackbuf_size<_CharT>]; [[__gnu__::__always_inline__]] constexpr @@ -2878,12 +3318,12 @@ namespace __format // A sink that fills a sequence (e.g. std::string, std::vector, std::deque). // Writes to a buffer then appends that to the sequence when it fills up. template<typename _Seq> - class _Seq_sink final : public _Buf_sink<typename _Seq::value_type> + class _Seq_sink : public _Buf_sink<typename _Seq::value_type> { using _CharT = typename _Seq::value_type; _Seq _M_seq; - + protected: // Transfer buffer contents to the sequence, so buffer can be refilled. void _M_overflow() override @@ -2955,6 +3395,17 @@ namespace __format } } + void _M_trim(span<const _CharT> __s) + requires __is_specialization_of<_Seq, basic_string> + { + _GLIBCXX_DEBUG_ASSERT(__s.data() == this->_M_buf + || __s.data() == _M_seq.data()); + if (__s.data() == _M_seq.data()) + _M_seq.resize(__s.size()); + else + this->_M_reset(this->_M_buf, __s.size()); + } + public: // TODO: for SSO string, use SSO buffer as initial span, then switch // to _M_buf if it overflows? Or even do that for all unused capacity? @@ -2980,7 +3431,7 @@ namespace __format // A writable span that views everything written to the sink. // Will be either a view over _M_seq or the used part of _M_buf. span<_CharT> - view() + _M_span() { auto __s = this->_M_used(); if (_M_seq.size()) @@ -2991,6 +3442,13 @@ namespace __format } return __s; } + + basic_string_view<_CharT> + view() + { + auto __span = _M_span(); + return basic_string_view<_CharT>(__span.data(), __span.size()); + } }; template<typename _CharT, typename _Alloc = allocator<_CharT>> @@ -2998,9 +3456,7 @@ namespace __format = _Seq_sink<basic_string<_CharT, char_traits<_CharT>, _Alloc>>; // template<typename _CharT, typename _Alloc = allocator<_CharT>> - // using _Vec_sink = _Seq_sink<vector<_CharT, _Alloc>>; - - // A sink that writes to an output iterator. + // using _Vec_sink = _Seq_sink<vector<_CharTthis-> sink that writes to an output iterator. // Writes to a fixed-size buffer and then flushes to the output iterator // when the buffer fills up. template<typename _CharT, typename _OutIter> @@ -3168,6 +3624,174 @@ namespace __format } }; + // A sink for handling the padded outputs (_M_padwidth) or truncated + // (_M_maxwidth). The handling is done by writting to buffer (_Str_strink) + // until sufficient number of characters is written. After that if sequence + // is longer than _M_padwidth it's written to _M_out, and further writes are + // either: + // * buffered and forwarded to _M_out, if below _M_maxwidth, + // * ignored otherwise + // If field width of written sequence is no greater than _M_padwidth, the + // sequence is written during _M_finish call. + template<typename _Out, typename _CharT> + class _Padding_sink : public _Str_sink<_CharT> + { + const size_t _M_padwidth; + const size_t _M_maxwidth; + _Out _M_out; + size_t _M_printwidth; + + [[__gnu__::__always_inline__]] + bool + _M_ignoring() const + { + return _M_printwidth >= _M_maxwidth; + } + + [[__gnu__::__always_inline__]] + bool + _M_buffering() const + { + if (_M_printwidth < _M_padwidth) + return true; + if (_M_maxwidth != (size_t)-1) + return _M_printwidth < _M_maxwidth; + return false; + } + + void + _M_flush() + { + span<_CharT> __new = this->_M_used(); + basic_string_view<_CharT> __str(__new.data(), __new.size()); + _M_out = __format::__write(std::move(_M_out), __str); + this->_M_rewind(); + } + + bool + _M_force_update() + { + auto __str = this->view(); + // Compute actual field width, possibly truncated. + _M_printwidth = __format::__truncate(__str, _M_maxwidth); + if (_M_ignoring()) + this->_M_trim(__str); + if (_M_buffering()) + return true; + + // We have more characters than padidng, no padding is needed, + // write direclty to _M_out. + if (_M_printwidth >= _M_padwidth) + _M_out = __format::__write(std::move(_M_out), __str); + // We reached _M_maxwidth that is smaller than _M_padwidth. + // Store the prefix sequence in _M_seq, and free _M_buf. + else + _Str_sink<_CharT>::_M_overflow(); + + // Use internal buffer for writes to _M_out. + this->_M_reset(this->_M_buf); + return false; + } + + bool + _M_update(size_t __new) + { + _M_printwidth += __new; + // Compute estimated width, to see if is not reduced. + if (_M_printwidth >= _M_padwidth || _M_printwidth >= _M_maxwidth) + return _M_force_update(); + return true; + } + + void + _M_overflow() override + { + // Ignore characters in buffer, and override it. + if (_M_ignoring()) + this->_M_rewind(); + // Write buffer to _M_out, and override it. + else if (!_M_buffering()) + _M_flush(); + // Update written count, and if input still should be buffered, + // flush the to _M_seq. + else if (_M_update(this->_M_used().size())) + _Str_sink<_CharT>::_M_overflow(); + } + + typename _Sink<_CharT>::_Reservation + _M_reserve(size_t __n) override + { + // Ignore characters in buffer, if any. + if (_M_ignoring()) + this->_M_rewind(); + else if constexpr (is_same_v<_Out, _Sink_iter<_CharT>>) + if (!_M_buffering()) + { + // Write pending characters if any + if (!this->_M_used().empty()) + _M_flush(); + // Try to reserve from _M_out sink. + if (auto __reserved = _M_out._M_reserve(__n)) + return __reserved; + } + return _Sink<_CharT>::_M_reserve(__n); + } + + void + _M_bump(size_t __n) override + { + // Ignore the written characters. + if (_M_ignoring()) + return; + // If reservation was made directy sink associated _M_out, + // _M_bump will be called on that sink. + _Sink<_CharT>::_M_bump(__n); + if (_M_buffering()) + _M_update(__n); + } + + public: + [[__gnu__::__always_inline__]] + explicit _Padding_sink(_Out __out, size_t __padwidth) + : _M_padwidth(__padwidth), _M_maxwidth(-1), + _M_out(std::move(__out)), _M_printwidth(0) + { } + + [[__gnu__::__always_inline__]] + explicit _Padding_sink(_Out __out, size_t __padwidth, size_t __maxwidth) + : _M_padwidth(__padwidth), _M_maxwidth(__maxwidth), + _M_out(std::move(__out)), _M_printwidth(0) + { } + + _Out + _M_finish(_Align __align, char32_t __fill_char) + { + // Handle any characters in the buffer. + if (auto __rem = this->_M_used().size()) + { + if (_M_ignoring()) + this->_M_rewind(); + else if (!_M_buffering()) + _M_flush(); + else + _M_update(__rem); + } + + if (!_M_buffering() || !_M_force_update()) + // Characters were already written to _M_out. + if (_M_printwidth >= _M_padwidth) + return std::move(_M_out); + + const auto __str = this->view(); + if (_M_printwidth >= _M_padwidth) + return __format::__write(std::move(_M_out), __str); + + const size_t __nfill = _M_padwidth - _M_printwidth; + return __format::__write_padded(std::move(_M_out), __str, + __align, __nfill, __fill_char); + } + }; + enum _Arg_t : unsigned char { _Arg_none, _Arg_bool, _Arg_c, _Arg_i, _Arg_u, _Arg_ll, _Arg_ull, _Arg_flt, _Arg_dbl, _Arg_ldbl, _Arg_str, _Arg_sv, _Arg_ptr, _Arg_handle, @@ -3675,17 +4299,17 @@ namespace __format return _M_visit([&__vis]<typename _Tp>(_Tp& __val) -> decltype(auto) { constexpr bool __user_facing = __is_one_of<_Tp, - monostate, bool, _CharT, - int, unsigned int, long long int, unsigned long long int, - float, double, long double, - const _CharT*, basic_string_view<_CharT>, - const void*, handle>::value; + monostate, bool, _CharT, + int, unsigned int, long long int, unsigned long long int, + float, double, long double, + const _CharT*, basic_string_view<_CharT>, + const void*, handle>::value; if constexpr (__user_facing) return std::forward<_Visitor>(__vis)(__val); else { - handle __h(__val); - return std::forward<_Visitor>(__vis)(__h); + handle __h(__val); + return std::forward<_Visitor>(__vis)(__h); } }, __type); } @@ -4713,7 +5337,7 @@ namespace __format } #endif -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED // [format.range], formatting of ranges // [format.range.fmtkind], variable template format_kind enum class range_format { @@ -4727,7 +5351,10 @@ namespace __format /// @cond undocumented template<typename _Rg> - constexpr auto format_kind = not defined(format_kind<_Rg>); + constexpr auto format_kind = + __primary_template_not_defined( + format_kind<_Rg> // you can specialize this for non-const input ranges + ); template<typename _Tp> consteval range_format @@ -4758,29 +5385,572 @@ namespace __format template<ranges::input_range _Rg> requires same_as<_Rg, remove_cvref_t<_Rg>> constexpr range_format format_kind<_Rg> = __fmt_kind<_Rg>(); - // [format.range.formatter], class template range_formatter - template<typename _Tp, typename _CharT = char> - requires same_as<remove_cvref_t<_Tp>, _Tp> && formattable<_Tp, _CharT> - class range_formatter; // TODO - /// @cond undocumented namespace __format { - // [format.range.fmtdef], class template range-default-formatter - template<range_format _Kind, ranges::input_range _Rg, typename _CharT> - struct __range_default_formatter; // TODO + template<typename _CharT, typename _Out, typename _Callback> + typename basic_format_context<_Out, _CharT>::iterator + __format_padded(basic_format_context<_Out, _CharT>& __fc, + const _Spec<_CharT>& __spec, + _Callback&& __call) + { + // This is required to implement formatting with padding, + // as we need to format to temporary buffer, using the same iterator. + static_assert(is_same_v<_Out, __format::_Sink_iter<_CharT>>); + + const size_t __padwidth = __spec._M_get_width(__fc); + if (__padwidth == 0) + return __call(__fc); + + struct _Restore_out + { + _Restore_out(basic_format_context<_Sink_iter<_CharT>, _CharT>& __fc) + : _M_ctx(std::addressof(__fc)), _M_out(__fc.out()) + { } + + void + _M_disarm() + { _M_ctx = nullptr; } + + ~_Restore_out() + { + if (_M_ctx) + _M_ctx->advance_to(_M_out); + } + + private: + basic_format_context<_Sink_iter<_CharT>, _CharT>* _M_ctx; + _Sink_iter<_CharT> _M_out; + }; + + _Restore_out __restore(__fc); + _Padding_sink<_Sink_iter<_CharT>, _CharT> __sink(__fc.out(), __padwidth); + __fc.advance_to(__sink.out()); + __call(__fc); + __fc.advance_to(__sink._M_finish(__spec._M_align, __spec._M_fill)); + __restore._M_disarm(); + return __fc.out(); + } + + template<size_t _Pos, typename _Tp, typename _CharT> + struct __indexed_formatter_storage + { + constexpr void + _M_parse() + { + basic_format_parse_context<_CharT> __pc({}); + if (_M_formatter.parse(__pc) != __pc.end()) + __format::__failed_to_parse_format_spec(); + } + + template<typename _Out> + void + _M_format(__maybe_const<_Tp, _CharT>& __elem, + basic_format_context<_Out, _CharT>& __fc, + basic_string_view<_CharT> __sep) const + { + if constexpr (_Pos != 0) + __fc.advance_to(__format::__write(__fc.out(), __sep)); + __fc.advance_to(_M_formatter.format(__elem, __fc)); + } + + [[__gnu__::__always_inline__]] + constexpr void + set_debug_format() + { + if constexpr (__has_debug_format<formatter<_Tp, _CharT>>) + _M_formatter.set_debug_format(); + } + + private: + formatter<_Tp, _CharT> _M_formatter; + }; + + template<typename _CharT, typename... _Tps> + class __tuple_formatter + { + using _String_view = basic_string_view<_CharT>; + using _Seps = __format::_Separators<_CharT>; + + public: + constexpr void + set_separator(basic_string_view<_CharT> __sep) noexcept + { _M_sep = __sep; } + + constexpr void + set_brackets(basic_string_view<_CharT> __open, + basic_string_view<_CharT> __close) noexcept + { + _M_open = __open; + _M_close = __close; + } + + // We deviate from standard, that declares this as template accepting + // unconstrained ParseContext type, which seems unimplementable. + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { + auto __first = __pc.begin(); + const auto __last = __pc.end(); + __format::_Spec<_CharT> __spec{}; + + auto __finished = [&] + { + if (__first != __last && *__first != '}') + return false; + + _M_spec = __spec; + _M_felems._M_parse(); + _M_felems.set_debug_format(); + return true; + }; + + if (__finished()) + return __first; + + __first = __spec._M_parse_fill_and_align(__first, __last, "{:"); + if (__finished()) + return __first; + + __first = __spec._M_parse_width(__first, __last, __pc); + if (__finished()) + return __first; + + if (*__first == 'n') + { + ++__first; + _M_open = _M_close = _String_view(); + } + else if (*__first == 'm') + { + ++__first; + if constexpr (sizeof...(_Tps) == 2) + { + _M_sep = _Seps::_S_colon(); + _M_open = _M_close = _String_view(); + } + else + __throw_format_error("format error: 'm' specifier requires range" + " of pair or tuple of two elements"); + } + + if (__finished()) + return __first; + + __format::__failed_to_parse_format_spec(); + } + + protected: + template<typename _Tuple, typename _Out, size_t... _Ids> + typename basic_format_context<_Out, _CharT>::iterator + _M_format(_Tuple& __tuple, index_sequence<_Ids...>, + basic_format_context<_Out, _CharT>& __fc) const + { return _M_format_elems(std::get<_Ids>(__tuple)..., __fc); } + + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + _M_format_elems(__maybe_const<_Tps, _CharT>&... __elems, + basic_format_context<_Out, _CharT>& __fc) const + { + return __format::__format_padded( + __fc, _M_spec, + [this, &__elems...](basic_format_context<_Out, _CharT>& __nfc) + { + __nfc.advance_to(__format::__write(__nfc.out(), _M_open)); + _M_felems._M_format(__elems..., __nfc, _M_sep); + return __format::__write(__nfc.out(), _M_close); + }); + } + + private: + template<size_t... _Ids> + struct __formatters_storage + : __indexed_formatter_storage<_Ids, _Tps, _CharT>... + { + template<size_t _Id, typename _Up> + using _Base = __indexed_formatter_storage<_Id, _Up, _CharT>; + + constexpr void + _M_parse() + { + (_Base<_Ids, _Tps>::_M_parse(), ...); + } + + template<typename _Out> + void + _M_format(__maybe_const<_Tps, _CharT>&... __elems, + basic_format_context<_Out, _CharT>& __fc, + _String_view __sep) const + { + (_Base<_Ids, _Tps>::_M_format(__elems, __fc, __sep), ...); + } + + constexpr void + set_debug_format() + { + (_Base<_Ids, _Tps>::set_debug_format(), ...); + } + }; + + template<size_t... _Ids> + static auto + _S_create_storage(index_sequence<_Ids...>) + -> __formatters_storage<_Ids...>; + using _Formatters + = decltype(_S_create_storage(index_sequence_for<_Tps...>())); + + _Spec<_CharT> _M_spec{}; + _String_view _M_open = _Seps::_S_parens().substr(0, 1); + _String_view _M_close = _Seps::_S_parens().substr(1, 1); + _String_view _M_sep = _Seps::_S_comma(); + _Formatters _M_felems; + }; + + template<typename _Tp> + concept __is_map_formattable + = __is_pair<_Tp> || (__is_tuple_v<_Tp> && tuple_size_v<_Tp> == 2); + } // namespace __format /// @endcond + // [format.tuple] Tuple formatter + template<__format::__char _CharT, formattable<_CharT> _Fp, + formattable<_CharT> _Sp> + struct formatter<pair<_Fp, _Sp>, _CharT> + : __format::__tuple_formatter<_CharT, remove_cvref_t<_Fp>, + remove_cvref_t<_Sp>> + { + private: + using __maybe_const_pair + = __conditional_t<formattable<const _Fp, _CharT> + && formattable<const _Sp, _CharT>, + const pair<_Fp, _Sp>, pair<_Fp, _Sp>>; + public: + // We deviate from standard, that declares this as template accepting + // unconstrained FormatContext type, which seems unimplementable. + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(__maybe_const_pair& __p, + basic_format_context<_Out, _CharT>& __fc) const + { return this->_M_format_elems(__p.first, __p.second, __fc); } + }; + + template<__format::__char _CharT, formattable<_CharT>... _Tps> + struct formatter<tuple<_Tps...>, _CharT> + : __format::__tuple_formatter<_CharT, remove_cvref_t<_Tps>...> + { + private: + using __maybe_const_tuple + = __conditional_t<(formattable<const _Tps, _CharT> && ...), + const tuple<_Tps...>, tuple<_Tps...>>; + public: + // We deviate from standard, that declares this as template accepting + // unconstrained FormatContext type, which seems unimplementable. + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(__maybe_const_tuple& __t, + basic_format_context<_Out, _CharT>& __fc) const + { return this->_M_format(__t, index_sequence_for<_Tps...>(), __fc); } + }; + + // [format.range.formatter], class template range_formatter + template<typename _Tp, __format::__char _CharT> + requires same_as<remove_cvref_t<_Tp>, _Tp> && formattable<_Tp, _CharT> + class range_formatter + { + using _String_view = basic_string_view<_CharT>; + using _Seps = __format::_Separators<_CharT>; + + public: + constexpr void + set_separator(basic_string_view<_CharT> __sep) noexcept + { _M_sep = __sep; } + + constexpr void + set_brackets(basic_string_view<_CharT> __open, + basic_string_view<_CharT> __close) noexcept + { + _M_open = __open; + _M_close = __close; + } + + constexpr formatter<_Tp, _CharT>& + underlying() noexcept + { return _M_fval; } + + constexpr const formatter<_Tp, _CharT>& + underlying() const noexcept + { return _M_fval; } + + // We deviate from standard, that declares this as template accepting + // unconstrained ParseContext type, which seems unimplementable. + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { + auto __first = __pc.begin(); + const auto __last = __pc.end(); + __format::_Spec<_CharT> __spec{}; + bool __no_brace = false; + + auto __finished = [&] + { return __first == __last || *__first == '}'; }; + + auto __finalize = [&] + { + _M_spec = __spec; + return __first; + }; + + auto __parse_val = [&](_String_view __nfs = _String_view()) + { + basic_format_parse_context<_CharT> __npc(__nfs); + if (_M_fval.parse(__npc) != __npc.end()) + __format::__failed_to_parse_format_spec(); + if constexpr (__format::__has_debug_format<formatter<_Tp, _CharT>>) + _M_fval.set_debug_format(); + return __finalize(); + }; + + if (__finished()) + return __parse_val(); + + __first = __spec._M_parse_fill_and_align(__first, __last, "{:"); + if (__finished()) + return __parse_val(); + + __first = __spec._M_parse_width(__first, __last, __pc); + if (__finished()) + return __parse_val(); + + if (*__first == '?') + { + ++__first; + __spec._M_type = __format::_Pres_esc; + if (__finished() || *__first != 's') + __throw_format_error("format error: '?' is allowed only in" + " combination with 's'"); + } + + if (*__first == 's') + { + ++__first; + if constexpr (same_as<_Tp, _CharT>) + { + if (__spec._M_type != __format::_Pres_esc) + __spec._M_type = __format::_Pres_str; + if (__finished()) + return __finalize(); + __throw_format_error("format error: element format specifier" + " cannot be provided when 's' specifier is used"); + } + else + __throw_format_error("format error: 's' specifier requires" + " range of character types"); + } + + if (__finished()) + return __parse_val(); + + if (*__first == 'n') + { + ++__first; + _M_open = _M_close = _String_view(); + __no_brace = true; + } + + if (__finished()) + return __parse_val(); + + if (*__first == 'm') + { + _String_view __m(__first, 1); + ++__first; + if constexpr (__format::__is_map_formattable<_Tp>) + { + _M_sep = _Seps::_S_comma(); + if (!__no_brace) + { + _M_open = _Seps::_S_braces().substr(0, 1); + _M_close = _Seps::_S_braces().substr(1, 1); + } + if (__finished()) + return __parse_val(__m); + __throw_format_error("format error: element format specifier" + " cannot be provided when 'm' specifier is used"); + } + else + __throw_format_error("format error: 'm' specifier requires" + " range of pairs or tuples of two elements"); + } + + if (__finished()) + return __parse_val(); + + if (*__first == ':') + { + __pc.advance_to(++__first); + __first = _M_fval.parse(__pc); + } + + if (__finished()) + return __finalize(); + + __format::__failed_to_parse_format_spec(); + } + + // We deviate from standard, that declares this as template accepting + // unconstrained FormatContext type, which seems unimplementable. + template<ranges::input_range _Rg, typename _Out> + requires formattable<ranges::range_reference_t<_Rg>, _CharT> && + same_as<remove_cvref_t<ranges::range_reference_t<_Rg>>, _Tp> + typename basic_format_context<_Out, _CharT>::iterator + format(_Rg&& __rg, basic_format_context<_Out, _CharT>& __fc) const + { + using _Range = remove_reference_t<_Rg>; + if constexpr (__format::__simply_formattable_range<_Range, _CharT>) + return _M_format<const _Range>(__rg, __fc); + else + return _M_format(__rg, __fc); + } + + private: + template<ranges::input_range _Rg, typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + _M_format(_Rg& __rg, basic_format_context<_Out, _CharT>& __fc) const + { + if constexpr (same_as<_Tp, _CharT>) + if (_M_spec._M_type == __format::_Pres_str + || _M_spec._M_type == __format::_Pres_esc) + { + __format::__formatter_str __fstr(_M_spec); + return __fstr._M_format_range(__rg, __fc); + } + return __format::__format_padded( + __fc, _M_spec, + [this, &__rg](basic_format_context<_Out, _CharT>& __nfc) + { return _M_format_elems(__rg, __nfc); }); + } + + + template<ranges::input_range _Rg, typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + _M_format_elems(_Rg& __rg, + basic_format_context<_Out, _CharT>& __fc) const + { + auto __out = __format::__write(__fc.out(), _M_open); + + auto __first = ranges::begin(__rg); + auto const __last = ranges::end(__rg); + if (__first == __last) + return __format::__write(__out, _M_close); + + __fc.advance_to(__out); + __out = _M_fval.format(*__first, __fc); + for (++__first; __first != __last; ++__first) + { + __out = __format::__write(__out, _M_sep); + __fc.advance_to(__out); + __out = _M_fval.format(*__first, __fc); + } + + return __format::__write(__out, _M_close); + } + + __format::_Spec<_CharT> _M_spec{}; + _String_view _M_open = _Seps::_S_squares().substr(0, 1); + _String_view _M_close = _Seps::_S_squares().substr(1, 1); + _String_view _M_sep = _Seps::_S_comma(); + formatter<_Tp, _CharT> _M_fval; + }; + + // In standard this is shown as inheriting from specialization of + // exposition only specialization for range-default-formatter for + // each range_format. We opt for simpler implementation. // [format.range.fmtmap], [format.range.fmtset], [format.range.fmtstr], // specializations for maps, sets, and strings - template<ranges::input_range _Rg, typename _CharT> + template<ranges::input_range _Rg, __format::__char _CharT> requires (format_kind<_Rg> != range_format::disabled) && formattable<ranges::range_reference_t<_Rg>, _CharT> struct formatter<_Rg, _CharT> - : __format::__range_default_formatter<format_kind<_Rg>, _Rg, _CharT> - { }; + { + private: + static const bool _S_range_format_is_string = + (format_kind<_Rg> == range_format::string) + || (format_kind<_Rg> == range_format::debug_string); + using _Vt = remove_cvref_t< + ranges::range_reference_t< + __format::__maybe_const_range<_Rg, _CharT>>>; + + static consteval bool _S_is_correct() + { + if constexpr (_S_range_format_is_string) + static_assert(same_as<_Vt, _CharT>); + return true; + } + + static_assert(_S_is_correct()); + + public: + constexpr formatter() noexcept + { + using _Seps = __format::_Separators<_CharT>; + if constexpr (format_kind<_Rg> == range_format::map) + { + static_assert(__format::__is_map_formattable<_Vt>); + _M_under.set_brackets(_Seps::_S_braces().substr(0, 1), + _Seps::_S_braces().substr(1, 1)); + _M_under.underlying().set_brackets({}, {}); + _M_under.underlying().set_separator(_Seps::_S_colon()); + } + else if constexpr (format_kind<_Rg> == range_format::set) + _M_under.set_brackets(_Seps::_S_braces().substr(0, 1), + _Seps::_S_braces().substr(1, 1)); + } + + constexpr void + set_separator(basic_string_view<_CharT> __sep) noexcept + requires (!_S_range_format_is_string) + { _M_under.set_separator(__sep); } + + constexpr void + set_brackets(basic_string_view<_CharT> __open, + basic_string_view<_CharT> __close) noexcept + requires (!_S_range_format_is_string) + { _M_under.set_brackets(__open, __close); } + + // We deviate from standard, that declares this as template accepting + // unconstrained ParseContext type, which seems unimplementable. + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { + auto __res = _M_under.parse(__pc); + if constexpr (format_kind<_Rg> == range_format::debug_string) + _M_under.set_debug_format(); + return __res; + } + + // We deviate from standard, that declares this as template accepting + // unconstrained FormatContext type, which seems unimplementable. + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(__format::__maybe_const_range<_Rg, _CharT>& __rg, + basic_format_context<_Out, _CharT>& __fc) const + { + if constexpr (_S_range_format_is_string) + return _M_under._M_format_range(__rg, __fc); + else + return _M_under.format(__rg, __fc); + } + + private: + using _Formatter_under + = __conditional_t<_S_range_format_is_string, + __format::__formatter_str<_CharT>, + range_formatter<_Vt, _CharT>>; + _Formatter_under _M_under; + }; #endif // C++23 formatting ranges +#undef _GLIBCXX_WIDEN _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/std/forward_list b/libstdc++-v3/include/std/forward_list index 166fdb0..d478851 100644 --- a/libstdc++-v3/include/std/forward_list +++ b/libstdc++-v3/include/std/forward_list @@ -49,6 +49,7 @@ #define __glibcxx_want_algorithm_default_value_type #define __glibcxx_want_allocator_traits_is_always_equal +#define __glibcxx_want_containers_ranges #define __glibcxx_want_erase_if #define __glibcxx_want_incomplete_container_elements #define __glibcxx_want_list_remove_return_type diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index b7ab233..0806900 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -1486,12 +1486,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)> final : __future_base::_Task_state_base<_Res(_Args...)> { +#ifdef __cpp_lib_is_invocable // C++ >= 17 + static_assert(is_invocable_r_v<_Res, _Fn&, _Args...>); +#else + static_assert(__is_invocable<_Fn&, _Args...>::value, + "_Fn& is invocable with _Args..."); +#endif + template<typename _Fn2> _Task_state(_Fn2&& __fn, const _Alloc& __a) : _Task_state_base<_Res(_Args...)>(__a), _M_impl(std::forward<_Fn2>(__fn), __a) { } + template<typename _Fn2> + static shared_ptr<_Task_state_base<_Res(_Args...)>> + _S_create(_Fn2&& __fn, const _Alloc& __a) + { + return std::allocate_shared<_Task_state>(__a, + std::forward<_Fn2>(__fn), + __a); + } + private: virtual void _M_run(_Args&&... __args) @@ -1515,7 +1531,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } virtual shared_ptr<_Task_state_base<_Res(_Args...)>> - _M_reset(); + _M_reset() + { return _S_create(std::move(_M_impl._M_fn), _M_impl); } struct _Impl : _Alloc { @@ -1525,38 +1542,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Fn _M_fn; } _M_impl; }; - - template<typename _Signature, typename _Fn, - typename _Alloc = std::allocator<int>> - shared_ptr<__future_base::_Task_state_base<_Signature>> - __create_task_state(_Fn&& __fn, const _Alloc& __a = _Alloc()) - { - typedef typename decay<_Fn>::type _Fn2; - typedef __future_base::_Task_state<_Fn2, _Alloc, _Signature> _State; - return std::allocate_shared<_State>(__a, std::forward<_Fn>(__fn), __a); - } - - template<typename _Fn, typename _Alloc, typename _Res, typename... _Args> - shared_ptr<__future_base::_Task_state_base<_Res(_Args...)>> - __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)>::_M_reset() - { - return __create_task_state<_Res(_Args...)>(std::move(_M_impl._M_fn), - static_cast<_Alloc&>(_M_impl)); - } /// @endcond /// packaged_task template<typename _Res, typename... _ArgTypes> class packaged_task<_Res(_ArgTypes...)> { - typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type; + using _State_type = __future_base::_Task_state_base<_Res(_ArgTypes...)>; shared_ptr<_State_type> _M_state; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3039. Unnecessary decay in thread and packaged_task template<typename _Fn, typename _Fn2 = __remove_cvref_t<_Fn>> - using __not_same - = typename enable_if<!is_same<packaged_task, _Fn2>::value>::type; + using __not_same = __enable_if_t<!is_same<packaged_task, _Fn2>::value>; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4154. The Mandates for std::packaged_task's constructor + // from a callable entity should consider decaying. + template<typename _Fn, typename _Alloc = std::allocator<int>> + using _Task_state + = __future_base::_Task_state<__decay_t<_Fn>, _Alloc, + _Res(_ArgTypes...)>; public: // Construction and destruction @@ -1565,16 +1571,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Fn, typename = __not_same<_Fn>> explicit packaged_task(_Fn&& __fn) - : _M_state( - __create_task_state<_Res(_ArgTypes...)>(std::forward<_Fn>(__fn))) - { -#ifdef __cpp_lib_is_invocable // C++ >= 17 - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 4154. The Mandates for std::packaged_task's constructor - // from a callable entity should consider decaying - static_assert(is_invocable_r_v<_Res, decay_t<_Fn>&, _ArgTypes...>); -#endif - } + : _M_state(_Task_state<_Fn>::_S_create(std::forward<_Fn>(__fn), {})) + { } #if __cplusplus < 201703L // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -1583,8 +1581,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 2921. packaged_task and type-erased allocators template<typename _Fn, typename _Alloc, typename = __not_same<_Fn>> packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn) - : _M_state(__create_task_state<_Res(_ArgTypes...)>( - std::forward<_Fn>(__fn), __a)) + : _M_state(_Task_state<_Fn, _Alloc>::_S_create(std::forward<_Fn>(__fn), + __a)) { } // _GLIBCXX_RESOLVE_LIB_DEFECTS diff --git a/libstdc++-v3/include/std/generator b/libstdc++-v3/include/std/generator index 3f781f1..7ab2c9e 100644 --- a/libstdc++-v3/include/std/generator +++ b/libstdc++-v3/include/std/generator @@ -153,6 +153,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept { return _Recursive_awaiter { std::move(__r.range) }; } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3899. co_yielding elements of an lvalue generator is + // unnecessarily inefficient + template<typename _R2, typename _V2, typename _A2, typename _U2> + requires std::same_as<_Yield2_t<_R2, _V2>, _Yielded> + auto + yield_value(ranges::elements_of<generator<_R2, _V2, _A2>&, _U2> __r) + noexcept + { return _Recursive_awaiter { std::move(__r.range) }; } + template<ranges::input_range _R, typename _Alloc> requires convertible_to<ranges::range_reference_t<_R>, _Yielded> auto diff --git a/libstdc++-v3/include/std/latch b/libstdc++-v3/include/std/latch index cf64854..dc147c2 100644 --- a/libstdc++-v3/include/std/latch +++ b/libstdc++-v3/include/std/latch @@ -62,7 +62,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr explicit latch(ptrdiff_t __expected) noexcept - : _M_a(__expected) + : _M_counter(__expected) { __glibcxx_assert(__expected >= 0 && __expected <= max()); } ~latch() = default; @@ -74,23 +74,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION count_down(ptrdiff_t __update = 1) { __glibcxx_assert(__update >= 0 && __update <= max()); - auto const __old = __atomic_impl::fetch_sub(&_M_a, __update, + auto const __old = __atomic_impl::fetch_sub(&_M_counter, __update, memory_order::release); if (std::cmp_equal(__old, __update)) - __atomic_impl::notify_all(&_M_a); + __atomic_impl::notify_all(&_M_counter); else __glibcxx_assert(std::cmp_less(__update, __old)); } _GLIBCXX_ALWAYS_INLINE bool try_wait() const noexcept - { return __atomic_impl::load(&_M_a, memory_order::acquire) == 0; } + { return __atomic_impl::load(&_M_counter, memory_order::acquire) == 0; } _GLIBCXX_ALWAYS_INLINE void wait() const noexcept { auto const __pred = [this] { return this->try_wait(); }; - std::__atomic_wait_address(&_M_a, __pred); + std::__atomic_wait_address(&_M_counter, __pred); } _GLIBCXX_ALWAYS_INLINE void @@ -102,7 +102,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: alignas(__detail::__platform_wait_alignment) - __detail::__platform_wait_t _M_a; + __detail::__platform_wait_t _M_counter; }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/std/list b/libstdc++-v3/include/std/list index 170499d..2ba0599 100644 --- a/libstdc++-v3/include/std/list +++ b/libstdc++-v3/include/std/list @@ -73,6 +73,7 @@ #define __glibcxx_want_algorithm_default_value_type #define __glibcxx_want_allocator_traits_is_always_equal +#define __glibcxx_want_containers_ranges #define __glibcxx_want_erase_if #define __glibcxx_want_incomplete_container_elements #define __glibcxx_want_list_remove_return_type diff --git a/libstdc++-v3/include/std/map b/libstdc++-v3/include/std/map index 16a397f..6bfb538 100644 --- a/libstdc++-v3/include/std/map +++ b/libstdc++-v3/include/std/map @@ -72,6 +72,7 @@ #endif #define __glibcxx_want_allocator_traits_is_always_equal +#define __glibcxx_want_containers_ranges #define __glibcxx_want_erase_if #define __glibcxx_want_generic_associative_lookup #define __glibcxx_want_map_try_emplace diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory index 99f542d..78a1250 100644 --- a/libstdc++-v3/include/std/memory +++ b/libstdc++-v3/include/std/memory @@ -97,6 +97,7 @@ # include <bits/out_ptr.h> #endif +#define __glibcxx_want_addressof_constexpr #define __glibcxx_want_allocator_traits_is_always_equal #define __glibcxx_want_assume_aligned #define __glibcxx_want_atomic_shared_ptr diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric index 4d36fcd..490963e 100644 --- a/libstdc++-v3/include/std/numeric +++ b/libstdc++-v3/include/std/numeric @@ -732,12 +732,11 @@ namespace __detail /// @} group numeric_ops #endif // C++17 +#if __glibcxx_ranges_iota >= 202202L // C++ >= 23 namespace ranges { -#if __glibcxx_ranges_iota >= 202202L // C++ >= 23 - template<typename _Out, typename _Tp> - using iota_result = out_value_result<_Out, _Tp>; + using iota_result = out_value_result<_Out, _Tp>; struct __iota_fn { @@ -762,9 +761,8 @@ namespace ranges }; inline constexpr __iota_fn iota{}; - -#endif // __glibcxx_ranges_iota } // namespace ranges +#endif // __glibcxx_ranges_iota _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index 644e568..3a0a0d3 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -193,7 +193,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __format::_Str_sink<char> __buf; std::vformat_to(__buf.out(), __os.getloc(), __fmt, __args); - auto __out = __buf.view(); + auto __out = __buf._M_span(); void* __open_terminal(streambuf*); error_code __write_to_terminal(void*, span<char>); diff --git a/libstdc++-v3/include/std/print b/libstdc++-v3/include/std/print index ea1aaac..92dbe11 100644 --- a/libstdc++-v3/include/std/print +++ b/libstdc++-v3/include/std/print @@ -73,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #else __format::_Str_sink<char> __buf; std::vformat_to(__buf.out(), __fmt, __args); - auto __out = __buf.view(); + auto __out = __buf._M_span(); void* __open_terminal(FILE*); error_code __write_to_terminal(void*, span<char>); diff --git a/libstdc++-v3/include/std/queue b/libstdc++-v3/include/std/queue index c06a4c3..9052589 100644 --- a/libstdc++-v3/include/std/queue +++ b/libstdc++-v3/include/std/queue @@ -61,13 +61,88 @@ #include <bits/requires_hosted.h> // containers +#define __glibcxx_want_adaptor_iterator_pair_constructor +#define __glibcxx_want_containers_ranges +#include <bits/version.h> + #include <deque> #include <vector> #include <bits/stl_heap.h> #include <bits/stl_function.h> #include <bits/stl_queue.h> -#define __glibcxx_want_adaptor_iterator_pair_constructor -#include <bits/version.h> +#ifdef __glibcxx_format_ranges // C++ >= 23 && HOSTED +#include <bits/formatfwd.h> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + // Standard does not constrain accepted _CharT, we do so we can + // befriend specializations. + template<__format::__char _CharT, typename _Tp, + formattable<_CharT> _Container> + struct formatter<queue<_Tp, _Container>, _CharT> + { + private: + using __maybe_const_adaptor + = __conditional_t< + __format::__const_formattable_range<_Container, _CharT>, + const queue<_Tp, _Container>, queue<_Tp, _Container>>; + + public: + // Standard declares this as template accepting unconstrained + // ParseContext type. + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f.parse(__pc); } + + // Standard declares this as template accepting unconstrained + // FormatContext type. + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(__maybe_const_adaptor& __a, + basic_format_context<_Out, _CharT>& __fc) const + { return _M_f.format(__a.c, __fc); } + + private: + // Standard uses formatter<ref_view<_Container>, _CharT>. + range_formatter<_Tp, _CharT> _M_f; + }; + + template<__format::__char _CharT, typename _Tp, + formattable<_CharT> _Container, typename _Compare> + struct formatter<priority_queue<_Tp, _Container, _Compare>, _CharT> + { + private: + using __maybe_const_adaptor + = __conditional_t< + __format::__const_formattable_range<_Container, _CharT>, + const priority_queue<_Tp, _Container, _Compare>, + priority_queue<_Tp, _Container, _Compare>>; + + public: + // Standard declares this as template accepting unconstrained + // ParseContext type. + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f.parse(__pc); } + + // Standard declares this as template accepting unconstrained + // FormatContext type. + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(__maybe_const_adaptor& __a, + basic_format_context<_Out, _CharT>& __fc) const + { return _M_f.format(__a.c, __fc); } + + private: + // Standard uses formatter<ref_view<_Container>, _CharT>. + range_formatter<_Tp, _CharT> _M_f; + }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif // __glibcxx_format_ranges + #endif /* _GLIBCXX_QUEUE */ diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 7a339c5..9300c36 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -64,7 +64,6 @@ #define __glibcxx_want_ranges_chunk #define __glibcxx_want_ranges_chunk_by #define __glibcxx_want_ranges_enumerate -#define __glibcxx_want_ranges_iota #define __glibcxx_want_ranges_join_with #define __glibcxx_want_ranges_repeat #define __glibcxx_want_ranges_slide diff --git a/libstdc++-v3/include/std/set b/libstdc++-v3/include/std/set index 2ebf485..cf7057a 100644 --- a/libstdc++-v3/include/std/set +++ b/libstdc++-v3/include/std/set @@ -72,6 +72,7 @@ #endif #define __glibcxx_want_allocator_traits_is_always_equal +#define __glibcxx_want_containers_ranges #define __glibcxx_want_erase_if #define __glibcxx_want_generic_associative_lookup #define __glibcxx_want_node_extract diff --git a/libstdc++-v3/include/std/stack b/libstdc++-v3/include/std/stack index 2f7951a..a57a5a0 100644 --- a/libstdc++-v3/include/std/stack +++ b/libstdc++-v3/include/std/stack @@ -61,10 +61,53 @@ #include <bits/requires_hosted.h> // containers +#define __glibcxx_want_adaptor_iterator_pair_constructor +#define __glibcxx_want_containers_ranges +#include <bits/version.h> + #include <deque> #include <bits/stl_stack.h> -#define __glibcxx_want_adaptor_iterator_pair_constructor -#include <bits/version.h> +#ifdef __glibcxx_format_ranges // C++ >= 23 && HOSTED +#include <bits/formatfwd.h> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + // Standard does not constrain accepted _CharT, we do so we can + // befriend specializations. + template<__format::__char _CharT, typename _Tp, + formattable<_CharT> _Container> + struct formatter<stack<_Tp, _Container>, _CharT> + { + private: + using __maybe_const_adaptor + = __conditional_t< + __format::__const_formattable_range<_Container, _CharT>, + const stack<_Tp, _Container>, stack<_Tp, _Container>>; + + public: + // Standard declares this as template accepting unconstrained + // ParseContext type. + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f.parse(__pc); } + + // Standard declares this as template accepting unconstrained + // FormatContext type. + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(__maybe_const_adaptor& __a, + basic_format_context<_Out, _CharT>& __fc) const + { return _M_f.format(__a.c, __fc); } + + private: + // Standard uses formatter<ref_view<_Container>, _CharT>. + range_formatter<_Tp, _CharT> _M_f; + }; +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif // __glibcxx_format_ranges + #endif /* _GLIBCXX_STACK */ diff --git a/libstdc++-v3/include/std/string b/libstdc++-v3/include/std/string index 6211da9..7186471 100644 --- a/libstdc++-v3/include/std/string +++ b/libstdc++-v3/include/std/string @@ -60,6 +60,7 @@ #define __glibcxx_want_allocator_traits_is_always_equal #define __glibcxx_want_constexpr_char_traits #define __glibcxx_want_constexpr_string +#define __glibcxx_want_containers_ranges #define __glibcxx_want_erase_if #define __glibcxx_want_nonmember_container_access #define __glibcxx_want_string_resize_and_overwrite diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index d2f91ad..0de08c0 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -297,7 +297,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // __cpp_lib_jthread #ifdef __cpp_lib_formatters // C++ >= 23 - template<typename _CharT> + // We deviate from the standard, that does not put requirements + // on _CharT here. + template<__format::__char _CharT> requires is_pointer_v<thread::native_handle_type> || is_integral_v<thread::native_handle_type> class formatter<thread::id, _CharT> @@ -307,6 +309,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION parse(basic_format_parse_context<_CharT>& __pc) { __format::_Spec<_CharT> __spec{}; + __spec._M_align = __format::_Align_right; const auto __last = __pc.end(); auto __first = __pc.begin(); @@ -334,36 +337,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__finished()) return __first; - __throw_format_error("format error: invalid format-spec for " - "std::thread::id"); + std::__throw_format_error("format error: invalid format-spec for " + "std::thread::id"); } template<typename _Out> typename basic_format_context<_Out, _CharT>::iterator format(thread::id __id, basic_format_context<_Out, _CharT>& __fc) const { - basic_string_view<_CharT> __sv; - if constexpr (is_same_v<_CharT, char>) - __sv = "{}thread::id of a non-executing thread"; - else - __sv = L"{}thread::id of a non-executing thread"; - basic_string<_CharT> __str; + if (__id == thread::id()) - __sv.remove_prefix(2); - else { - using _FmtStr = __format::_Runtime_format_string<_CharT>; - // Convert non-void pointers to const void* for formatted output. - using __output_type - = __conditional_t<is_pointer_v<thread::native_handle_type>, - const void*, - thread::native_handle_type>; - auto __o = static_cast<__output_type>(__id._M_thread); - __sv = __str = std::format(_FmtStr(__sv.substr(0, 2)), __o); + const _CharT* __msg; + if constexpr (is_same_v<_CharT, char>) + __msg = "thread::id of a non-executing thread"; + else + __msg = L"thread::id of a non-executing thread"; + + __format::__formatter_str<_CharT> __formatter(_M_spec); + return __formatter.format(__msg, __fc); } - return __format::__write_padded_as_spec(__sv, __sv.size(), - __fc, _M_spec, - __format::_Align_right); + + using _HandleFormatter + = __conditional_t<is_pointer_v<thread::native_handle_type>, + __format::__formatter_ptr<_CharT>, + __format::__formatter_int<_CharT>>; + + _HandleFormatter __formatter(_M_spec); + return __formatter.format(__id._M_thread, __fc); } private: diff --git a/libstdc++-v3/include/std/unordered_map b/libstdc++-v3/include/std/unordered_map index 37f2273..3ae25d7 100644 --- a/libstdc++-v3/include/std/unordered_map +++ b/libstdc++-v3/include/std/unordered_map @@ -49,6 +49,7 @@ #endif #define __glibcxx_want_allocator_traits_is_always_equal +#define __glibcxx_want_containers_ranges #define __glibcxx_want_erase_if #define __glibcxx_want_generic_unordered_lookup #define __glibcxx_want_node_extract diff --git a/libstdc++-v3/include/std/unordered_set b/libstdc++-v3/include/std/unordered_set index 4c73e5d..b561163 100644 --- a/libstdc++-v3/include/std/unordered_set +++ b/libstdc++-v3/include/std/unordered_set @@ -49,6 +49,7 @@ #endif #define __glibcxx_want_allocator_traits_is_always_equal +#define __glibcxx_want_containers_ranges #define __glibcxx_want_erase_if #define __glibcxx_want_generic_unordered_lookup #define __glibcxx_want_node_extract diff --git a/libstdc++-v3/include/std/vector b/libstdc++-v3/include/std/vector index 8bb2543..a98ffb1 100644 --- a/libstdc++-v3/include/std/vector +++ b/libstdc++-v3/include/std/vector @@ -81,6 +81,7 @@ #define __glibcxx_want_algorithm_default_value_type #define __glibcxx_want_allocator_traits_is_always_equal #define __glibcxx_want_constexpr_vector +#define __glibcxx_want_containers_ranges #define __glibcxx_want_erase_if #define __glibcxx_want_incomplete_container_elements #define __glibcxx_want_nonmember_container_access diff --git a/libstdc++-v3/include/tr2/dynamic_bitset b/libstdc++-v3/include/tr2/dynamic_bitset index 2446f35..b308e72 100644 --- a/libstdc++-v3/include/tr2/dynamic_bitset +++ b/libstdc++-v3/include/tr2/dynamic_bitset @@ -99,7 +99,9 @@ namespace tr2 if (__val == 0) return; - if _GLIBCXX17_CONSTEXPR (sizeof(__val) == sizeof(block_type)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + if constexpr (sizeof(__val) == sizeof(block_type)) _M_w[0] = __val; else { @@ -111,6 +113,7 @@ namespace tr2 __val >>= _S_bits_per_block; } } +#pragma GCC diagnostic pop } void @@ -667,13 +670,16 @@ namespace tr2 operator=(dynamic_bitset&& __b) noexcept(std::is_nothrow_move_assignable<_Base>::value) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr static_cast<_Base&>(*this) = static_cast<_Base&&>(__b); _M_Nb = __b._M_Nb; - if _GLIBCXX17_CONSTEXPR (std::is_nothrow_move_assignable<_Base>::value) + if constexpr (std::is_nothrow_move_assignable<_Base>::value) __b._M_Nb = 0; else if (get_allocator() == __b.get_allocator()) __b._M_Nb = 0; return *this; +#pragma GCC diagnostic pop } /** |