Commit graph

6480 commits

Author SHA1 Message Date
François Dumont
9662c9526f
libstdc++: Add _GLIBCXX_DEBUG checks on unordered container local_iterator
Complete tests on  _GLIBCXX_DEBUG checks in include/debug/safe_local_iterator.h.

Fix several tests not testing the container corresponding to their location in the
testsuite directory.

libstdc++-v3/ChangeLog:

	* testsuite/util/debug/unordered_checks.h (fill_container): New helper method.
	(use_erased_local_iterator, invalid_local_iterator_pre_increment)
	(invalid_local_iterator_post_increment, invalid_local_iterator_compare)
	(invalid_local_iterator_range): Use latter.
	(fill_and_get_local_iterator): New, use fill_container.
	(use_invalid_local_iterator): Use latter.
	(invalid_local_iterator_arrow_operator): New test function.
	(invalid_local_iterator_copy_instantiation): New test function.
	(invalid_local_iterator_move_instantiation): New test function.
	(invalid_local_iterator_copy_assignment): New test function.
	(invalid_local_iterator_move_assignment): New test function.
	(invalid_local_iterator_const_conversion): New test function.
	* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_arrow_operator_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_const_conversion_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_copy_assignment_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_copy_construction_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_move_assignment_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_move_construction_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_map/debug/max_load_factor_neg.cc: Test unordered_map.
	* testsuite/23_containers/unordered_multimap/debug/begin2_neg.cc: Test unordered_multimap.
	* testsuite/23_containers/unordered_multimap/debug/bucket_size_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multimap/debug/cbegin_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multimap/debug/cend_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multimap/debug/end1_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multimap/debug/end2_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_arrow_operator_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_const_conversion_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_copy_assignment_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_copy_construction_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_move_assignment_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_move_construction_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_multimap/debug/max_load_factor_neg.cc:
	Test unordered_multimap.
	* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_arrow_operator_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_const_conversion_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_copy_assignment_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_copy_construction_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_move_assignment_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_move_construction_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_arrow_operator_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_const_conversion_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_copy_assignment_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_copy_construction_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_move_assignment_neg.cc:
	New test case.
	* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_move_construction_neg.cc:
	New test case.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-04-18 21:26:46 +02:00
Jason Merrill
20e31f507a c++: improve pack index diagnostics
While looking at pack-indexing16.C I thought it would be helpful to print
the problematic type/value.

gcc/cp/ChangeLog:

	* semantics.cc (finish_type_pack_element): Add more info
	to diagnostics.

libstdc++-v3/ChangeLog:

	* testsuite/20_util/tuple/element_access/get_neg.cc: Adjust
	diagnostic.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp26/pack-indexing2.C: Adjust diagnostics.
	* g++.dg/ext/type_pack_element2.C: Likewise.
	* g++.dg/ext/type_pack_element4.C: Likewise.
2025-04-17 13:19:42 -04:00
Jonathan Wakely
0be3dff1aa
libstdc++: Do not use 'not' alternative token in <format>
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.
2025-04-17 10:11:49 +01:00
Tomasz Kamiński
aef8797522 libstdc++: Fix constification in range_formatter::format [PR109162]
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>
2025-04-16 14:32:57 +02:00
Tomasz Kamiński
473dde5252 libstdc++: Implement formatters for pair and tuple [PR109162]
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>
2025-04-16 12:20:56 +02:00
Jonathan Wakely
df59bf20d8
libstdc++: Do not declare namespace ranges in <numeric> unconditionally
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.
2025-04-15 17:34:34 +01:00
Tomasz Kamiński
f62e5d720d libstdc++: Implement formatter for ranges and range_formatter [PR109162]
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>
2025-04-15 17:09:59 +02:00
Jonathan Wakely
05d3aebe24
libstdc++: Fix std::string construction from volatile char* [PR119748]
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>
2025-04-15 09:24:58 +01:00
Jonathan Wakely
8a208899e9
libstdc++: Enable __gnu_test::test_container constructor for C++98
The only reason this constructor wasn't defined for C++98 is that it
uses constructor delegation, but that isn't necessary.

libstdc++-v3/ChangeLog:

	* testsuite/util/testsuite_iterators.h (test_container): Define
	array constructor for C++98 as well.
2025-04-15 09:24:44 +01:00
Tomasz Kamiński
c2f1dda34d libstdc++: Use UTF-32BE as wide encoding for big-endian machines [PR119725]
This changes the `dg-options` line so UTF-32 with byte order native to the
machine is used as wide encoding.

We still do not handle mismatch in the byte order of the Unicode encodings
(UTF32-BE on little-endian machines). This would require larger changes,
as for example `unicode-data.h` tables are encoded with native byte order.

	PR libstdc++/119725

libstdc++-v3/ChangeLog:

	* testsuite/std/format/debug.cc: Updated dg-options.
	* testsuite/std/format/debug_nonunicode.cc: Updated dg-options.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-04-14 13:19:15 +02:00
