diff options
Diffstat (limited to 'libstdc++-v3/include')
56 files changed, 2112 insertions, 386 deletions
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 4dc771a..537774c 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -195,6 +195,7 @@ bits_headers = \ ${bits_srcdir}/cow_string.h \ ${bits_srcdir}/deque.tcc \ ${bits_srcdir}/erase_if.h \ + ${bits_srcdir}/formatfwd.h \ ${bits_srcdir}/forward_list.h \ ${bits_srcdir}/forward_list.tcc \ ${bits_srcdir}/fs_dir.h \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 0e3d09b..7b96b22 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -548,6 +548,7 @@ bits_freestanding = \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/cow_string.h \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/deque.tcc \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/erase_if.h \ +@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/formatfwd.h \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/forward_list.h \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/forward_list.tcc \ @GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/fs_dir.h \ diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 86841cb..c90bd09 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -45,15 +45,21 @@ #include <initializer_list> #endif -#if __cplusplus >= 201703L +#include <bits/version.h> + +#ifdef __glibcxx_string_view // >= C++17 # 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 -#include <bits/version.h> #if ! _GLIBCXX_USE_CXX11_ABI # include "cow_string.h" @@ -146,7 +152,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 return __p; } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 // A helper type for avoiding boiler-plate. typedef basic_string_view<_CharT, _Traits> __sv_type; @@ -467,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> @@ -474,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 @@ -716,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. @@ -788,7 +861,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #endif } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Construct string from a substring of a string_view. * @param __t Source object convertible to string view. @@ -944,7 +1017,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } #endif // C++11 -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Set value to string constructed from a string_view. * @param __svt An object convertible to string_view. @@ -1439,7 +1512,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { return this->append(__l.begin(), __l.size()); } #endif // C++11 -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Append a string_view. * @param __svt An object convertible to string_view to be appended. @@ -1525,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. @@ -1556,7 +1681,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 append(_InputIterator __first, _InputIterator __last) { return this->replace(end(), end(), __first, __last); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view /** * @brief Append a string_view. * @param __svt An object convertible to string_view to be appended. @@ -1784,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. @@ -1809,7 +1953,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } #endif // C++11 -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Set value from a string_view. * @param __svt The source object convertible to string_view. @@ -1933,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. @@ -2090,7 +2265,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 return iterator(_M_data() + __pos); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Insert a string_view. * @param __pos Position in string to insert at. @@ -2521,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. @@ -2542,7 +2741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { return this->replace(__i1, __i2, __l.begin(), __l.size()); } #endif // C++11 -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Replace range of characters with string_view. * @param __pos The position to replace at. @@ -2741,7 +2940,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX_NOEXCEPT { return this->find(__str.data(), __pos, __str.size()); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find position of a string_view. * @param __svt The object convertible to string_view to locate. @@ -2807,7 +3006,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX_NOEXCEPT { return this->rfind(__str.data(), __pos, __str.size()); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find last position of a string_view. * @param __svt The object convertible to string_view to locate. @@ -2891,7 +3090,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX_NOEXCEPT { return this->find_first_of(__str.data(), __pos, __str.size()); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find position of a character of a string_view. * @param __svt An object convertible to string_view containing @@ -2980,7 +3179,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX_NOEXCEPT { return this->find_last_of(__str.data(), __pos, __str.size()); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find last position of a character of string. * @param __svt An object convertible to string_view containing @@ -3068,7 +3267,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX_NOEXCEPT { return this->find_first_not_of(__str.data(), __pos, __str.size()); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find position of a character not in a string_view. * @param __svt A object convertible to string_view containing @@ -3155,7 +3354,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX_NOEXCEPT { return this->find_last_not_of(__str.data(), __pos, __str.size()); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find last position of a character not in a string_view. * @param __svt An object convertible to string_view containing @@ -3271,7 +3470,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 return __r; } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Compare to a string_view. * @param __svt An object convertible to string_view to compare against. @@ -3598,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 @@ -4605,7 +4813,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 constexpr #endif inline wstring -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 __to_wstring_numeric(string_view __s) #else __to_wstring_numeric(const string& __s) @@ -4808,7 +5016,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // inline namespace literals #endif // __glibcxx_string_udls -#if __cplusplus >= 201703L +#ifdef __glibcxx_variant // >= C++17 namespace __detail::__variant { template<typename> struct _Never_valueless_alt; // see <variant> diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index a5df7cb..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; } @@ -279,11 +280,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Length of string constructed is easier to propagate inter-procedurally // than difference between iterators. template<typename _CharT, typename _Traits, typename _Alloc> - template<bool _Terminated> + template<bool _Terminated> _GLIBCXX20_CONSTEXPR void basic_string<_CharT, _Traits, _Alloc>:: - _M_construct(const _CharT *__str, size_type __n) + _M_construct(const _CharT* __str, size_type __n) { if (__n > size_type(_S_local_capacity)) { 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 740e046..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 @@ -467,7 +467,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_empty_rep() _GLIBCXX_NOEXCEPT { return _Rep::_S_empty_rep(); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 // A helper type for avoiding boiler-plate. typedef basic_string_view<_CharT, _Traits> __sv_type; @@ -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. @@ -685,7 +727,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_dataplus(_S_construct(__beg, __end, __a), __a) { } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Construct string from a substring of a string_view. * @param __t Source object convertible to string view. @@ -775,7 +817,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif // C++11 -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Set value to string constructed from a string_view. * @param __svt An object convertible to string_view. @@ -1246,7 +1288,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return this->append(__l.begin(), __l.size()); } #endif // C++11 -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Append a string_view. * @param __svt The object convertible to string_view to be appended. @@ -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. @@ -1338,7 +1396,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION append(_InputIterator __first, _InputIterator __last) { return this->replace(_M_iend(), _M_iend(), __first, __last); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Append a string_view. * @param __svt The object convertible to string_view to be appended. @@ -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. @@ -1496,7 +1570,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return this->assign(__l.begin(), __l.size()); } #endif // C++11 -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Set value from a string_view. * @param __svt The source object convertible to string_view. @@ -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. @@ -1703,7 +1804,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return iterator(_M_data() + __pos); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Insert a string_view. * @param __pos Position in string to insert at. @@ -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. @@ -2092,7 +2214,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return this->replace(__i1, __i2, __l.begin(), __l.end()); } #endif // C++11 -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Replace range of characters with string_view. * @param __pos The position to replace at. @@ -2354,7 +2476,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_type find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT; -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find position of a string_view. * @param __svt The object convertible to string_view to locate. @@ -2432,7 +2554,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_type rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT; -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find last position of a string_view. * @param __svt The object convertible to string_view to locate. @@ -2515,7 +2637,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find(__c, __pos); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find position of a character of a string_view. * @param __svt An object convertible to string_view containing @@ -2599,7 +2721,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->rfind(__c, __pos); } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find last position of a character of string. * @param __svt An object convertible to string_view containing @@ -2680,7 +2802,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT; -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find position of a character not in a string_view. * @param __svt An object convertible to string_view containing @@ -2762,7 +2884,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find_last_not_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT; -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Find last position of a character not in a string_view. * @param __svt An object convertible to string_view containing @@ -2824,7 +2946,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __r; } -#if __cplusplus >= 201703L +#ifdef __glibcxx_string_view // >= C++17 /** * @brief Compare to a string_view. * @param __svt An object convertible to string_view to compare against. 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 new file mode 100644 index 0000000..a6b5ac8 --- /dev/null +++ b/libstdc++-v3/include/bits/formatfwd.h @@ -0,0 +1,70 @@ +// <format> Formatting -*- C++ -*- + +// Copyright The GNU Toolchain Authors. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file bits/formatfwd.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{format} + */ + +#ifndef _GLIBCXX_FORMAT_FWD_H +#define _GLIBCXX_FORMAT_FWD_H 1 + +#ifdef _GLIBCXX_SYSHDR +#pragma GCC system_header +#endif + +// <bits/version.h> must have been included before this header: +#ifdef __glibcxx_format // C++ >= 20 && HOSTED + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // [format.context], class template basic_format_context + template<typename _Out, typename _CharT> class basic_format_context; + + // [format.parse.ctx], class template basic_format_parse_context + template<typename _CharT> class basic_format_parse_context; + + // [format.formatter], formatter + template<typename _Tp, typename _CharT = char> struct formatter; + +namespace __format +{ +#ifdef _GLIBCXX_USE_WCHAR_T + template<typename _CharT> + concept __char = same_as<_CharT, char> || same_as<_CharT, wchar_t>; +#else + template<typename _CharT> + concept __char = same_as<_CharT, char>; +#endif + + template<__char _CharT> + struct __formatter_int; +} + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif // __glibcxx_format +#endif // _GLIBCXX_FORMAT_FWD_H 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/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index 13bfbb3..488907d 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; diff --git a/libstdc++-v3/include/bits/ranges_uninitialized.h b/libstdc++-v3/include/bits/ranges_uninitialized.h index b558007..12a714b 100644 --- a/libstdc++-v3/include/bits/ranges_uninitialized.h +++ b/libstdc++-v3/include/bits/ranges_uninitialized.h @@ -263,26 +263,6 @@ namespace ranges inline constexpr __uninitialized_value_construct_n_fn uninitialized_value_construct_n; - namespace __detail - { - // This is only intended for finding smaller iterator differences below, - // not as a general purpose replacement for std::min. - struct __mindist_fn - { - template<typename _Dp1, typename _Dp2> - constexpr common_type_t<_Dp1, _Dp2> - operator()(_Dp1 __d1, _Dp2 __d2) const noexcept - { - // Every C++20 iterator I satisfies weakly_incrementable<I> which - // requires signed-integer-like<iter_difference_t<I>>. - static_assert(std::__detail::__is_signed_integer_like<_Dp1>); - static_assert(std::__detail::__is_signed_integer_like<_Dp2>); - return std::min<common_type_t<_Dp1, _Dp2>>(__d1, __d2); - } - }; - inline constexpr __mindist_fn __mindist{}; - } - template<typename _Iter, typename _Out> using uninitialized_copy_result = in_out_result<_Iter, _Out>; @@ -305,10 +285,10 @@ namespace ranges && is_trivially_assignable_v<_OutType&, iter_reference_t<_Iter>>) { - auto __d1 = __ilast - __ifirst; - auto __d2 = __olast - __ofirst; - return ranges::copy_n(std::move(__ifirst), - __detail::__mindist(__d1, __d2), __ofirst); + auto __d = __ilast - __ifirst; + if (auto __d2 = __olast - __ofirst; __d2 < __d) + __d = static_cast<iter_difference_t<_Iter>>(__d2); + return ranges::copy_n(std::move(__ifirst), __d, __ofirst); } else { @@ -356,9 +336,9 @@ namespace ranges && is_trivially_assignable_v<_OutType&, iter_reference_t<_Iter>>) { - auto __d = __olast - __ofirst; - return ranges::copy_n(std::move(__ifirst), - __detail::__mindist(__n, __d), __ofirst); + if (auto __d = __olast - __ofirst; __d < __n) + __n = static_cast<iter_difference_t<_Iter>>(__d); + return ranges::copy_n(std::move(__ifirst), __n, __ofirst); } else { @@ -397,11 +377,12 @@ namespace ranges && is_trivially_assignable_v<_OutType&, iter_rvalue_reference_t<_Iter>>) { - auto __d1 = __ilast - __ifirst; - auto __d2 = __olast - __ofirst; + auto __d = __ilast - __ifirst; + if (auto __d2 = __olast - __ofirst; __d2 < __d) + __d = static_cast<iter_difference_t<_Iter>>(__d2); auto [__in, __out] = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)), - __detail::__mindist(__d1, __d2), __ofirst); + __d, __ofirst); return {std::move(__in).base(), __out}; } else @@ -452,10 +433,11 @@ namespace ranges && is_trivially_assignable_v<_OutType&, iter_rvalue_reference_t<_Iter>>) { - auto __d = __olast - __ofirst; + if (auto __d = __olast - __ofirst; __d < __n) + __n = static_cast<iter_difference_t<_Iter>>(__d); auto [__in, __out] = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)), - __detail::__mindist(__n, __d), __ofirst); + __n, __ofirst); return {std::move(__in).base(), __out}; } else 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..9203a66 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; } 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..006ff46 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 @@ -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..554e076 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 @@ -213,7 +213,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 +326,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) @@ -397,7 +397,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 +766,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 +849,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) @@ -924,7 +924,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..0799fd0 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 @@ -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..7b32464 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 @@ -181,7 +181,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 +300,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) @@ -371,7 +371,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_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 458adc9..aff9d5d 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. @@ -763,7 +763,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 +926,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 +982,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 +1648,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 +1769,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 +2313,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/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h index 49e97e2..5bc58e8 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 @@ -277,7 +277,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : 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 +681,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 +1291,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>>, @@ -1530,7 +1530,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 +1802,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 +2311,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..091bae6 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 @@ -271,7 +271,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 +533,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 @@ -1013,7 +1013,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>>, @@ -1249,7 +1249,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 +1483,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 @@ -1977,7 +1977,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/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 66d73b4..b21e1d3 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -977,7 +977,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 +1100,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 1468c04..0afaf0d 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -30,6 +30,7 @@ AutoGen Definitions version.tpl; // ftms = { // name = FTM NAME; // [stdname = FTM STANDARD MACRO NAME;] +// [no_stdname = true;] // values = { // v = VALUE FOR FTM IF MATCHING; // [extra_cond = STRING;] @@ -56,7 +57,8 @@ AutoGen Definitions version.tpl; // stdname configures the name of the *standard* macro emitted, i.e. it // replaces only the __cpp_lib_ macro in the emitted definition. Defaults to -// __cpp_lib_${name} +// __cpp_lib_${name}. If no_stdname exists (with any value), the stdname +// define is not emitted. // N.B This list needs to be in topological sort order, as later entries in // this list can and do use the earlier entries. @@ -1271,7 +1273,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"; }; @@ -1404,18 +1411,18 @@ ftms = { }; }; -// ftms = { - // name = format_ranges; +ftms = { + name = format_ranges; // 202207 P2286R8 Formatting Ranges // 202207 P2585R1 Improving default container formatting // LWG3750 Too many papers bump __cpp_lib_format - // TODO: #define __cpp_lib_format_ranges 202207L - // values = { - // v = 202207; - // cxxmin = 23; - // hosted = yes; - // }; -// }; + no_stdname = true; // TODO remove + values = { + v = 1; // TODO 202207 + cxxmin = 23; + hosted = yes; + }; +}; ftms = { name = freestanding_algorithm; @@ -1508,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 f7c9849..980fee6 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -1406,11 +1406,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 @@ -1555,6 +1560,15 @@ #endif /* !defined(__cpp_lib_expected) && defined(__glibcxx_want_expected) */ #undef __glibcxx_want_expected +#if !defined(__cpp_lib_format_ranges) +# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED +# define __glibcxx_format_ranges 1L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_format_ranges) +# endif +# endif +#endif /* !defined(__cpp_lib_format_ranges) && defined(__glibcxx_want_format_ranges) */ +#undef __glibcxx_want_format_ranges + #if !defined(__cpp_lib_freestanding_algorithm) # if (__cplusplus >= 202100L) # define __glibcxx_freestanding_algorithm 202311L @@ -1655,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/bits/version.tpl b/libstdc++-v3/include/bits/version.tpl index dd5f851..ccda71d 100644 --- a/libstdc++-v3/include/bits/version.tpl +++ b/libstdc++-v3/include/bits/version.tpl @@ -143,13 +143,15 @@ h }*/# /*{(unless (first-for?) "el")}*/if /*{(generate-cond)}*/ # define __glibcxx_/*{name}*/ /*{v}*/L -# if defined(__glibcxx_want_all) || defined(__glibcxx_want_/*{name}*/) +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_/*{name}*/)/*{ + IF (not (exist? "no_stdname")) }*/ # define /*{ ;; Compute the name for this FTM based on stdname/name. (if (exist? "stdname") (get "stdname") (format #f "__cpp_lib_~a" (get "name"))) -}*/ /*{v}*/L +}*/ /*{v}*/L/*{ + ENDIF no_std_name }*/ # endif /*{ ENDFOR values }*/# endif 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..448f681 100644 --- a/libstdc++-v3/include/debug/unordered_map +++ b/libstdc++-v3/include/debug/unordered_map @@ -201,7 +201,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 +869,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>>, @@ -1077,7 +1077,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 +1655,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..4255f6e 100644 --- a/libstdc++-v3/include/debug/unordered_set +++ b/libstdc++-v3/include/debug/unordered_set @@ -194,7 +194,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, @@ -902,7 +902,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, @@ -1444,7 +1444,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 +1479,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/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h index 1ffde3e..f4b312d 100644 --- a/libstdc++-v3/include/precompiled/stdc++.h +++ b/libstdc++-v3/include/precompiled/stdc++.h @@ -230,15 +230,15 @@ #include <generator> #include <print> #include <spanstream> -#if __has_include(<stacktrace>) -# include <stacktrace> -#endif +#include <stacktrace> #include <stdatomic.h> #include <stdfloat> #endif #if __cplusplus > 202302L #include <text_encoding> +#include <stdbit.h> +#include <stdckdint.h> #endif #endif // HOSTED 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_set b/libstdc++-v3/include/std/flat_set index a7b0b8a..3e15d1a 100644 --- a/libstdc++-v3/include/std/flat_set +++ b/libstdc++-v3/include/std/flat_set @@ -350,12 +350,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_cont.max_size(); } // modifiers - template<typename... _Args> + template<typename _Arg, typename... _Args> pair<iterator, bool> - _M_try_emplace(optional<const_iterator> __hint, _Args&&... __args) + _M_try_emplace(optional<const_iterator> __hint, _Arg&& __arg, _Args&&... __args) { // TODO: Simplify and audit the hint handling. - value_type __k(std::forward<_Args>(__args)...); + auto&& __k = [&] -> decltype(auto) { + if constexpr (sizeof...(_Args) == 0 + && same_as<remove_cvref_t<_Arg>, value_type>) + return std::forward<_Arg>(__arg); + else + return value_type(std::forward<_Arg>(__arg), + std::forward<_Args>(__args)...); + }(); typename container_type::iterator __it; int __r = -1, __s = -1; if (__hint.has_value() @@ -397,12 +404,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return {__it, false}; auto __guard = _M_make_clear_guard(); - __it = _M_cont.insert(__it, std::move(__k)); + __it = _M_cont.insert(__it, std::forward<decltype(__k)>(__k)); __guard._M_disable(); return {__it, true}; } template<typename... _Args> + pair<iterator, bool> + _M_try_emplace(optional<const_iterator> __hint) + { return _M_try_emplace(__hint, value_type()); } + + template<typename... _Args> requires is_constructible_v<value_type, _Args...> __emplace_result_t emplace(_Args&&... __args) diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index 9ef719e..e557e10 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -52,6 +52,7 @@ #include <string_view> #include <string> #include <bits/monostate.h> +#include <bits/formatfwd.h> #include <bits/ranges_base.h> // input_range, range_reference_t #include <bits/ranges_util.h> // subrange #include <bits/ranges_algobase.h> // ranges::copy @@ -73,17 +74,45 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - // [format.context], class template basic_format_context - template<typename _Out, typename _CharT> class basic_format_context; - // [format.fmt.string], class template basic_format_string template<typename _CharT, typename... _Args> struct basic_format_string; /// @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 _Seq> class _Seq_sink; + + template<typename _CharT, typename _Alloc = allocator<_CharT>> + using _Str_sink + = _Seq_sink<basic_string<_CharT, char_traits<_CharT>, _Alloc>>; + + // template<typename _CharT, typename _Alloc = allocator<_CharT>> + // using _Vec_sink = _Seq_sink<vector<_CharT, _Alloc>>; + // Output iterator that writes to a type-erase character sink. template<typename _CharT> class _Sink_iter; @@ -178,7 +207,7 @@ namespace __format // [format.formatter], formatter /// The primary template of std::formatter is disabled. - template<typename _Tp, typename _CharT = char> + template<typename _Tp, typename _CharT> struct formatter { formatter() = delete; // No std::formatter specialization for this type. @@ -450,9 +479,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. + _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 _Align { @@ -519,42 +549,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; } @@ -850,6 +886,302 @@ namespace __format __spec._M_fill); } + // 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 { @@ -923,17 +1255,16 @@ namespace __format bool _M_hasval = false; }; -#ifdef _GLIBCXX_USE_WCHAR_T - template<typename _CharT> - concept __char = same_as<_CharT, char> || same_as<_CharT, wchar_t>; -#else - template<typename _CharT> - concept __char = same_as<_CharT, char>; -#endif - 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) { @@ -971,7 +1302,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; @@ -990,43 +1321,107 @@ namespace __format format(basic_string_view<_CharT> __s, basic_format_context<_Out, _CharT>& __fc) const { - if (_M_spec._M_type == _Pres_esc) + constexpr auto __term = __format::_Term_char::_Tc_quote; + const auto __write_direct = [&] { - // TODO: C++23 escaped string presentation - } + if (_M_spec._M_type == _Pres_esc) + return __format::__write_escaped(__fc.out(), __s, __term); + else + return __format::__write(__fc.out(), __s); + }; if (_M_spec._M_width_kind == _WP_none && _M_spec._M_prec_kind == _WP_none) - return __format::__write(__fc.out(), __s); + return __write_direct(); - size_t __estimated_width; - if constexpr (__unicode::__literal_encoding_is_unicode<_CharT>()) + const size_t __prec = + _M_spec._M_prec_kind != _WP_none + ? _M_spec._M_get_precision(__fc) + : basic_string_view<_CharT>::npos; + + const size_t __estimated_width = _S_trunc(__s, __prec); + // N.B. Escaping only increases width + if (_M_spec._M_get_width(__fc) <= __estimated_width + && _M_spec._M_prec_kind == _WP_none) + return __write_direct(); + + if (_M_spec._M_type != _Pres_esc) + return __format::__write_padded_as_spec(__s, __estimated_width, + __fc, _M_spec); + + __format::_Str_sink<_CharT> __sink; + __format::__write_escaped(__sink.out(), __s, __term); + basic_string_view<_CharT> __escaped(__sink.view().data(), + __sink.view().size()); + const size_t __escaped_width = _S_trunc(__escaped, __prec); + // 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. + return __format::__write_padded_as_spec(__escaped, __escaped_width, + __fc, _M_spec); + } + +#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> + typename basic_format_context<_Out, _CharT>::iterator + _M_format_range(_Rg&& __rg, basic_format_context<_Out, _CharT>& __fc) const + { + using _String = basic_string<_CharT>; + using _String_view = basic_string_view<_CharT>; + if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>) { - if (_M_spec._M_prec_kind != _WP_none) + const size_t __n(ranges::distance(__rg)); + if constexpr (ranges::contiguous_range<_Rg>) + return format(_String_view(ranges::data(__rg), __n), __fc); + else if (__n <= __format::__stackbuf_size<_CharT>) + { + _CharT __buf[__format::__stackbuf_size<_CharT>]; + ranges::copy(__rg, __buf); + return format(_String_view(__buf, __n), __fc); + } + else if constexpr (ranges::sized_range<_Rg>) + return format(_String(from_range, __rg), __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 + __n); + return format(_String(from_range, __sub), __fc); } else - __estimated_width = __unicode::__field_width(__s); + { + // N.B. preserve the computed size + ranges::subrange __sub(__rg, __n); + return format(_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 format(_String(from_range, __rg), __fc); } -#if __cpp_lib_format_ranges constexpr void set_debug_format() noexcept { _M_spec._M_type = _Pres_esc; } #endif private: + static size_t + _S_trunc(basic_string_view<_CharT>& __s, size_t __prec) + { + if constexpr (__unicode::__literal_encoding_is_unicode<_CharT>()) + { + if (__prec != basic_string_view<_CharT>::npos) + return __unicode::__truncate(__s, __prec); + else + return __unicode::__field_width(__s); + } + else + { + __s = __s.substr(0, __prec); + return __s.size(); + } + } + _Spec<_CharT> _M_spec{}; }; @@ -1130,7 +1525,7 @@ namespace __format ++__first; } break; -#if __cpp_lib_format_ranges +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED case '?': if (__type == _AsChar) { @@ -1282,7 +1677,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 @@ -1296,7 +1691,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> @@ -1848,9 +2269,9 @@ namespace __format if (_M_spec._M_localized && __builtin_isfinite(__v)) { - __wstr = _M_localize(__str, __expc, __fc.locale()); - if (!__wstr.empty()) - __str = __wstr; + auto __s = _M_localize(__str, __expc, __fc.locale()); + if (!__s.empty()) + __str = __wstr = std::move(__s); } size_t __width = _M_spec._M_get_width(__fc); @@ -1983,15 +2404,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; } @@ -2022,15 +2440,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; } @@ -2060,7 +2475,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 @@ -2085,7 +2500,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 @@ -2109,7 +2524,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 @@ -2133,7 +2548,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 @@ -2158,7 +2573,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 @@ -2183,7 +2598,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 @@ -2208,7 +2623,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 @@ -2585,7 +3000,7 @@ namespace __format }; /// @} -#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 @@ -2645,32 +3060,21 @@ namespace __format 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 -// 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 +#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>; -#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 @@ -2869,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 @@ -3003,13 +3433,6 @@ namespace __format } }; - template<typename _CharT, typename _Alloc = allocator<_CharT>> - using _Str_sink - = _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. // Writes to a fixed-size buffer and then flushes to the output iterator // when the buffer fills up. @@ -3685,17 +4108,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); } @@ -4723,7 +5146,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 { @@ -4737,7 +5160,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 @@ -4768,29 +5194,602 @@ 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>>); + + if (__spec._M_get_width(__fc) == 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_trigger() + { + if (_M_ctx) + _M_ctx->advance_to(_M_out); + _M_ctx = nullptr; + } + + ~_Restore_out() + { _M_trigger(); } + + private: + basic_format_context<_Sink_iter<_CharT>, _CharT>* _M_ctx; + _Sink_iter<_CharT> _M_out; + }; + + _Restore_out __restore(__fc); + // TODO Consider double sinking, first buffer of width + // size and then original sink, if first buffer is overun + // we do not need to align + _Str_sink<_CharT> __buf; + __fc.advance_to(__buf.out()); + __call(__fc); + __restore._M_trigger(); + + basic_string_view<_CharT> __str(__buf.view()); + size_t __width; + if constexpr (__unicode::__literal_encoding_is_unicode<_CharT>()) + __width = __unicode::__field_width(__str); + else + __width = __str.size(); + + return __format::__write_padded_as_spec(__str, __width, __fc, __spec); + } + + 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>; + + 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 = char> + 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/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/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/queue b/libstdc++-v3/include/std/queue index c06a4c3..74b6c07 100644 --- a/libstdc++-v3/include/std/queue +++ b/libstdc++-v3/include/std/queue @@ -68,6 +68,7 @@ #include <bits/stl_queue.h> #define __glibcxx_want_adaptor_iterator_pair_constructor +#define __glibcxx_want_containers_ranges #include <bits/version.h> #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..5cea476 100644 --- a/libstdc++-v3/include/std/stack +++ b/libstdc++-v3/include/std/stack @@ -65,6 +65,7 @@ #include <bits/stl_stack.h> #define __glibcxx_want_adaptor_iterator_pair_constructor +#define __glibcxx_want_containers_ranges #include <bits/version.h> #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/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 0f04334..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 @@ -157,4 +158,36 @@ _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // __cpp_lib_erase_if +#ifdef __glibcxx_format_ranges // C++ >= 20 && HOSTED +#include <bits/formatfwd.h> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + // Standard does not constrain accepted _CharT and declares it as formatter + // of Tp that statisfies is-vector-bool-reference<T>, + template<__format::__char _CharT> + struct formatter<_GLIBCXX_STD_C::_Bit_reference, _CharT> + { + // 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.template _M_parse<bool>(__pc); } + + // Standard declares this as template accepting unconstrained + // FormatContext type. + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const _GLIBCXX_STD_C::_Bit_reference& __u, + basic_format_context<_Out, _CharT>& __fc) const + { return _M_f.format(static_cast<bool>(__u), __fc); } + + private: + __format::__formatter_int<_CharT> _M_f; + }; +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif // __glibcxx_format_ranges + #endif /* _GLIBCXX_VECTOR */ |