Commit graph

227 commits

Author SHA1 Message Date
Jonathan Wakely
6cf214b4fc libstdc++: Add std::formatter specializations for extended float types
This makes it possible to format _Float32, _Float64 etc. in C++20 mode.
Previously it was only possible to format them in C++23 when the
<stdfloat> typedefs and the std::to_chars overloads were defined.

Instead of relying on std::to_chars for those types, we can just reuse
the formatters for float, double and long double. This also avoids
template bloat by reusing the same specializations instead of
instantiating __formatter_fp for every different type.

libstdc++-v3/ChangeLog:

	* include/std/format (formatter): Add partial specializations
	for extended floating-point types.
	* testsuite/std/format/functions/format.cc: Move test_float128()
	to ...
	* testsuite/std/format/formatter/ext_float.cc: New test.
2023-08-17 20:24:18 +01:00
Jonathan Wakely
023a62b77f libstdc++: Rework std::format support for wchar_t
This changes how std::format creates wide strings, by replacing uses of
std::ctype<wchar_t>::widen with the recently-added __to_wstring_numeric
helper function. This removes the dependency on the locale, which should
only be used for locale-specific formats such as {:Ld}.

Also disable all the wide string formatting support if the
_GLIBCXX_USE_WCHAR_T macro is not defined. This is consistent with other
wchar_t support being disabled if the library is built without that
macro defined.

libstdc++-v3/ChangeLog:

	* include/std/format [_GLIBCXX_USE_WCHAR_T]: Guard all wide
	string formatters with this macro.
	(__formatter_int::_M_format_int, __formatter_fp::format)
	(formatter<const void*, C>::format): Use __to_wstring_numeric
	instead of std::ctype::widen.
	(__formatter_fp::_M_localize): Use hardcoded wchar_t values
	instead of std::ctype::widen.
	* testsuite/std/format/functions/format.cc: Add more checks for
	wstring formatting of arithmetic types.
2023-08-17 20:24:17 +01:00
Patrick Palka
bad357dd1b libstdc++: Implement P2770R0 changes to join_view / join_with_view
This C++23 paper fixes an issue in these views when adapting a certain
kind of non-forward range, and we treat it as a DR against C++20.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>

libstdc++-v3/ChangeLog:

	* include/bits/regex.h (regex_iterator::iterator_concept):
	Define for C++20 as per P2770R0.
	(regex_token_iterator::iterator_concept): Likewise.
	* include/std/ranges (__detail::__as_lvalue): Define.
	(join_view::_Iterator): Befriend join_view.
	(join_view::_Iterator::_M_satisfy): Use _M_get_outer
	instead of _M_outer.
	(join_view::_Iterator::_M_get_outer): Define.
	(join_view::_Iterator::_Iterator): Split constructor taking
	_Parent argument into two as per P2770R0.  Remove constraint on
	default constructor.
	(join_view::_Iterator::_M_outer): Make this data member present
	only when the underlying range is forward.
	(join_view::_Iterator::operator++): Use _M_get_outer instead of
	_M_outer.
	(join_view::_Iterator::operator--): Use __as_lvalue helper.
	(join_view::_Iterator::operator==): Adjust constraints as per
	P2770R0.
	(join_view::_Sentinel::__equal): Use _M_get_outer instead of
	_M_outer.
	(join_view::_M_outer): New data member when the underlying range
	is non-forward.
	(join_view::begin): Adjust definition as per P2770R0.
	(join_view::end): Likewise.
	(join_with_view::_M_outer_it): New data member when the
	underlying range is non-forward.
	(join_with_view::begin): Adjust definition as per P2770R0.
	(join_with_view::end): Likewise.
	(join_with_view::_Iterator::_M_outer_it): Make this data member
	present only when the underlying range is forward.
	(join_with_view::_Iterator::_M_get_outer): Define.
	(join_with_view::_Iterator::_Iterator): Split constructor
	taking _Parent argument into two as per P2770R0.  Remove
	constraint on default constructor.
	(join_with_view::_Iterator::_M_update_inner): Adjust definition
	as per P2770R0.
	(join_with_view::_Iterator::_M_get_inner): Likewise.
	(join_with_view::_Iterator::_M_satisfy): Adjust calls to
	_M_get_inner.  Use _M_get_outer instead of _M_outer_it.
	(join_with_view::_Iterator::operator==): Adjust constraints
	as per P2770R0.
	(join_with_view::_Sentinel::operator==): Use _M_get_outer
	instead of _M_outer_it.
	* testsuite/std/ranges/adaptors/p2770r0.cc: New test.
2023-08-17 12:56:32 -04:00
Patrick Palka
4a6f3676e7 libstdc++: Convert _RangeAdaptorClosure into a CRTP base [PR108827]
Using the CRTP idiom for this base class avoids bloating the size of a
pipeline when adding distinct empty range adaptor closure objects to it,
as detailed in section 4.1 of P2387R3.

But it means we can no longer define its operator| overloads as hidden
friends, since it'd mean each instantiation of _RangeAdaptorClosure
introduces its own distinct set of hidden friends.  So e.g. for the
outer | in

  x | (views::reverse | views::join)

ADL would find 6 distinct hidden operator| friends:

  two from _RangeAdaptorClosure<_Reverse>
  two from _RangeAdaptorClosure<_Join>
  two from _RangeAdaptorClosure<_Pipe<_Reverse, _Join>>

but we really only want to consider the last two.

We avoid this issue by instead defining the operator| overloads at
namespace scope alongside _RangeAdaptorClosure.  This should be fine
because the only types defined in this namespace are _RangeAdaptorClosure,
_RangeAdaptor, _Pipe and _Partial, so we don't have to worry about
unintentional ADL.

Reviewed-by: Jonathan Wakely <jwakely@redhat.com>

	PR libstdc++/108827