Tomasz Kamiński
ae54d8cb51 libstdc++: Define __cpp_lib_containers_ranges in appropriate headers [PR111055]
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>
2025-04-11 13:56:03 +02:00
Jonathan Wakely
882d3b319d
libstdc++: Add P1206R7 from_range members to std::string [PR111055]
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>
2025-04-11 11:18:30 +01:00
Tomasz Kamiński
3b33d792cf libstdc++: Implement debug format for strings and characters formatters [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>
2025-04-11 08:43:50 +02:00
Jonathan Wakely
bb323ec8fd
libstdc++: Adjust value of __cpp_lib_constrained_equality for C++20
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.
2025-04-10 17:10:33 +01:00
Patrick Palka
d69f73c033 libstdc++: Fix constraint recursion in basic_const_iterator operator- [PR115046]
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-09 17:48:05 -04:00
Jonathan Wakely
e33b62eed7
libstdc++: Fix use-after-free in std::format [PR119671]
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-08 08:43:22 +01:00
Patrick Palka
2a36d22ab5 libstdc++: Avoid redundant value_type object in flat_set::emplace [PR119620]
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-04 15:05:09 -04:00
Jonathan Wakely
03ac8886e5
libstdc++: Replace use of __mindist in ranges::uninitialized_xxx algos [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-04 12:56:59 +01:00
Tomasz Kamiński
84d668b0ca libstdc++: Provide formatter for vector<bool>::reference [PR109162]
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-04 13:03:34 +02:00
Tomasz Kamiński
81c990aa84 libstdc++: Restored accidentally removed test case.
It was removed by accident r15-9178-g5c7f6272f43f42.

libstdc++-v3/ChangeLog:

	* testsuite/std/format/functions/format.cc: Restored line.
2025-04-03 14:58:57 +02:00
Tomasz Kamiński
5c7f6272f4 libstdc++: Fix handling of field width for wide strings and characters [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-03 13:46:20 +02:00
Iain Sandoe
efe72d9f05 libstdc++, testsuite, Darwin: Prune a new linker warning present form XCode 16.
Darwin's linker now warns when duplicate rpaths are presented - which
happens when we emit duplicate '-B' paths.  In principle, we should avoid
this in the test-suite, however at present we tend to have duplicates
because different parts of the machinery add them.  At some point, it might
be nice to have an "add_option_if_missing" and apply that across the whole
of the test infra. However this is not something for late in stage 4.  So
the solution here is to prune the warning - the effect of the duplicate in
the libstdc++ testsuite is not important; it will make the exes very slightly
larger but it won't alter the paths that are presented for loading the
runtimes.

libstdc++-v3/ChangeLog:

	* testsuite/lib/prune.exp: Prune ld warning about duplicatei
	rpaths.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
2025-04-02 15:04:17 +01:00
Jonathan Wakely
844eed3364
libstdc++: Fix -Warray-bounds warning in std::vector::resize [PR114945]
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-04-01 19:38:33 +01:00
Jonathan Wakely
aa3aaf2bfb
libstdc++: Fix -Warray-bounds warning in std::vector<bool> [PR110498]
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-31 22:54:08 +01:00
Jonathan Wakely
1f6c19f307
libstdc++: Fix -Wstringop-overread warning in std::vector<bool> [PR114758]
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-31 22:54:08 +01:00
Jonathan Wakely
b9adf3a4c8
libstdc++: Make operator== for std::tuple convert to bool [PR119545]
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-31 17:12:26 +01:00
Tomasz Kamiński
5f2078ca11 libstdc++: Constrain formatters for chrono types [PR119517]
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-31 10:56:54 +02:00
Jonathan Wakely
878812b6f6
libstdc++: Add testcase for bogus -Wstringop-overflow in std::vector [PR117983]
This was fixed on trunk by r15-4473-g3abe751ea86e34, just add the
testcase.

libstdc++-v3/ChangeLog:

	PR libstdc++/117983
	* testsuite/23_containers/vector/modifiers/insert/117983.cc: New
	test.
2025-03-28 21:58:11 +00:00
David Malcolm
1ee9caf2f8 libstdc++-v3 testsuite: fix malformed dg-require-static-libstdcxx directives
I believe these don't get detected by DejaGnu's regexp.

Found by dg-lint.

libstdc++-v3/ChangeLog:
	* testsuite/17_intro/shared_with_static_deps.cc: Fix malformed
	dg-require-static-libstdcxx directive.
	* testsuite/17_intro/static.cc: Likewise.
	* testsuite/18_support/type_info/110572.cc: Likewise.
	* testsuite/20_util/to_chars/4.cc: Likewise.
	* testsuite/std/time/tzdb_list/pr118811.cc: Likewise.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2025-03-27 20:00:34 -04:00
Jonathan Wakely
f4b6acfc36
libstdc++: Replace use of std::min in ranges::uninitialized_xxx algos [PR101587]
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-27 15:26:32 +00:00
Sam James
7d3bbdcc9d
testsuite: fix dg-* typos
I have a handful more of these left but those introduce FAILs, while
these all introduce new PASSes.

libstdc++-v3/ChangeLog:

	* testsuite/std/format/string_neg.cc: Add missing brace for dg-error.

gcc/testsuite/ChangeLog:

	* gcc.dg/analyzer/fd-datagram-socket.c: Fix 'dg-message' spelling.
	* gcc.dg/analyzer/out-of-bounds-zero.c: Fix whitespace in 'dg-additional-options'.
	* gcc.dg/analyzer/strchr-1.c: Fix 'dg-message' whitespace.
	* gnat.dg/sso/q11.adb: Fix 'dg-output' whitespace.
2025-03-27 13:29:48 +00:00
Giuseppe D'Angelo
6acfb68dc0 libstdc++: re-bump the feature-test macro for P2562R1 [PR119488]
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-27 13:47:30 +01:00
Giuseppe D'Angelo
aba3018af8 libstdc++: add constexpr stable_partition
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-27 13:47:30 +01:00
Giuseppe D'Angelo
698ef4b29d libstdc++: add constexpr inplace_merge
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-27 13:47:30 +01:00
Jonathan Wakely
3e52eb28c5
libstdc++: Fix std::ranges::iter_move for function references [PR119469]
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-27 11:14:52 +00:00
Giuseppe D'Angelo
a264c270fd libstdc++: do not advertise full P2562R1 support
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-26 18:42:04 +01:00
Tomasz Kamiński
272d26d519 libstdc++: Check presence of iterator_category for flat_sets insert_range [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-26 11:53:26 +01:00
Tomasz Kamiński
157c14a387 libstdc++: Add P1206R7 range operations to std::deque [PR111055]
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-26 10:37:02 +01:00
Jonathan Wakely
479a0a8644
libstdc++: Allow std::ranges::to to create unions
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-25 17:44:25 +00:00
Jonathan Wakely
e200f53a55
libstdc++: Optimize std::vector construction from input iterators [PR108487]
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-25 17:38:39 +00:00
Jonathan Wakely
d4f7d18b3e
libstdc++: Fix std::vector::append_range for overlapping ranges
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-25 17:38:39 +00:00
Jonathan Wakely
466da4baba
libstdc++: Add testcase for std::filesystem::copy [PR118699]
This was fixed last year by r15-2409-g017e3f89b081e4 (and backports), so
just add the testcase.

libstdc++-v3/ChangeLog:

	PR libstdc++/118699
	* testsuite/27_io/filesystem/operations/copy.cc: Check copying a
	file to a directory.
2025-03-25 12:33:38 +00:00
Tomasz Kamiński
4d1b196956 libstdc++: Fix handling of common cpp20-only ranges for flat sets [PR119415]
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-25 10:24:58 +01:00
Jonathan Wakely
f7c0b0fc4f
libstdc++: Add testcases for resolved bug [PR101527]
These tests were fixed by a front-end change r13-465-g4df735e01e3199 so
this just adds them to the testsuite to be sure we don't regress.

libstdc++-v3/ChangeLog:

	PR libstdc++/101527
	* testsuite/24_iterators/common_iterator/101527.cc: New test.
	* testsuite/24_iterators/counted_iterator/101527.cc: New test.
2025-03-24 21:38:07 +00:00
Jonathan Wakely
75df481fcc
libstdc++: Ensure that std::vector<bool> allocator has bool value_type
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-24 11:34:49 +00:00
Jonathan Wakely
778c28c70f
libstdc++: Fix localized %c formatting for non-UTC times [PR117214]
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-21 10:28:16 +00:00
XU Kailiang
c24a1d58bc
libstdc++: Fix localized D_T_FMT %c formatting for <chrono> [PR117214]
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>
2025-03-21 10:28:15 +00:00
Jonathan Wakely
3c7f2fd8c4
libstdc++: Use formatting locale for std::time_put formats
When using std::time_put to format a chrono value, we should imbue the
formatting locale into the stream. This ensures that when
std::time_put::do_put uses a ctype or __timepunct facet from the locale,
it gets the correct facets.

libstdc++-v3/ChangeLog:

	* include/bits/chrono_io.h (__formatter_chrono::_M_locale_fmt):
	Imbue locale into ostringstream.
	* testsuite/std/time/format/localized.cc: Check that correct
	locale is used for call to time_put::put.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-03-21 10:28:11 +00:00
Jakub Jelinek
d458020e19 libstdc++: Fix comment typo
Another IEE typo.

2025-03-20  Jakub Jelinek  <jakub@redhat.com>

	* testsuite/18_support/numeric_limits/traps.cc (main): Fix comment
	typo.
2025-03-20 10:36:29 +01:00
François Dumont
e3b3290f73
libstdc++: Activate a __cpp_lib_ranges_to_container dependent test
Now that std::set has support for __cpp_lib_ranges_to_container we can
activate a test using it in a fancy allocator pointer context.

libstdc++-v3/ChangeLog

	* testsuite/23_containers/set/requirements/explicit_instantiation/alloc_ptr.cc:
	Activate the template member tests involving __cpp_lib_ranges_to_container
	support.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
2025-03-19 22:05:05 +01:00