aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
AgeCommit message (Collapse)AuthorFilesLines
5 dayslibstdc++: Fixed signed comparision in _M_parse_fill_and_align [PR119840]Tomasz Kamiński1-2/+2
Explicitly cast elements of __not_fill to _CharT. Only '{' and ':' are used as `__not_fill`, so they are never negative. PR libstdc++/119840 libstdc++-v3/ChangeLog: * include/std/format (_M_parse_fill_and_align): Cast elements of __not_fill to _CharT.
5 dayslibstdc++: Do not use 'not' alternative token in <format>Jonathan Wakely1-1/+4
This fixes: FAIL: 17_intro/headers/c++1998/operator_names.cc -std=gnu++23 (test for excess errors) FAIL: 17_intro/headers/c++1998/operator_names.cc -std=gnu++26 (test for excess errors) The purpose of 'not defined<format_kind<R>>' is to be ill-formed (as required by [format.range.fmtkind]) and to give an error that includes the string "not defined<format_kind<R>>". That was intended to tell you that format_kind<R> is not defined, just like it says! But user code can use -fno-operator-names so we can't use 'not' here, and "! defined" in the diagnostic doesn't seem as user-friendly. It also raises questions about whether it was intended to be the preprocessor token 'defined' (it's not) or where 'defined' is defined (it's not). Replace it with __primary_template_not_defined<format_kind<R>> and a comment, which seems to give a fairly clear diagnostic with both GCC and Clang. The diagnostic now looks like: .../include/c++/15.0.1/format:5165:7: error: use of 'std::format_kind<int>' before deduction of 'auto' 5165 | format_kind<_Rg> // you can specialize this for non-const input ranges | ^~~~~~~~~~~~~~~~ .../include/c++/15.0.1/format:5164:35: error: '__primary_template_not_defined' was not declared in this scope 5164 | __primary_template_not_defined( | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ 5165 | format_kind<_Rg> // you can specialize this for non-const input ranges | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5166 | ); | ~ libstdc++-v3/ChangeLog: * include/std/format (format_kind): Do not use 'not' alternative token to make the primary template ill-formed. Use the undeclared identifier __primary_template_not_defined and a comment that will appear in diagnostics. * testsuite/std/format/ranges/format_kind_neg.cc: New test.
5 dayslibstdc++: Remove dead code in range_formatter::format [PR109162]Tomasz Kamiński1-7/+12
Because the _M_format(__rg, __fc) were placed outside of if constexpr, these method and its children where instantiated, even if _M_format<const _Range> could be used. To simplify the if constexpr chain, we introduce a __simply_formattable_range (name based on simple-view) exposition only concept, that checks if range is const and mutable formattable and uses same formatter specialization for references in each case. PR libstdc++/109162 libstdc++-v3/ChangeLog: * include/std/format (__format::__simply_formattable_range): Define. (range_formatter::format): Do not instantiate _M_format for mutable _Rg if const _Rg can be used. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
6 dayslibstdc++: Fix constification in range_formatter::format [PR109162]Tomasz Kamiński1-3/+8
The _Rg is deduced to lvalue reference for the lvalue arguments, and in such case __format::__maybe_const_range<_Rg, _CharT> is always _Rg (adding const to reference does not change behavior). Now we correctly check if _Range = remove_reference_t<_Rg> is const formattable range, furthermore as range_formatter<T> can only format ranges of values of type (possibly const) _Tp, we additional check if the remove_cvref_t<range_reference_t<const _Range>> is _Tp. The range_reference_t<R> and range_reference_t<const R> have different types (modulo remove_cvref_t) for std::vector<bool> (::reference and bool) or flat_map<T, U> (pair<const T&, U&> and pair<const T&, const U&>). PR libstdc++/109162 libstdc++-v3/ChangeLog: * include/std/format (range_formatter::format): Format const range, only if reference type is not changed. * testsuite/std/format/ranges/formatter.cc: New tests. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
6 dayslibstdc++: Implement formatters for pair and tuple [PR109162]Tomasz Kamiński1-74/+303
This patch implements formatter specializations for pair and tuple form P2286R8. In addition using 'm` and range_format::map (from P2585R1) for ranges are now supported. The formatters for pairs and tuples whose corresponding elements are the same (after applying remove_cvref_t) derive from the same __tuple_formatter class. This reduce the code duplication, as most of the parsing and formatting is the same in such cases. We use a custom reduced implementation of the tuple (__formatters_storage) to store the elements formatters. Handling of the padding (width and fill) options, is extracted to __format::__format_padded function, that is used both by __tuple_formatter and range_formatter. To reduce number of instantations range_formatter::format triggers, we cast incoming range to __format::__maybe_const_range<_Rg, _CharT>&, before formatting it. As in the case of previous commits, the signatures of the user-facing parse and format methods of the provided formatters deviate from the standard by constraining types of parameters: * _CharT is constrained __formatter::__char * basic_format_parse_context<_CharT> for parse argument * basic_format_context<_Out, _CharT> for format second argument The standard specifies last three of above as unconstrained types. Finally, test for tuple-like std::array and std::ranges::subrange, that illustrate that they remain formatted as ranges. PR libstdc++/109162 libstdc++-v3/ChangeLog: * include/std/format (__formatter_int::_M_format_character_escaped) (__formatter_str::format): Use __sink.out() to produce _Sink_iter. (__format::__const_formattable_range): Moved closer to range_formatter. (__format::__maybe_const_range): Use `__conditional_t` and moved closer to range_formatter. (__format::__format_padded, __format::maybe_const) (__format::__indexed_formatter_storage, __format::__tuple_formatter) (std::formatter<pair<_Fp, _Sp>, _CharT>>) (std::formatter<tuple<_Tps...>, _CharT): Define. (std::formatter<_Rg, _CharT>::format): Cast incoming range to __format::__maybe_const_range<_Rg, _CharT>&. (std::formatter<_Rg, _CharT>::_M_format): Extracted from format, and use __format_padded. (std::formatter<_Rg, _CharT>::_M_format_no_padding): Rename... (std::formatter<_Rg, _CharT>::_M_format_elems): ...to this. (std::formatter<_Rg, _CharT>::_M_format_with_padding): Extracted as __format_padded. * testsuite/util/testsuite_iterators.h (test_input_range_nocopy): Define. * testsuite/std/format/ranges/formatter.cc: Tests for `m` specifier. * testsuite/std/format/ranges/sequence.cc: Tests for array and subrange. * testsuite/std/format/ranges/map.cc: New test. * testsuite/std/format/tuple.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
7 dayslibstdc++: Do not define __cpp_lib_ranges_iota in <ranges>Jonathan Wakely1-1/+0
In r14-7153-gadbc46942aee75 we removed a duplicate definition of __glibcxx_want_range_iota from <ranges>, but __cpp_lib_ranges_iota should be defined in <ranges> at all. libstdc++-v3/ChangeLog: * include/std/ranges (__glibcxx_want_ranges_iota): Do not define.
7 dayslibstdc++: Do not declare namespace ranges in <numeric> unconditionallyJonathan Wakely1-5/+3
Move namespace ranges inside the feature test macro guard, because 'ranges' is not a reserved name before C++20. libstdc++-v3/ChangeLog: * include/std/numeric (ranges): Only declare namespace for C++23 and later. (ranges::iota_result): Fix indentation. * testsuite/17_intro/names.cc: Check ranges is not used as an identifier before C++20.
7 dayslibstdc++: Implement formatter for ranges and range_formatter [PR109162]Tomasz Kamiński1-57/+448
This patch implements formatter specialization for input_ranges and range_formatter class from P2286R8, as adjusted by P2585R1. The formatter for pair/tuple is not yet provided, making maps not formattable. This introduces an new _M_format_range member to internal __formatter_str, that formats range as _CharT as string, according to the format spec. This function transform any contiguous range into basic_string_view directly, by computing size if necessary. Otherwise, for ranges for which size can be computed (forward_range or sized_range) we use a stack buffer, if they are sufficiently small. Finally, we create a basic_string<_CharT> from the range, and format its content. In case when padding is specified, this is handled by firstly formatting the content of the range to the temporary string object. However, this can be only implemented if the iterator of the basic_format_context is internal type-erased iterator used by implementation. Otherwise a new basic_format_context would need to be created, which would require rebinding of handles stored in the arguments: note that format spec for element type could retrieve any format argument from format context, visit and use handle to format it. As basic_format_context provide no user-facing constructor, the user are not able to construct object of that type with arbitrary iterators. The signatures of the user-facing parse and format methods of the provided formatters deviate from the standard by constraining types of params: * _CharT is constrained __formatter::__char * basic_format_parse_context<_CharT> for parse argument * basic_format_context<_Out, _CharT> for format second argument The standard specifies last three of above as unconstrained types. These types are later passed to possibly user-provided formatter specializations, that are required via formattable concept to only accept above types. Finally, the formatter<input_range, _CharT> specialization is implemented without using specialization of range-default-formatter exposition only template as base class, while providing same functionality. PR libstdc++/109162 libstdc++-v3/ChangeLog: * include/std/format (__format::__has_debug_format, _Pres_type::_Pres_seq) (_Pres_type::_Pres_str, __format::__Stackbuf_size): Define. (_Separators::_S_squares, _Separators::_S_parens, _Separators::_S_comma) (_Separators::_S_colon): Define additional constants. (_Spec::_M_parse_fill_and_align): Define overload accepting list of excluded characters for fill, and forward existing overload. (__formatter_str::_M_format_range): Define. (__format::_Buf_sink) Use __Stackbuf_size for size of array. (__format::__is_map_formattable, std::range_formatter) (std::formatter<_Rg, _CharT>): Define. * src/c++23/std.cc.in (std::format_kind, std::range_format) (std::range_formatter): Export. * testsuite/std/format/formatter/lwg3944.cc: Guarded tests with __glibcxx_format_ranges. * testsuite/std/format/formatter/requirements.cc: Adjusted for standard behavior. * testsuite/23_containers/vector/bool/format.cc: Test vector<bool> formatting. * testsuite/std/format/ranges/format_kind.cc: New test. * testsuite/std/format/ranges/formatter.cc: New test. * testsuite/std/format/ranges/sequence.cc: New test. * testsuite/std/format/ranges/string.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
7 dayslibstdc++: Fix std::string construction from volatile char* [PR119748]Jonathan Wakely3-13/+31
My recent r15-9381-g648d5c26e25497 change assumes that a contiguous iterator with the correct value_type can be converted to a const charT* but that's not true for volatile charT*. The optimization should only be done if it can be converted to the right pointer type. Additionally, some generic loops for non-contiguous iterators need an explicit cast to deal with iterator reference types that do not bind to the const charT& parameter of traits_type::assign. libstdc++-v3/ChangeLog: PR libstdc++/119748 * include/bits/basic_string.h (_S_copy_chars): Only optimize for contiguous iterators that are convertible to const charT*. Use explicit conversion to charT after dereferencing iterator. (_S_copy_range): Likewise for contiguous ranges. * include/bits/basic_string.tcc (_M_construct): Use explicit conversion to charT after dereferencing iterator. * include/bits/cow_string.h (_S_copy_chars): Likewise. (basic_string(from_range_t, R&&, const Allocator&)): Likewise. Only optimize for contiguous iterators that are convertible to const charT*. * testsuite/21_strings/basic_string/cons/char/119748.cc: New test. * testsuite/21_strings/basic_string/cons/wchar_t/119748.cc: New test. Reviewed-by: Tomasz Kaminski <tkaminsk@redhat.com>
11 dayslibstdc++: Use constexpr-if for std::basic_string::_S_copy_charsJonathan Wakely1-8/+23
For C++11 and later we can remove four overloads of _S_copy_chars and use constexpr-if in the generic _S_copy_chars. This simplifies overload resolution for _S_copy_chars, and also means that we use the optimized memcpy path for other iterators such as std::vector<char>::iterator. We still need all the _S_copy_chars overloads to be part of the explicit instantiation definition, so make them depend on the macro that is defined by src/c++11/string-inst.cc for that purpose. For C++98 the _S_copy_chars overloads are still needed, but the macros _GLIBCXX_NOEXCEPT and _GLIBCXX20_CONSTEXPR do nothing for C++98, so this change removes them from those overloads. When instantiated in src/c++11/string-inst.cc the removed _GLIBCXX_NOEXCEPT macros would expand to 'noexcept', but in practice that doesn't make any difference for those instantiations. At -O2 the instantiations inline all the calls to _S_copy_chars and the presence or absence of noexcept doesn't change anything in the generated code. libstdc++-v3/ChangeLog: * include/bits/basic_string.h (_S_copy_chars): Replace overloads with constexpr-if and extend optimization to all contiguous iterators. * src/c++11/string-inst.cc: Extend comment. Reviewed-by: Tomasz Kaminski <tkaminsk@redhat.com>
11 dayslibstdc++: Define __cpp_lib_containers_ranges in appropriate headers [PR111055]Tomasz Kamiński41-134/+157
This is final piece of P1206R7, adding a feature test macros, as range constructors and member operations are now implemented for all containers and adaptors. For consistency with the proposal, all new container operations and helpers are now defined if __glibcxx_containers_ranges, instead of __glibcxx_ranges_to_container. PR libstdc++/111055 libstdc++-v3/ChangeLog: * include/bits/version.def (containers_ranges): Define. * include/bits/version.h: Regenerate. * include/bits/ranges_base.h (__detail::__container_compatible_range) (__detail::__range_to_alloc_type, __detail::__range_mapped_type) (__detail::__range_key_type): Depend on __glibcxx_containers_ranges instead of __glibcxx_ranges_to_container. * include/bits/basic_string.h: Replace __glibcxx_ranges_to_container with __glibcxx_containers_ranges. * include/bits/cow_string.h: Likewise. * include/bits/deque.tcc: Likewise. * include/bits/forward_list.h: Likewise. * include/bits/stl_bvector.h: Likewise. * include/bits/stl_deque.h: Likewise. * include/bits/stl_list.h: Likewise. * include/bits/stl_map.h: Likewise. * include/bits/stl_multimap.h: Likewise. * include/bits/stl_multiset.h: Likewise. * include/bits/stl_queue.h: Likewise. * include/bits/stl_set.h: Likewise. * include/bits/stl_stack.h: Likewise. * include/bits/stl_vector.h: Likewise. * include/bits/unordered_map.h: Likewise. * include/bits/unordered_set.h: Likewise. * include/bits/vector.tcc: Likewise. * include/debug/deque: Likewise. * include/debug/forward_list: Likewise. * include/debug/list: Likewise. * include/debug/map.h: Likewise. * include/debug/multimap.h: Likewise. * include/debug/multiset.h: Likewise. * include/debug/set.h: Likewise. * include/debug/unordered_map: Likewise. * include/debug/unordered_set: Likewise. * include/debug/vector: Likewise. * include/std/deque: Provide __cpp_lib_containers_ranges. * include/std/forward_list: Likewise. * include/std/list: Likewise. * include/std/map: Likewise. * include/std/queue: Likewise. * include/std/set: Likewise. * include/std/stack: Likewise. * include/std/string: Likewise. * include/std/unordered_map: Likewise. * include/std/unordered_set: Likewise. * include/std/vector: Likewise. * testsuite/21_strings/basic_string/cons/from_range.cc: Test for value __cpp_lib_containers_ranges. * testsuite/23_containers/deque/cons/from_range.cc: Likewise. * testsuite/23_containers/forward_list/cons/from_range.cc: Likewise. * testsuite/23_containers/list/cons/from_range.cc: Likewise. * testsuite/23_containers/map/cons/from_range.cc: Likewise. * testsuite/23_containers/multimap/cons/from_range.cc: Likewise. * testsuite/23_containers/multiset/cons/from_range.cc: Likewise. * testsuite/23_containers/priority_queue/cons_from_range.cc: Likewise. * testsuite/23_containers/queue/cons_from_range.cc: Likewise. * testsuite/23_containers/set/cons/from_range.cc: Likewise. * testsuite/23_containers/stack/cons_from_range.cc: Likewise. * testsuite/23_containers/unordered_map/cons/from_range.cc: Likewise. * testsuite/23_containers/unordered_multimap/cons/from_range.cc: Likewise. * testsuite/23_containers/unordered_multiset/cons/from_range.cc: Likewise. * testsuite/23_containers/unordered_set/cons/from_range.cc: Likewise. * testsuite/23_containers/vector/bool/cons/from_range.cc: Likewise. * testsuite/23_containers/vector/cons/from_range.cc: Likewise. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
11 dayslibstdc++: Add P1206R7 from_range members to std::string [PR111055]Jonathan Wakely2-0/+297
This is the last piece of P1206R7, adding new members to std::basic_string. libstdc++-v3/ChangeLog: PR libstdc++/111055 * include/bits/basic_string.h (_S_copy_range): New function. (basic_string(from_range_t, R%%, const Alloc&)): New constructor. (append_range, assign_range, insert_range, replace_with_range): New functions. * include/bits/cow_string.h: Likewise. * testsuite/21_strings/basic_string/cons/from_range.cc: New test. * testsuite/21_strings/basic_string/modifiers/append/append_range.cc: New test. * testsuite/21_strings/basic_string/modifiers/assign/assign_range.cc: New test. * testsuite/21_strings/basic_string/modifiers/insert/insert_range.cc: New test. * testsuite/21_strings/basic_string/modifiers/replace/replace_with_range.cc: New test. Co-authored-by: Tomasz Kamiński <tkaminsk@redhat.com>
11 dayslibstdc++: Implement debug format for strings and characters formatters ↵Tomasz Kamiński4-77/+708
[PR109162] This patch implements part P2286R8 that specified debug (escaped) format for the strings and characters sequences. This include both handling of the '?' format specifier and set_debug_format member. To indicate partial support we define __glibcxx_format_ranges macro value 1, without defining __cpp_lib_format_ranges. We provide two separate escaping routines depending on the literal encoding for the corresponding character types. If the character encoding is Unicode, we follow the specification for the standard (__format::__write_escaped_unicode). For other encodings, we escape only characters in range [0x00, 0x80), interpreting them as ASCII values: [0x00, 0x20), 0x7f and '\t', '\r', '\n', '\\', '"', '\'' are escaped. We assume every character outside this range is printable (__format::_write_escaped_ascii). In particular we do not yet implement special handling of shift sequences. For Unicode escaping a new __unicode::__escape_edges table is introduced, that encodes information if character belongs to General_Category that is escaped by the standard (Control or Other). This table is generated from DerivedGeneralCategory.txt provided by Unicode. Only boolean flag is preserved to reduce the number of entries. The additional rules for escaping are handled by __format::__should_escape_unicode. When width or precision is specified, we emit escaped string to the temporary buffer and format the resulting string according to the format spec. For characters use a fixed size stack buffer, for which a new _Fixedbuf_sink is introduced. For strings, we use _Str_sink and to avoid allocations, we compute the estimated size of (possibly truncated) input, and if it is larger than width field we print directly. PR libstdc++/109162 contrib/ChangeLog: * unicode/README: Mentioned DerivedGeneralCategory.txt. * unicode/gen_libstdcxx_unicode_data.py: Generation __escape_edges table from DerivedGeneralCategory.txt. Update file name in comments. * unicode/DerivedGeneralCategory.txt: Copy of file distributed by Unicode Consortium. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__detail::_Widen): Moved to std/format file. * include/bits/unicode-data.h: Regnerate. * include/bits/unicode.h (__unicode::_Utf_iterator::_M_units) (__unicode::__should_escape_category): Define. * include/std/format (_GLIBCXX_WIDEN_, _GLIBCXX_WIDEN): Copied from include/bits/chrono_io.h. (__format::_Widen): Moved from include/bits/chrono_io.h. (__format::_Term_char, __format::_Escapes, __format::_Separators) (__format::__should_escape_ascii, __format::__should_escape_unicode) (__format::__write_escape_seq, __format::__write_escaped_char) (__format::__write_escaped_acii, __format::__write_escaped_unicode) (__format::__write_escaped): Define. (__formatter_str::_S_trunc): Extracted truncation of character sequences. (__formatter_str::format): Handle _Pres_esc. (__formatter_int::_M_do_parse) [__glibcxx_format_ranges]: Parse '?'. (__formatter_int::_M_format_character_escaped): Define. (formatter<_CharT, _CharT>::format, formatter<char, wchar_t>::format): Handle _Pres_esc. (__formatter_str::set_debug_format, formatter<...>::set_debug_format) Guard with __glibcxx_format_ranges. (__format::_Fixedbuf_sink): Define. * testsuite/23_containers/vector/bool/format.cc: Use __format::_Widen and remove unnecessary <chrono> include. * testsuite/std/format/debug.cc: New test. * testsuite/std/format/debug_nonunicode.cc: New test. * testsuite/std/format/parse_ctx.cc (escaped_strings_supported): Define to true if __glibcxx_format_ranges is defined. * testsuite/std/format/string.cc (escaped_strings_supported): Define to true if __glibcxx_format_ranges is defined. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
12 dayslibstdc++: Adjust value of __cpp_lib_constrained_equality for C++20Jonathan Wakely2-2/+12
The P3379R0 bump to __cpp_lib_constrained_equality relates to changes that only affect std::expected, so there's no reason to define the updated value in C++20. This change restores the previous value (202403) for C++20, and only uses the new value (202411) for C++23 and later. Also remove the TODO comments, because I correctly predicted that the final value would be 202411. libstdc++-v3/ChangeLog: * include/bits/version.def (constrained_equality): Only define as 202411 for C++23 and later, use 202403 for C++20. * include/bits/version.h: Regenerate. * testsuite/20_util/expected/equality_constrained.cc: Remove TODO comment.
13 dayslibstdc++: Fix constraint recursion in basic_const_iterator operator- [PR115046]Patrick Palka1-2/+2
It was proposed in PR112490 to also adjust basic_const_iterator's friend operator-(sent, iter) overload alongside the r15-7757-g4342c50ca84ae5 adjustments to its comparison operators, but we lacked a concrete testcase demonstrating fixable constraint recursion there. It turns out Hewill Kang's PR115046 is such a testcase! So this patch makes the same adjustments to that overload as well, fixing PR115046. The LWG 4218 P/R will need to get adjusted too. PR libstdc++/115046 PR libstdc++/112490 libstdc++-v3/ChangeLog: * include/bits/stl_iterator.h (basic_const_iterator::operator-): Replace non-dependent basic_const_iterator function parameter with a dependent one of type basic_const_iterator<_It2> where _It2 matches _It. * testsuite/std/ranges/adaptors/as_const/1.cc (test04): New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-04-08libstdc++: Fix use-after-free in std::format [PR119671]Jonathan Wakely1-3/+3
When formatting floating-point values to wide strings there's a case where we invalidate a std::wstring buffer while a std::wstring_view is still referring to it. libstdc++-v3/ChangeLog: PR libstdc++/119671 * include/std/format (__formatter_fp::format): Do not invalidate __wstr unless _M_localized returns a valid string. * testsuite/std/format/functions/format.cc: Check wide string formatting of floating-point types with classic locale. Reviewed-by: Tomasz Kaminski <tkaminsk@redhat.com>
2025-04-07libstdc++: Remove stray pragma in new header [PR119642]Jonathan Wakely1-1/+0
libstdc++-v3/ChangeLog: PR libstdc++/119642 * include/bits/formatfwd.h: Remove stray pragma.
2025-04-07libstdc++: Add new headers to <bits/stdc++.h> for PCHJonathan Wakely1-3/+3
This adds the new C23 headers to the PCH, and also removes the __has_include check for <stacktrace> because we provide that unconditionally now. libstdc++-v3/ChangeLog: * include/precompiled/stdc++.h: Include <stdbit.h> and <stdckdint.h>. Include <stacktrace> unconditionally.
2025-04-04libstdc++: Avoid redundant value_type object in flat_set::emplace [PR119620]Patrick Palka1-4/+16
flat_set::emplace (and flat_multiset's) currently unconditionally constructs an object outside of the container, but if we're passed a value_type object we can and should avoid that. PR libstdc++/119620 libstdc++-v3/ChangeLog: * include/std/flat_set (_Flat_set_impl::_M_try_emplace): Split out into two overloads, one taking at least one argument and one taking zero arguments. Turn __k into an auto&& reference bound to __arg if it's already a value_type and otherwise bound to a lifetime-extended value_type temporary. * testsuite/23_containers/flat_multiset/1.cc (test08): New test. * testsuite/23_containers/flat_set/1.cc (test08): New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-04-04libstdc++: Replace use of __mindist in ranges::uninitialized_xxx algos ↵Jonathan Wakely1-32/+14
[PR101587] In r15-8980-gf4b6acfc36fb1f I introduced a new function object for finding the smaller of two distances. In bugzilla Hewill Kang pointed out that we still need to explicitly convert the result back to the right difference type, because the result might be an integer-like class type that doesn't convert to an integral type explicitly. Rather than doing that conversion in the __mindist function object, I think it's simpler to remove it again and just do a comparison and assignment. We always want the result to have a specific type, so we can just check if the value of the other type is smaller, and then convert that to the other type if so. libstdc++-v3/ChangeLog: PR libstdc++/101587 * include/bits/ranges_uninitialized.h (__detail::__mindist): Remove. (ranges::uninitialized_copy, ranges::uninitialized_copy_n) (ranges::uninitialized_move, ranges::uninitialized_move_n): Use comparison and assignment instead of __mindist. * testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc: Check with ranges that use integer-like class type for difference type. * testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc: Likewise. Reviewed-by: Tomasz Kaminski <tkaminsk@redhat.com> Reviewed-by: Hewill Kang <hewillk@gmail.com>
2025-04-04libstdc++: Provide formatter for vector<bool>::reference [PR109162]Tomasz Kamiński7-21/+125
This patch implement formatter for vector<bool>::reference which is part of P2286R8. To indicate partial support we define __glibcxx_format_ranges macro value 1, without defining __cpp_lib_format_ranges. To avoid including the whole content of the <format> header, we introduce new bits/formatfwd.h forward declares classes required for newly introduce formatter. The signatures of the user-facing parse and format method of the provided formatters deviate from the standard by constraining types of params: * _Bit_reference instead T satisfying is-vector-bool-reference<T> * _CharT is constrained __formatter::__char * basic_format_parse_context<_CharT> for parse argument * basic_format_context<_Out, _CharT> for format second argument The standard specifies last three of above as unconstrained types, which leads to formattable<vector<bool>::reference, char32_t> (and any other type as char) being true. PR libstdc++/109162 libstdc++-v3/ChangeLog: * include/Makefile.am: Add bits/formatfwd.h. * include/Makefile.in: Add bits/formatfwd.h. * include/bits/version.def: Define __glibcxx_format_ranges without corresponding std name. * include/bits/version.h: Regenerate. * include/std/format (basic_format_context, __format::__char): Move declartions to bits/formatfwd.h. (formatter<_Tp, _CharT>): Remove default argument for _CharT parameter, now specified in forward declaration in bits/formatfwd.h. * include/std/vector (formatter<_Bit_reference, _CharT>): Define. * include/bits/formatfwd.h: New file with forward declarations for bits of std/format. * testsuite/23_containers/vector/bool/format.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-04-04libstdc++: Check feature test macro for std::string_view in <string>Jonathan Wakely2-34/+35
We can use the __glibcxx_string_view macro to guard the uses of std::string_view in <string>, instead of just checking the value of __cplusplus. It makes no practical difference because __glibcxx_string_view is defined for C++17 and up, but it makes it clear to readers that the lines guarded by that macro are features that depend on string_view. We could be more precise and check __glibcxx_string_view >= 201606L which is the value for the P0254R2 paper that integrated std::string_view with std::string, but I think just checking for the macro being defined is clear enough. We can also check __glibcxx_variant for the _Never_valueless_alt partial specialization. libstdc++-v3/ChangeLog: * include/bits/basic_string.h: Check __glibcxx_string_view and __glibcxx_variant instead of __cplusplus >= 2017L. * include/bits/cow_string.h: Likewise. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-04-04libstdc++: Fix whitespace in std::basic_string::_M_construct<bool>Jonathan Wakely1-2/+2
libstdc++-v3/ChangeLog: * include/bits/basic_string.tcc: Fix whitespace.
2025-04-04libstdc++: allow defining version FTMs without standard-named macrosArsen Arsenović2-3/+7
This is useful to provide libstdc++-internal-only macros. libstdc++-v3/ChangeLog: * include/bits/version.tpl: Implement no_stdname. * include/bits/version.def: Document no_stdname.
2025-04-03libstdc++: Fix handling of field width for wide strings and characters ↵Tomasz Kamiński2-1/+17
[PR119593] This patch corrects handling of UTF-32LE and UTF32-BE in __unicode::__literal_encoding_is_unicode<_CharT>, so they are recognized as unicode and functions produces correct result for wchar_t. Use `__unicode::__field_width` to compute the estimated witdh of the charcter for unicode wide encoding. PR libstdc++/119593 libstdc++-v3/ChangeLog: * include/bits/unicode.h (__unicode::__literal_encoding_is_unicode<_CharT>): Corrected handing for UTF-16 and UTF-32 with "LE" or "BE" suffix. * include/std/format (__formatter_str::_S_character_width): Define. (__formatter_str::_S_character_width): Updated passed char length. * testsuite/std/format/functions/format.cc: Test for wchar_t. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-04-01libstdc++: Fix -Warray-bounds warning in std::vector::resize [PR114945]Jonathan Wakely1-0/+3
This is yet another false positive warning fix. This time the compiler can't prove that when the vector has sufficient excess capacity to append new elements, the pointer to the existing storage is not null. libstdc++-v3/ChangeLog: PR libstdc++/114945 * include/bits/vector.tcc (vector::_M_default_append): Add unreachable condition so the compiler knows that _M_finish is not null. * testsuite/23_containers/vector/capacity/114945.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-31libstdc++: Fix -Warray-bounds warning in std::vector<bool> [PR110498]Jonathan Wakely1-1/+4
In this case, we need to tell the compiler that the current size is not larger than the new size so that all the existing elements can be copied to the new storage. This avoids bogus warnings about overflowing the new storage when the compiler can't tell that that cannot happen. We might as well also hoist the loads of begin() and end() before the allocation too. All callers will have loaded at least begin() before calling _M_reallocate. libstdc++-v3/ChangeLog: PR libstdc++/110498 * include/bits/vector.tcc (vector<bool, A>::_M_reallocate): Hoist loads of begin() and end() before allocation and use them to state an unreachable condition. * testsuite/23_containers/vector/bool/capacity/110498.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-31libstdc++: Fix -Wstringop-overread warning in std::vector<bool> [PR114758]Jonathan Wakely1-2/+3
As in r13-4393-gcca06f0d6d76b0 and a few other commits, we can avoid bogus warnings in std::vector<bool> by hoisting some loads to before the allocation that calls operator new. This means that the compiler has enough info to remove the dead branches that trigger bogus warnings. On trunk this is only needed with -fno-assume-sane-operators-new-delete but it will help on the branches where that option doesn't exist. libstdc++-v3/ChangeLog: PR libstdc++/114758 * include/bits/vector.tcc (vector<bool, A>::_M_fill_insert): Hoist loads of begin() and end() before allocation. * testsuite/23_containers/vector/bool/capacity/114758.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-31Libstdc++: Fix bootstrap failure for cross without tm.tm_zone [PR119550]Jonathan Wakely1-1/+1
In r15-8491-g778c28c70f8573 I added a use of the Autoconf macro AC_STRUCT_TIMEZONE, but that requires a link-test for the global tzname object if tm.tm_zone isn't supported. That link-test isn't allowed for cross-compilation, so bootstrap fails if tm.tm_zone isn't supported. Since libstdc++ only cares about tm.tm_zone and won't use tzname anyway, we don't need the link-test. Replace AC_STRUCT_TIMEZONE with a custom macro that only checks for tm.tm_zone. We can improve on the Autoconf macro by checking it's a suitable type, which isn't actually checked by AC_STRUCT_TIMEZONE. libstdc++-v3/ChangeLog: PR libstdc++/119550 * acinclude.m4 (GLIBCXX_STRUCT_TM_TM_ZONE): New macro. * config.h.in: Regenerate. * configure: Regenerate. * configure.ac: Use GLIBCXX_STRUCT_TM_TM_ZONE. * include/bits/chrono_io.h (__formatter_chrono::_M_c): Check _GLIBCXX_USE_STRUCT_TM_TM_ZONE instead of _GLIBCXX_HAVE_STRUCT_TM_TM_ZONE.
2025-03-31libstdc++: Make operator== for std::tuple convert to bool [PR119545]Jonathan Wakely1-1/+1
The boolean-testable requirements don't require the type to be copyable, so we need to convert to bool before it might need to be copied. libstdc++-v3/ChangeLog: PR libstdc++/119545 * include/std/tuple (operator==): Convert comparison results to bool. * testsuite/20_util/tuple/comparison_operators/119545.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-31libstdc++: Constrain formatters for chrono types [PR119517]Tomasz Kamiński1-230/+218
The formatters for chrono types defined the parse/format methods as accepting unconstrained types, this in combination with lack of constrain on _CharT lead to them falsely satisfying formattable requirements for any type used as character. This patch adjust the fromatter<T, CharT>::parse signature to: constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc); And formatter<T, CharT>::format to: template<typename _Out> typename basic_format_context<_Out, _CharT>::iterator format(const T& __t, basic_format_context<_Out, _CharT>& __fc) const; Furthermore we _CharT with __format::__char (char or wchar_t), PR libstdc++/119517 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (formatter): Add __format::__char for _CharT and adjust parse and format method signatures. * testsuite/std/time/format/pr119517.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-30Optimize string constructorJan Hubicka2-2/+33
this patch improves code generation on string constructors. We currently have _M_construct which takes as a parameter two iterators (begin/end pointers to other string) and produces new string. This patch adds special case of constructor where instead of begining/end pointers we readily know the string size and also special case when we know that source is 0 terminated. This happens commonly when producing stirng copies. Moreover currently ipa-prop is not able to propagate information that beg-end is known constant (copied string size) which makes it impossible for inliner to spot the common case where string size is known to be shorter than 15 bytes and fits in local buffer. Finally I made new constructor inline. Because it is explicitely instantiated without C++20 constexpr we do not produce implicit instantiation (as required by standard) which prevents inlining, ipa-modref and any other IPA analysis to happen. I think we need to make many of the other functions inline, since optimization accross string manipulation is quite important. There is PR94960 to track this issue. Bootstrapped/regtested x86_64-linux, OK? libstdc++-v3/ChangeLog: PR tree-optimization/103827 PR tree-optimization/80331 PR tree-optimization/87502 * config/abi/pre/gnu.ver: Add version for _M_construct<bool> * include/bits/basic_string.h: (basic_string::_M_construct<bool>): Declare. (basic_string constructors): Use it. * include/bits/basic_string.tcc: (basic_string::_M_construct<bool>): New template. * src/c++11/string-inst.cc: Instantated S::_M_construct<bool>. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/pr80331.C: New test. * g++.dg/tree-ssa/pr87502.C: New test.
2025-03-27libstdc++: Replace use of std::min in ranges::uninitialized_xxx algos [PR101587]Jonathan Wakely1-6/+26
Because ranges can have any signed integer-like type as difference_type, it's not valid to use std::min(diff1, diff2). Instead of calling std::min with an explicit template argument, this adds a new __mindist helper that determines the common type and uses that with std::min. libstdc++-v3/ChangeLog: PR libstdc++/101587 * include/bits/ranges_uninitialized.h (__detail::__mindist): New function object. (ranges::uninitialized_copy, ranges::uninitialized_copy_n) (ranges::uninitialized_move, ranges::uninitialized_move_n): Use __mindist instead of std::min. * testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc: Check ranges with difference difference types. * testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc: Likewise.
2025-03-27libstdc++: Use const_cast to workaround tm_zone being non-constJonathan Wakely1-3/+4
Iain reported that he's seeing this on Darwin: include/bits/chrono_io.h:914: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] This is because the BSD definition ot tm::tm_zone is a char* (and has been since 1987) rather than const char* as in Glibc and POSIX.1-2024. We can fix it by using const_cast<char*> when setting the tm_zone member. This should be safe because libc doesn't actually write anything to tm_zone; it's only non-const because the BSD definition predates the addition of the const keyword to C. For targets where it's a const char* the cast won't matter because it will be converted back to const char* on assignment anyway. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono::_M_c): Use const_cast when setting tm.tm_zone. Reviewed-by: Iain Sandoe <iain@sandoe.co.uk>
2025-03-27libstdc++: re-bump the feature-test macro for P2562R1 [PR119488]Giuseppe D'Angelo2-3/+3
Now that the algorithms have been merged we can advertise full support for P2562R1. This effectively reverts r15-8933-ga264c270fde292. libstdc++-v3/ChangeLog: PR libstdc++/119488 * include/bits/version.def (constexpr_algorithms): Bump the feature-testing macro. * include/bits/version.h: Regenerate. * testsuite/25_algorithms/cpp_lib_constexpr.cc: Test the bumped value for the feature-testing macro.
2025-03-27libstdc++: add constexpr stable_partitionGiuseppe D'Angelo3-2/+22
This completes the implementation of P2562R1 for C++26. Unlike the other constexpr algorithms of the same family, stable_partition does not have a constexpr-friendly version "ready to use" during constant evaluation. In fact, it is not even available on freestanding, because it always allocates a temporary memory buffer. This commit implements the simplest possible strategy: during constant evaluation allocate a buffer of length 1 on the stack, and use that as a working area. libstdc++-v3/ChangeLog: * include/bits/algorithmfwd.h (stable_partition): Mark it as constexpr for C++26. * include/bits/ranges_algo.h (__stable_partition_fn): Likewise. * include/bits/stl_algo.h (stable_partition): Mark it as constexpr for C++26; during constant evaluation use a new codepath where a temporary buffer of 1 element is used. * testsuite/25_algorithms/headers/algorithm/synopsis.cc (stable_partition): Add constexpr. * testsuite/25_algorithms/stable_partition/constexpr.cc: New test.
2025-03-27libstdc++: add constexpr inplace_mergeGiuseppe D'Angelo3-0/+13
This commit adds support for constexpr inplace_merge, added by P2562R1 for C++26. The implementation strategy is the same as for constexpr stable_sort: use if consteval to detect if we're in constant evaluation, and dispatch to a suitable path (same one as freestanding). libstdc++-v3/ChangeLog: * include/bits/algorithmfwd.h (inplace_merge): Mark it as constexpr for C++26. * include/bits/ranges_algo.h (__inplace_merge_fn): Likewise. * include/bits/stl_algo.h (inplace_merge): Mark it as constexpr; during constant evaluation, dispatch to the non-allocating codepath. * testsuite/25_algorithms/headers/algorithm/synopsis.cc (inplace_merge): Add constexpr. * testsuite/25_algorithms/inplace_merge/constexpr.cc: New test.
2025-03-27libstdc++: Fix std::ranges::iter_move for function references [PR119469]Jonathan Wakely1-2/+9
The result of std::move (or a cast to an rvalue reference) on a function reference is always an lvalue. Because std::ranges::iter_move was using the type std::remove_reference_t<X>&& as the result of std::move, it was giving the wrong type for function references. Use a decltype-specifier with declval<remove_reference_t<X>>() instead of just using the remove_reference_t<X>&& type directly. This gives the right result, while still avoiding the cost of doing overload resolution for std::move. libstdc++-v3/ChangeLog: PR libstdc++/119469 * include/bits/iterator_concepts.h (_IterMove::__result): Use decltype-specifier instead of an explicit type. * testsuite/24_iterators/customization_points/iter_move.cc: Check results for function references. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-26libstdc++: do not advertise full P2562R1 supportGiuseppe D'Angelo2-3/+3
P2562R1 ("constexpr Stable Sorting") adds constexpr to stable_sort, stable_partition and inplace_merge. However only the first is already implemented in libstdc++, so we shouldn't bump the feature-testing macro to the bumped C++26 value. This commit sets it to one less than the final value. Amends r15-7708-gff43f9853d3b10. libstdc++-v3/ChangeLog: * include/bits/version.def (constexpr_algorithms): Change the value of the feature-testing macro. * include/bits/version.h: Regenerate. * testsuite/25_algorithms/cpp_lib_constexpr.cc: Amend the check of the feature-testing macro.
2025-03-26libstdc++: Check presence of iterator_category for flat_sets insert_range ↵Tomasz Kamiński1-1/+1
[PR119415] As pointed out by Hewill Kang (reporter) in the issue, checking if iterator of the incoming range satisfies __cpp17_input_iterator, may still lead to hard errors inside of insert_range for iterators that satisfies that concept, but specialize iterator_traits without iterator_category typedef (std::common_iterator specialize iterator_traits without iterator_category in some cases). To address that we instead check if the iterator_traits<It>::iterator_category is present and denote at least input_iterator_tag, using existing __has_input_iter_cat. PR libstdc++/119415 libstdc++-v3/ChangeLog: * include/std/flat_set (_Flat_set_impl:insert_range): Replace __detail::__cpp17_input_iterator with __has_input_iter_cat. * testsuite/23_containers/flat_multiset/1.cc: New tests * testsuite/23_containers/flat_set/1.cc: New tests Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-26libstdc++: Add P1206R7 range operations to std::deque [PR111055]Tomasz Kamiński3-31/+360
This is another piece of P1206R7, adding from_range constructor, append_range, prepend_range, insert_range, and assign_range members to std::deque. For append_front of input non-sized range, we are emplacing element at the front and then reverse inserted elements. This does not existing elements, and properly handle aliasing ranges. For insert_range, the handling of insertion in the middle of input-only ranges that are sized could be optimized, we still insert nodes one-by-one in such case. For forward and stronger ranges, we reduce them to common_range case, by computing the iterator when computing the distance. This is slightly suboptimal, as it require range to be iterated for non-common forward ranges that are sized, but reduces number of instantiations. This patch extract _M_range_prepend, _M_range_append helper functions that accepts (iterator, sentinel) pair. This all used in all standard modes. PR libstdc++/111055 libstdc++-v3/ChangeLog: * include/bits/deque.tcc (deque::prepend_range, deque::append_range) (deque::insert_range, __advance_dist): Define. (deque::_M_range_prepend, deque::_M_range_append): Extract from _M_range_insert_aux for _ForwardIterator(s). * include/bits/stl_deque.h (deque::assign_range): Define. (deque::prepend_range, deque::append_range, deque::insert_range): Declare. (deque(from_range_t, _Rg&&, const allocator_type&)): Define constructor and deduction guide. * include/debug/deque (deque::prepend_range, deque::append_range) (deque::assign_range): Define. (deque(from_range_t, _Rg&&, const allocator_type&)): Define constructor and deduction guide. * testsuite/23_containers/deque/cons/from_range.cc: New test. * testsuite/23_containers/deque/modifiers/append_range.cc: New test. * testsuite/23_containers/deque/modifiers/assign/assign_range.cc: New test. * testsuite/23_containers/deque/modifiers/prepend_range.cc: New test. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-25libstdc++: Allow std::ranges::to to create unionsJonathan Wakely1-2/+2
LWG 4229 points out that the std::ranges::to wording refers to class types, but I added an assertion using std::is_class_v which only allows non-union class types. LWG consensus is that unions should be allowed, so this additionally uses std::is_union_v. libstdc++-v3/ChangeLog: * include/std/ranges (ranges::to): Allow unions as well as non-union class types. * testsuite/std/ranges/conv/lwg4229.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-25libstdc++: Optimize std::vector construction from input iterators [PR108487]Jonathan Wakely1-16/+32
LWG 3291 make std::ranges::iota_view's iterator have input_iterator_tag as its iterator_category, even though it satisfies the C++20 std::forward_iterator concept. This means that the traditional std::vector::vector(InputIterator, InputIterator) constructor treats iota_view iterators as input iterators, because it only understands the C++17 iterator requirements, not the C++20 iterator concepts. This results in a loop that calls emplace_back for each individual element of the iota_view, requiring the vector to reallocate repeatedly as the values are inserted. This makes it unnecessarily slow to construct a vector from an iota_view. This change adds a new _M_range_initialize_n function for initializing a vector from a range (which doesn't have to be common) and a size. This new function can be used by vector(InputIterator, InputIterator) and vector(from_range_t, R&&) when std::ranges::distance can be used to get the size. It can also be used by the _M_range_initialize overload that gets the size for a Cpp17ForwardIterator pair using std::distance, and by the vector(initializer_list) constructor. With this new function constructing a std::vector from iota_view does a single allocation of the correct size and so doesn't need to reallocate in a loop. Previously the _M_range_initialize overload for Cpp17ForwardIterator was using a local RAII _Guard_alloc object to own the storage, but that was redundant. The _Vector_base can own the storage right away, and its destructor will deallocate it if _M_range_initialize exits via an exception. libstdc++-v3/ChangeLog: PR libstdc++/108487 * include/bits/stl_vector.h (vector(initializer_list)): Call _M_range_initialize_n instead of _M_range_initialize. (vector(InputIterator, InputIterator)): Use _M_range_initialize_n for C++20 sized sentinels and forward iterators. (vector(from_range_t, R&&)): Use _M_range_initialize_n for sized ranges and forward ranges. (vector::_M_range_initialize(FwIt, FwIt, forward_iterator_tag)): Likewise. (vector::_M_range_initialize_n): New function. * testsuite/23_containers/vector/cons/108487.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-25libstdc++: Adjust how __gnu_debug::vector detects invalidationJonathan Wakely1-8/+6
The new C++23 member functions assign_range, insert_range and append_range were checking whether the begin() iterator changed after calling the base class member. That works, but is technically undefined when the original iterator has been invalidated by a change in capacity. We can just check the capacity directly, because reallocation only occurs if a change in capacity is required. N.B. we can't use data() either because std::vector<bool> doesn't have it. libstdc++-v3/ChangeLog: * include/debug/vector (vector::assign_range): Use change in capacity to detect reallocation. (vector::insert_range, vector::append_range): Likewise. Remove unused variables. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-25libstdc++: Fix std::vector::append_range for overlapping rangesJonathan Wakely3-20/+169
Unlike insert_range and assign_range, the append_range function does not have a precondition that the range doesn't overlap *this. That means we need to avoid relocating the existing elements until after copying from the range. This means I need to revert r15-8488-g3e1d760bf49d0e which made the from_range_t constructor use append_range, because the constructor can avoid the additional complexity needed by append_range. When relocating the existing elements in append_range we can use std::__relocate_a to do it more efficiently, if that's valid. std::vector<bool>::append_range needs similar treatment, although it's a bit simpler as we know that the elements are trivially copyable and so we don't need to worry about them throwing. assign_range doesn't allow overlapping ranges, so can be rewritten to be more efficient than calling append_range for the forward or sized range case. libstdc++-v3/ChangeLog: * include/bits/stl_bvector.h (vector::assign_range): More efficient implementation for forward/sized ranges. (vector::append_range): Handle potentially overlapping range. * include/bits/stl_vector.h (vector(from_range_t, R&&, Alloc)): Do not use append_range for non-sized input range case. (vector::append_range): Handle potentially overlapping range. * include/bits/vector.tcc (vector::insert_range): Forward range instead of moving it. * testsuite/23_containers/vector/bool/modifiers/insert/append_range.cc: Test overlapping ranges. * testsuite/23_containers/vector/modifiers/append_range.cc: Likewise. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-25libstdc++: Cast -1 to size_t in <format> [PR119429]Jonathan Wakely1-1/+1
This avoids a runtime error from Clang's annoying -fsanitize=integer (even though it's not undefined and behaves correctly). libstdc++-v3/ChangeLog: PR libstdc++/119429 * include/std/format (__format::_Scanner::_Scanner): Cast default argument to size_t.
2025-03-25libstdc++: Fix handling of common cpp20-only ranges for flat sets [PR119415]Tomasz Kamiński1-1/+2
These patch add check to verify if common range iterators satisfies Cpp17LegacyIterator requirements (__detail::__cpp17_input_iterator), before invoking overloads of insert that accepts two iterators. As such overloads existed before c++20 iterators were introduced, they commonly assume existence of iterator_traits<..>::iterator_category, and passing a cpp20-only iterators, leads to hard errors. In case if user-defined container wants to support more efficient insertion in such cases, it should provided insert_range method, as in the case of standard containers. PR libstdc++/119415 libstdc++-v3/ChangeLog: * include/std/flat_set (_Flat_set_impl:insert_range): Add __detail::__cpp17_input_iterator check. * testsuite/23_containers/flat_multiset/1.cc: New tests * testsuite/23_containers/flat_set/1.cc: New tests Reviewed-by: Patrick Palka <ppalka@redhat.com>, Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-24libstdc++: Ensure that std::vector<bool> allocator has bool value_typeJonathan Wakely1-0/+4
This is the subject of LWG 4228 which notes that libstdc++ doesn't enforce this requirement. That's just a bug because I forgot to add it to vector<bool> when adding it elsewhere. For consistency with the other containers we should not allow incorrect allocator types for strict -std=c++NN modes, but it is very late to make that change for GCC 15 so this only enables the assertion for C++20 (where it's required). For GCC 16 we can enable it for strict modes too. libstdc++-v3/ChangeLog: * include/bits/stl_bvector.h (vector<bool, A>): Enforce the C++20 requirement that the allocator's value_type matches the container. * testsuite/23_containers/vector/bool/cons/from_range.cc: Fix incorrect allocator type. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-21libstdc++: Fix localized %c formatting for non-UTC times [PR117214]Jonathan Wakely1-1/+31
The previous commit fixed most cases of %c formatting, but it incorrectly prints times using the system's local time zone. This only matters if the locale's %c format includes %Z, but some do. To print a correct value for %Z we can set tm.tm_zone to either "UTC" or the abbreviation passed to the formatter in the local-time-format-t structure. For local times with no info and for systems that don't support tm_zone (which is new in POSIX.1-2024) we just set tm_isdst = -1 so that no zone name is printed. In theory, a locale's %c format could use %z which should print a +hhmm offset from UTC. I'm unsure how to control that though. The new tm_gmtoff field in combination with tm_isdst != -1 seems like it should work, but using that without also setting tm_zone causes the system zone to be used for %Z again. That means local_time_format(lt, nullptr, &off) might work for a locale that uses %z but prints the wrong thing for %Z. This commit doesn't set tm_gmtoff even if _M_offset_sec is provided for a local-time-format-t value. libstdc++-v3/ChangeLog: PR libstdc++/117214 * configure.ac: Use AC_STRUCT_TIMEZONE. * config.h.in: Regenerate. * configure: Regenerate. * include/bits/chrono_io.h (__formatter_chrono::_M_c): Set tm_isdst and tm_zone. * testsuite/std/time/format/pr117214.cc: Check %c formatting of zoned_time and local time.
2025-03-21libstdc++: Fix localized D_T_FMT %c formatting for <chrono> [PR117214]XU Kailiang1-16/+19
Formatting a time point with %c was implemented by calling std::vprint_to with format string constructed from locale's D_T_FMT string, but in some locales this string contains strftime specifiers which are not valid for chrono-specs, e.g. %l. So just use _M_locale_fmt to avoid this problem. libstdc++-v3/ChangeLog: PR libstdc++/117214 * include/bits/chrono_io.h (__formatter_chrono::_M_c): Use _M_locale_fmt to format %c time point. * testsuite/std/time/format/pr117214.cc: New test. Signed-off-by: XU Kailiang <xu2k3l4@outlook.com> Co-authored-by: Jonathan Wakely <jwakely@redhat.com>