libstdc++-v3/ChangeLog:

	* include/std/ranges (__adaptor::_RangeAdaptorClosure):
	Convert into a CRTP class template.  Move hidden operator|
	friends into namespace scope and adjust their constraints.
	(__closure::__is_range_adaptor_closure_fn): Define.
	(__closure::__is_range_adaptor_closure): Define.
	(__adaptor::_Partial): Adjust use of _RangeAdaptorClosure.
	(__adaptor::_Pipe): Likewise.
	(views::_All): Likewise.
	(views::_Join): Likewise.
	(views::_Common): Likewise.
	(views::_Reverse): Likewise.
	(views::_Elements): Likewise.
	(views::_Adjacent): Likewise.
	(views::_AsRvalue): Likewise.
	(views::_Enumerate): Likewise.
	(views::_AsConst): Likewise.
	* testsuite/std/ranges/adaptors/all.cc: Reinstate assertion
	expecting that adding empty range adaptor closure objects to a
	pipeline doesn't increase the size of a pipeline.
2023-08-17 12:40:04 -04:00
Jonathan Wakely
d07bce478f libstdc++: Fix std::format("{:F}", inf) to use uppercase
std::format was treating {:f} and {:F} identically on the basis that for
the fixed 1.234567 format there are no alphabetical characters that need
to be in uppercase. But that's wrong for infinities and NaNs, which
should be formatted as "INF" and "NAN" for {:F}.

libstdc++-v3/ChangeLog:

	* include/std/format (__format::_Pres_type): Add _Pres_F.
	(__formatter_fp::parse): Use _Pres_F for 'F'.
	(__formatter_fp::format): Set __upper for _Pres_F.
	* testsuite/std/format/functions/format.cc: Check formatting of
	infinity and NaN for each presentation type.
2023-08-17 13:12:39 +01:00
Jonathan Wakely
51d702f3ba libstdc++: Disable PCH for tests that rely on include order
These tests expect to be able to #undef a feature test macro and then
include <version> to get it redefined. But if <version> has already been
included by the <bits/stdc++.h> PCH then including it again does nothing
and the macro remains undefined.

libstdc++-v3/ChangeLog:

	* testsuite/24_iterators/move_iterator/p2520r0.cc: Add no_pch.
	* testsuite/std/format/functions/format.cc: Likewise.
	* testsuite/std/format/functions/format_c++23.cc: Likewise.
2023-08-17 08:42:45 +01:00
Jonathan Wakely
4a2b262597 libstdc++: Fix std::basic_string::resize_and_overwrite
The callable used for resize_and_overwrite was being passed the string's
expanded capacity, which might be greater than the new size being
requested. This is not conforming, as the standard requires the same n
to be passed to the callable that the user passed to
resize_and_overwrite.

The existing tests didn't catch this because they all used a value which
was more than twice the existing capacity, so the _M_create call
allocated exactly what was requested, and the value passed to the
callable was correct. But when the requested size is greater than the
current capacity but smaller than twice the current capacity, _M_create
will allocate twice the current capacity and then that value was being
passed to the callable.

I noticed this because std::format(L"{}", 0.25) was producing L"0.25XX"
where the XX characters were whatever happened to be on the stack before
the call. When std::format used resize_and_overwrite to widen a string
it was copying too many characters into the destination and setting the
result's length too long. I've added a test for this case, and a new
test that doesn't hardcode -std=gnu++20 so can be used to test
std::format in C++23 and C++26 modes.

libstdc++-v3/ChangeLog:

	* include/bits/basic_string.tcc (resize_and_overwrite): Invoke
	the callable with the same size as resize_and_overwrite was
	called with.
	* testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc:
	Check with small values for the new size.
	* testsuite/std/format/functions/format.cc: Check wide
	formatting of double values that produce small strings.
	* testsuite/std/format/functions/format_c++23.cc: New test.
2023-08-16 18:36:37 +01:00
Jonathan Wakely
003016a408 libstdc++: Fix std::format_to_n return value [PR110990]
When writing to a contiguous iterator, std::format_to_n(out, n, ...)
always returns out + n, even if it wrote fewer than n characters to the
iterator.

The problem is in the _M_finish() member function of the _Iter_sink
specialization for contiguous iterators. _M_finish() calls _M_overflow()
to update its count of characters written, so it can return the count of
characters that would be written if there was room. But _M_overflow()
assumes it's only called when the buffer is full, and so switches to the
internal buffer. _M_finish() then thinks that if the internal buffer is
in use, we already wrote at least n characters and so returns out+n as
the output position.

We can fix the problem by adding a check in _M_overflow() so that we
don't update the count and switch to the internal buffer unless we've
run out of room, i.e. _M_unused().size() is zero. The caller then needs
to be prepared for _M_count not being the final total, and so add
_M_used.size() to it.

However, there's not actually any need for _M_finish() to call
_M_overflow() to get the count. We now need to use _M_count and
_M_used.size() to get the total anyway so _M_overflow() doesn't help
with that. And we don't need to use _M_overflow() to flush unwritten
characters to the output, because the specialization for contiguous
iterators always writes directly to the output without buffering (except
when we've exceeded the maximum number of characters, in which case we
want to discard the buffered characters anyway). So _M_finish() can be
simplified and can avoid calling _M_overflow().

This change also fixes some member functions of other sink classes to
only call _M_overflow() when there are characters in the buffer, which
is needed to meet _M_overflow's precondition that _M_used().size()!=0.

libstdc++-v3/ChangeLog:

	PR libstdc++/110990
	* include/std/format (_Seq_sink::get): Only call _M_overflow if
	its precondition is met.
	(_Iter_sink::_M_finish): Likewise.
	(_Iter_sink<C, ContigIter>::_M_overflow): Only switch to the
	internal buffer after running out of space.
	(_Iter_sink<C, ContigIter>::_M_finish): Do not use _M_overflow.
	(_Counting_sink::count): Likewise.
	* testsuite/std/format/functions/format_to_n.cc: Check cases
	where the output fits into the buffer.
2023-08-11 23:27:59 +01:00
Jonathan Wakely
ce6c4d3b4d libstdc++: Implement C++20 std::chrono::parse [PR104167]
This adds the missing C++20 features to <chrono>.

I've implemented my proposed resolutions to LWG issues 3960, 3961, and
3962. There are some unimplemented flags such as %OI which I think are
not implementable in general. It might be possible to use na_llanginfo
with ALT_DIGITS, but that isn't available on all targets. I intend to
file another LWG issue about that.

