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