libstdc++-v3/ChangeLog:

	PR libstdc++/104167
	* include/bits/chrono_io.h (operator|=, operator|): Add noexcept
	to _ChronoParts operators.
	(from_stream, parse): Define new functions.
	(__detail::_Parse, __detail::_Parser): New class templates.
	* include/std/chrono (__cpp_lib_chrono): Define to 201907L for
	C++20.
	* include/std/version (__cpp_lib_chrono): Likewise.
	* testsuite/20_util/duration/arithmetic/constexpr_c++17.cc:
	Adjust expected value of feature test macro.
	* testsuite/20_util/duration/io.cc: Test parsing.
	* testsuite/std/time/clock/file/io.cc: Likewise.
	* testsuite/std/time/clock/gps/io.cc: Likewise.
	* testsuite/std/time/clock/system/io.cc: Likewise.
	* testsuite/std/time/clock/tai/io.cc: Likewise.
	* testsuite/std/time/clock/utc/io.cc: Likewise.
	* testsuite/std/time/day/io.cc: Likewise.
	* testsuite/std/time/month/io.cc: Likewise.
	* testsuite/std/time/month_day/io.cc: Likewise.
	* testsuite/std/time/weekday/io.cc: Likewise.
	* testsuite/std/time/year/io.cc: Likewise.
	* testsuite/std/time/year_month/io.cc: Likewise.
	* testsuite/std/time/year_month_day/io.cc: Likewise.
	* testsuite/std/time/syn_c++20.cc: Check value of macro and for
	the existence of parse and from_stream in namespace chrono.
	* testsuite/std/time/clock/local/io.cc: New test.
	* testsuite/std/time/parse.cc: New test.
2023-08-11 19:58:06 +01:00
Jonathan Wakely
ecfd8c7ffe libstdc++: Fix out-of-bounds read in format string "{:{}." [PR110974]
libstdc++-v3/ChangeLog:

	PR libstdc++/110974
	* include/std/format (_Spec::_S_parse_width_or_precision): Check
	for empty range before dereferencing iterator.
	* testsuite/std/format/string.cc: Check for expected exception.
	Fix expected exception message in test_pr110862() and actually
	call it.
2023-08-10 23:31:37 +01:00
Jonathan Wakely
f48a542396 libstdc++: Fix std::format for localized floats [PR110968]
The __formatter_fp::_M_localize function just returns an empty string if
the formatting locale is the C locale, as there is nothing to do. But
the caller was assuming that the returned string contains the localized
string. The caller should use the original string if _M_localize returns
an empty string.

libstdc++-v3/ChangeLog:

	PR libstdc++/110968
	* include/std/format (__formatter_fp::format): Check return
	value of _M_localize.
	* testsuite/std/format/functions/format.cc: Check classic
	locale.
2023-08-10 23:31:37 +01:00
Jonathan Wakely
c5ea5aecac libstdc++: Constrain __format::_Iter_sink for contiguous iterators [PR110917]
We can't write to a span<_CharT> if the contiguous iterator has a value
type that isn't _CharT.

libstdc++-v3/ChangeLog:

	PR libstdc++/110917
	* include/std/format (__format::_Iter_sink<CharT, OutIter>):
	Constrain partial specialization for contiguous iterators to
	require the value type to be CharT.
	* testsuite/std/format/functions/format_to.cc: New test.
2023-08-07 22:09:11 +01:00
Jonathan Wakely
5d87f71bb4 libstdc++: Fix past-the-end increment in std::format [PR110862]
At the end of a replacement field we should check that the closing brace
is actually present before incrementing past it.

libstdc++-v3/ChangeLog:

	PR libstdc++/110862
	* include/std/format (_Scanner::_M_on_replacement_field):
	Check for expected '}' before incrementing iterator.
	* testsuite/std/format/string.cc: Check "{0:{0}" format string.
2023-08-07 22:09:10 +01:00
Jonathan Wakely
50bc490c09 libstdc++: Fix std::format alternate form for floating-point [PR108046]
A decimal point was being added to the end of the string for {:#.0}
because the __expc character was not being set, for the _Pres_none
presentation type, so __s.find(__expc) didn't the 'e' in "1e+01" and so
we created "1e+01." by appending the radix char to the end.

This can be fixed by ensuring that __expc='e' is set for the _Pres_none
case. I realized we can also set __expc='P' and __expc='E' when needed,
to save a call to std::toupper later.

For the {:#.0g} format, __expc='e' was being set and so the 'e' was
found in "1e+10" but then __z = __prec - __sigfigs would wraparound to
SIZE_MAX. That meant we would decide not to add a radix char because the
number of extra characters to insert would be 1+SIZE_MAX i.e. zero.

This can be fixed by using __z == 0 when __prec == 0.

libstdc++-v3/ChangeLog:

	PR libstdc++/108046
	* include/std/format (__formatter_fp::format): Ensure __expc is
	always set for all presentation types. Set __z correctly for
	zero precision.
	* testsuite/std/format/functions/format.cc: Check problem cases.
2023-07-27 15:43:39 +01:00
Jonathan Wakely
344f413220 libstdc++: Fix formatting of negative chrono::hh_mm_ss
When formatting with an empty chrono spec ("{}") two minus signs were
being added to hh_mm_ss values. This is because the __is_neg flag was
checked to add one explicitly, and then the ostream operator added
another one.

We should only check the __is_neg flag for durations, because those are
the only types which are modified to be non-negative before calling
_M_format. We don't change hh_mm_ss values to be negative, because that
would require performing arithmetic on the hh_mm_ss members to sum them,
and then again to construct a new hh_mm_ss object with the positive
value.  Instead, we can just be careful about using the __is_neg flag
correctly.

To fix the bug, _M_format_to_ostream no longer checks the __is_neg flag
for non-durations, and _M_format doesn't set it for hh_mm_ss until after
the call to _M_format_to_ostream. We can also avoid setting it for types
that it doesn't apply to, by making the __print_sign lambda only inspect
it for duration and hh_mm_ss types.

libstdc++-v3/ChangeLog:

	* include/bits/chrono_io.h (__formatter_chrono::_M_format):
	Do not set __is_neg for hh_mm_ss before calling
	_M_format_to_ostream. Change __print_sign lambda to only check
	__is_neg for durations and hh_mm_ss types.
	(__formatter_chrono::_M_format_to_ostream): Only check __is_neg
	for duration types.
	* testsuite/std/time/hh_mm_ss/io.cc: Check negative values.
2023-07-19 16:48:56 +01:00
Jonathan Wakely
86b36e9f7e libstdc++: Fix locale-specific duration formatting [PR110719]
The r14-2640-gf4bce119f617dc commit only removed fractional seconds for
time points, but it needs to be done for durations and hh_mm_ss types
too.

libstdc++-v3/ChangeLog:

	PR libstdc++/110719
	* include/bits/chrono_io.h (__formatter_chrono::_S_floor_seconds):
	Handle duration and hh_mm_ss.
	* testsuite/20_util/duration/io.cc: Check locale-specific
	formats.
	* testsuite/std/time/hh_mm_ss/io.cc: Likewise.
2023-07-19 14:51:51 +01:00
Jonathan Wakely
f4bce119f6 libstdc++: Implement correct locale-specific chrono formatting [PR110719]
This fixes some TODOs in the C++20 <chrono> format support, where the
locale-specific output was incorrect or unimplemented. The approach
taken here is to either use the formatting locale's std::time_put facet
to do the formatting, or to remove subsecond precision from time points
so that locale-specific formats don't print fractional seconds. This
ensures that we are consistent with what the std::time_put facet would
print (which never includes fractional seconds) even if we actually
reimplement the formatting by hand instead of using the facet.

This also fixes a misplaced statement that allowed modifiers for %Z
which should have been on %z instead. There was also some ill-formed
code in an untested branch for formatting time zone names to wide
characters. A new test for zoned_time I/O has been added to exercise
that code properly.

libstdc++-v3/ChangeLog:

	PR libstdc++/110719
	* include/bits/chrono_io.h (__formatter_chrono::_M_parse): Fix
	allowed modifiers for %z and %Z. Fix -Wparentheses and
	-Wnarrowing warnings.
	(__formatter_chrono::_M_format): Call new functions for %d, %e,
	%H, %I, %m and %M.
	(__formatter_chrono::_M_c): Use _S_floor_seconds to remove
	subsecond precision.
	(__formatter_chrono::_M_C_y_Y): Use _M_locale_fmt to handle
	modifiers.
	(__formatter_chrono::_M_e): Replace with _M_d_e and use
	_M_locale_fmt.
	(__formatter_chrono::_M_I): Replace with _M_H_I and use
	_M_locale_fmt.
	(__formatter_chrono::_M_m): New function.
	(__formatter_chrono::_M_M): New function.
	(__formatter_chrono::_M_r): Use _M_locale_fmt.
	(__formatter_chrono::_M_S): Likewise.
	(__formatter_chrono::_M_u_w): Likewise.
	(__formatter_chrono::_M_U_V_W): Likewise.
	(__formatter_chrono::_M_X): Use _S_floor_seconds.
	(__formatter_chrono::_M_Z): Fix untested branch for wchar_t.
	(__formatter_chrono::_S_altnum): Remove function.
	(__formatter_chrono::_S_dd_zero_fill): Remove function.
	(__formatter_chrono::_S_floor_seconds): New function.
	(__formatter_chrono::_M_locale_fmt): New function.
	* testsuite/std/time/clock/system/io.cc: Adjust expected output
	for locale-specific formats and check modified formats.
	* testsuite/std/time/clock/utc/io.cc: Likewise.
	* testsuite/std/time/zoned_time/io.cc: New test.
2023-07-19 12:36:59 +01:00
Jonathan Wakely
52bfec7ea0 libstdc++: Check for multiple modifiers in chrono format string [PR110708]
The logic for handling modified chrono specs like %Ey was just
restarting the loop after each modifier, and not checking whether we'd
already seen a modifier.

libstdc++-v3/ChangeLog:

	PR libstdc++/110708
	* include/bits/chrono_io.h (__formatter_chrono::_M_parse): Only
	allow a single modifier.
	* testsuite/std/time/format.cc: Check multiple modifiers.
2023-07-19 11:03:32 +01:00
Jonathan Wakely
3bb9f9329c libstdc++: Fix std::format for pointers [PR110239]
The formatter for pointers was casting to uint64_t which sign extends a
32-bit pointer and produces a value that won't fit in the provided
buffer. Cast to uintptr_t instead.

There was also a bug in the __parse_integer helper when converting a
wide string to a narrow string in order to use std::from_chars on it.
The function would always try to read 32 characters, even if the format
string was shorter than that. Fix that bug, and remove the constexpr
implementation of __parse_integer by just using __from_chars_alnum
instead of from_chars, because that's usable in constexpr even in
C++20.

libstdc++-v3/ChangeLog:

	PR libstdc++/110239
	* include/std/format (__format::__parse_integer): Fix buffer
	overflow for wide chars.
	(formatter<const void*, C>::format): Cast to uintptr_t instead
	of uint64_t.
	* testsuite/std/format/string.cc: Test too-large widths.
2023-06-26 17:43:22 +01:00
Jonathan Wakely
628ba410b9 libstdc++: Fix P2510R3 "Formatting pointers" [PR110149]
I had intended to support the P2510R3 proposal unconditionally in C++20
mode, but I left it half implemented. The parse function supported the
new extensions, but the format function didn't.

This adds the missing pieces, and makes it only enabled for C++26 and
non-strict modes.

libstdc++-v3/ChangeLog:

	PR libstdc++/110149
	* include/std/format (formatter<const void*, charT>::parse):
	Only alow 0 and P for C++26 and non-strict modes.
	(formatter<const void*, charT>::format): Use toupper for P
	type, and insert zero-fill characters for 0 option.
	* testsuite/std/format/functions/format.cc: Check pointer
	formatting. Only check P2510R3 extensions conditionally.
	* testsuite/std/format/parse_ctx.cc: Only check P2510R3
	extensions conditionally.
2023-06-09 13:08:25 +01:00
Jonathan Wakely
aa39ed4467 libstdc++: Fix chrono::hh_mm_ss::subseconds() [PR109772]
I borked the logic in r13-4526-g5329e1a8e1480d so that the selected
partial specialization of hh_mm_ss::__subseconds might not be able to
represent the correct number of subseconds. This can result in a
truncated value being stored for the subseconds, e.g., 4755859375 gets
truncated to 460892079 because the correct value doesn't fit in
uint_least32_t.

Instead of checking whether the maximum value of the incoming duration
type can be represented, we would need to check whether that maximum value
can be represented after being converted to the correct precision type:

       template<typename _Tp>
         static constexpr bool __fits
           = duration_cast<precision>(_Duration::max()).count()
               <= duration_values<_Tp>::max();

However, this can fail to compile, due to integer overflow in the
constexpr multiplications. Instead, we could limit the check to the case
where the incoming duration has the same period as the precision, where
no conversion is needed and so no overflow can happen. But that seems of
very limited value, as it would only benefit specializations like
hh_mm_ss<duration<int, std::pico>>, which can only represent a
time-of-day between -00:00:00.0215 and +00:00:00.0215 measured in
picoseconds!

Additionally, the hh_mm_ss::__subseconds partial specializations do not
have disjoint constraints, so that some hh_mm_ss specializations result
in ambiguities tying to match a __subseconds partial specialization.

The most practical fix is to just stop using the __fits variable
template in the constraints of the partial specializations. This fixes
the truncated values by not selecting an inappropriate partial
specialization, and fixes the ambiguous match by ensuring the
constraints are disjoint.

Fixing this changes the layout of some specializations, so is an ABI
change. It only affects specializations that have a small (less than
64-bit) representation type and either a very small period (e.g. like
the picosecond specialization above) or a non-power-of-ten period like
ratio<1, 1024>.  For example both hh_mm_ss<duration<int, std::pico>> and
hh_mm_ss<duration<int, ratio<1, 1024>> are affected (increasing from 16
bytes to 24 on x86_64), but hh_mm_ss<duration<int, ratio<1, 1000>> and
hh_mm_ss<duration<long, ratio<1, 1024>> are not affected.

libstdc++-v3/ChangeLog:

	PR libstdc++/109772
	* include/std/chrono (hh_mm_ss::__fits): Remove variable
	template.
	(hh_mm_ss::__subseconds): Remove __fits from constraints.
	* testsuite/std/time/hh_mm_ss/109772.cc: New test.
	* testsuite/std/time/hh_mm_ss/1.cc: Adjust expected size for
	hh_mm_ss<duration<int, std::pico>>.
2023-05-11 21:15:22 +01:00
Patrick Palka
83470a5cd4 libstdc++: Fix __max_diff_type::operator>>= for negative values
This patch fixes sign bit propagation when right-shifting a negative
__max_diff_type value by more than one, a bug that our existing test
coverage didn't expose until r14-159-g03cebd304955a6 fixed the front
end's 'signed typedef-name' handling that the test relies on (which is
a non-standard extension to the language grammar).

libstdc++-v3/ChangeLog:

	* include/bits/max_size_type.h (__max_diff_type::operator>>=):
	Fix propagation of sign bit.
	* testsuite/std/ranges/iota/max_size_type.cc: Avoid using the
	non-standard 'signed typedef-name'.  Add some compile-time tests
	for right-shifting a negative __max_diff_type value by more than
	one.
2023-04-24 13:39:54 -04:00
Patrick Palka
cb5c71d16d libstdc++: Implement range_adaptor_closure from P2387R3 [PR108827]
PR libstdc++/108827

libstdc++-v3/ChangeLog:

	* include/bits/ranges_cmp.h (__cpp_lib_ranges): Bump value
	for C++23.
	* include/std/ranges (range_adaptor_closure): Define for C++23.
	* include/std/version (__cpp_lib_ranges): Bump value for
	C++23.
	* testsuite/std/ranges/version_c++23.cc: Bump expected value
	of __cpp_lib_ranges.
	* testsuite/std/ranges/range_adaptor_closure.cc: New test.
2023-04-18 07:21:13 -04:00
Patrick Palka
95525c5b8c libstdc++: Adding missing feature-test macros for C++23 ranges algos
This patch also renames __cpp_lib_fold to __cpp_lib_ranges_fold
as per the current draft standard.

libstdc++-v3/ChangeLog:

	* include/bits/ranges_algo.h (__cpp_lib_ranges_contains):
	Define for C++23.
	(__cpp_lib_ranges_iota): Likewise.
	(__cpp_lib_ranges_find_last): Likewise.
	(__cpp_lib_fold): Rename to ...
	(__cpp_lib_ranges_fold): ... this.
	* include/std/version: As above.
	* testsuite/25_algorithms/fold_left/1.cc: Adjust after
	renaming __cpp_lib_fold.
	* testsuite/std/ranges/version_c++23.cc: Verify values
	of the above feature-test macros.
2023-04-18 07:21:09 -04:00
Patrick Palka
4ec4ceafcc libstdc++: Fix typo in views::as_const's operator() [PR109525]
PR libstdc++/109525

libstdc++-v3/ChangeLog:

	* include/std/ranges (views::_AsConst::operator()): Add
	missing const to constant_range test.
	* testsuite/std/ranges/adaptors/as_const/1.cc (test02):
	Improve formatting.  Adjust expected type of v2.
	(test03): New test.
2023-04-18 07:21:07 -04:00
Patrick Palka
0d94c6df18 libstdc++: Implement P2278R4 "cbegin should always return a constant iterator"
This also implements the approved follow-up LWG issues 3765, 3766, 3769,
3770, 3811, 3850, 3853, 3862 and 3872.

libstdc++-v3/ChangeLog:

	* include/bits/ranges_base.h (const_iterator_t): Define for C++23.
	(const_sentinel_t): Likewise.
	(range_const_reference_t): Likewise.
	(constant_range): Likewise.
	(__cust_access::__possibly_const_range): Likewise, replacing ...
	(__cust_access::__as_const): ... this.
	(__cust_access::_CBegin::operator()): Redefine for C++23 as per P2278R4.
	(__cust_access::_CEnd::operator()): Likewise.
	(__cust_access::_CRBegin::operator()): Likewise.
	(__cust_access::_CREnd::operator()): Likewise.
	(__cust_access::_CData::operator()): Likewise.
	* include/bits/ranges_util.h (ranges::__detail::__different_from):
	Make it an alias of std::__detail::__different_from.
	(view_interface::cbegin): Define for C++23.
	(view_interface::cend): Likewise.
	* include/bits/stl_iterator.h (__detail::__different_from): Define.
	(iter_const_reference_t): Define for C++23.
	(__detail::__constant_iterator): Likewise.
	(__detail::__is_const_iterator): Likewise.
	(__detail::__not_a_const_iterator): Likewise.
	(__detail::__iter_const_rvalue_reference_t): Likewise.
	(__detail::__basic_const_iter_cat):: Likewise.
	(const_iterator): Likewise.
	(__detail::__const_sentinel): Likewise.
	(const_sentinel): Likewise.
	(basic_const_iterator): Likewise.
	(common_type<basic_const_iterator<_Tp>, _Up>): Likewise.
	(common_type<_Up, basic_const_iterator<_Tp>>): Likewise.
	(common_type<basic_const_iterator<_Tp>, basic_const_iterator<Up>>):
	Likewise.
	(make_const_iterator): Define for C++23.
	(make_const_sentinel): Likewise.
	* include/std/ranges (__cpp_lib_ranges_as_const): Likewise.
	(as_const_view): Likewise.
	(enable_borrowed_range<as_const_view>): Likewise.
	(views::__detail::__is_ref_view): Likewise.
	(views::__detail::__can_is_const_view): Likewise.
	(views::_AsConst, views::as_const): Likewise.
	* include/std/span (span::const_iterator): Likewise.
	(span::const_reverse_iterator): Likewise.
	(span::cbegin): Likewise.
	(span::cend): Likewise.
	(span::crbegin): Likewise.
	(span::crend): Likewise.
	* include/std/version (__cpp_lib_ranges_as_const): Likewise.
	* testsuite/std/ranges/adaptors/join.cc (test06): Adjust to
	behave independently of C++20 vs C++23.
	* testsuite/std/ranges/version_c++23.cc: Verify value of
	__cpp_lib_ranges_as_const macro.
	* testsuite/24_iterators/const_iterator/1.cc: New test.
	* testsuite/std/ranges/adaptors/as_const/1.cc: New test.
2023-04-14 10:32:12 -04:00
Patrick Palka
0f3b4d38d4 libstdc++: Implement ranges::enumerate_view from P2164R9
libstdc++-v3/ChangeLog:

	* include/std/ranges (__cpp_lib_ranges_enumerate): Define
	for C++23.
	(__detail::__range_with_movable_reference): Likewise.
	(enumerate_view): Likewise.
	(enumerate_view::_Iterator): Likewise.
	(enumerate_view::_Sentinel): Likewise.
	(views::__detail::__can_enumerate_view): Likewise.
	(views::_Enumerate, views::enumerate): Likewise.
	* include/std/version (__cpp_lib_ranges_enumerate): Likewise.
	* testsuite/std/ranges/version_c++23.cc: Verify value of
	__cpp_lib_ranges_enumerate.
	* testsuite/std/ranges/adaptors/enumerate/1.cc: New test.
2023-04-12 13:24:37 -04:00
Patrick Palka
aa65771427 libstdc++: Implement LWG 3904 change to lazy_split_view's iterator
libstdc++-v3/ChangeLog:

	* include/std/ranges (lazy_split_view::_OuterIter::_OuterIter):
	Propagate _M_trailing_empty in the const-converting constructor
	as per LWG 3904.
	* testsuite/std/ranges/adaptors/adjacent/1.cc (test04): Correct
	assertion.
	* testsuite/std/ranges/adaptors/lazy_split.cc (test12): New test.
2023-04-12 13:04:36 -04:00
Patrick Palka
ae8f903632 libstdc++: Fix chunk_by_view when value_type& and reference differ [PR108291]
PR libstdc++/108291

libstdc++-v3/ChangeLog:

	* include/std/ranges (chunk_by_view::_M_find_next): Generalize
	parameter types of the lambda wrapper passed to adjacent_find.
	(chunk_by_view::_M_find_prev): Likewise.
	* testsuite/std/ranges/adaptors/chunk_by/1.cc (test04, test05):
	New tests.
2023-04-12 12:10:23 -04:00
Jonathan Wakely
cf19ef9eca libstdc++: Update tzdata to 2023a [PR109288]
Import the new 2023a tzdata.zi file and update the expiry dates of the
hardcoded lists of leapseconds to 2023-12-28.

With the new data, Africa/Egypt no longer has a single unbroken sys_info
from 2014-09-25 to chrono::year::max(). Only check up to 2014-09-01 so
that the test isn't sensitive to differences between 2022g and 2023a
data.

libstdc++-v3/ChangeLog:

	PR libstdc++/109288
	* include/std/chrono (__detail::__get_leap_second_info): Update
	expiry date of hardcoded leapseconds list.
	* src/c++20/tzdb.cc (tzdb_list::_Node::_S_read_leap_seconds()):
	Likewise.
	* src/c++20/tzdata.zi: Import new file from 2023a release.
	* testsuite/std/time/time_zone/get_info_local.cc: Only check
	transitions for Egypt up to 2014.
2023-03-28 21:12:18 +01:00
Jonathan Wakely
f2e70da638 libstdc++: Remove std::formatter<const charT[N], charT> specialization
This was approved in Issaquah as LWG 3833.

libstdc++-v3/ChangeLog:

	* include/std/format (formatter<const charT[N], charT>): Do not
	define partial speclialization, as per LWG 3833.
	* testsuite/std/format/formatter/requirements.cc: Check it.
2023-03-22 17:48:20 +00:00
Jonathan Wakely
02e86035d3 libstdc++: Add missing __cpp_lib_format macro to <version>
libstdc++-v3/ChangeLog:

	* include/std/version (__cpp_lib_format): Define.
	* testsuite/std/format/functions/format.cc: Check it.
2023-03-22 17:48:20 +00:00
Patrick Palka
f2e7dd8b02 libstdc++: Implement LWG 3715 changes to view_interface::empty
libstdc++-v3/ChangeLog:

	* include/bits/ranges_util.h (view_interface::empty): Add
	preferred overloads that use ranges::size when the range is
	sized as per LWG 3715.
	* testsuite/std/ranges/adaptors/lwg3715.cc: New test.
2023-03-14 16:44:30 -04:00
Patrick Palka
96abc82224 libstdc++: Implement LWG 3820/3849 changes to cartesian_product_view
The LWG 3820 testcase revealed a bug in _M_advance, which this patch
also fixes.

libstdc++-v3/ChangeLog:

	* include/std/ranges
	(cartesian_product_view::_Iterator::_Iterator): Remove
	constraint on default constructor as per LWG 3849.
	(cartesian_product_view::_Iterator::_M_prev): Adjust position
	of _Nm > 0 test as per LWG 3820.
	(cartesian_product_view::_Iterator::_M_advance): Perform bounds
	checking only on sized cartesian products.
	* testsuite/std/ranges/cartesian_product/1.cc (test08): New test.
2023-03-09 13:41:03 -05:00
Patrick Palka
065c93b89c libstdc++: Implement LWG 3796 changes to repeat_/chunk_by_view [PR109024]
PR libstdc++/109024

libstdc++-v3/ChangeLog:

	* include/std/ranges (chunk_by_view::_M_pred): Remove DMI as per
	LWG 3796.
	(repeat_view::_M_pred): Likewise.
	* testsuite/std/ranges/adaptors/chunk_by/1.cc (test03): New test.
	* testsuite/std/ranges/repeat/1.cc (test05): New test.
2023-03-09 13:37:29 -05:00
Patrick Palka
95827e1b9f libstdc++: Make views::single/iota/istream SFINAE-friendly [PR108362]
PR libstdc++/108362

libstdc++-v3/ChangeLog:

	* include/std/ranges (__detail::__can_single_view): New concept.
	(_Single::operator()): Constrain it.  Move [[nodiscard]] to the
	end of the function declarator.
	(__detail::__can_iota_view): New concept.
	(_Iota::operator()): Constrain it.  Move [[nodiscard]] to the
	end of the function declarator.
	(__detail::__can_istream_view): New concept.
	(_Istream::operator()): Constrain it.  Move [[nodiscard]] to the
	end of the function declarator.
	* testsuite/std/ranges/iota/iota_view.cc (test07): New test.
	* testsuite/std/ranges/istream_view.cc (test08): New test.
	* testsuite/std/ranges/single_view.cc (test07): New test.
2023-03-09 13:35:04 -05:00
Patrick Palka
3df9760d56 libstdc++: extraneous begin in cartesian_product_view::end [PR107572]
ranges::begin() isn't guaranteed to be equality-preserving for non-forward
ranges, so in cartesian_product_view::end we need to avoid needlessly
calling begin() on the first range (which could be non-forward) in the
case where __empty_tail is false as per its specification.

Since we're already using a variadic lambda to compute __empty_tail, we
might as well use that same lambda to build up the tuple of iterators
instead of building it separately via e.g. std::apply or __tuple_transform.

	PR libstdc++/107572

libstdc++-v3/ChangeLog:

	* include/std/ranges (cartesian_product_view::end): When
	building the tuple of iterators, avoid calling ranges::begin on
	the first range if __empty_tail is false.
	* testsuite/std/ranges/cartesian_product/1.cc (test07): New test.
2023-03-09 13:25:44 -05:00
Jonathan Wakely
4abd5bc600 libstdc++: Make std::chrono::current_zone() default to UTC
This is consistent with the behaviour of glibc, which assumes UTC when
/etc/localtime and TZ do not identify a valid time zone. The fallback
tzdb used when no valid tzdata exists always contains the UTC zone, so
this change means we have a valid tzdb and valid current zone even in
the degenerate case.

With this default we no longer need the AIX-specific kluge to try and
identify TZ values specifying a 0-offset zone. We can just use the UTC
default for those, as it has the same effect.

It's still possible for chrono::current_zone() to fail, because the user
could have provided a custom tzdata.zi file which doesn't contain the
UTC time zone, so the "UTC" default would fail to find a valid zone, and
throw an exception. That's just user error, they should not provide bad
data and expect reasonable behaviour.

libstdc++-v3/ChangeLog:

	* src/c++20/tzdb.cc (chrono::tzdb::current_zone()) Use "UTC" if
	current time zone cannot be determined.
	* testsuite/std/time/tzdb/1.cc: Remove conditions based on
	HAVE_TZDB macro and test all members unconditionally.
2023-03-01 21:26:08 +00:00
Jonathan Wakely
f30421fa72 libstdc++: Reorder dg-options before dg-do
The options need to be set first, so that -std=gnu++20 is used when
checking the c++20 effective target.

libstdc++-v3/ChangeLog:

	* testsuite/std/format/arguments/lwg3810.cc: Move dg-options
	before dg-do.
2023-02-24 14:18:35 +00:00
Jonathan Wakely
feff71e035 libstdc++: Replace non-ascii character in test
This ensures the test will work with -fexec-charset=ascii.

libstdc++-v3/ChangeLog:

	* testsuite/std/format/arguments/lwg3810.cc: Replace UTF-8
	ellipsis character.
2023-02-16 14:48:45 +00:00
Jonathan Wakely
4024f39941 libstdc++: Enable CTAD for std::basic_format_args (LWG 3810)
This was just approved in Issaquah.

libstdc++-v3/ChangeLog:

	* include/std/format (__format::_Arg_store): New class template.
	(basic_format_args): Remove nested type _Store and add deduction
	guide from _Arg_store.
	(basic_format_arg, make_format_args): Adjust.
	* testsuite/std/format/arguments/lwg3810.cc: New test.
2023-02-16 14:38:38 +00:00
Hans-Peter Nilsson
a939dd8357 libstdc++ testsuite: Correct S0 in std/time/hh_mm_ss/1.cc
For targets where the ABI mandates structure layout that has
no padding, like cris-elf, this test started failing when
introduced as an add-on to the existing 1.cc, thereby
effectively causing a regression in testsuite results.
Adding an empty structure to S0, corresponds better to the
layout of hh_mm_ss<seconds>.

	PR testsuite/108632
	* testsuite/std/time/hh_mm_ss/1.cc (size): Add empty
	struct at end of S0.
2023-02-01 17:58:22 +01:00
Jakub Jelinek
83ffe9cde7 Update copyright years. 2023-01-16 11:52:17 +01:00
Jonathan Wakely
05cd79c242 libstdc++: Remove dg-xfail-run-if in std/time/tzdb_list/1.cc
Use the global override_used to tell whether the target supports the
override functionality that the test_reload and test_erase functions
rely on.

libstdc++-v3/ChangeLog:

	* testsuite/std/time/tzdb_list/1.cc: Remove dg-xfail-run-if
	and fail gracefully if defining the weak symbol doesn't work.
2023-01-15 16:45:57 +00:00
Jonathan Wakely
4dc4584b60 libstdc++: Fix narrowing conversion in std/time/clock/utc/io.cc
For a port with signed char and unsigned wchar_t initializing a wchar_t
array with a char is a narrowing conversion. The code is wrong for
assuming that (int)'a' == (int)L'a' anyway, so fix it properly by using
ctype<wchar_t>::widen(char).

libstdc++-v3/ChangeLog:

	* testsuite/std/time/clock/utc/io.cc: Use ctype to widen char.
2023-01-15 12:44:23 +00:00
Jonathan Wakely
c47dcb9566 libstdc++: Disable unwanted code for --with-libstdcxx-zoneinfo=no
This allows most of the tzdb functionality to be disabled by
configuring with --with-libstdcxx-zoneinfo=no. This might be desirable
for small targets that don't need the time zone support.

libstdc++-v3/ChangeLog:

	* src/c++20/tzdb.cc (TZDB_DISABLED): Disable all code for
	loading tzdb.
	* testsuite/std/time/tzdb/leap_seconds.cc: Require tzdb
	effective target.
	* testsuite/std/time/tzdb_list/1.cc: Likewise.
2023-01-14 18:06:07 +00:00
Jonathan Wakely
9afc914809 libstdc++: Fix ostream insertion operators for calendar types
libstdc++-v3/ChangeLog:

	* include/bits/chrono_io.h (operator<<): Fix syntax errors.
	* testsuite/std/time/month_day/io.cc: New test.
	* testsuite/std/time/month_day_last/io.cc: New test.
	* testsuite/std/time/month_weekday/io.cc: New test.
	* testsuite/std/time/month_weekday_last/io.cc: New test.
	* testsuite/std/time/weekday_indexed/io.cc: New test.
	* testsuite/std/time/weekday_last/io.cc: New test.
	* testsuite/std/time/year_month/io.cc: New test.
	* testsuite/std/time/year_month_day_last/io.cc: New test.
	* testsuite/std/time/year_month_weekday/io.cc: New test.
	* testsuite/std/time/year_month_weekday_last/io.cc: New test.
2023-01-14 16:59:58 +00:00
Arsen Arsenović
450eb6b3b5 libstdc++: Fix a few !HOSTED test regressions
libstdc++-v3/ChangeLog:

	* testsuite/20_util/to_chars/version.cc: Mark hosted-only.
	* testsuite/20_util/uses_allocator/lwg3677.cc: Ditto.
	* testsuite/20_util/weak_ptr/cons/self_move.cc: Ditto.
	* testsuite/std/ranges/adaptors/as_rvalue/1.cc: Replace usage of
	std::make_unique with a freestanding-compatible wrapper around
	unique_ptr.
	* testsuite/21_strings/basic_string_view/operations/contains/char.cc:
	Don't test for presence of __cpp_lib_string_contains on !HOSTED.
	* testsuite/21_strings/basic_string_view/operations/contains/char/2.cc:
	Ditto.
	* testsuite/std/ranges/version_c++23.cc: Don't test for presence
	of __cpp_lib_ranges in !HOSTED.
2023-01-13 13:34:21 +00:00
Patrick Palka
f7bd48c6bb libstdc++: Add feature-test macros for implemented C++23 views [PR108260]
PR libstdc++/108260

libstdc++-v3/ChangeLog:

	* include/bits/utility.h (__cpp_lib_ranges_zip): Define for C++23.
	* include/std/ranges (__cpp_lib_ranges_zip): Likewise.
	(__cpp_lib_ranges_chunk): Likewise.
	(__cpp_lib_ranges_slide): Likewise.
	(__cpp_lib_ranges_chunk_by): Likewise.
	(__cpp_lib_ranges_join_with): Likewise.
	(__cpp_lib_ranges_repeat): Likewise.
	(__cpp_lib_ranges_stride): Likewise.
	(__cpp_lib_ranges_cartesian_product): Likewise.
	(__cpp_lib_ranges_as_rvalue): Likewise.
	* include/std/version: Ditto.
	* testsuite/20_util/tuple/p2321r2.cc: Verify value of
	feature-test macro.
	* testsuite/std/ranges/adaptors/as_rvalue/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/chunk/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/chunk_by/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/join_with/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/slide/1.cc: Likewise.
	* testsuite/std/ranges/adaptors/stride/1.cc: Likewise.
	* testsuite/std/ranges/cartesian_product/1.cc: Likewise.
	* testsuite/std/ranges/repeat/1.cc: Likewise.
	* testsuite/std/ranges/zip/1.cc: Likewise.
	* testsuite/std/ranges/version_c++23.cc: New test.
2023-01-06 10:32:10 -05:00
Jonathan Wakely
e36e57b032 libstdc++: Fix std::chrono::hh_mm_ss with unsigned rep [PR108265]
libstdc++-v3/ChangeLog:

	PR libstdc++/108265
	* include/std/chrono (hh_mm_ss): Do not use chrono::abs if
	duration rep is unsigned.
	* testsuite/std/time/hh_mm_ss/1.cc: Check unsigned rep.
2023-01-05 00:46:00 +00:00