aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-09-05 10:44:56 +0200
committerMartin Liska <mliska@suse.cz>2022-09-05 10:44:56 +0200
commitd8e441f4b8698f38e4564fe1bbe9ff112814ecff (patch)
tree62aac45da0a2358e1ea29a07ab734f607a201e5b /libstdc++-v3
parent4483fe115cef3eea1d64e913816e2d117b38ac73 (diff)
parentca60bd93e216ae0425f790e1d4f4dc4a48763c0e (diff)
downloadgcc-d8e441f4b8698f38e4564fe1bbe9ff112814ecff.zip
gcc-d8e441f4b8698f38e4564fe1bbe9ff112814ecff.tar.gz
gcc-d8e441f4b8698f38e4564fe1bbe9ff112814ecff.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog414
-rwxr-xr-xlibstdc++-v3/configure14
-rw-r--r--libstdc++-v3/crossconfig.m49
-rw-r--r--libstdc++-v3/doc/xml/manual/debug_mode.xml6
-rw-r--r--libstdc++-v3/doc/xml/manual/using.xml10
-rw-r--r--libstdc++-v3/include/bits/basic_string.h208
-rw-r--r--libstdc++-v3/include/bits/cow_string.h3
-rw-r--r--libstdc++-v3/include/bits/ranges_algo.h54
-rw-r--r--libstdc++-v3/include/bits/ranges_base.h2
-rw-r--r--libstdc++-v3/include/bits/ranges_util.h55
-rw-r--r--libstdc++-v3/include/bits/refwrap.h3
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h5
-rw-r--r--libstdc++-v3/include/bits/stl_pair.h7
-rw-r--r--libstdc++-v3/include/debug/debug.h11
-rw-r--r--libstdc++-v3/include/debug/formatter.h44
-rw-r--r--libstdc++-v3/include/debug/string25
-rw-r--r--libstdc++-v3/include/std/ranges1471
-rw-r--r--libstdc++-v3/include/std/string_view104
-rw-r--r--libstdc++-v3/include/std/system_error38
-rw-r--r--libstdc++-v3/include/std/tuple10
-rw-r--r--libstdc++-v3/include/std/type_traits697
-rw-r--r--libstdc++-v3/src/c++11/debug.cc75
-rw-r--r--libstdc++-v3/src/libbacktrace/Makefile.am1
-rw-r--r--libstdc++-v3/src/libbacktrace/Makefile.in12
-rw-r--r--libstdc++-v3/src/libbacktrace/backtrace-rename.h1
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/error_code/cons/1.cc31
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/1.cc31
-rw-r--r--libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc5
-rw-r--r--libstdc++-v3/testsuite/20_util/logical_traits/requirements/base_classes.cc34
-rw-r--r--libstdc++-v3/testsuite/20_util/logical_traits/requirements/short_circuit.cc55
-rw-r--r--libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc3
-rw-r--r--libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-3.cc3
-rw-r--r--libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-noexcept.cc15
-rw-r--r--libstdc++-v3/testsuite/20_util/reference_wrapper/invoke.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc41
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc6
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc6
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/cons/char/self_move.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/1.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/21674.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/1.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/21674.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/lwg2758.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/lwg2946.cc16
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/nonnull.cc12
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/char.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc12
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/wchar_t.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/char.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc12
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/wchar_t.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/operators/char/1.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/operators/wchar_t/1.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/capacity/1.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/1.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/2.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/1.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/2.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc12
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc12
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc12
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc17
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/stable_sort/4.cc51
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/sputbackc/char/1.cc10
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/sputbackc/wchar_t/1.cc10
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/sungetc/char/1.cc10
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/sungetc/wchar_t/1.cc10
-rw-r--r--libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc110
-rw-r--r--libstdc++-v3/testsuite/std/ranges/adaptors/adjacent_transform/1.cc106
-rw-r--r--libstdc++-v3/testsuite/std/ranges/zip/1.cc111
-rw-r--r--libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc108
72 files changed, 3521 insertions, 675 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index d88ffec..d905767 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,417 @@
+2022-09-02 Patrick Palka <ppalka@redhat.com>
+
+ * include/std/tuple (tuple::_UseOtherCtor): Use ::type when
+ deriving from __and_, __or_ or __not_.
+ * include/std/type_traits (negation): Likewise.
+ (is_unsigned): Likewise.
+ (__is_implicitly_default_constructible): Likewise.
+ (is_trivially_destructible): Likewise.
+ (__is_nt_invocable_impl): Likewise.
+
+2022-09-02 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/type_traits (is_constructible_v)
+ (is_default_constructible_v, is_copy_constructible_v)
+ (is_move_constructible_v): Define using __is_constructible.
+ (is_assignable_v, is_copy_assignable_v, is_move_assignable_v):
+ Define using __is_assignable.
+ (is_trivially_constructible_v)
+ (is_trivially_default_constructible_v)
+ (is_trivially_copy_constructible_v)
+ (is_trivially_move_constructible_v): Define using
+ __is_trivially_constructible.
+ (is_trivially_assignable_v, is_trivially_copy_assignable_v)
+ (is_trivially_move_assignable_v): Define using
+ __is_trivially_assignable.
+ (is_nothrow_constructible_v)
+ (is_nothrow_default_constructible_v)
+ (is_nothrow_copy_constructible_v)
+ (is_nothrow_move_constructible_v): Define using
+ __is_nothrow_constructible.
+ (is_nothrow_assignable_v, is_nothrow_copy_assignable_v)
+ (is_nothrow_move_assignable_v): Define using
+ __is_nothrow_assignable.
+
+2022-09-02 Patrick Palka <ppalka@redhat.com>
+
+ * include/std/type_traits (__or_, __and_, __not_): Redefine as a
+ class template instead of as an alias template.
+ * testsuite/20_util/logical_traits/requirements/short_circuit.cc:
+ Add more tests for conjunction and disjunction. Add corresponding
+ tests for __and_ and __or_.
+
+2022-09-01 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/ranges (adjacent_transform_view::_Iterator): Add
+ typename keyword before dependent qualified-id.
+
+2022-09-01 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/type_traits (__is_referenceable): Remove.
+ (__add_lvalue_reference_helper, __add_rvalue_reference_helper):
+ Use __void_t instead of __is_referenceable.
+ (__add_pointer_helper): Likewise.
+ (add_pointer): Add partial specializations for reference types.
+
+2022-09-01 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/type_traits (__is_constructible_impl): Replace
+ class template with alias template.
+ (is_default_constructible, is_nothrow_constructible)
+ (is_nothrow_constructible): Simplify base-specifier.
+ (__is_copy_constructible_impl, __is_move_constructible_impl)
+ (__is_nothrow_copy_constructible_impl)
+ (__is_nothrow_move_constructible_impl): Remove class templates.
+ (is_copy_constructible, is_move_constructible)
+ (is_nothrow_constructible, is_nothrow_default_constructible)
+ (is_nothrow_copy_constructible, is_nothrow_move_constructible):
+ Adjust base-specifiers to use __is_constructible_impl.
+ (__is_copy_assignable_impl, __is_move_assignable_impl)
+ (__is_nt_copy_assignable_impl, __is_nt_move_assignable_impl):
+ Remove class templates.
+ (__is_assignable_impl): New alias template.
+ (is_assignable, is_copy_assignable, is_move_assignable):
+ Adjust base-specifiers to use new alias template.
+ (is_nothrow_copy_assignable, is_nothrow_move_assignable):
+ Adjust base-specifiers to use existing alias template.
+ (__is_trivially_constructible_impl): New alias template.
+ (is_trivially_constructible, is_trivially_default_constructible)
+ (is_trivially_copy_constructible)
+ (is_trivially_move_constructible): Adjust base-specifiers to use
+ new alias template.
+ (__is_trivially_assignable_impl): New alias template.
+ (is_trivially_assignable, is_trivially_copy_assignable)
+ (is_trivially_move_assignable): Adjust base-specifier to use
+ new alias template.
+ (__add_lval_ref_t, __add_rval_ref_t): New alias templates.
+ (add_lvalue_reference, add_rvalue_reference): Use new alias
+ templates.
+
+2022-09-01 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/type_traits (__decay_selector): Add partial
+ specializations for array types. Only check for function types
+ when not dealing with an array.
+ (decay): Add partial specializations for reference types.
+
+2022-09-01 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/type_traits (is_lvalue_reference_v)
+ (is_rvalue_reference_v, is_reference_v, is_const_v)
+ (is_volatile_v): Define using partial specializations instead
+ of instantiating class templates.
+
+2022-09-01 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/type_traits (is_enum_v, is_class_v, is_union_v)
+ (is_empty_v, is_polymoprhic_v, is_abstract_v, is_final_v)
+ (is_base_of_v, is_aggregate_v): Use built-in directly instead of
+ instantiating class template.
+
+2022-09-01 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/type_traits (is_scoped_enum): Remove workaround.
+
+2022-09-01 Patrick Palka <ppalka@redhat.com>
+
+ * include/std/ranges (__detail::__unarize): Define.
+ (adjacent_view::_Iterator): Befriend adjacent_transform_view.
+ (adjacent_transform_view): Define.
+ (adjacent_transform_view::_Iterator): Define.
+ (adjacent_transform_view::_Sentinel): Define.
+ (views::__detail::__can_adjacent_transform_view): Define.
+ (views::_AdjacentTransform): Define.
+ (views::adjacent_transform): Define.
+ (views::pairwise_transform): Define.
+ * testsuite/std/ranges/adaptors/adjacent_transform/1.cc: New test.
+
+2022-09-01 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/type_traits (__is_array_known_bounds): Add partial
+ specialization instead of using std::extent.
+ (__is_array_unknown_bounds): Likewise.
+ (extent): Add partial specializations to stop recursion after
+ the result is found.
+ (is_array_v): Add partial specializations instead of
+ instantiating the class template.
+ (rank_v, extent_v): Likewise.
+ (is_bounded_array_v, is_unbounded_array_v): Likewise.
+ (is_bounded_array, is_unbounded_array): Define in terms of the
+ variable templates.
+
+2022-08-31 Patrick Palka <ppalka@redhat.com>
+
+ * include/bits/ranges_base.h (__advance_fn::operator()): Add
+ parentheses in assert condition to avoid -Wparentheses warning.
+ * include/std/ranges: (take_view::take_view): Uglify 'base'.
+ (take_while_view::take_while_view): Likewise.
+ (elements_view::elements_view): Likewise.
+ (views::_Zip::operator()): Adjust position of [[nodiscard]] for
+ compatibility with -fconcepts-ts.
+ (zip_transform_view::_Sentinel): Uglify 'OtherConst'.
+ (views::_ZipTransform::operator()): Adjust position of
+ [[nodiscard]] for compatibilty with -fconcepts-ts.
+
+2022-08-31 Martin Liska <mliska@suse.cz>
+
+ * configure: Regenerate.
+ * crossconfig.m4: Remove deprecated ports.
+
+2022-08-31 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/debug/debug.h: Use nullptr rather than '0' in checks in post-C++11.
+ * include/debug/string: Likewise.
+ * testsuite/21_strings/basic_string/operations/ends_with/char.cc: Use __gnu_test::string.
+ * testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc: Likewise.
+ * testsuite/21_strings/basic_string/operations/ends_with/wchar_t.cc: Likewise.
+ * testsuite/21_strings/basic_string/operations/starts_with/wchar_t.cc: Likewise.
+ * testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc: Likewise.
+ * testsuite/21_strings/basic_string/operations/starts_with/char.cc: Likewise..
+
+2022-08-31 Patrick Palka <ppalka@redhat.com>
+
+ * include/std/ranges (adjacent_view): Define.
+ (enable_borrowed_range<adjacent_view>): Define.
+ (__detail::__repeated_tuple): Define.
+ (adjacent_view::_Iterator): Define.
+ (adjacent_view::_Sentinel): Define.
+ (views::__detail::__can_adjacent_view): Define.
+ (views::_Adjacent): Define.
+ (views::adjacent): Define.
+ (views::pairwise): Define.
+ * testsuite/std/ranges/adaptors/adjacent/1.cc: New test.
+
+2022-08-31 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/debug/formatter.h
+ [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare.
+ [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare.
+ [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define.
+ [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define.
+ [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define.
+ [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare.
+ [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New.
+ [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New.
+ * src/c++11/debug.cc [_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New.
+ (_Error_formatter::_M_error()): Adapt.
+ * src/libbacktrace/Makefile.am: Add backtrace.c.
+ * src/libbacktrace/Makefile.in: Regenerate.
+ * src/libbacktrace/backtrace-rename.h (backtrace_full): New.
+ * testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc: New test.
+ * doc/xml/manual/debug_mode.xml: Document _GLIBCXX_DEBUG_BACKTRACE.
+ * doc/xml/manual/using.xml: Likewise.
+
+2022-08-31 Patrick Palka <ppalka@redhat.com>
+
+ * testsuite/20_util/logical_traits/requirements/short_circuit.cc: New test.
+
+2022-08-31 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/refwrap.h (reference_wrapper::operator()): Add
+ noexcept-specifier and use __invoke_result instead of result_of.
+ * testsuite/20_util/reference_wrapper/invoke-noexcept.cc: New test.
+
+2022-08-31 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/20_util/reference_wrapper/invoke-2.cc: Improve
+ comments.
+ * testsuite/20_util/reference_wrapper/invoke-3.cc: Likewise.
+ * testsuite/20_util/reference_wrapper/invoke.cc: Likewise.
+
+2022-08-31 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/basic_string.h (basic_string): Add nodiscard
+ attribute to all relevant functions.
+ * include/std/string_view (basic_string_view): Likewise.
+ * testsuite/21_strings/basic_string/capacity/1.cc: Cast unused
+ results to void.
+ * testsuite/21_strings/basic_string/capacity/char/1.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string/capacity/wchar_t/1.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string/cons/char/self_move.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string/element_access/char/1.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string/element_access/char/21674.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string/element_access/wchar_t/1.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string/element_access/wchar_t/21674.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string/lwg2758.cc: Likewise.
+ * testsuite/21_strings/basic_string/lwg2946.cc: Likewise.
+ * testsuite/21_strings/basic_string/operations/contains/nonnull.cc:
+ Add -Wno-unused-result to options.
+ * testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string/operators/char/1.cc: Cast
+ unused results to void.
+ * testsuite/21_strings/basic_string/operators/wchar_t/1.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string_view/capacity/1.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string_view/element_access/char/1.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string_view/element_access/char/2.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string_view/element_access/wchar_t/1.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string_view/element_access/wchar_t/2.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc:
+ Likewise.
+ Add -Wno-unused-result to options.
+ * testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc:
+ Likewise.
+ * testsuite/27_io/basic_stringbuf/sputbackc/char/1.cc: Cast
+ unused results to void.
+ * testsuite/27_io/basic_stringbuf/sputbackc/wchar_t/1.cc:
+ Likewise.
+ * testsuite/27_io/basic_stringbuf/sungetc/char/1.cc: Likewise.
+ * testsuite/27_io/basic_stringbuf/sungetc/wchar_t/1.cc:
+ Likewise.
+
+2022-08-27 Patrick Palka <ppalka@redhat.com>
+
+ * testsuite/20_util/logical_traits/requirements/base_classes.cc: New test.
+
+2022-08-26 Patrick Palka <ppalka@redhat.com>
+
+ * include/std/ranges (zip_view::_Iterator::operator<): Remove
+ as per LWG 3692.
+ (zip_view::_Iterator::operator>): Likewise.
+ (zip_view::_Iterator::operator<=): Likewise.
+ (zip_view::_Iterator::operator>=): Likewise.
+ (zip_view::_Iterator::operator<=>): Remove three_way_comparable
+ constraint as per LWG 3692.
+ (zip_transform_view::_Iterator): Ditto as per LWG 3702.
+
+2022-08-26 Patrick Palka <ppalka@redhat.com>
+
+ * include/std/ranges (zip_view::_Iterator): Befriend
+ zip_transform_view.
+ (__detail::__range_iter_cat): Define.
+ (zip_transform_view): Define.
+ (zip_transform_view::_Iterator): Define.
+ (zip_transform_view::_Sentinel): Define.
+ (views::__detail::__can_zip_transform_view): Define.
+ (views::_ZipTransform): Define.
+ (views::zip_transform): Define.
+ * testsuite/std/ranges/zip_transform/1.cc: New test.
+
+2022-08-26 Patrick Palka <ppalka@redhat.com>
+
+ * include/std/type_traits (enable_if, __enable_if_t): Define them
+ earlier.
+ (__detail::__first_t): Define.
+ (__detail::__or_fn, __detail::__and_fn): Declare.
+ (__or_, __and_): Redefine as alias templates in terms of __or_fn
+ and __and_fn.
+ (__not_): Redefine as an alias template.
+ (__detail::__disjunction_impl, __detail::__conjunction_impl):
+ Define.
+ (conjuction, disjunction): Redefine in terms of __disjunction_impl
+ and __conjunction_impl.
+
+2022-08-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/system_error (error_code::_Check): New alias
+ template for constructor SFINAE constraint.
+ (error_code::error_code(ErrorCodeEnum)): Use it.
+ (error_code::operator=(ErrorCodeEnum)): Remove.
+ (error_condition::_Check): New alias template for constraint.
+ (error_condition::error_condition(ErrorConditionEnum)): Use it.
+ (error_condition::operator=(ErrorConditionEnum)): Remove.
+ * testsuite/19_diagnostics/error_code/cons/1.cc: Check
+ constructor taking user-defined error enum.
+ * testsuite/19_diagnostics/error_condition/cons/1.cc: Likewise.
+
+2022-08-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/basic_string.h (starts_with, ends_with, contains):
+ Add nonnull attribute.
+ * include/bits/cow_string.h (starts_with, ends_with, contains):
+ Likewise.
+ * include/std/string_view (starts_with, ends_with, contains):
+ Likewise.
+ * testsuite/21_strings/basic_string/operations/contains/nonnull.cc
+ * testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc
+ * testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc
+ * testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc
+ * testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc
+ * testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc
+
+2022-08-25 Patrick Palka <ppalka@redhat.com>
+
+ * include/std/ranges (lazy_split_view::_OuterIter::_M_current):
+ Remove redundant comment.
+ (lazy_split_view::_M_current): Likewise.
+ (common_view::common_view): Remove commented out view-converting
+ constructor as per LWG3405.
+ (elements_view::_Iterator::_Iterator): Uglify 'current' and 'i'.
+
+2022-08-24 Patrick Palka <ppalka@redhat.com>
+
+ * include/bits/ranges_algo.h (__min_fn, min): Move to ...
+ * include/bits/ranges_util.h: ... here, in order to avoid
+ including all of ranges_algo.h from <ranges>.
+ * include/std/ranges (__detail::__zip_is_common): Define for
+ C++23 as per P2321R2.
+ (__detail::__tuple_or_pair): Likewise.
+ (__detail::__tuple_or_pair_t): Likewise.
+ (__detail::__tuple_transform): Likewise.
+ (__detail::__tuple_for_each): Likewise.
+ (zip_view): Likewise.
+ (enable_borrowed_range<zip_view>): Likewise.
+ (__detail::__all_random_access): Likewise.
+ (__detail::__all_bidirectional): Likewise.
+ (__detail::__all_forward): Likewise.
+ (__detail::__zip_view_iter_cat): Likewise.
+ (zip_view::_Iterator): Likewise.
+ (zip_view::_Sentinel): Likewise.
+ * testsuite/std/ranges/zip/1.cc: New test.
+
+2022-08-24 Jonathan Wakely <jwakely@redhat.com>
+
+ Revert:
+ 2022-08-24 Will Hawkins <whh8b@obs.cr>
+
+ * include/bits/basic_string.h (operator+(const string&, const char*)):
+ Remove naive implementation.
+ * include/bits/basic_string.tcc (operator+(const string&, const char*)):
+ Add single-allocation implementation.
+
+2022-08-24 Patrick Palka <ppalka@redhat.com>
+
+ * include/bits/stl_pair.h (pair::swap const): Add non-standard
+ is_swappable_v constraints.
+ * include/std/tuple (tuple::swap const): Likewise.
+ * testsuite/20_util/tuple/cons/noexcept_specs.cc: Correct some
+ asserts in C++23 mode.
+
+2022-08-24 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/stl_algo.h (__stable_sort): Cast size to
+ iterator's difference type.
+ * testsuite/25_algorithms/stable_sort/4.cc: New test.
+
+2022-08-24 Will Hawkins <whh8b@obs.cr>
+
+ * include/bits/basic_string.h (operator+(const string&, const char*)):
+ Remove naive implementation.
+ * include/bits/basic_string.tcc (operator+(const string&, const char*)):
+ Add single-allocation implementation.
+
+2022-08-24 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/20_util/duration_cast/rounding.cc: Check abs with
+ non-reduced duration.
+
2022-08-23 Patrick Palka <ppalka@redhat.com>
* include/bits/stl_bvector.h (_Bit_reference::operator=): Define
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 9e2ee86..1772eef 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -47955,20 +47955,6 @@ $as_echo "$gcc_cv_have_tls" >&6; }
$as_echo "#define HAVE_TLS 1" >>confdefs.h
fi
- case "$target" in
- *-hpux10*)
- $as_echo "#define HAVE_ISINF 1" >>confdefs.h
-
- $as_echo "#define HAVE_ISINFF 1" >>confdefs.h
-
- $as_echo "#define HAVE_ISNANF 1" >>confdefs.h
-
- $as_echo "#define HAVE_FINITE 1" >>confdefs.h
-
- $as_echo "#define HAVE_FINITEF 1" >>confdefs.h
-
- ;;
- esac
;;
*-linux* | *-uclinux* | *-gnu* | *-kfreebsd*-gnu | *-cygwin* | *-solaris*)
diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4
index e8ff89f..130f47f 100644
--- a/libstdc++-v3/crossconfig.m4
+++ b/libstdc++-v3/crossconfig.m4
@@ -173,15 +173,6 @@ case "${host}" in
AC_DEFINE(HAVE_STRTOLD)
GCC_CHECK_TLS
- case "$target" in
- *-hpux10*)
- AC_DEFINE(HAVE_ISINF)
- AC_DEFINE(HAVE_ISINFF)
- AC_DEFINE(HAVE_ISNANF)
- AC_DEFINE(HAVE_FINITE)
- AC_DEFINE(HAVE_FINITEF)
- ;;
- esac
;;
*-linux* | *-uclinux* | *-gnu* | *-kfreebsd*-gnu | *-cygwin* | *-solaris*)
GLIBCXX_CHECK_COMPILER_FEATURES
diff --git a/libstdc++-v3/doc/xml/manual/debug_mode.xml b/libstdc++-v3/doc/xml/manual/debug_mode.xml
index 988c4a9..dadc0cd 100644
--- a/libstdc++-v3/doc/xml/manual/debug_mode.xml
+++ b/libstdc++-v3/doc/xml/manual/debug_mode.xml
@@ -161,6 +161,12 @@ which always works correctly.
<code>GLIBCXX_DEBUG_MESSAGE_LENGTH</code> can be used to request a
different length.</para>
+<para>Note that libstdc++ is able to produce backtraces on error.
+ It requires that you configure libstdc++ build with
+ <option>--enable-libstdcxx-backtrace=yes</option>.
+ Use <code>-D_GLIBCXX_DEBUG_BACKTRACE</code> to activate it.
+ You'll then have to link with libstdc++_libbacktrace static library
+ (<option>-lstdc++_libbacktrace</option>) to build your application.</para>
</section>
<section xml:id="debug_mode.using.specific" xreflabel="Using Specific"><info><title>Using a Specific Debug Container</title></info>
diff --git a/libstdc++-v3/doc/xml/manual/using.xml b/libstdc++-v3/doc/xml/manual/using.xml
index 0b9a0c9..0acdba6 100644
--- a/libstdc++-v3/doc/xml/manual/using.xml
+++ b/libstdc++-v3/doc/xml/manual/using.xml
@@ -1144,6 +1144,15 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 hello.cc -o test.exe
extensions and libstdc++-specific behavior into errors.
</para>
</listitem></varlistentry>
+ <varlistentry><term><code>_GLIBCXX_DEBUG_BACKTRACE</code></term>
+ <listitem>
+ <para>
+ Undefined by default. Considered only if libstdc++ has been configured with
+ <option>--enable-libstdcxx-backtrace=yes</option> and if <code>_GLIBCXX_DEBUG</code>
+ is defined. When defined display backtraces on
+ <link linkend="manual.ext.debug_mode">debug mode</link> assertions.
+ </para>
+ </listitem></varlistentry>
<varlistentry><term><code>_GLIBCXX_PARALLEL</code></term>
<listitem>
<para>Undefined by default. When defined, compiles user code
@@ -1650,6 +1659,7 @@ A quick read of the relevant part of the GCC
header will remain compatible between different GCC releases.
</para>
</section>
+
</section>
<section xml:id="manual.intro.using.concurrency" xreflabel="Concurrency"><info><title>Concurrency</title></info>
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index b04fba9..0df64ea 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -942,7 +942,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Returns a read/write iterator that points to the first character in
* the %string.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
iterator
begin() _GLIBCXX_NOEXCEPT
{ return iterator(_M_data()); }
@@ -951,7 +951,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Returns a read-only (constant) iterator that points to the first
* character in the %string.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_iterator
begin() const _GLIBCXX_NOEXCEPT
{ return const_iterator(_M_data()); }
@@ -960,7 +960,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Returns a read/write iterator that points one past the last
* character in the %string.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
iterator
end() _GLIBCXX_NOEXCEPT
{ return iterator(_M_data() + this->size()); }
@@ -969,7 +969,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Returns a read-only (constant) iterator that points one past the
* last character in the %string.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_iterator
end() const _GLIBCXX_NOEXCEPT
{ return const_iterator(_M_data() + this->size()); }
@@ -979,7 +979,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* character in the %string. Iteration is done in reverse element
* order.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
reverse_iterator
rbegin() _GLIBCXX_NOEXCEPT
{ return reverse_iterator(this->end()); }
@@ -989,7 +989,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* to the last character in the %string. Iteration is done in
* reverse element order.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_reverse_iterator
rbegin() const _GLIBCXX_NOEXCEPT
{ return const_reverse_iterator(this->end()); }
@@ -999,7 +999,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* first character in the %string. Iteration is done in reverse
* element order.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
reverse_iterator
rend() _GLIBCXX_NOEXCEPT
{ return reverse_iterator(this->begin()); }
@@ -1009,7 +1009,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* to one before the first character in the %string. Iteration
* is done in reverse element order.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_reverse_iterator
rend() const _GLIBCXX_NOEXCEPT
{ return const_reverse_iterator(this->begin()); }
@@ -1019,7 +1019,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Returns a read-only (constant) iterator that points to the first
* character in the %string.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_iterator
cbegin() const noexcept
{ return const_iterator(this->_M_data()); }
@@ -1028,7 +1028,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Returns a read-only (constant) iterator that points one past the
* last character in the %string.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_iterator
cend() const noexcept
{ return const_iterator(this->_M_data() + this->size()); }
@@ -1038,7 +1038,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* to the last character in the %string. Iteration is done in
* reverse element order.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_reverse_iterator
crbegin() const noexcept
{ return const_reverse_iterator(this->end()); }
@@ -1048,7 +1048,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* to one before the first character in the %string. Iteration
* is done in reverse element order.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_reverse_iterator
crend() const noexcept
{ return const_reverse_iterator(this->begin()); }
@@ -1058,20 +1058,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
// Capacity:
/// Returns the number of characters in the string, not including any
/// null-termination.
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
size() const _GLIBCXX_NOEXCEPT
{ return _M_string_length; }
/// Returns the number of characters in the string, not including any
/// null-termination.
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
length() const _GLIBCXX_NOEXCEPT
{ return _M_string_length; }
/// Returns the size() of the largest possible %string.
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
max_size() const _GLIBCXX_NOEXCEPT
{ return (_Alloc_traits::max_size(_M_get_allocator()) - 1) / 2; }
@@ -1127,7 +1127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Returns the total number of characters that the %string can hold
* before needing to allocate more memory.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
capacity() const _GLIBCXX_NOEXCEPT
{
@@ -1194,7 +1194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* out_of_range lookups are not defined. (For checked lookups
* see at().)
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_reference
operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT
{
@@ -1212,7 +1212,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* out_of_range lookups are not defined. (For checked lookups
* see at().)
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
reference
operator[](size_type __pos)
{
@@ -1234,7 +1234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* first checked that it is in the range of the string. The function
* throws out_of_range if the check fails.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_reference
at(size_type __n) const
{
@@ -1256,7 +1256,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* first checked that it is in the range of the string. The function
* throws out_of_range if the check fails.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
reference
at(size_type __n)
{
@@ -1273,7 +1273,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Returns a read/write reference to the data at the first
* element of the %string.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
reference
front() noexcept
{
@@ -1285,7 +1285,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Returns a read-only (constant) reference to the data at the first
* element of the %string.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_reference
front() const noexcept
{
@@ -1297,7 +1297,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Returns a read/write reference to the data at the last
* element of the %string.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
reference
back() noexcept
{
@@ -1309,7 +1309,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* Returns a read-only (constant) reference to the data at the
* last element of the %string.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const_reference
back() const noexcept
{
@@ -2549,7 +2549,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* This is a handle to internal data. Do not modify or dire things may
* happen.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const _CharT*
c_str() const _GLIBCXX_NOEXCEPT
{ return _M_data(); }
@@ -2562,7 +2562,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* allows modifying the contents use @c &str[0] instead,
* (or in C++17 the non-const @c str.data() overload).
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
const _CharT*
data() const _GLIBCXX_NOEXCEPT
{ return _M_data(); }
@@ -2574,7 +2574,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* This is a pointer to the character sequence held by the string.
* Modifying the characters in the sequence is allowed.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
_CharT*
data() noexcept
{ return _M_data(); }
@@ -2583,7 +2583,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
/**
* @brief Return copy of allocator used to construct this string.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
allocator_type
get_allocator() const _GLIBCXX_NOEXCEPT
{ return _M_get_allocator(); }
@@ -2600,7 +2600,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* returns the index where it begins. If not found, returns
* npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find(const _CharT* __s, size_type __pos, size_type __n) const
_GLIBCXX_NOEXCEPT;
@@ -2615,7 +2615,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* this string. If found, returns the index where it begins. If not
* found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find(const basic_string& __str, size_type __pos = 0) const
_GLIBCXX_NOEXCEPT
@@ -2629,7 +2629,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return Index of start of first occurrence.
*/
template<typename _Tp>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
_If_sv<_Tp, size_type>
find(const _Tp& __svt, size_type __pos = 0) const
noexcept(is_same<_Tp, __sv_type>::value)
@@ -2649,7 +2649,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* __s within this string. If found, returns the index where
* it begins. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
{
@@ -2667,7 +2667,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* this string. If found, returns the index where it was
* found. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT;
@@ -2681,7 +2681,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* __str within this string. If found, returns the index where
* it begins. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
rfind(const basic_string& __str, size_type __pos = npos) const
_GLIBCXX_NOEXCEPT
@@ -2695,7 +2695,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return Index of start of last occurrence.
*/
template<typename _Tp>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
_If_sv<_Tp, size_type>
rfind(const _Tp& __svt, size_type __pos = npos) const
noexcept(is_same<_Tp, __sv_type>::value)
@@ -2717,7 +2717,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* returns the index where it begins. If not found, returns
* npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
rfind(const _CharT* __s, size_type __pos, size_type __n) const
_GLIBCXX_NOEXCEPT;
@@ -2732,7 +2732,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @a __s within this string. If found, returns the index
* where it begins. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
rfind(const _CharT* __s, size_type __pos = npos) const
{
@@ -2750,7 +2750,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* this string. If found, returns the index where it was
* found. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT;
@@ -2765,7 +2765,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* returns the index where it was found. If not found, returns
* npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_first_of(const basic_string& __str, size_type __pos = 0) const
_GLIBCXX_NOEXCEPT
@@ -2780,7 +2780,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return Index of first occurrence.
*/
template<typename _Tp>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
_If_sv<_Tp, size_type>
find_first_of(const _Tp& __svt, size_type __pos = 0) const
noexcept(is_same<_Tp, __sv_type>::value)
@@ -2802,7 +2802,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* found, returns the index where it was found. If not found,
* returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
_GLIBCXX_NOEXCEPT;
@@ -2817,7 +2817,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* characters of @a __s within this string. If found, returns
* the index where it was found. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_first_of(const _CharT* __s, size_type __pos = 0) const
_GLIBCXX_NOEXCEPT
@@ -2838,7 +2838,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*
* Note: equivalent to find(__c, __pos).
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
{ return this->find(__c, __pos); }
@@ -2854,7 +2854,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* returns the index where it was found. If not found, returns
* npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_last_of(const basic_string& __str, size_type __pos = npos) const
_GLIBCXX_NOEXCEPT
@@ -2869,7 +2869,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return Index of last occurrence.
*/
template<typename _Tp>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
_If_sv<_Tp, size_type>
find_last_of(const _Tp& __svt, size_type __pos = npos) const
noexcept(is_same<_Tp, __sv_type>::value)
@@ -2891,7 +2891,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* found, returns the index where it was found. If not found,
* returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
_GLIBCXX_NOEXCEPT;
@@ -2906,7 +2906,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* characters of @a __s within this string. If found, returns
* the index where it was found. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_last_of(const _CharT* __s, size_type __pos = npos) const
_GLIBCXX_NOEXCEPT
@@ -2927,7 +2927,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*
* Note: equivalent to rfind(__c, __pos).
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
{ return this->rfind(__c, __pos); }
@@ -2942,7 +2942,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* in @a __str within this string. If found, returns the index where it
* was found. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_first_not_of(const basic_string& __str, size_type __pos = 0) const
_GLIBCXX_NOEXCEPT
@@ -2957,8 +2957,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return Index of first occurrence.
*/
template<typename _Tp>
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
_If_sv<_Tp, size_type>
- _GLIBCXX20_CONSTEXPR
find_first_not_of(const _Tp& __svt, size_type __pos = 0) const
noexcept(is_same<_Tp, __sv_type>::value)
{
@@ -2979,7 +2979,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* this string. If found, returns the index where it was
* found. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_first_not_of(const _CharT* __s, size_type __pos,
size_type __n) const _GLIBCXX_NOEXCEPT;
@@ -2994,7 +2994,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* contained in @a __s within this string. If found, returns
* the index where it was found. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_first_not_of(const _CharT* __s, size_type __pos = 0) const
_GLIBCXX_NOEXCEPT
@@ -3013,7 +3013,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* other than @a __c within this string. If found, returns the
* index where it was found. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_first_not_of(_CharT __c, size_type __pos = 0) const
_GLIBCXX_NOEXCEPT;
@@ -3029,7 +3029,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* returns the index where it was found. If not found, returns
* npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_last_not_of(const basic_string& __str, size_type __pos = npos) const
_GLIBCXX_NOEXCEPT
@@ -3044,7 +3044,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return Index of last occurrence.
*/
template<typename _Tp>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
_If_sv<_Tp, size_type>
find_last_not_of(const _Tp& __svt, size_type __pos = npos) const
noexcept(is_same<_Tp, __sv_type>::value)
@@ -3066,7 +3066,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* If found, returns the index where it was found. If not found,
* returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_last_not_of(const _CharT* __s, size_type __pos,
size_type __n) const _GLIBCXX_NOEXCEPT;
@@ -3081,7 +3081,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* returns the index where it was found. If not found, returns
* npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_last_not_of(const _CharT* __s, size_type __pos = npos) const
_GLIBCXX_NOEXCEPT
@@ -3100,7 +3100,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @a __c within this string. If found, returns the index where it was
* found. If not found, returns npos.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
size_type
find_last_not_of(_CharT __c, size_type __pos = npos) const
_GLIBCXX_NOEXCEPT;
@@ -3117,7 +3117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* short, use the remainder of the characters. If @a __pos is
* beyond the end of the string, out_of_range is thrown.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
basic_string
substr(size_type __pos = 0, size_type __n = npos) const
{ return basic_string(*this,
@@ -3137,7 +3137,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* If the result of the comparison is nonzero returns it,
* otherwise the shorter one is ordered first.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
int
compare(const basic_string& __str) const
{
@@ -3158,7 +3158,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return Integer < 0, 0, or > 0.
*/
template<typename _Tp>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
_If_sv<_Tp, int>
compare(const _Tp& __svt) const
noexcept(is_same<_Tp, __sv_type>::value)
@@ -3183,7 +3183,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return Integer < 0, 0, or > 0.
*/
template<typename _Tp>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
_If_sv<_Tp, int>
compare(size_type __pos, size_type __n, const _Tp& __svt) const
noexcept(is_same<_Tp, __sv_type>::value)
@@ -3203,7 +3203,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @return Integer < 0, 0, or > 0.
*/
template<typename _Tp>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
_If_sv<_Tp, int>
compare(size_type __pos1, size_type __n1, const _Tp& __svt,
size_type __pos2, size_type __n2 = npos) const
@@ -3234,7 +3234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* result of the comparison is nonzero returns it, otherwise
* the shorter one is ordered first.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
int
compare(size_type __pos, size_type __n, const basic_string& __str) const
{
@@ -3271,7 +3271,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* If the result of the comparison is nonzero returns it,
* otherwise the shorter one is ordered first.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
int
compare(size_type __pos1, size_type __n1, const basic_string& __str,
size_type __pos2, size_type __n2 = npos) const
@@ -3302,7 +3302,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* comparison is nonzero returns it, otherwise the shorter one is
* ordered first.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
int
compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT
{
@@ -3337,7 +3337,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* the comparison is nonzero returns it, otherwise the shorter
* one is ordered first.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
int
compare(size_type __pos, size_type __n1, const _CharT* __s) const
{
@@ -3376,7 +3376,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* NB: s must have at least n2 characters, &apos;\\0&apos; has
* no special meaning.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
int
compare(size_type __pos, size_type __n1, const _CharT* __s,
size_type __n2) const
@@ -3392,40 +3392,49 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
}
#if __cplusplus >= 202002L
+ [[nodiscard]]
constexpr bool
starts_with(basic_string_view<_CharT, _Traits> __x) const noexcept
{ return __sv_type(this->data(), this->size()).starts_with(__x); }
+ [[nodiscard]]
constexpr bool
starts_with(_CharT __x) const noexcept
{ return __sv_type(this->data(), this->size()).starts_with(__x); }
+ [[nodiscard, __gnu__::__nonnull__]]
constexpr bool
starts_with(const _CharT* __x) const noexcept
{ return __sv_type(this->data(), this->size()).starts_with(__x); }
+ [[nodiscard]]
constexpr bool
ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept
{ return __sv_type(this->data(), this->size()).ends_with(__x); }
+ [[nodiscard]]
constexpr bool
ends_with(_CharT __x) const noexcept
{ return __sv_type(this->data(), this->size()).ends_with(__x); }
+ [[nodiscard, __gnu__::__nonnull__]]
constexpr bool
ends_with(const _CharT* __x) const noexcept
{ return __sv_type(this->data(), this->size()).ends_with(__x); }
#endif // C++20
#if __cplusplus > 202002L
+ [[nodiscard]]
constexpr bool
contains(basic_string_view<_CharT, _Traits> __x) const noexcept
{ return __sv_type(this->data(), this->size()).contains(__x); }
+ [[nodiscard]]
constexpr bool
contains(_CharT __x) const noexcept
{ return __sv_type(this->data(), this->size()).contains(__x); }
+ [[nodiscard, __gnu__::__nonnull__]]
constexpr bool
contains(const _CharT* __x) const noexcept
{ return __sv_type(this->data(), this->size()).contains(__x); }
@@ -3480,7 +3489,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return New string with value of @a __lhs followed by @a __rhs.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
basic_string<_CharT, _Traits, _Alloc>
operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3497,7 +3506,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return New string with value of @a __lhs followed by @a __rhs.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
basic_string<_CharT,_Traits,_Alloc>
operator+(const _CharT* __lhs,
const basic_string<_CharT,_Traits,_Alloc>& __rhs);
@@ -3509,7 +3518,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return New string with @a __lhs followed by @a __rhs.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
basic_string<_CharT,_Traits,_Alloc>
operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
@@ -3520,7 +3529,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return New string with @a __lhs followed by @a __rhs.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline basic_string<_CharT, _Traits, _Alloc>
operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const _CharT* __rhs)
@@ -3537,7 +3546,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return New string with @a __lhs followed by @a __rhs.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline basic_string<_CharT, _Traits, _Alloc>
operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
{
@@ -3550,7 +3559,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
#if __cplusplus >= 201103L
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline basic_string<_CharT, _Traits, _Alloc>
operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3564,7 +3573,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
{ return std::move(__rhs.insert(0, __lhs)); }
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline basic_string<_CharT, _Traits, _Alloc>
operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
basic_string<_CharT, _Traits, _Alloc>&& __rhs)
@@ -3587,28 +3596,28 @@ _GLIBCXX_END_NAMESPACE_CXX11
}
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline basic_string<_CharT, _Traits, _Alloc>
operator+(const _CharT* __lhs,
basic_string<_CharT, _Traits, _Alloc>&& __rhs)
{ return std::move(__rhs.insert(0, __lhs)); }
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline basic_string<_CharT, _Traits, _Alloc>
operator+(_CharT __lhs,
basic_string<_CharT, _Traits, _Alloc>&& __rhs)
{ return std::move(__rhs.insert(0, 1, __lhs)); }
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline basic_string<_CharT, _Traits, _Alloc>
operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
const _CharT* __rhs)
{ return std::move(__lhs.append(__rhs)); }
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline basic_string<_CharT, _Traits, _Alloc>
operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
_CharT __rhs)
@@ -3623,7 +3632,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3640,7 +3649,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const _CharT* __rhs)
@@ -3658,6 +3667,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* greater than, or incomparable with `__rhs`.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ [[nodiscard]]
constexpr auto
operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs) noexcept
@@ -3672,6 +3682,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* greater than, or incomparable with `__rhs`.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ [[nodiscard]]
constexpr auto
operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const _CharT* __rhs) noexcept
@@ -3685,6 +3696,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __rhs.compare(@a __lhs) == 0. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator==(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3698,6 +3710,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3711,6 +3724,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __rhs.compare(@a __lhs) != 0. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator!=(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3723,6 +3737,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const _CharT* __rhs)
@@ -3736,6 +3751,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs precedes @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3749,6 +3765,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs precedes @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const _CharT* __rhs)
@@ -3761,6 +3778,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs precedes @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator<(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3774,6 +3792,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs follows @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3787,6 +3806,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs follows @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const _CharT* __rhs)
@@ -3799,6 +3819,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs follows @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator>(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3812,6 +3833,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3825,6 +3847,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const _CharT* __rhs)
@@ -3837,6 +3860,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs doesn't follow @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator<=(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3850,6 +3874,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -3863,6 +3888,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const _CharT* __rhs)
@@ -3875,6 +3901,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
* @return True if @a __lhs doesn't precede @a __rhs. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX_NODISCARD
inline bool
operator>=(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
@@ -4057,6 +4084,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
// DR 1261. Insufficent overloads for to_string / to_wstring
+ _GLIBCXX_NODISCARD
inline string
to_string(int __val)
#if _GLIBCXX_USE_CXX11_ABI && (__CHAR_BIT__ * __SIZEOF_INT__) <= 32
@@ -4071,6 +4099,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
return __str;
}
+ _GLIBCXX_NODISCARD
inline string
to_string(unsigned __val)
#if _GLIBCXX_USE_CXX11_ABI && (__CHAR_BIT__ * __SIZEOF_INT__) <= 32
@@ -4082,6 +4111,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
return __str;
}
+ _GLIBCXX_NODISCARD
inline string
to_string(long __val)
#if _GLIBCXX_USE_CXX11_ABI && (__CHAR_BIT__ * __SIZEOF_LONG__) <= 32
@@ -4096,6 +4126,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
return __str;
}
+ _GLIBCXX_NODISCARD
inline string
to_string(unsigned long __val)
#if _GLIBCXX_USE_CXX11_ABI && (__CHAR_BIT__ * __SIZEOF_LONG__) <= 32
@@ -4107,6 +4138,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
return __str;
}
+ _GLIBCXX_NODISCARD
inline string
to_string(long long __val)
{
@@ -4119,6 +4151,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
return __str;
}
+ _GLIBCXX_NODISCARD
inline string
to_string(unsigned long long __val)
{
@@ -4130,6 +4163,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
#if _GLIBCXX_USE_C99_STDIO
// NB: (v)snprintf vs sprintf.
+ _GLIBCXX_NODISCARD
inline string
to_string(float __val)
{
@@ -4139,6 +4173,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
"%f", __val);
}
+ _GLIBCXX_NODISCARD
inline string
to_string(double __val)
{
@@ -4148,6 +4183,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
"%f", __val);
}
+ _GLIBCXX_NODISCARD
inline string
to_string(long double __val)
{
@@ -4199,40 +4235,47 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
#ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF
// DR 1261.
+ _GLIBCXX_NODISCARD
inline wstring
to_wstring(int __val)
{ return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(int),
L"%d", __val); }
+ _GLIBCXX_NODISCARD
inline wstring
to_wstring(unsigned __val)
{ return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
4 * sizeof(unsigned),
L"%u", __val); }
+ _GLIBCXX_NODISCARD
inline wstring
to_wstring(long __val)
{ return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(long),
L"%ld", __val); }
+ _GLIBCXX_NODISCARD
inline wstring
to_wstring(unsigned long __val)
{ return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
4 * sizeof(unsigned long),
L"%lu", __val); }
+ _GLIBCXX_NODISCARD
inline wstring
to_wstring(long long __val)
{ return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
4 * sizeof(long long),
L"%lld", __val); }
+ _GLIBCXX_NODISCARD
inline wstring
to_wstring(unsigned long long __val)
{ return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
4 * sizeof(unsigned long long),
L"%llu", __val); }
+ _GLIBCXX_NODISCARD
inline wstring
to_wstring(float __val)
{
@@ -4242,6 +4285,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
L"%f", __val);
}
+ _GLIBCXX_NODISCARD
inline wstring
to_wstring(double __val)
{
@@ -4251,6 +4295,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
L"%f", __val);
}
+ _GLIBCXX_NODISCARD
inline wstring
to_wstring(long double __val)
{
@@ -4284,6 +4329,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __str_hash_base
: public __hash_base<size_t, _StrT>
{
+ [[__nodiscard__]]
size_t
operator()(const _StrT& __s) const noexcept
{ return _Hash_impl::hash(__s.data(), __s.length() * sizeof(_CharT)); }
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index f16e33a..f5f0333 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -3012,6 +3012,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
starts_with(_CharT __x) const noexcept
{ return __sv_type(this->data(), this->size()).starts_with(__x); }
+ [[__gnu__::__nonnull__]]
bool
starts_with(const _CharT* __x) const noexcept
{ return __sv_type(this->data(), this->size()).starts_with(__x); }
@@ -3024,6 +3025,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
ends_with(_CharT __x) const noexcept
{ return __sv_type(this->data(), this->size()).ends_with(__x); }
+ [[__gnu__::__nonnull__]]
bool
ends_with(const _CharT* __x) const noexcept
{ return __sv_type(this->data(), this->size()).ends_with(__x); }
@@ -3038,6 +3040,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
contains(_CharT __x) const noexcept
{ return __sv_type(this->data(), this->size()).contains(__x); }
+ [[__gnu__::__nonnull__]]
bool
contains(const _CharT* __x) const noexcept
{ return __sv_type(this->data(), this->size()).contains(__x); }
diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
index 3d30fb1..2a11636 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -2902,59 +2902,7 @@ namespace ranges
inline constexpr __set_symmetric_difference_fn set_symmetric_difference{};
- struct __min_fn
- {
- template<typename _Tp, typename _Proj = identity,
- indirect_strict_weak_order<projected<const _Tp*, _Proj>>
- _Comp = ranges::less>
- constexpr const _Tp&
- operator()(const _Tp& __a, const _Tp& __b,
- _Comp __comp = {}, _Proj __proj = {}) const
- {
- if (std::__invoke(__comp,
- std::__invoke(__proj, __b),
- std::__invoke(__proj, __a)))
- return __b;
- else
- return __a;
- }
-
- template<input_range _Range, typename _Proj = identity,
- indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
- _Comp = ranges::less>
- requires indirectly_copyable_storable<iterator_t<_Range>,
- range_value_t<_Range>*>
- constexpr range_value_t<_Range>
- operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
- {
- auto __first = ranges::begin(__r);
- auto __last = ranges::end(__r);
- __glibcxx_assert(__first != __last);
- auto __result = *__first;
- while (++__first != __last)
- {
- auto __tmp = *__first;
- if (std::__invoke(__comp,
- std::__invoke(__proj, __tmp),
- std::__invoke(__proj, __result)))
- __result = std::move(__tmp);
- }
- return __result;
- }
-
- template<copyable _Tp, typename _Proj = identity,
- indirect_strict_weak_order<projected<const _Tp*, _Proj>>
- _Comp = ranges::less>
- constexpr _Tp
- operator()(initializer_list<_Tp> __r,
- _Comp __comp = {}, _Proj __proj = {}) const
- {
- return (*this)(ranges::subrange(__r),
- std::move(__comp), std::move(__proj));
- }
- };
-
- inline constexpr __min_fn min{};
+ // min is defined in <bits/ranges_util.h>.
struct __max_fn
{
diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h
index 38db33f..866d7c5 100644
--- a/libstdc++-v3/include/bits/ranges_base.h
+++ b/libstdc++-v3/include/bits/ranges_base.h
@@ -778,7 +778,7 @@ namespace ranges
else if (__n != 0) [[likely]]
{
// n and bound must not lead in opposite directions:
- __glibcxx_assert(__n < 0 == __diff < 0);
+ __glibcxx_assert((__n < 0) == (__diff < 0));
(*this)(__it, __n);
return 0;
diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h
index 37d7bc8..bb56dee 100644
--- a/libstdc++-v3/include/bits/ranges_util.h
+++ b/libstdc++-v3/include/bits/ranges_util.h
@@ -649,6 +649,61 @@ namespace ranges
};
inline constexpr __search_fn search{};
+
+ struct __min_fn
+ {
+ template<typename _Tp, typename _Proj = identity,
+ indirect_strict_weak_order<projected<const _Tp*, _Proj>>
+ _Comp = ranges::less>
+ constexpr const _Tp&
+ operator()(const _Tp& __a, const _Tp& __b,
+ _Comp __comp = {}, _Proj __proj = {}) const
+ {
+ if (std::__invoke(__comp,
+ std::__invoke(__proj, __b),
+ std::__invoke(__proj, __a)))
+ return __b;
+ else
+ return __a;
+ }
+
+ template<input_range _Range, typename _Proj = identity,
+ indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
+ _Comp = ranges::less>
+ requires indirectly_copyable_storable<iterator_t<_Range>,
+ range_value_t<_Range>*>
+ constexpr range_value_t<_Range>
+ operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
+ {
+ auto __first = ranges::begin(__r);
+ auto __last = ranges::end(__r);
+ __glibcxx_assert(__first != __last);
+ auto __result = *__first;
+ while (++__first != __last)
+ {
+ auto __tmp = *__first;
+ if (std::__invoke(__comp,
+ std::__invoke(__proj, __tmp),
+ std::__invoke(__proj, __result)))
+ __result = std::move(__tmp);
+ }
+ return __result;
+ }
+
+ template<copyable _Tp, typename _Proj = identity,
+ indirect_strict_weak_order<projected<const _Tp*, _Proj>>
+ _Comp = ranges::less>
+ constexpr _Tp
+ operator()(initializer_list<_Tp> __r,
+ _Comp __comp = {}, _Proj __proj = {}) const
+ {
+ return (*this)(ranges::subrange(__r),
+ std::move(__comp), std::move(__proj));
+ }
+ };
+
+ inline constexpr __min_fn min{};
+
} // namespace ranges
using ranges::get;
diff --git a/libstdc++-v3/include/bits/refwrap.h b/libstdc++-v3/include/bits/refwrap.h
index 8016f87..976902b 100644
--- a/libstdc++-v3/include/bits/refwrap.h
+++ b/libstdc++-v3/include/bits/refwrap.h
@@ -348,8 +348,9 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type)
template<typename... _Args>
_GLIBCXX20_CONSTEXPR
- typename result_of<_Tp&(_Args&&...)>::type
+ typename __invoke_result<_Tp&, _Args...>::type
operator()(_Args&&... __args) const
+ noexcept(__is_nothrow_invocable<_Tp&, _Args...>::value)
{
#if __cplusplus > 201703L
if constexpr (is_object_v<type>)
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index c607805..57fa1c1 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -5026,8 +5026,9 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
_TmpBuf __buf(__first, (__last - __first + 1) / 2);
if (__builtin_expect(__buf.requested_size() == __buf.size(), true))
- std::__stable_sort_adaptive(__first, __first + __buf.size(), __last,
- __buf.begin(), __comp);
+ std::__stable_sort_adaptive(__first,
+ __first + _DistanceType(__buf.size()),
+ __last, __buf.begin(), __comp);
else if (__builtin_expect(__buf.begin() == 0, false))
std::__inplace_stable_sort(__first, __last, __comp);
else
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index bffca0d..d0f07b0 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -213,10 +213,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#if __cplusplus > 202002L
+ // As an extension, we constrain the const swap member function in order
+ // to continue accepting explicit instantiation of pairs whose elements
+ // are not all const swappable. Without this constraint, such an
+ // explicit instantiation would also instantiate the ill-formed body of
+ // this function and yield a hard error. This constraint shouldn't
+ // affect the behavior of valid programs.
constexpr void
swap(const pair& __p) const
noexcept(__and_v<__is_nothrow_swappable<const _T1>,
__is_nothrow_swappable<const _T2>>)
+ requires is_swappable_v<const _T1> && is_swappable_v<const _T2>
{
using std::swap;
swap(first, __p.first);
diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h
index 28e250f..f423376 100644
--- a/libstdc++-v3/include/debug/debug.h
+++ b/libstdc++-v3/include/debug/debug.h
@@ -118,10 +118,17 @@ namespace __gnu_debug
__glibcxx_check_heap(_First,_Last)
# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \
__glibcxx_check_heap_pred(_First,_Last,_Pred)
-# define __glibcxx_requires_string(_String) \
+# if __cplusplus < 201103L
+# define __glibcxx_requires_string(_String) \
_GLIBCXX_DEBUG_PEDASSERT(_String != 0)
-# define __glibcxx_requires_string_len(_String,_Len) \
+# define __glibcxx_requires_string_len(_String,_Len) \
_GLIBCXX_DEBUG_PEDASSERT(_String != 0 || _Len == 0)
+# else
+# define __glibcxx_requires_string(_String) \
+ _GLIBCXX_DEBUG_PEDASSERT(_String != nullptr)
+# define __glibcxx_requires_string_len(_String,_Len) \
+ _GLIBCXX_DEBUG_PEDASSERT(_String != nullptr || _Len == 0)
+# endif
# define __glibcxx_requires_irreflexive(_First,_Last) \
__glibcxx_check_irreflexive(_First,_Last)
# define __glibcxx_requires_irreflexive2(_First,_Last) \
diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h
index 748d4fb..b4b7238 100644
--- a/libstdc++-v3/include/debug/formatter.h
+++ b/libstdc++-v3/include/debug/formatter.h
@@ -31,6 +31,37 @@
#include <bits/c++config.h>
+#if _GLIBCXX_HAVE_STACKTRACE
+struct __glibcxx_backtrace_state;
+
+extern "C"
+{
+ __glibcxx_backtrace_state*
+ __glibcxx_backtrace_create_state(const char*, int,
+ void(*)(void*, const char*, int),
+ void*);
+
+ typedef int (*__glibcxx_backtrace_full_callback) (
+ void*, __UINTPTR_TYPE__, const char *, int, const char*);
+
+ typedef void (*__glibcxx_backtrace_error_callback) (
+ void*, const char*, int);
+
+ typedef int (*__glibcxx_backtrace_full_func) (
+ __glibcxx_backtrace_state*, int,
+ __glibcxx_backtrace_full_callback,
+ __glibcxx_backtrace_error_callback,
+ void*);
+
+ int
+ __glibcxx_backtrace_full(
+ __glibcxx_backtrace_state*, int,
+ __glibcxx_backtrace_full_callback,
+ __glibcxx_backtrace_error_callback,
+ void*);
+}
+#endif
+
#if __cpp_rtti
# include <typeinfo>
# define _GLIBCXX_TYPEID(_Type) &typeid(_Type)
@@ -576,6 +607,15 @@ namespace __gnu_debug
const char* __function)
: _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0)
, _M_function(__function)
+#if _GLIBCXX_HAVE_STACKTRACE
+# ifdef _GLIBCXX_DEBUG_BACKTRACE
+ , _M_backtrace_state(
+ __glibcxx_backtrace_create_state(nullptr, 0, nullptr, nullptr))
+ , _M_backtrace_full(&__glibcxx_backtrace_full)
+# else
+ , _M_backtrace_state()
+# endif
+#endif
{ }
#if !_GLIBCXX_INLINE_VERSION
@@ -591,6 +631,10 @@ namespace __gnu_debug
unsigned int _M_num_parameters;
const char* _M_text;
const char* _M_function;
+#if _GLIBCXX_HAVE_STACKTRACE
+ __glibcxx_backtrace_state* _M_backtrace_state;
+ __glibcxx_backtrace_full_func _M_backtrace_full;
+#endif
public:
static _Error_formatter&
diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string
index a4482db..c16751c 100644
--- a/libstdc++-v3/include/debug/string
+++ b/libstdc++-v3/include/debug/string
@@ -50,14 +50,25 @@
#endif
#ifdef _GLIBCXX_DEBUG_PEDANTIC
-# define __glibcxx_check_string(_String) \
+# if __cplusplus < 201103L
+# define __glibcxx_check_string(_String) \
_GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != 0, \
__FILE__, __LINE__, \
__PRETTY_FUNCTION__);
-# define __glibcxx_check_string_len(_String,_Len) \
+# define __glibcxx_check_string_len(_String,_Len) \
_GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != 0 || _Len == 0, \
__FILE__, __LINE__, \
__PRETTY_FUNCTION__);
+# else
+# define __glibcxx_check_string(_String) \
+ _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != nullptr, \
+ __FILE__, __LINE__, \
+ __PRETTY_FUNCTION__);
+# define __glibcxx_check_string_len(_String,_Len) \
+ _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != nullptr || _Len == 0, \
+ __FILE__, __LINE__, \
+ __PRETTY_FUNCTION__);
+# endif
#else
# define __glibcxx_check_string(_String)
# define __glibcxx_check_string_len(_String,_Len)
@@ -75,8 +86,13 @@ namespace __gnu_debug
const char* __function __attribute__((__unused__)))
{
#ifdef _GLIBCXX_DEBUG_PEDANTIC
+# if __cplusplus < 201103L
_GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0 || __n == 0,
__file, __line, __function);
+# else
+ _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != nullptr || __n == 0,
+ __file, __line, __function);
+# endif
#endif
return __s;
}
@@ -90,8 +106,13 @@ namespace __gnu_debug
const char* __function __attribute__((__unused__)))
{
#ifdef _GLIBCXX_DEBUG_PEDANTIC
+# if __cplusplus < 201103L
_GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0,
__file, __line, __function);
+# else
+ _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != nullptr,
+ __file, __line, __function);
+# endif
#endif
return __s;
}
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 3e71ecb..2b5cb05 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -2121,8 +2121,8 @@ namespace views::__adaptor
take_view() requires default_initializable<_Vp> = default;
constexpr
- take_view(_Vp base, range_difference_t<_Vp> __count)
- : _M_base(std::move(base)), _M_count(std::move(__count))
+ take_view(_Vp __base, range_difference_t<_Vp> __count)
+ : _M_base(std::move(__base)), _M_count(std::move(__count))
{ }
constexpr _Vp
@@ -2355,8 +2355,8 @@ namespace views::__adaptor
= default;
constexpr
- take_while_view(_Vp base, _Pred __pred)
- : _M_base(std::move(base)), _M_pred(std::move(__pred))
+ take_while_view(_Vp __base, _Pred __pred)
+ : _M_base(std::move(__base)), _M_pred(std::move(__pred))
{ }
constexpr _Vp
@@ -3116,7 +3116,6 @@ namespace views::__adaptor
_Parent* _M_parent = nullptr;
- // XXX: _M_current is present only if "V models forward_range"
[[no_unique_address]]
__detail::__maybe_present_t<forward_range<_Vp>,
iterator_t<_Base>> _M_current;
@@ -3370,7 +3369,6 @@ namespace views::__adaptor
_Vp _M_base = _Vp();
_Pattern _M_pattern = _Pattern();
- // XXX: _M_current is "present only if !forward_range<V>"
[[no_unique_address]]
__detail::__maybe_present_t<!forward_range<_Vp>,
__detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
@@ -3725,16 +3723,6 @@ namespace views::__adaptor
: _M_base(std::move(__r))
{ }
- /* XXX: LWG 3280 didn't remove this constructor, but I think it should?
- template<viewable_range _Range>
- requires (!common_range<_Range>)
- && constructible_from<_Vp, views::all_t<_Range>>
- constexpr explicit
- common_view(_Range&& __r)
- : _M_base(views::all(std::forward<_Range>(__r)))
- { }
- */
-
constexpr _Vp
base() const& requires copy_constructible<_Vp>
{ return _M_base; }
@@ -3994,8 +3982,8 @@ namespace views::__adaptor
elements_view() requires default_initializable<_Vp> = default;
constexpr explicit
- elements_view(_Vp base)
- : _M_base(std::move(base))
+ elements_view(_Vp __base)
+ : _M_base(std::move(__base))
{ }
constexpr _Vp
@@ -4115,14 +4103,14 @@ namespace views::__adaptor
_Iterator() requires default_initializable<iterator_t<_Base>> = default;
constexpr explicit
- _Iterator(iterator_t<_Base> current)
- : _M_current(std::move(current))
+ _Iterator(iterator_t<_Base> __current)
+ : _M_current(std::move(__current))
{ }
constexpr
- _Iterator(_Iterator<!_Const> i)
+ _Iterator(_Iterator<!_Const> __i)
requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
- : _M_current(std::move(i._M_current))
+ : _M_current(std::move(__i._M_current))
{ }
constexpr const iterator_t<_Base>&
@@ -4352,6 +4340,1445 @@ namespace views::__adaptor
inline constexpr auto values = elements<1>;
} // namespace views
+#if __cplusplus > 202002L
+ namespace __detail
+ {
+ template<typename... _Rs>
+ concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
+ || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
+ || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
+
+ template<typename... _Ts>
+ struct __tuple_or_pair
+ { using type = std::tuple<_Ts...>; };
+
+ template<typename _Tp, typename _Up>
+ struct __tuple_or_pair<_Tp, _Up>
+ { using type = pair<_Tp, _Up>; };
+
+ template<typename... _Ts>
+ using __tuple_or_pair_t = typename __tuple_or_pair<_Ts...>::type;
+
+ template<typename _Fp, typename _Tuple>
+ constexpr auto
+ __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
+ {
+ return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
+ return __tuple_or_pair_t<invoke_result_t<_Fp&, _Ts>...>
+ (std::__invoke(__f, std::forward<_Ts>(__elts))...);
+ }, std::forward<_Tuple>(__tuple));
+ }
+
+ template<typename _Fp, typename _Tuple>
+ constexpr void
+ __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
+ {
+ std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
+ (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
+ }, std::forward<_Tuple>(__tuple));
+ }
+ } // namespace __detail
+
+ template<input_range... _Vs>
+ requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
+ class zip_view : public view_interface<zip_view<_Vs...>>
+ {
+ tuple<_Vs...> _M_views;
+
+ template<bool> class _Iterator;
+ template<bool> class _Sentinel;
+
+ public:
+ zip_view() = default;
+
+ constexpr explicit
+ zip_view(_Vs... __views)
+ : _M_views(std::move(__views)...)
+ { }
+
+ constexpr auto
+ begin() requires (!(__detail::__simple_view<_Vs> && ...))
+ { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
+
+ constexpr auto
+ begin() const requires (range<const _Vs> && ...)
+ { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
+
+ constexpr auto
+ end() requires (!(__detail::__simple_view<_Vs> && ...))
+ {
+ if constexpr (!__detail::__zip_is_common<_Vs...>)
+ return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
+ else if constexpr ((random_access_range<_Vs> && ...))
+ return begin() + iter_difference_t<_Iterator<false>>(size());
+ else
+ return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
+ }
+
+ constexpr auto
+ end() const requires (range<const _Vs> && ...)
+ {
+ if constexpr (!__detail::__zip_is_common<const _Vs...>)
+ return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
+ else if constexpr ((random_access_range<const _Vs> && ...))
+ return begin() + iter_difference_t<_Iterator<true>>(size());
+ else
+ return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
+ }
+
+ constexpr auto
+ size() requires (sized_range<_Vs> && ...)
+ {
+ return std::apply([](auto... sizes) {
+ using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
+ return ranges::min({_CT(sizes)...});
+ }, __detail::__tuple_transform(ranges::size, _M_views));
+ }
+
+ constexpr auto
+ size() const requires (sized_range<const _Vs> && ...)
+ {
+ return std::apply([](auto... sizes) {
+ using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
+ return ranges::min({_CT(sizes)...});
+ }, __detail::__tuple_transform(ranges::size, _M_views));
+ }
+ };
+
+ template<typename... _Rs>
+ zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
+
+ template<typename... _Views>
+ inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
+ = (enable_borrowed_range<_Views> && ...);
+
+ namespace __detail
+ {
+ template<bool _Const, typename... _Vs>
+ concept __all_random_access
+ = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
+
+ template<bool _Const, typename... _Vs>
+ concept __all_bidirectional
+ = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
+
+ template<bool _Const, typename... _Vs>
+ concept __all_forward
+ = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
+
+ template<bool _Const, typename... _Views>
+ struct __zip_view_iter_cat
+ { };
+
+ template<bool _Const, typename... _Views>
+ requires __all_forward<_Const, _Views...>
+ struct __zip_view_iter_cat<_Const, _Views...>
+ { using iterator_category = input_iterator_tag; };
+ } // namespace __detail
+
+ template<input_range... _Vs>
+ requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
+ template<bool _Const>
+ class zip_view<_Vs...>::_Iterator
+ : public __detail::__zip_view_iter_cat<_Const, _Vs...>
+ {
+ __detail::__tuple_or_pair_t<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
+
+ constexpr explicit
+ _Iterator(decltype(_M_current) __current)
+ : _M_current(std::move(__current))
+ { }
+
+ static auto
+ _S_iter_concept()
+ {
+ if constexpr (__detail::__all_random_access<_Const, _Vs...>)
+ return random_access_iterator_tag{};
+ else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
+ return bidirectional_iterator_tag{};
+ else if constexpr (__detail::__all_forward<_Const, _Vs...>)
+ return forward_iterator_tag{};
+ else
+ return input_iterator_tag{};
+ }
+
+ template<copy_constructible _Fp, input_range... _Ws>
+ requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
+ && regular_invocable<_Fp&, range_reference_t<_Ws>...>
+ && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
+ friend class zip_transform_view;
+
+ public:
+ // iterator_category defined in __zip_view_iter_cat
+ using iterator_concept = decltype(_S_iter_concept());
+ using value_type
+ = __detail::__tuple_or_pair_t<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
+ using difference_type
+ = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
+
+ _Iterator() = default;
+
+ constexpr
+ _Iterator(_Iterator<!_Const> __i)
+ requires _Const
+ && (convertible_to<iterator_t<_Vs>,
+ iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
+ : _M_current(std::move(__i._M_current))
+ { }
+
+ constexpr auto
+ operator*() const
+ {
+ auto __f = [](auto& __i) -> decltype(auto) {
+ return *__i;
+ };
+ return __detail::__tuple_transform(__f, _M_current);
+ }
+
+ constexpr _Iterator&
+ operator++()
+ {
+ __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
+ return *this;
+ }
+
+ constexpr void
+ operator++(int)
+ { ++*this; }
+
+ constexpr _Iterator
+ operator++(int)
+ requires __detail::__all_forward<_Const, _Vs...>
+ {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ constexpr _Iterator&
+ operator--()
+ requires __detail::__all_bidirectional<_Const, _Vs...>
+ {
+ __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
+ return *this;
+ }
+
+ constexpr _Iterator
+ operator--(int)
+ requires __detail::__all_bidirectional<_Const, _Vs...>
+ {
+ auto __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ constexpr _Iterator&
+ operator+=(difference_type __x)
+ requires __detail::__all_random_access<_Const, _Vs...>
+ {
+ auto __f = [&]<typename _It>(_It& __i) {
+ __i += iter_difference_t<_It>(__x);
+ };
+ __detail::__tuple_for_each(__f, _M_current);
+ return *this;
+ }
+
+ constexpr _Iterator&
+ operator-=(difference_type __x)
+ requires __detail::__all_random_access<_Const, _Vs...>
+ {
+ auto __f = [&]<typename _It>(_It& __i) {
+ __i -= iter_difference_t<_It>(__x);
+ };
+ __detail::__tuple_for_each(__f, _M_current);
+ return *this;
+ }
+
+ constexpr auto
+ operator[](difference_type __n) const
+ requires __detail::__all_random_access<_Const, _Vs...>
+ {
+ auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
+ return __i[iter_difference_t<_It>(__n)];
+ };
+ return __detail::__tuple_transform(__f, _M_current);
+ }
+
+ friend constexpr bool
+ operator==(const _Iterator& __x, const _Iterator& __y)
+ requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
+ {
+ if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
+ return __x._M_current == __y._M_current;
+ else
+ return [&]<size_t... _Is>(index_sequence<_Is...>) {
+ return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
+ }(make_index_sequence<sizeof...(_Vs)>{});
+ }
+
+ friend constexpr auto
+ operator<=>(const _Iterator& __x, const _Iterator& __y)
+ requires __detail::__all_random_access<_Const, _Vs...>
+ { return __x._M_current <=> __y._M_current; }
+
+ friend constexpr _Iterator
+ operator+(const _Iterator& __i, difference_type __n)
+ requires __detail::__all_random_access<_Const, _Vs...>
+ {
+ auto __r = __i;
+ __r += __n;
+ return __r;
+ }
+
+ friend constexpr _Iterator
+ operator+(difference_type __n, const _Iterator& __i)
+ requires __detail::__all_random_access<_Const, _Vs...>
+ {
+ auto __r = __i;
+ __r += __n;
+ return __r;
+ }
+
+ friend constexpr _Iterator
+ operator-(const _Iterator& __i, difference_type __n)
+ requires __detail::__all_random_access<_Const, _Vs...>
+ {
+ auto __r = __i;
+ __r -= __n;
+ return __r;
+ }
+
+ friend constexpr difference_type
+ operator-(const _Iterator& __x, const _Iterator& __y)
+ requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
+ iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
+ {
+ return [&]<size_t... _Is>(index_sequence<_Is...>) {
+ return ranges::min({difference_type(std::get<_Is>(__x._M_current)
+ - std::get<_Is>(__y._M_current))...},
+ ranges::less{},
+ [](difference_type __i) -> make_unsigned_t<difference_type> {
+ return __i < 0 ? -__i : __i;
+ });
+ }(make_index_sequence<sizeof...(_Vs)>{});
+ }
+
+ friend constexpr auto
+ iter_move(const _Iterator& __i)
+ { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
+
+ friend constexpr void
+ iter_swap(const _Iterator& __l, const _Iterator& __r)
+ requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
+ {
+ [&]<size_t... _Is>(index_sequence<_Is...>) {
+ (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
+ }(make_index_sequence<sizeof...(_Vs)>{});
+ }
+
+ friend class zip_view;
+ };
+
+ template<input_range... _Vs>
+ requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
+ template<bool _Const>
+ class zip_view<_Vs...>::_Sentinel
+ {
+ __detail::__tuple_or_pair_t<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
+
+ constexpr explicit
+ _Sentinel(decltype(_M_end) __end)
+ : _M_end(__end)
+ { }
+
+ friend class zip_view;
+
+ public:
+ _Sentinel() = default;
+
+ constexpr
+ _Sentinel(_Sentinel<!_Const> __i)
+ requires _Const
+ && (convertible_to<sentinel_t<_Vs>,
+ sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
+ : _M_end(std::move(__i._M_end))
+ { }
+
+ template<bool _OtherConst>
+ requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
+ iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
+ friend constexpr bool
+ operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
+ {
+ return [&]<size_t... _Is>(index_sequence<_Is...>) {
+ return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
+ }(make_index_sequence<sizeof...(_Vs)>{});
+ }
+
+ template<bool _OtherConst>
+ requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
+ iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
+ friend constexpr auto
+ operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
+ {
+ using _Ret
+ = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
+ return [&]<size_t... _Is>(index_sequence<_Is...>) {
+ return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
+ ranges::less{},
+ [](_Ret __i) -> make_unsigned_t<_Ret> {
+ return __i < 0 ? -__i : __i;
+ });
+ }(make_index_sequence<sizeof...(_Vs)>{});
+ }
+
+ template<bool _OtherConst>
+ requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
+ iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
+ friend constexpr auto
+ operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
+ { return -(__x - __y); }
+ };
+
+ namespace views
+ {
+ namespace __detail
+ {
+ template<typename... _Ts>
+ concept __can_zip_view
+ = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
+ }
+
+ struct _Zip
+ {
+ template<typename... _Ts>
+ requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
+ constexpr auto
+ operator() [[nodiscard]] (_Ts&&... __ts) const
+ {
+ if constexpr (sizeof...(_Ts) == 0)
+ return views::empty<tuple<>>;
+ else
+ return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
+ }
+ };
+
+ inline constexpr _Zip zip;
+ }
+
+ namespace __detail
+ {
+ template<typename _Range, bool _Const>
+ using __range_iter_cat
+ = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
+ }
+
+ template<copy_constructible _Fp, input_range... _Vs>
+ requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
+ && regular_invocable<_Fp&, range_reference_t<_Vs>...>
+ && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
+ class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
+ {
+ [[no_unique_address]] __detail::__box<_Fp> _M_fun;
+ zip_view<_Vs...> _M_zip;
+
+ using _InnerView = zip_view<_Vs...>;
+
+ template<bool _Const>
+ using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
+
+ template<bool _Const>
+ using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
+
+ template<bool _Const>
+ using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
+
+ template<bool _Const>
+ struct __iter_cat
+ { };
+
+ template<bool _Const>
+ requires forward_range<_Base<_Const>>
+ struct __iter_cat<_Const>
+ {
+ private:
+ static auto
+ _S_iter_cat()
+ {
+ using __detail::__maybe_const_t;
+ using __detail::__range_iter_cat;
+ using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
+ range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
+ if constexpr (!is_lvalue_reference_v<_Res>)
+ return input_iterator_tag{};
+ else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
+ random_access_iterator_tag> && ...))
+ return random_access_iterator_tag{};
+ else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
+ bidirectional_iterator_tag> && ...))
+ return bidirectional_iterator_tag{};
+ else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
+ forward_iterator_tag> && ...))
+ return forward_iterator_tag{};
+ else
+ return input_iterator_tag{};
+ }
+ public:
+ using iterator_category = decltype(_S_iter_cat());
+ };
+
+ template<bool> class _Iterator;
+ template<bool> class _Sentinel;
+
+ public:
+ zip_transform_view() = default;
+
+ constexpr explicit
+ zip_transform_view(_Fp __fun, _Vs... __views)
+ : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
+ { }
+
+ constexpr auto
+ begin()
+ { return _Iterator<false>(*this, _M_zip.begin()); }
+
+ constexpr auto
+ begin() const
+ requires range<const _InnerView>
+ && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
+ { return _Iterator<true>(*this, _M_zip.begin()); }
+
+ constexpr auto
+ end()
+ {
+ if constexpr (common_range<_InnerView>)
+ return _Iterator<false>(*this, _M_zip.end());
+ else
+ return _Sentinel<false>(_M_zip.end());
+ }
+
+ constexpr auto
+ end() const
+ requires range<const _InnerView>
+ && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
+ {
+ if constexpr (common_range<const _InnerView>)
+ return _Iterator<true>(*this, _M_zip.end());
+ else
+ return _Sentinel<true>(_M_zip.end());
+ }
+
+ constexpr auto
+ size() requires sized_range<_InnerView>
+ { return _M_zip.size(); }
+
+ constexpr auto
+ size() const requires sized_range<const _InnerView>
+ { return _M_zip.size(); }
+ };
+
+ template<class _Fp, class... Rs>
+ zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
+
+ template<copy_constructible _Fp, input_range... _Vs>
+ requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
+ && regular_invocable<_Fp&, range_reference_t<_Vs>...>
+ && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
+ template<bool _Const>
+ class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
+ {
+ using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
+
+ _Parent* _M_parent = nullptr;
+ __ziperator<_Const> _M_inner;
+
+ constexpr
+ _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
+ : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
+ { }
+
+ friend class zip_transform_view;
+
+ public:
+ // iterator_category defined in zip_transform_view::__iter_cat
+ using iterator_concept = typename __ziperator<_Const>::iterator_concept;
+ using value_type
+ = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
+ range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
+ using difference_type = range_difference_t<_Base<_Const>>;
+
+ _Iterator() = default;
+
+ constexpr
+ _Iterator(_Iterator<!_Const> __i)
+ requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
+ : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
+ { }
+
+ constexpr decltype(auto)
+ operator*() const
+ {
+ return std::apply([&](const auto&... __iters) -> decltype(auto) {
+ return std::__invoke(*_M_parent->_M_fun, *__iters...);
+ }, _M_inner._M_current);
+ }
+
+ constexpr _Iterator&
+ operator++()
+ {
+ ++_M_inner;
+ return *this;
+ }
+
+ constexpr void
+ operator++(int)
+ { ++*this; }
+
+ constexpr _Iterator
+ operator++(int) requires forward_range<_Base<_Const>>
+ {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ constexpr _Iterator&
+ operator--() requires bidirectional_range<_Base<_Const>>
+ {
+ --_M_inner;
+ return *this;
+ }
+
+ constexpr _Iterator
+ operator--(int) requires bidirectional_range<_Base<_Const>>
+ {
+ auto __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ constexpr _Iterator&
+ operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
+ {
+ _M_inner += __x;
+ return *this;
+ }
+
+ constexpr _Iterator&
+ operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
+ {
+ _M_inner -= __x;
+ return *this;
+ }
+
+ constexpr decltype(auto)
+ operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
+ {
+ return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
+ return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
+ }, _M_inner._M_current);
+ }
+
+ friend constexpr bool
+ operator==(const _Iterator& __x, const _Iterator& __y)
+ requires equality_comparable<__ziperator<_Const>>
+ { return __x._M_inner == __y._M_inner; }
+
+ friend constexpr auto
+ operator<=>(const _Iterator& __x, const _Iterator& __y)
+ requires random_access_range<_Base<_Const>>
+ { return __x._M_inner <=> __y._M_inner; }
+
+ friend constexpr _Iterator
+ operator+(const _Iterator& __i, difference_type __n)
+ requires random_access_range<_Base<_Const>>
+ { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
+
+ friend constexpr _Iterator
+ operator+(difference_type __n, const _Iterator& __i)
+ requires random_access_range<_Base<_Const>>
+ { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
+
+ friend constexpr _Iterator
+ operator-(const _Iterator& __i, difference_type __n)
+ requires random_access_range<_Base<_Const>>
+ { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
+
+ friend constexpr difference_type
+ operator-(const _Iterator& __x, const _Iterator& __y)
+ requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
+ { return __x._M_inner - __y._M_inner; }
+ };
+
+ template<copy_constructible _Fp, input_range... _Vs>
+ requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
+ && regular_invocable<_Fp&, range_reference_t<_Vs>...>
+ && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
+ template<bool _Const>
+ class zip_transform_view<_Fp, _Vs...>::_Sentinel
+ {
+ __zentinel<_Const> _M_inner;
+
+ constexpr explicit
+ _Sentinel(__zentinel<_Const> __inner)
+ : _M_inner(__inner)
+ { }
+
+ friend class zip_transform_view;
+
+ public:
+ _Sentinel() = default;
+
+ constexpr
+ _Sentinel(_Sentinel<!_Const> __i)
+ requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
+ : _M_inner(std::move(__i._M_inner))
+ { }
+
+ template<bool _OtherConst>
+ requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
+ friend constexpr bool
+ operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
+ { return __x._M_inner == __y._M_inner; }
+
+ template<bool _OtherConst>
+ requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
+ friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
+ operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
+ { return __x._M_inner - __y._M_inner; }
+
+ template<bool _OtherConst>
+ requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
+ friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
+ operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
+ { return __x._M_inner - __y._M_inner; }
+ };
+
+ namespace views
+ {
+ namespace __detail
+ {
+ template<typename _Fp, typename... _Ts>
+ concept __can_zip_transform_view
+ = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
+ }
+
+ struct _ZipTransform
+ {
+ template<typename _Fp, typename... _Ts>
+ requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
+ constexpr auto
+ operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
+ {
+ if constexpr (sizeof...(_Ts) == 0)
+ return views::empty<decay_t<invoke_result_t<_Fp>>>;
+ else
+ return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
+ }
+ };
+
+ inline constexpr _ZipTransform zip_transform;
+ }
+
+ template<forward_range _Vp, size_t _Nm>
+ requires view<_Vp> && (_Nm > 0)
+ class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
+ {
+ _Vp _M_base = _Vp();
+
+ template<bool> class _Iterator;
+ template<bool> class _Sentinel;
+
+ struct __as_sentinel
+ { };
+
+ public:
+ adjacent_view() requires default_initializable<_Vp> = default;
+
+ constexpr explicit
+ adjacent_view(_Vp __base)
+ : _M_base(std::move(__base))
+ { }
+
+ constexpr auto
+ begin() requires (!__detail::__simple_view<_Vp>)
+ { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
+
+ constexpr auto
+ begin() const requires range<const _Vp>
+ { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
+
+ constexpr auto
+ end() requires (!__detail::__simple_view<_Vp>)
+ {
+ if constexpr (common_range<_Vp>)
+ return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
+ else
+ return _Sentinel<false>(ranges::end(_M_base));
+ }
+
+ constexpr auto
+ end() const requires range<const _Vp>
+ {
+ if constexpr (common_range<const _Vp>)
+ return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
+ else
+ return _Sentinel<true>(ranges::end(_M_base));
+ }
+
+ constexpr auto
+ size() requires sized_range<_Vp>
+ {
+ using _ST = decltype(ranges::size(_M_base));
+ using _CT = common_type_t<_ST, size_t>;
+ auto __sz = static_cast<_CT>(ranges::size(_M_base));
+ __sz -= std::min<_CT>(__sz, _Nm - 1);
+ return static_cast<_ST>(__sz);
+ }
+
+ constexpr auto
+ size() const requires sized_range<const _Vp>
+ {
+ using _ST = decltype(ranges::size(_M_base));
+ using _CT = common_type_t<_ST, size_t>;
+ auto __sz = static_cast<_CT>(ranges::size(_M_base));
+ __sz -= std::min<_CT>(__sz, _Nm - 1);
+ return static_cast<_ST>(__sz);
+ }
+ };
+
+ template<typename _Vp, size_t _Nm>
+ inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
+ = enable_borrowed_range<_Vp>;
+
+ namespace __detail
+ {
+ // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
+ template<typename _Tp, size_t _Nm>
+ using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
+
+ // For a functor F that is callable with N arguments, the expression
+ // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
+ template<typename _Fp, size_t _Nm>
+ struct __unarize
+ {
+ template<typename... _Ts>
+ static invoke_result_t<_Fp, _Ts...>
+ __tuple_apply(const tuple<_Ts...>&); // not defined
+
+ template<typename _Tp>
+ decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
+ operator()(_Tp&&); // not defined
+ };
+ }
+
+ template<forward_range _Vp, size_t _Nm>
+ requires view<_Vp> && (_Nm > 0)
+ template<bool _Const>
+ class adjacent_view<_Vp, _Nm>::_Iterator
+ {
+ using _Base = __detail::__maybe_const_t<_Const, _Vp>;
+ array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
+
+ constexpr
+ _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
+ {
+ for (auto& __i : _M_current)
+ {
+ __i = __first;
+ ranges::advance(__first, 1, __last);
+ }
+ }
+
+ constexpr
+ _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
+ {
+ if constexpr (!bidirectional_range<_Base>)
+ for (auto& __it : _M_current)
+ __it = __last;
+ else
+ for (size_t __i = 0; __i < _Nm; ++__i)
+ {
+ _M_current[_Nm - 1 - __i] = __last;
+ ranges::advance(__last, -1, __first);
+ }
+ }
+
+ static auto
+ _S_iter_concept()
+ {
+ if constexpr (random_access_range<_Base>)
+ return random_access_iterator_tag{};
+ else if constexpr (bidirectional_range<_Base>)
+ return bidirectional_iterator_tag{};
+ else
+ return forward_iterator_tag{};
+ }
+
+ friend class adjacent_view;
+
+ template<forward_range _Wp, copy_constructible _Fp, size_t _Mm>
+ requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
+ && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
+ && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
+ range_reference_t<_Wp>>>
+ friend class adjacent_transform_view;
+
+ public:
+ using iterator_category = input_iterator_tag;
+ using iterator_concept = decltype(_S_iter_concept());
+ using value_type = conditional_t<_Nm == 2,
+ pair<range_value_t<_Base>, range_value_t<_Base>>,
+ __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
+ using difference_type = range_difference_t<_Base>;
+
+ _Iterator() = default;
+
+ constexpr
+ _Iterator(_Iterator<!_Const> __i)
+ requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
+ {
+ for (size_t __j = 0; __j < _Nm; ++__j)
+ _M_current[__j] = std::move(__i[__j]);
+ }
+
+ constexpr auto
+ operator*() const
+ {
+ auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
+ return __detail::__tuple_transform(__f, _M_current);
+ }
+
+ constexpr _Iterator&
+ operator++()
+ {
+ for (auto& __i : _M_current)
+ ++__i;
+ return *this;
+ }
+
+ constexpr _Iterator
+ operator++(int)
+ {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ constexpr _Iterator&
+ operator--() requires bidirectional_range<_Base>
+ {
+ for (auto& __i : _M_current)
+ --__i;
+ return *this;
+ }
+
+ constexpr _Iterator
+ operator--(int) requires bidirectional_range<_Base>
+ {
+ auto __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ constexpr _Iterator&
+ operator+=(difference_type __x)
+ requires random_access_range<_Base>
+ {
+ for (auto& __i : _M_current)
+ __i += __x;
+ return *this;
+ }
+
+ constexpr _Iterator&
+ operator-=(difference_type __x)
+ requires random_access_range<_Base>
+ {
+ for (auto& __i : _M_current)
+ __i -= __x;
+ return *this;
+ }
+
+ constexpr auto
+ operator[](difference_type __n) const
+ requires random_access_range<_Base>
+ {
+ auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
+ return __detail::__tuple_transform(__f, _M_current);
+ }
+
+ friend constexpr bool
+ operator==(const _Iterator& __x, const _Iterator& __y)
+ { return __x._M_current.back() == __y._M_current.back(); }
+
+ friend constexpr bool
+ operator<(const _Iterator& __x, const _Iterator& __y)
+ requires random_access_range<_Base>
+ { return __x._M_current.back() < __y._M_current.back(); }
+
+ friend constexpr bool
+ operator>(const _Iterator& __x, const _Iterator& __y)
+ requires random_access_range<_Base>
+ { return __y < __x; }
+
+ friend constexpr bool
+ operator<=(const _Iterator& __x, const _Iterator& __y)
+ requires random_access_range<_Base>
+ { return !(__y < __x); }
+
+ friend constexpr bool
+ operator>=(const _Iterator& __x, const _Iterator& __y)
+ requires random_access_range<_Base>
+ { return !(__x < __y); }
+
+ friend constexpr auto
+ operator<=>(const _Iterator& __x, const _Iterator& __y)
+ requires random_access_range<_Base>
+ && three_way_comparable<iterator_t<_Base>>
+ { return __x._M_current.back() <=> __y._M_current.back(); }
+
+ friend constexpr _Iterator
+ operator+(const _Iterator& __i, difference_type __n)
+ requires random_access_range<_Base>
+ {
+ auto __r = __i;
+ __r += __n;
+ return __r;
+ }
+
+ friend constexpr _Iterator
+ operator+(difference_type __n, const _Iterator& __i)
+ requires random_access_range<_Base>
+ {
+ auto __r = __i;
+ __r += __n;
+ return __r;
+ }
+
+ friend constexpr _Iterator
+ operator-(const _Iterator& __i, difference_type __n)
+ requires random_access_range<_Base>
+ {
+ auto __r = __i;
+ __r -= __n;
+ return __r;
+ }
+
+ friend constexpr difference_type
+ operator-(const _Iterator& __x, const _Iterator& __y)
+ requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
+ { return __x._M_current.back() - __y._M_current.back(); }
+
+ friend constexpr auto
+ iter_move(const _Iterator& __i)
+ { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
+
+ friend constexpr void
+ iter_swap(const _Iterator& __l, const _Iterator& __r)
+ requires indirectly_swappable<iterator_t<_Base>>
+ {
+ for (size_t __i = 0; __i < _Nm; __i++)
+ ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
+ }
+ };
+
+ template<forward_range _Vp, size_t _Nm>
+ requires view<_Vp> && (_Nm > 0)
+ template<bool _Const>
+ class adjacent_view<_Vp, _Nm>::_Sentinel
+ {
+ using _Base = __detail::__maybe_const_t<_Const, _Vp>;
+
+ sentinel_t<_Base> _M_end = sentinel_t<_Base>();
+
+ constexpr explicit
+ _Sentinel(sentinel_t<_Base> __end)
+ : _M_end(__end)
+ { }
+
+ friend class adjacent_view;
+
+ public:
+ _Sentinel() = default;
+
+ constexpr
+ _Sentinel(_Sentinel<!_Const> __i)
+ requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
+ : _M_end(std::move(__i._M_end))
+ { }
+
+ template<bool _OtherConst>
+ requires sentinel_for<sentinel_t<_Base>,
+ iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
+ friend constexpr bool
+ operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
+ { return __x._M_current.back() == __y._M_end; }
+
+ template<bool _OtherConst>
+ requires sized_sentinel_for<sentinel_t<_Base>,
+ iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
+ friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
+ operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
+ { return __x._M_current.back() - __y._M_end; }
+
+ template<bool _OtherConst>
+ requires sized_sentinel_for<sentinel_t<_Base>,
+ iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
+ friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
+ operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
+ { return __y._M_end - __x._M_current.back(); }
+ };
+
+ namespace views
+ {
+ namespace __detail
+ {
+ template<size_t _Nm, typename _Range>
+ concept __can_adjacent_view
+ = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
+ }
+
+ template<size_t _Nm>
+ struct _Adjacent : __adaptor::_RangeAdaptorClosure
+ {
+ template<viewable_range _Range>
+ requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
+ constexpr auto
+ operator() [[nodiscard]] (_Range&& __r) const
+ {
+ if constexpr (_Nm == 0)
+ return views::empty<tuple<>>;
+ else
+ return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
+ }
+ };
+
+ template<size_t _Nm>
+ inline constexpr _Adjacent<_Nm> adjacent;
+
+ inline constexpr auto pairwise = adjacent<2>;
+ }
+
+ template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
+ requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
+ && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
+ && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
+ range_reference_t<_Vp>>>
+ class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
+ {
+ [[no_unique_address]] __detail::__box<_Fp> _M_fun;
+ adjacent_view<_Vp, _Nm> _M_inner;
+
+ using _InnerView = adjacent_view<_Vp, _Nm>;
+
+ template<bool _Const>
+ using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
+
+ template<bool _Const>
+ using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
+
+ template<bool> class _Iterator;
+ template<bool> class _Sentinel;
+
+ public:
+ adjacent_transform_view() = default;
+
+ constexpr explicit
+ adjacent_transform_view(_Vp __base, _Fp __fun)
+ : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
+ { }
+
+ constexpr auto
+ begin()
+ { return _Iterator<false>(*this, _M_inner.begin()); }
+
+ constexpr auto
+ begin() const
+ requires range<const _InnerView>
+ && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
+ range_reference_t<const _Vp>>
+ { return _Iterator<true>(*this, _M_inner.begin()); }
+
+ constexpr auto
+ end()
+ {
+ if constexpr (common_range<_InnerView>)
+ return _Iterator<false>(*this, _M_inner.end());
+ else
+ return _Sentinel<false>(_M_inner.end());
+ }
+
+ constexpr auto
+ end() const
+ requires range<const _InnerView>
+ && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
+ range_reference_t<const _Vp>>
+ {
+ if constexpr (common_range<const _InnerView>)
+ return _Iterator<true>(*this, _M_inner.end());
+ else
+ return _Sentinel<true>(_M_inner.end());
+ }
+
+ constexpr auto
+ size() requires sized_range<_InnerView>
+ { return _M_inner.size(); }
+
+ constexpr auto
+ size() const requires sized_range<const _InnerView>
+ { return _M_inner.size(); }
+ };
+
+ template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
+ requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
+ && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
+ && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
+ range_reference_t<_Vp>>>
+ template<bool _Const>
+ class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
+ {
+ using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
+ using _Base = __detail::__maybe_const_t<_Const, _Vp>;
+
+ _Parent* _M_parent = nullptr;
+ _InnerIter<_Const> _M_inner;
+
+ constexpr
+ _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
+ : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
+ { }
+
+ static auto
+ _S_iter_cat()
+ {
+ using __detail::__maybe_const_t;
+ using __detail::__unarize;
+ using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
+ range_reference_t<_Base>>;
+ using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
+ if constexpr (!is_lvalue_reference_v<_Res>)
+ return input_iterator_tag{};
+ else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
+ return random_access_iterator_tag{};
+ else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
+ return bidirectional_iterator_tag{};
+ else if constexpr (derived_from<_Cat, forward_iterator_tag>)
+ return forward_iterator_tag{};
+ else
+ return input_iterator_tag{};
+ }
+
+ friend class adjacent_transform_view;
+
+ public:
+ using iterator_category = decltype(_S_iter_cat());
+ using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
+ using value_type
+ = remove_cvref_t<invoke_result_t
+ <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
+ range_reference_t<_Base>>>;
+ using difference_type = range_difference_t<_Base>;
+
+ _Iterator() = default;
+
+ constexpr
+ _Iterator(_Iterator<!_Const> __i)
+ requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
+ : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
+ { }
+
+ constexpr decltype(auto)
+ operator*() const
+ {
+ return std::apply([&](const auto&... __iters) -> decltype(auto) {
+ return std::__invoke(*_M_parent->_M_fun, *__iters...);
+ }, _M_inner._M_current);
+ }
+
+ constexpr _Iterator&
+ operator++()
+ {
+ ++_M_inner;
+ return *this;
+ }
+
+ constexpr _Iterator
+ operator++(int)
+ {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ constexpr _Iterator&
+ operator--() requires bidirectional_range<_Base>
+ {
+ --_M_inner;
+ return *this;
+ }
+
+ constexpr _Iterator
+ operator--(int) requires bidirectional_range<_Base>
+ {
+ auto __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ constexpr _Iterator&
+ operator+=(difference_type __x) requires random_access_range<_Base>
+ {
+ _M_inner += __x;
+ return *this;
+ }
+
+ constexpr _Iterator&
+ operator-=(difference_type __x) requires random_access_range<_Base>
+ {
+ _M_inner -= __x;
+ return *this;
+ }
+
+ constexpr decltype(auto)
+ operator[](difference_type __n) const requires random_access_range<_Base>
+ {
+ return std::apply([&](const auto&... __iters) -> decltype(auto) {
+ return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
+ }, _M_inner._M_current);
+ }
+
+ friend constexpr bool
+ operator==(const _Iterator& __x, const _Iterator& __y)
+ { return __x._M_inner == __y._M_inner; }
+
+ friend constexpr bool
+ operator<(const _Iterator& __x, const _Iterator& __y)
+ requires random_access_range<_Base>
+ { return __x._M_inner < __y._M_inner; }
+
+ friend constexpr bool
+ operator>(const _Iterator& __x, const _Iterator& __y)
+ requires random_access_range<_Base>
+ { return __x._M_inner > __y._M_inner; }
+
+ friend constexpr bool
+ operator<=(const _Iterator& __x, const _Iterator& __y)
+ requires random_access_range<_Base>
+ { return __x._M_inner <= __y._M_inner; }
+
+ friend constexpr bool
+ operator>=(const _Iterator& __x, const _Iterator& __y)
+ requires random_access_range<_Base>
+ { return __x._M_inner >= __y._M_inner; }
+
+ friend constexpr auto
+ operator<=>(const _Iterator& __x, const _Iterator& __y)
+ requires random_access_range<_Base> &&
+ three_way_comparable<_InnerIter<_Const>>
+ { return __x._M_inner <=> __y._M_inner; }
+
+ friend constexpr _Iterator
+ operator+(const _Iterator& __i, difference_type __n)
+ requires random_access_range<_Base>
+ { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
+
+ friend constexpr _Iterator
+ operator+(difference_type __n, const _Iterator& __i)
+ requires random_access_range<_Base>
+ { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
+
+ friend constexpr _Iterator
+ operator-(const _Iterator& __i, difference_type __n)
+ requires random_access_range<_Base>
+ { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
+
+ friend constexpr difference_type
+ operator-(const _Iterator& __x, const _Iterator& __y)
+ requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
+ { return __x._M_inner - __y._M_inner; }
+ };
+
+ template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
+ requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
+ && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
+ && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
+ range_reference_t<_Vp>>>
+ template<bool _Const>
+ class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
+ {
+ _InnerSent<_Const> _M_inner;
+
+ constexpr explicit
+ _Sentinel(_InnerSent<_Const> __inner)
+ : _M_inner(__inner)
+ { }
+
+ friend class adjacent_transform_view;
+
+ public:
+ _Sentinel() = default;
+
+ constexpr
+ _Sentinel(_Sentinel<!_Const> __i)
+ requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
+ : _M_inner(std::move(__i._M_inner))
+ { }
+
+ template<bool _OtherConst>
+ requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
+ friend constexpr bool
+ operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
+ { return __x._M_inner == __y._M_inner; }
+
+ template<bool _OtherConst>
+ requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
+ friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
+ operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
+ { return __x._M_inner - __y._M_inner; }
+
+ template<bool _OtherConst>
+ requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
+ friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
+ operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
+ { return __x._M_inner - __y._M_inner; }
+ };
+
+ namespace views
+ {
+ namespace __detail
+ {
+ template<size_t _Nm, typename _Range, typename _Fp>
+ concept __can_adjacent_transform_view
+ = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
+ (std::declval<_Range>(), std::declval<_Fp>()); };
+ }
+
+ template<size_t _Nm>
+ struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
+ {
+ template<viewable_range _Range, typename _Fp>
+ requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
+ constexpr auto
+ operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
+ {
+ if constexpr (_Nm == 0)
+ return views::empty<tuple<>>;
+ else
+ return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
+ (std::forward<_Range>(__r), std::forward<_Fp>(__f));
+ }
+
+ using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
+ static constexpr int _S_arity = 2;
+ static constexpr bool _S_has_simple_extra_args = true;
+ };
+
+ template<size_t _Nm>
+ inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
+
+ inline constexpr auto pairwise_transform = adjacent_transform<2>;
+ }
+#endif // C++23
} // namespace ranges
namespace views = ranges::views;
diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view
index 30ff136..2604af2 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -129,7 +129,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr basic_string_view(const basic_string_view&) noexcept = default;
- __attribute__((__nonnull__)) constexpr
+ [[__gnu__::__nonnull__]]
+ constexpr
basic_string_view(const _CharT* __str) noexcept
: _M_len{traits_type::length(__str)},
_M_str{__str}
@@ -172,54 +173,64 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif // C++23
#endif // C++20
-
constexpr basic_string_view&
operator=(const basic_string_view&) noexcept = default;
// [string.view.iterators], iterator support
+ [[nodiscard]]
constexpr const_iterator
begin() const noexcept
{ return this->_M_str; }
+ [[nodiscard]]
constexpr const_iterator
end() const noexcept
{ return this->_M_str + this->_M_len; }
+ [[nodiscard]]
constexpr const_iterator
cbegin() const noexcept
{ return this->_M_str; }
+ [[nodiscard]]
constexpr const_iterator
cend() const noexcept
{ return this->_M_str + this->_M_len; }
+ [[nodiscard]]
constexpr const_reverse_iterator
rbegin() const noexcept
{ return const_reverse_iterator(this->end()); }
+ [[nodiscard]]
constexpr const_reverse_iterator
rend() const noexcept
{ return const_reverse_iterator(this->begin()); }
+ [[nodiscard]]
constexpr const_reverse_iterator
crbegin() const noexcept
{ return const_reverse_iterator(this->end()); }
+ [[nodiscard]]
constexpr const_reverse_iterator
crend() const noexcept
{ return const_reverse_iterator(this->begin()); }
// [string.view.capacity], capacity
+ [[nodiscard]]
constexpr size_type
size() const noexcept
{ return this->_M_len; }
+ [[nodiscard]]
constexpr size_type
length() const noexcept
{ return _M_len; }
+ [[nodiscard]]
constexpr size_type
max_size() const noexcept
{
@@ -227,12 +238,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/ sizeof(value_type) / 4;
}
- [[nodiscard]] constexpr bool
+ [[nodiscard]]
+ constexpr bool
empty() const noexcept
{ return this->_M_len == 0; }
// [string.view.access], element access
+ [[nodiscard]]
constexpr const_reference
operator[](size_type __pos) const noexcept
{
@@ -240,6 +253,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *(this->_M_str + __pos);
}
+ [[nodiscard]]
constexpr const_reference
at(size_type __pos) const
{
@@ -250,6 +264,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *(this->_M_str + __pos);
}
+ [[nodiscard]]
constexpr const_reference
front() const noexcept
{
@@ -257,6 +272,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this->_M_str;
}
+ [[nodiscard]]
constexpr const_reference
back() const noexcept
{
@@ -264,6 +280,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *(this->_M_str + this->_M_len - 1);
}
+ [[nodiscard]]
constexpr const_pointer
data() const noexcept
{ return this->_M_str; }
@@ -305,6 +322,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __rlen;
}
+ [[nodiscard]]
constexpr basic_string_view
substr(size_type __pos = 0, size_type __n = npos) const noexcept(false)
{
@@ -313,6 +331,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return basic_string_view{_M_str + __pos, __rlen};
}
+ [[nodiscard]]
constexpr int
compare(basic_string_view __str) const noexcept
{
@@ -323,10 +342,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __ret;
}
+ [[nodiscard]]
constexpr int
compare(size_type __pos1, size_type __n1, basic_string_view __str) const
{ return this->substr(__pos1, __n1).compare(__str); }
+ [[nodiscard]]
constexpr int
compare(size_type __pos1, size_type __n1,
basic_string_view __str, size_type __pos2, size_type __n2) const
@@ -334,14 +355,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2));
}
- __attribute__((__nonnull__)) constexpr int
+ [[nodiscard, __gnu__::__nonnull__]]
+ constexpr int
compare(const _CharT* __str) const noexcept
{ return this->compare(basic_string_view{__str}); }
- __attribute__((__nonnull__)) constexpr int
+ [[nodiscard, __gnu__::__nonnull__]]
+ constexpr int
compare(size_type __pos1, size_type __n1, const _CharT* __str) const
{ return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
+ [[nodiscard]]
constexpr int
compare(size_type __pos1, size_type __n1,
const _CharT* __str, size_type __n2) const noexcept(false)
@@ -352,18 +376,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus > 201703L
#define __cpp_lib_starts_ends_with 201711L
+ [[nodiscard]]
constexpr bool
starts_with(basic_string_view __x) const noexcept
{ return this->substr(0, __x.size()) == __x; }
+ [[nodiscard]]
constexpr bool
starts_with(_CharT __x) const noexcept
{ return !this->empty() && traits_type::eq(this->front(), __x); }
+ [[nodiscard, __gnu__::__nonnull__]]
constexpr bool
starts_with(const _CharT* __x) const noexcept
{ return this->starts_with(basic_string_view(__x)); }
+ [[nodiscard]]
constexpr bool
ends_with(basic_string_view __x) const noexcept
{
@@ -373,10 +401,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& traits_type::compare(end() - __xlen, __x.data(), __xlen) == 0;
}
+ [[nodiscard]]
constexpr bool
ends_with(_CharT __x) const noexcept
{ return !this->empty() && traits_type::eq(this->back(), __x); }
+ [[nodiscard, __gnu__::__nonnull__]]
constexpr bool
ends_with(const _CharT* __x) const noexcept
{ return this->ends_with(basic_string_view(__x)); }
@@ -384,14 +414,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus > 202002L
#define __cpp_lib_string_contains 202011L
+ [[nodiscard]]
constexpr bool
contains(basic_string_view __x) const noexcept
{ return this->find(__x) != npos; }
+ [[nodiscard]]
constexpr bool
contains(_CharT __x) const noexcept
{ return this->find(__x) != npos; }
+ [[nodiscard, __gnu__::__nonnull__]]
constexpr bool
contains(const _CharT* __x) const noexcept
{ return this->find(__x) != npos; }
@@ -399,99 +432,123 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// [string.view.find], searching
+ [[nodiscard]]
constexpr size_type
find(basic_string_view __str, size_type __pos = 0) const noexcept
{ return this->find(__str._M_str, __pos, __str._M_len); }
+ [[nodiscard]]
constexpr size_type
find(_CharT __c, size_type __pos = 0) const noexcept;
+ [[nodiscard]]
constexpr size_type
find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
- __attribute__((__nonnull__)) constexpr size_type
+ [[nodiscard, __gnu__::__nonnull__]]
+ constexpr size_type
find(const _CharT* __str, size_type __pos = 0) const noexcept
{ return this->find(__str, __pos, traits_type::length(__str)); }
+ [[nodiscard]]
constexpr size_type
rfind(basic_string_view __str, size_type __pos = npos) const noexcept
{ return this->rfind(__str._M_str, __pos, __str._M_len); }
+ [[nodiscard]]
constexpr size_type
rfind(_CharT __c, size_type __pos = npos) const noexcept;
+ [[nodiscard]]
constexpr size_type
rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
- __attribute__((__nonnull__)) constexpr size_type
+ [[nodiscard, __gnu__::__nonnull__]]
+ constexpr size_type
rfind(const _CharT* __str, size_type __pos = npos) const noexcept
{ return this->rfind(__str, __pos, traits_type::length(__str)); }
+ [[nodiscard]]
constexpr size_type
find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
{ return this->find_first_of(__str._M_str, __pos, __str._M_len); }
+ [[nodiscard]]
constexpr size_type
find_first_of(_CharT __c, size_type __pos = 0) const noexcept
{ return this->find(__c, __pos); }
+ [[nodiscard]]
constexpr size_type
find_first_of(const _CharT* __str, size_type __pos,
size_type __n) const noexcept;
- __attribute__((__nonnull__)) constexpr size_type
+ [[nodiscard, __gnu__::__nonnull__]]
+ constexpr size_type
find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
{ return this->find_first_of(__str, __pos, traits_type::length(__str)); }
+ [[nodiscard]]
constexpr size_type
find_last_of(basic_string_view __str,
size_type __pos = npos) const noexcept
{ return this->find_last_of(__str._M_str, __pos, __str._M_len); }
+ [[nodiscard]]
constexpr size_type
find_last_of(_CharT __c, size_type __pos=npos) const noexcept
{ return this->rfind(__c, __pos); }
+ [[nodiscard]]
constexpr size_type
find_last_of(const _CharT* __str, size_type __pos,
size_type __n) const noexcept;
- __attribute__((__nonnull__)) constexpr size_type
+ [[nodiscard, __gnu__::__nonnull__]]
+ constexpr size_type
find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
{ return this->find_last_of(__str, __pos, traits_type::length(__str)); }
+ [[nodiscard]]
constexpr size_type
find_first_not_of(basic_string_view __str,
size_type __pos = 0) const noexcept
{ return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
+ [[nodiscard]]
constexpr size_type
find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
+ [[nodiscard]]
constexpr size_type
find_first_not_of(const _CharT* __str,
size_type __pos, size_type __n) const noexcept;
- __attribute__((__nonnull__)) constexpr size_type
+ [[nodiscard, __gnu__::__nonnull__]]
+ constexpr size_type
find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
{
return this->find_first_not_of(__str, __pos,
traits_type::length(__str));
}
+ [[nodiscard]]
constexpr size_type
find_last_not_of(basic_string_view __str,
size_type __pos = npos) const noexcept
{ return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
+ [[nodiscard]]
constexpr size_type
find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
+ [[nodiscard]]
constexpr size_type
find_last_not_of(const _CharT* __str,
size_type __pos, size_type __n) const noexcept;
- __attribute__((__nonnull__)) constexpr size_type
+ [[nodiscard, __gnu__::__nonnull__]]
+ constexpr size_type
find_last_not_of(const _CharT* __str,
size_type __pos = npos) const noexcept
{
@@ -536,12 +593,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// type (see N3766).
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator==(basic_string_view<_CharT, _Traits> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.size() == __y.size() && __x.compare(__y) == 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator==(basic_string_view<_CharT, _Traits> __x,
__type_identity_t<basic_string_view<_CharT, _Traits>> __y)
@@ -550,6 +609,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cpp_lib_three_way_comparison
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr auto
operator<=>(basic_string_view<_CharT, _Traits> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
@@ -557,6 +617,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr auto
operator<=>(basic_string_view<_CharT, _Traits> __x,
__type_identity_t<basic_string_view<_CharT, _Traits>> __y)
@@ -565,18 +626,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
#else
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.size() == __y.size() && __x.compare(__y) == 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator!=(basic_string_view<_CharT, _Traits> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return !(__x == __y); }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator!=(basic_string_view<_CharT, _Traits> __x,
__type_identity_t<basic_string_view<_CharT, _Traits>> __y)
@@ -584,18 +648,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return !(__x == __y); }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator!=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return !(__x == __y); }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator< (basic_string_view<_CharT, _Traits> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) < 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator< (basic_string_view<_CharT, _Traits> __x,
__type_identity_t<basic_string_view<_CharT, _Traits>> __y)
@@ -603,18 +670,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __x.compare(__y) < 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) < 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator> (basic_string_view<_CharT, _Traits> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) > 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator> (basic_string_view<_CharT, _Traits> __x,
__type_identity_t<basic_string_view<_CharT, _Traits>> __y)
@@ -622,18 +692,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __x.compare(__y) > 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator> (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) > 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator<=(basic_string_view<_CharT, _Traits> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) <= 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator<=(basic_string_view<_CharT, _Traits> __x,
__type_identity_t<basic_string_view<_CharT, _Traits>> __y)
@@ -641,18 +714,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __x.compare(__y) <= 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator<=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) <= 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator>=(basic_string_view<_CharT, _Traits> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) >= 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator>=(basic_string_view<_CharT, _Traits> __x,
__type_identity_t<basic_string_view<_CharT, _Traits>> __y)
@@ -660,6 +736,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __x.compare(__y) >= 0; }
template<typename _CharT, typename _Traits>
+ [[nodiscard]]
constexpr bool
operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
@@ -693,6 +770,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct hash<string_view>
: public __hash_base<size_t, string_view>
{
+ [[nodiscard]]
size_t
operator()(const string_view& __str) const noexcept
{ return std::_Hash_impl::hash(__str.data(), __str.length()); }
@@ -706,6 +784,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct hash<wstring_view>
: public __hash_base<size_t, wstring_view>
{
+ [[nodiscard]]
size_t
operator()(const wstring_view& __s) const noexcept
{ return std::_Hash_impl::hash(__s.data(),
@@ -721,6 +800,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct hash<u8string_view>
: public __hash_base<size_t, u8string_view>
{
+ [[nodiscard]]
size_t
operator()(const u8string_view& __str) const noexcept
{ return std::_Hash_impl::hash(__str.data(), __str.length()); }
@@ -735,6 +815,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct hash<u16string_view>
: public __hash_base<size_t, u16string_view>
{
+ [[nodiscard]]
size_t
operator()(const u16string_view& __s) const noexcept
{ return std::_Hash_impl::hash(__s.data(),
@@ -749,6 +830,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct hash<u32string_view>
: public __hash_base<size_t, u32string_view>
{
+ [[nodiscard]]
size_t
operator()(const u32string_view& __s) const noexcept
{ return std::_Hash_impl::hash(__s.data(),
diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error
index 87cf720..0504394 100644
--- a/libstdc++-v3/include/std/system_error
+++ b/libstdc++-v3/include/std/system_error
@@ -216,6 +216,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
*/
class error_code
{
+ template<typename _ErrorCodeEnum>
+ using _Check
+ = __enable_if_t<is_error_code_enum<_ErrorCodeEnum>::value>;
+
public:
error_code() noexcept
: _M_value(0), _M_cat(&system_category()) { }
@@ -223,11 +227,15 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
error_code(int __v, const error_category& __cat) noexcept
: _M_value(__v), _M_cat(&__cat) { }
- template<typename _ErrorCodeEnum, typename = typename
- enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type>
+ /// Initialize with a user-defined type, by calling make_error_code.
+ template<typename _ErrorCodeEnum,
+ typename = _Check<_ErrorCodeEnum>>
error_code(_ErrorCodeEnum __e) noexcept
{ *this = make_error_code(__e); }
+ error_code(const error_code&) = default;
+ error_code& operator=(const error_code&) = default;
+
void
assign(int __v, const error_category& __cat) noexcept
{
@@ -239,13 +247,6 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
clear() noexcept
{ assign(0, system_category()); }
- // DR 804.
- template<typename _ErrorCodeEnum>
- typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value,
- error_code&>::type
- operator=(_ErrorCodeEnum __e) noexcept
- { return *this = make_error_code(__e); }
-
/// The error value.
[[__nodiscard__]]
int
@@ -345,6 +346,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
*/
class error_condition
{
+ template<typename _ErrorConditionEnum>
+ using _Check
+ = __enable_if_t<is_error_condition_enum<_ErrorConditionEnum>::value>;
+
public:
/// Initialize with a zero (no error) value and the generic category.
error_condition() noexcept
@@ -354,11 +359,15 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
error_condition(int __v, const error_category& __cat) noexcept
: _M_value(__v), _M_cat(&__cat) { }
- template<typename _ErrorConditionEnum, typename = typename
- enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type>
+ /// Initialize with a user-defined type, by calling make_error_condition.
+ template<typename _ErrorConditionEnum,
+ typename = _Check<_ErrorConditionEnum>>
error_condition(_ErrorConditionEnum __e) noexcept
{ *this = make_error_condition(__e); }
+ error_condition(const error_condition&) = default;
+ error_condition& operator=(const error_condition&) = default;
+
/// Set the value and category.
void
assign(int __v, const error_category& __cat) noexcept
@@ -367,13 +376,6 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_M_cat = &__cat;
}
- // DR 804.
- template<typename _ErrorConditionEnum>
- typename enable_if<is_error_condition_enum
- <_ErrorConditionEnum>::value, error_condition&>::type
- operator=(_ErrorConditionEnum __e) noexcept
- { return *this = make_error_condition(__e); }
-
/// Reset the value and category to the default-constructed state.
void
clear() noexcept
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 05433d5..26e2484 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -826,7 +826,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// then TUPLE should match tuple(UTypes&&...) instead.
template<typename _Tuple, typename _Tp, typename _Up>
struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>>
- : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>
+ : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>::type
{ };
// If TUPLE and *this each have a single element of the same type,
// then TUPLE should match a copy/move constructor instead.
@@ -1176,9 +1176,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ _Inherited::_M_swap(__in); }
#if __cplusplus > 202002L
+ // As an extension, we constrain the const swap member function in order
+ // to continue accepting explicit instantiation of tuples whose elements
+ // are not all const swappable. Without this constraint, such an
+ // explicit instantiation would also instantiate the ill-formed body of
+ // this function and yield a hard error. This constraint shouldn't
+ // affect the behavior of valid programs.
constexpr void
swap(const tuple& __in) const
noexcept(__and_v<__is_nothrow_swappable<const _Elements>...>)
+ requires (is_swappable_v<const _Elements> && ...)
{ _Inherited::_M_swap(__in); }
#endif // C++23
};
@@ -1730,6 +1737,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
swap(const tuple& __in) const
noexcept(__and_v<__is_nothrow_swappable<const _T1>,
__is_nothrow_swappable<const _T2>>)
+ requires is_swappable_v<const _T1> && is_swappable_v<const _T2>
{ _Inherited::_M_swap(__in); }
#endif // C++23
};
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 14b029c..c7a9607 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -100,6 +100,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Metaprogramming helper types.
+ // Primary template.
+ /// Define a member typedef `type` only if a boolean constant is true.
+ template<bool, typename _Tp = void>
+ struct enable_if
+ { };
+
+ // Partial specialization for true.
+ template<typename _Tp>
+ struct enable_if<true, _Tp>
+ { typedef _Tp type; };
+
+ // __enable_if_t (std::enable_if_t for C++11)
+ template<bool _Cond, typename _Tp = void>
+ using __enable_if_t = typename enable_if<_Cond, _Tp>::type;
+
template<bool>
struct __conditional
{
@@ -127,55 +142,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
using __type_identity_t = typename __type_identity<_Tp>::type;
- template<typename...>
- struct __or_;
-
- template<>
- struct __or_<>
- : public false_type
- { };
-
- template<typename _B1>
- struct __or_<_B1>
- : public _B1
- { };
-
- template<typename _B1, typename _B2>
- struct __or_<_B1, _B2>
- : public __conditional_t<_B1::value, _B1, _B2>
- { };
+ namespace __detail
+ {
+ // A variadic alias template that resolves to its first argument.
+ template<typename _Tp, typename...>
+ using __first_t = _Tp;
- template<typename _B1, typename _B2, typename _B3, typename... _Bn>
- struct __or_<_B1, _B2, _B3, _Bn...>
- : public __conditional_t<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>
- { };
+ // These are deliberately not defined.
+ template<typename... _Bn>
+ auto __or_fn(int) -> __first_t<false_type,
+ __enable_if_t<!bool(_Bn::value)>...>;
- template<typename...>
- struct __and_;
+ template<typename... _Bn>
+ auto __or_fn(...) -> true_type;
- template<>
- struct __and_<>
- : public true_type
- { };
+ template<typename... _Bn>
+ auto __and_fn(int) -> __first_t<true_type,
+ __enable_if_t<bool(_Bn::value)>...>;
- template<typename _B1>
- struct __and_<_B1>
- : public _B1
- { };
+ template<typename... _Bn>
+ auto __and_fn(...) -> false_type;
+ } // namespace detail
- template<typename _B1, typename _B2>
- struct __and_<_B1, _B2>
- : public __conditional_t<_B1::value, _B2, _B1>
+ // Like C++17 std::dis/conjunction, but usable in C++11 and resolves
+ // to either true_type or false_type which allows for a more efficient
+ // implementation that avoids recursive class template instantiation.
+ template<typename... _Bn>
+ struct __or_
+ : decltype(__detail::__or_fn<_Bn...>(0))
{ };
- template<typename _B1, typename _B2, typename _B3, typename... _Bn>
- struct __and_<_B1, _B2, _B3, _Bn...>
- : public __conditional_t<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>
+ template<typename... _Bn>
+ struct __and_
+ : decltype(__detail::__and_fn<_Bn...>(0))
{ };
template<typename _Pp>
struct __not_
- : public __bool_constant<!bool(_Pp::value)>
+ : __bool_constant<!bool(_Pp::value)>
{ };
/// @endcond
@@ -186,23 +190,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline constexpr bool __or_v = __or_<_Bn...>::value;
template<typename... _Bn>
inline constexpr bool __and_v = __and_<_Bn...>::value;
+
+ namespace __detail
+ {
+ template<typename /* = void */, typename _B1, typename... _Bn>
+ struct __disjunction_impl
+ { using type = _B1; };
+
+ template<typename _B1, typename _B2, typename... _Bn>
+ struct __disjunction_impl<__enable_if_t<!bool(_B1::value)>, _B1, _B2, _Bn...>
+ { using type = typename __disjunction_impl<void, _B2, _Bn...>::type; };
+
+ template<typename /* = void */, typename _B1, typename... _Bn>
+ struct __conjunction_impl
+ { using type = _B1; };
+
+ template<typename _B1, typename _B2, typename... _Bn>
+ struct __conjunction_impl<__enable_if_t<bool(_B1::value)>, _B1, _B2, _Bn...>
+ { using type = typename __conjunction_impl<void, _B2, _Bn...>::type; };
+ } // namespace __detail
/// @endcond
#define __cpp_lib_logical_traits 201510L
template<typename... _Bn>
struct conjunction
- : __and_<_Bn...>
+ : __detail::__conjunction_impl<void, _Bn...>::type
+ { };
+
+ template<>
+ struct conjunction<>
+ : true_type
{ };
template<typename... _Bn>
struct disjunction
- : __or_<_Bn...>
+ : __detail::__disjunction_impl<void, _Bn...>::type
+ { };
+
+ template<>
+ struct disjunction<>
+ : false_type
{ };
template<typename _Pp>
struct negation
- : __not_<_Pp>
+ : __not_<_Pp>::type
{ };
/** @ingroup variable_templates
@@ -685,18 +718,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// __void_t (std::void_t for C++11)
template<typename...> using __void_t = void;
-
- // Utility to detect referenceable types ([defns.referenceable]).
-
- template<typename _Tp, typename = void>
- struct __is_referenceable
- : public false_type
- { };
-
- template<typename _Tp>
- struct __is_referenceable<_Tp, __void_t<_Tp&>>
- : public true_type
- { };
/// @endcond
// Type properties.
@@ -824,7 +845,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// is_unsigned
template<typename _Tp>
struct is_unsigned
- : public __and_<is_arithmetic<_Tp>, __not_<is_signed<_Tp>>>
+ : public __and_<is_arithmetic<_Tp>, __not_<is_signed<_Tp>>>::type
{ };
/// @cond undocumented
@@ -840,21 +861,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
auto declval() noexcept -> decltype(__declval<_Tp>(0));
- template<typename, unsigned = 0>
- struct extent;
-
template<typename>
struct remove_all_extents;
/// @cond undocumented
template<typename _Tp>
struct __is_array_known_bounds
- : public integral_constant<bool, (extent<_Tp>::value > 0)>
+ : public false_type
+ { };
+
+ template<typename _Tp, size_t _Size>
+ struct __is_array_known_bounds<_Tp[_Size]>
+ : public true_type
{ };
template<typename _Tp>
struct __is_array_unknown_bounds
- : public __and_<is_array<_Tp>, __not_<extent<_Tp>>>
+ : public false_type
+ { };
+
+ template<typename _Tp>
+ struct __is_array_unknown_bounds<_Tp[]>
+ : public true_type
{ };
// Destructible and constructible type properties.
@@ -967,9 +995,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @cond undocumented
template<typename _Tp, typename... _Args>
- struct __is_constructible_impl
- : public __bool_constant<__is_constructible(_Tp, _Args...)>
- { };
+ using __is_constructible_impl
+ = __bool_constant<__is_constructible(_Tp, _Args...)>;
/// @endcond
/// is_constructible
@@ -984,53 +1011,51 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// is_default_constructible
template<typename _Tp>
struct is_default_constructible
- : public __is_constructible_impl<_Tp>::type
+ : public __is_constructible_impl<_Tp>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
/// @cond undocumented
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_copy_constructible_impl;
+ template<typename _Tp, typename = void>
+ struct __add_lvalue_reference_helper
+ { using type = _Tp; };
template<typename _Tp>
- struct __is_copy_constructible_impl<_Tp, false>
- : public false_type { };
+ struct __add_lvalue_reference_helper<_Tp, __void_t<_Tp&>>
+ { using type = _Tp&; };
template<typename _Tp>
- struct __is_copy_constructible_impl<_Tp, true>
- : public __is_constructible_impl<_Tp, const _Tp&>
- { };
+ using __add_lval_ref_t = typename __add_lvalue_reference_helper<_Tp>::type;
/// @endcond
/// is_copy_constructible
template<typename _Tp>
struct is_copy_constructible
- : public __is_copy_constructible_impl<_Tp>
+ : public __is_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
/// @cond undocumented
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_move_constructible_impl;
+ template<typename _Tp, typename = void>
+ struct __add_rvalue_reference_helper
+ { using type = _Tp; };
template<typename _Tp>
- struct __is_move_constructible_impl<_Tp, false>
- : public false_type { };
+ struct __add_rvalue_reference_helper<_Tp, __void_t<_Tp&&>>
+ { using type = _Tp&&; };
template<typename _Tp>
- struct __is_move_constructible_impl<_Tp, true>
- : public __is_constructible_impl<_Tp, _Tp&&>
- { };
+ using __add_rval_ref_t = typename __add_rvalue_reference_helper<_Tp>::type;
/// @endcond
/// is_move_constructible
template<typename _Tp>
struct is_move_constructible
- : public __is_move_constructible_impl<_Tp>
+ : public __is_constructible_impl<_Tp, __add_rval_ref_t<_Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -1045,7 +1070,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// is_nothrow_constructible
template<typename _Tp, typename... _Args>
struct is_nothrow_constructible
- : public __is_nothrow_constructible_impl<_Tp, _Args...>::type
+ : public __is_nothrow_constructible_impl<_Tp, _Args...>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -1054,112 +1079,68 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// is_nothrow_default_constructible
template<typename _Tp>
struct is_nothrow_default_constructible
- : public __bool_constant<__is_nothrow_constructible(_Tp)>
+ : public __is_nothrow_constructible_impl<_Tp>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
- /// @cond undocumented
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_nothrow_copy_constructible_impl;
-
- template<typename _Tp>
- struct __is_nothrow_copy_constructible_impl<_Tp, false>
- : public false_type { };
-
- template<typename _Tp>
- struct __is_nothrow_copy_constructible_impl<_Tp, true>
- : public __is_nothrow_constructible_impl<_Tp, const _Tp&>
- { };
- /// @endcond
-
/// is_nothrow_copy_constructible
template<typename _Tp>
struct is_nothrow_copy_constructible
- : public __is_nothrow_copy_constructible_impl<_Tp>::type
+ : public __is_nothrow_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
- /// @cond undocumented
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_nothrow_move_constructible_impl;
-
- template<typename _Tp>
- struct __is_nothrow_move_constructible_impl<_Tp, false>
- : public false_type { };
-
- template<typename _Tp>
- struct __is_nothrow_move_constructible_impl<_Tp, true>
- : public __is_nothrow_constructible_impl<_Tp, _Tp&&>
- { };
- /// @endcond
-
/// is_nothrow_move_constructible
template<typename _Tp>
struct is_nothrow_move_constructible
- : public __is_nothrow_move_constructible_impl<_Tp>::type
+ : public __is_nothrow_constructible_impl<_Tp, __add_rval_ref_t<_Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
+ /// @cond undocumented
+ template<typename _Tp, typename _Up>
+ using __is_assignable_impl = __bool_constant<__is_assignable(_Tp, _Up)>;
+ /// @endcond
+
/// is_assignable
template<typename _Tp, typename _Up>
struct is_assignable
- : public __bool_constant<__is_assignable(_Tp, _Up)>
+ : public __is_assignable_impl<_Tp, _Up>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_copy_assignable_impl;
-
- template<typename _Tp>
- struct __is_copy_assignable_impl<_Tp, false>
- : public false_type { };
-
- template<typename _Tp>
- struct __is_copy_assignable_impl<_Tp, true>
- : public __bool_constant<__is_assignable(_Tp&, const _Tp&)>
- { };
-
/// is_copy_assignable
template<typename _Tp>
struct is_copy_assignable
- : public __is_copy_assignable_impl<_Tp>::type
+ : public __is_assignable_impl<__add_lval_ref_t<_Tp>,
+ __add_lval_ref_t<const _Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_move_assignable_impl;
-
- template<typename _Tp>
- struct __is_move_assignable_impl<_Tp, false>
- : public false_type { };
-
- template<typename _Tp>
- struct __is_move_assignable_impl<_Tp, true>
- : public __bool_constant<__is_assignable(_Tp&, _Tp&&)>
- { };
-
/// is_move_assignable
template<typename _Tp>
struct is_move_assignable
- : public __is_move_assignable_impl<_Tp>::type
+ : public __is_assignable_impl<__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
+ /// @cond undocumented
template<typename _Tp, typename _Up>
using __is_nothrow_assignable_impl
= __bool_constant<__is_nothrow_assignable(_Tp, _Up)>;
+ /// @endcond
/// is_nothrow_assignable
template<typename _Tp, typename _Up>
@@ -1170,52 +1151,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
"template argument must be a complete class or an unbounded array");
};
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_nt_copy_assignable_impl;
-
- template<typename _Tp>
- struct __is_nt_copy_assignable_impl<_Tp, false>
- : public false_type { };
-
- template<typename _Tp>
- struct __is_nt_copy_assignable_impl<_Tp, true>
- : public __is_nothrow_assignable_impl<_Tp&, const _Tp&>
- { };
-
/// is_nothrow_copy_assignable
template<typename _Tp>
struct is_nothrow_copy_assignable
- : public __is_nt_copy_assignable_impl<_Tp>
+ : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>,
+ __add_lval_ref_t<const _Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_nt_move_assignable_impl;
-
- template<typename _Tp>
- struct __is_nt_move_assignable_impl<_Tp, false>
- : public false_type { };
-
- template<typename _Tp>
- struct __is_nt_move_assignable_impl<_Tp, true>
- : public __is_nothrow_assignable_impl<_Tp&, _Tp&&>
- { };
-
/// is_nothrow_move_assignable
template<typename _Tp>
struct is_nothrow_move_assignable
- : public __is_nt_move_assignable_impl<_Tp>
+ : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>,
+ __add_rval_ref_t<_Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
+ /// @cond undocumented
+ template<typename _Tp, typename... _Args>
+ using __is_trivially_constructible_impl
+ = __bool_constant<__is_trivially_constructible(_Tp, _Args...)>;
+ /// @endcond
+
/// is_trivially_constructible
template<typename _Tp, typename... _Args>
struct is_trivially_constructible
- : public __bool_constant<__is_trivially_constructible(_Tp, _Args...)>
+ : public __is_trivially_constructible_impl<_Tp, _Args...>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -1224,7 +1189,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// is_trivially_default_constructible
template<typename _Tp>
struct is_trivially_default_constructible
- : public __bool_constant<__is_trivially_constructible(_Tp)>
+ : public __is_trivially_constructible_impl<_Tp>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -1257,101 +1222,57 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template <typename _Tp>
struct __is_implicitly_default_constructible
: public __and_<__is_constructible_impl<_Tp>,
- __is_implicitly_default_constructible_safe<_Tp>>
- { };
-
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_trivially_copy_constructible_impl;
-
- template<typename _Tp>
- struct __is_trivially_copy_constructible_impl<_Tp, false>
- : public false_type { };
-
- template<typename _Tp>
- struct __is_trivially_copy_constructible_impl<_Tp, true>
- : public __and_<__is_copy_constructible_impl<_Tp>,
- integral_constant<bool,
- __is_trivially_constructible(_Tp, const _Tp&)>>
+ __is_implicitly_default_constructible_safe<_Tp>>::type
{ };
/// is_trivially_copy_constructible
template<typename _Tp>
struct is_trivially_copy_constructible
- : public __is_trivially_copy_constructible_impl<_Tp>
+ : public __is_trivially_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_trivially_move_constructible_impl;
-
- template<typename _Tp>
- struct __is_trivially_move_constructible_impl<_Tp, false>
- : public false_type { };
-
- template<typename _Tp>
- struct __is_trivially_move_constructible_impl<_Tp, true>
- : public __and_<__is_move_constructible_impl<_Tp>,
- integral_constant<bool,
- __is_trivially_constructible(_Tp, _Tp&&)>>
- { };
-
/// is_trivially_move_constructible
template<typename _Tp>
struct is_trivially_move_constructible
- : public __is_trivially_move_constructible_impl<_Tp>
+ : public __is_trivially_constructible_impl<_Tp, __add_rval_ref_t<_Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
+ /// @cond undocumented
+ template<typename _Tp, typename _Up>
+ using __is_trivially_assignable_impl
+ = __bool_constant<__is_trivially_assignable(_Tp, _Up)>;
+ /// @endcond
+
/// is_trivially_assignable
template<typename _Tp, typename _Up>
struct is_trivially_assignable
- : public __bool_constant<__is_trivially_assignable(_Tp, _Up)>
+ : public __is_trivially_assignable_impl<_Tp, _Up>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_trivially_copy_assignable_impl;
-
- template<typename _Tp>
- struct __is_trivially_copy_assignable_impl<_Tp, false>
- : public false_type { };
-
- template<typename _Tp>
- struct __is_trivially_copy_assignable_impl<_Tp, true>
- : public __bool_constant<__is_trivially_assignable(_Tp&, const _Tp&)>
- { };
-
/// is_trivially_copy_assignable
template<typename _Tp>
struct is_trivially_copy_assignable
- : public __is_trivially_copy_assignable_impl<_Tp>
+ : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>,
+ __add_lval_ref_t<const _Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
};
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __is_trivially_move_assignable_impl;
-
- template<typename _Tp>
- struct __is_trivially_move_assignable_impl<_Tp, false>
- : public false_type { };
-
- template<typename _Tp>
- struct __is_trivially_move_assignable_impl<_Tp, true>
- : public __bool_constant<__is_trivially_assignable(_Tp&, _Tp&&)>
- { };
-
/// is_trivially_move_assignable
template<typename _Tp>
struct is_trivially_move_assignable
- : public __is_trivially_move_assignable_impl<_Tp>
+ : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>,
+ __add_rval_ref_t<_Tp>>
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -1361,7 +1282,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
struct is_trivially_destructible
: public __and_<__is_destructible_safe<_Tp>,
- __bool_constant<__has_trivial_destructor(_Tp)>>
+ __bool_constant<__has_trivial_destructor(_Tp)>>::type
{
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
"template argument must be a complete class or an unbounded array");
@@ -1403,23 +1324,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
/// extent
- template<typename, unsigned _Uint>
+ template<typename, unsigned _Uint = 0>
struct extent
- : public integral_constant<std::size_t, 0> { };
+ : public integral_constant<size_t, 0> { };
+
+ template<typename _Tp, size_t _Size>
+ struct extent<_Tp[_Size], 0>
+ : public integral_constant<size_t, _Size> { };
- template<typename _Tp, unsigned _Uint, std::size_t _Size>
+ template<typename _Tp, unsigned _Uint, size_t _Size>
struct extent<_Tp[_Size], _Uint>
- : public integral_constant<std::size_t,
- _Uint == 0 ? _Size : extent<_Tp,
- _Uint - 1>::value>
- { };
+ : public extent<_Tp, _Uint - 1>::type { };
+
+ template<typename _Tp>
+ struct extent<_Tp[], 0>
+ : public integral_constant<size_t, 0> { };
template<typename _Tp, unsigned _Uint>
struct extent<_Tp[], _Uint>
- : public integral_constant<std::size_t,
- _Uint == 0 ? 0 : extent<_Tp,
- _Uint - 1>::value>
- { };
+ : public extent<_Tp, _Uint - 1>::type { };
// Type relations.
@@ -1633,33 +1556,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct remove_reference<_Tp&&>
{ typedef _Tp type; };
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __add_lvalue_reference_helper
- { typedef _Tp type; };
-
- template<typename _Tp>
- struct __add_lvalue_reference_helper<_Tp, true>
- { typedef _Tp& type; };
-
/// add_lvalue_reference
template<typename _Tp>
struct add_lvalue_reference
- : public __add_lvalue_reference_helper<_Tp>
- { };
-
- template<typename _Tp, bool = __is_referenceable<_Tp>::value>
- struct __add_rvalue_reference_helper
- { typedef _Tp type; };
-
- template<typename _Tp>
- struct __add_rvalue_reference_helper<_Tp, true>
- { typedef _Tp&& type; };
+ { using type = __add_lval_ref_t<_Tp>; };
/// add_rvalue_reference
template<typename _Tp>
struct add_rvalue_reference
- : public __add_rvalue_reference_helper<_Tp>
- { };
+ { using type = __add_rval_ref_t<_Tp>; };
#if __cplusplus > 201103L
/// Alias template for remove_reference
@@ -2060,14 +1965,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
{ };
- template<typename _Tp, bool = __or_<__is_referenceable<_Tp>,
- is_void<_Tp>>::value>
+ template<typename _Tp, typename = void>
struct __add_pointer_helper
- { typedef _Tp type; };
+ { using type = _Tp; };
template<typename _Tp>
- struct __add_pointer_helper<_Tp, true>
- { typedef typename remove_reference<_Tp>::type* type; };
+ struct __add_pointer_helper<_Tp, __void_t<_Tp*>>
+ { using type = _Tp*; };
/// add_pointer
template<typename _Tp>
@@ -2075,6 +1979,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: public __add_pointer_helper<_Tp>
{ };
+ template<typename _Tp>
+ struct add_pointer<_Tp&>
+ { using type = _Tp*; };
+
+ template<typename _Tp>
+ struct add_pointer<_Tp&&>
+ { using type = _Tp*; };
+
#if __cplusplus > 201103L
/// Alias template for remove_pointer
template<typename _Tp>
@@ -2167,34 +2079,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Decay trait for arrays and functions, used for perfect forwarding
// in make_pair, make_tuple, etc.
- template<typename _Up,
- bool _IsArray = is_array<_Up>::value,
- bool _IsFunction = is_function<_Up>::value>
- struct __decay_selector;
-
- // NB: DR 705.
template<typename _Up>
- struct __decay_selector<_Up, false, false>
- { typedef __remove_cv_t<_Up> __type; };
+ struct __decay_selector
+ : __conditional_t<is_const<const _Up>::value, // false for functions
+ remove_cv<_Up>, // N.B. DR 705.
+ add_pointer<_Up>> // function decays to pointer
+ { };
- template<typename _Up>
- struct __decay_selector<_Up, true, false>
- { typedef typename remove_extent<_Up>::type* __type; };
+ template<typename _Up, size_t _Nm>
+ struct __decay_selector<_Up[_Nm]>
+ { using type = _Up*; };
template<typename _Up>
- struct __decay_selector<_Up, false, true>
- { typedef typename add_pointer<_Up>::type __type; };
+ struct __decay_selector<_Up[]>
+ { using type = _Up*; };
+
/// @endcond
/// decay
template<typename _Tp>
- class decay
- {
- typedef typename remove_reference<_Tp>::type __remove_type;
+ struct decay
+ { using type = typename __decay_selector<_Tp>::type; };
- public:
- typedef typename __decay_selector<__remove_type>::__type type;
- };
+ template<typename _Tp>
+ struct decay<_Tp&>
+ { using type = typename __decay_selector<_Tp>::type; };
+
+ template<typename _Tp>
+ struct decay<_Tp&&>
+ { using type = typename __decay_selector<_Tp>::type; };
/// @cond undocumented
@@ -2219,23 +2132,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using __decay_and_strip = __strip_reference_wrapper<__decay_t<_Tp>>;
/// @endcond
- // Primary template.
- /// Define a member typedef `type` only if a boolean constant is true.
- template<bool, typename _Tp = void>
- struct enable_if
- { };
-
- // Partial specialization for true.
- template<typename _Tp>
- struct enable_if<true, _Tp>
- { typedef _Tp type; };
-
/// @cond undocumented
- // __enable_if_t (std::enable_if_t for C++11)
- template<bool _Cond, typename _Tp = void>
- using __enable_if_t = typename enable_if<_Cond, _Tp>::type;
-
// Helper for SFINAE constraints
template<typename... _Cond>
using _Require = __enable_if_t<__and_<_Cond...>::value>;
@@ -3077,7 +2975,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __is_nt_invocable_impl<_Result, _Ret,
__void_t<typename _Result::type>>
: __or_<is_void<_Ret>,
- __is_nothrow_convertible<typename _Result::type, _Ret>>
+ __is_nothrow_convertible<typename _Result::type, _Ret>>::type
{ };
/// @endcond
@@ -3121,16 +3019,24 @@ template <typename _Tp>
inline constexpr bool is_integral_v = is_integral<_Tp>::value;
template <typename _Tp>
inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
+
+template <typename _Tp>
+ inline constexpr bool is_array_v = false;
template <typename _Tp>
- inline constexpr bool is_array_v = is_array<_Tp>::value;
+ inline constexpr bool is_array_v<_Tp[]> = true;
+template <typename _Tp, size_t _Num>
+ inline constexpr bool is_array_v<_Tp[_Num]> = true;
+
template <typename _Tp>
inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
template <typename _Tp>
- inline constexpr bool is_lvalue_reference_v =
- is_lvalue_reference<_Tp>::value;
+ inline constexpr bool is_lvalue_reference_v = false;
+template <typename _Tp>
+ inline constexpr bool is_lvalue_reference_v<_Tp&> = true;
template <typename _Tp>
- inline constexpr bool is_rvalue_reference_v =
- is_rvalue_reference<_Tp>::value;
+ inline constexpr bool is_rvalue_reference_v = false;
+template <typename _Tp>
+ inline constexpr bool is_rvalue_reference_v<_Tp&&> = true;
template <typename _Tp>
inline constexpr bool is_member_object_pointer_v =
is_member_object_pointer<_Tp>::value;
@@ -3138,15 +3044,19 @@ template <typename _Tp>
inline constexpr bool is_member_function_pointer_v =
is_member_function_pointer<_Tp>::value;
template <typename _Tp>
- inline constexpr bool is_enum_v = is_enum<_Tp>::value;
+ inline constexpr bool is_enum_v = __is_enum(_Tp);
template <typename _Tp>
- inline constexpr bool is_union_v = is_union<_Tp>::value;
+ inline constexpr bool is_union_v = __is_union(_Tp);
template <typename _Tp>
- inline constexpr bool is_class_v = is_class<_Tp>::value;
+ inline constexpr bool is_class_v = __is_class(_Tp);
template <typename _Tp>
inline constexpr bool is_function_v = is_function<_Tp>::value;
template <typename _Tp>
- inline constexpr bool is_reference_v = is_reference<_Tp>::value;
+ inline constexpr bool is_reference_v = false;
+template <typename _Tp>
+ inline constexpr bool is_reference_v<_Tp&> = true;
+template <typename _Tp>
+ inline constexpr bool is_reference_v<_Tp&&> = true;
template <typename _Tp>
inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
template <typename _Tp>
@@ -3160,9 +3070,13 @@ template <typename _Tp>
template <typename _Tp>
inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
template <typename _Tp>
- inline constexpr bool is_const_v = is_const<_Tp>::value;
+ inline constexpr bool is_const_v = false;
+template <typename _Tp>
+ inline constexpr bool is_const_v<const _Tp> = true;
template <typename _Tp>
- inline constexpr bool is_volatile_v = is_volatile<_Tp>::value;
+ inline constexpr bool is_volatile_v = false;
+template <typename _Tp>
+ inline constexpr bool is_volatile_v<volatile _Tp> = true;
template <typename _Tp>
inline constexpr bool is_trivial_v = is_trivial<_Tp>::value;
template <typename _Tp>
@@ -3179,83 +3093,93 @@ template <typename _Tp>
_GLIBCXX17_DEPRECATED
inline constexpr bool is_literal_type_v = is_literal_type<_Tp>::value;
#pragma GCC diagnostic pop
- template <typename _Tp>
- inline constexpr bool is_empty_v = is_empty<_Tp>::value;
template <typename _Tp>
- inline constexpr bool is_polymorphic_v = is_polymorphic<_Tp>::value;
+ inline constexpr bool is_empty_v = __is_empty(_Tp);
+template <typename _Tp>
+ inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
template <typename _Tp>
- inline constexpr bool is_abstract_v = is_abstract<_Tp>::value;
+ inline constexpr bool is_abstract_v = __is_abstract(_Tp);
template <typename _Tp>
- inline constexpr bool is_final_v = is_final<_Tp>::value;
+ inline constexpr bool is_final_v = __is_final(_Tp);
template <typename _Tp>
inline constexpr bool is_signed_v = is_signed<_Tp>::value;
template <typename _Tp>
inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
+
template <typename _Tp, typename... _Args>
- inline constexpr bool is_constructible_v =
- is_constructible<_Tp, _Args...>::value;
+ inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
template <typename _Tp>
- inline constexpr bool is_default_constructible_v =
- is_default_constructible<_Tp>::value;
+ inline constexpr bool is_default_constructible_v = __is_constructible(_Tp);
template <typename _Tp>
- inline constexpr bool is_copy_constructible_v =
- is_copy_constructible<_Tp>::value;
+ inline constexpr bool is_copy_constructible_v
+ = __is_constructible(_Tp, __add_lval_ref_t<const _Tp>);
template <typename _Tp>
- inline constexpr bool is_move_constructible_v =
- is_move_constructible<_Tp>::value;
+ inline constexpr bool is_move_constructible_v
+ = __is_constructible(_Tp, __add_rval_ref_t<_Tp>);
+
template <typename _Tp, typename _Up>
- inline constexpr bool is_assignable_v = is_assignable<_Tp, _Up>::value;
+ inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Up);
template <typename _Tp>
- inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value;
+ inline constexpr bool is_copy_assignable_v
+ = __is_assignable(__add_lval_ref_t<_Tp>, __add_lval_ref_t<const _Tp>);
template <typename _Tp>
- inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value;
+ inline constexpr bool is_move_assignable_v
+ = __is_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>);
+
template <typename _Tp>
inline constexpr bool is_destructible_v = is_destructible<_Tp>::value;
+
template <typename _Tp, typename... _Args>
- inline constexpr bool is_trivially_constructible_v =
- is_trivially_constructible<_Tp, _Args...>::value;
+ inline constexpr bool is_trivially_constructible_v
+ = __is_trivially_constructible(_Tp, _Args...);
template <typename _Tp>
- inline constexpr bool is_trivially_default_constructible_v =
- is_trivially_default_constructible<_Tp>::value;
+ inline constexpr bool is_trivially_default_constructible_v
+ = __is_trivially_constructible(_Tp);
template <typename _Tp>
- inline constexpr bool is_trivially_copy_constructible_v =
- is_trivially_copy_constructible<_Tp>::value;
+ inline constexpr bool is_trivially_copy_constructible_v
+ = __is_trivially_constructible(_Tp, __add_lval_ref_t<const _Tp>);
template <typename _Tp>
- inline constexpr bool is_trivially_move_constructible_v =
- is_trivially_move_constructible<_Tp>::value;
+ inline constexpr bool is_trivially_move_constructible_v
+ = __is_trivially_constructible(_Tp, __add_rval_ref_t<_Tp>);
+
template <typename _Tp, typename _Up>
- inline constexpr bool is_trivially_assignable_v =
- is_trivially_assignable<_Tp, _Up>::value;
+ inline constexpr bool is_trivially_assignable_v
+ = __is_trivially_assignable(_Tp, _Up);
template <typename _Tp>
- inline constexpr bool is_trivially_copy_assignable_v =
- is_trivially_copy_assignable<_Tp>::value;
+ inline constexpr bool is_trivially_copy_assignable_v
+ = __is_trivially_assignable(__add_lval_ref_t<_Tp>,
+ __add_lval_ref_t<const _Tp>);
template <typename _Tp>
- inline constexpr bool is_trivially_move_assignable_v =
- is_trivially_move_assignable<_Tp>::value;
+ inline constexpr bool is_trivially_move_assignable_v
+ = __is_trivially_assignable(__add_lval_ref_t<_Tp>,
+ __add_rval_ref_t<_Tp>);
template <typename _Tp>
inline constexpr bool is_trivially_destructible_v =
is_trivially_destructible<_Tp>::value;
template <typename _Tp, typename... _Args>
- inline constexpr bool is_nothrow_constructible_v =
- is_nothrow_constructible<_Tp, _Args...>::value;
+ inline constexpr bool is_nothrow_constructible_v
+ = __is_nothrow_constructible(_Tp, _Args...);
template <typename _Tp>
- inline constexpr bool is_nothrow_default_constructible_v =
- is_nothrow_default_constructible<_Tp>::value;
+ inline constexpr bool is_nothrow_default_constructible_v
+ = __is_nothrow_constructible(_Tp);
template <typename _Tp>
- inline constexpr bool is_nothrow_copy_constructible_v =
- is_nothrow_copy_constructible<_Tp>::value;
+ inline constexpr bool is_nothrow_copy_constructible_v
+ = __is_nothrow_constructible(_Tp, __add_lval_ref_t<const _Tp>);
template <typename _Tp>
- inline constexpr bool is_nothrow_move_constructible_v =
- is_nothrow_move_constructible<_Tp>::value;
+ inline constexpr bool is_nothrow_move_constructible_v
+ = __is_nothrow_constructible(_Tp, __add_rval_ref_t<_Tp>);
+
template <typename _Tp, typename _Up>
- inline constexpr bool is_nothrow_assignable_v =
- is_nothrow_assignable<_Tp, _Up>::value;
+ inline constexpr bool is_nothrow_assignable_v
+ = __is_nothrow_assignable(_Tp, _Up);
template <typename _Tp>
- inline constexpr bool is_nothrow_copy_assignable_v =
- is_nothrow_copy_assignable<_Tp>::value;
+ inline constexpr bool is_nothrow_copy_assignable_v
+ = __is_nothrow_assignable(__add_lval_ref_t<_Tp>,
+ __add_lval_ref_t<const _Tp>);
template <typename _Tp>
- inline constexpr bool is_nothrow_move_assignable_v =
- is_nothrow_move_assignable<_Tp>::value;
+ inline constexpr bool is_nothrow_move_assignable_v
+ = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>);
+
template <typename _Tp>
inline constexpr bool is_nothrow_destructible_v =
is_nothrow_destructible<_Tp>::value;
@@ -3264,10 +3188,25 @@ template <typename _Tp>
has_virtual_destructor<_Tp>::value;
template <typename _Tp>
inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value;
+
template <typename _Tp>
- inline constexpr size_t rank_v = rank<_Tp>::value;
+ inline constexpr size_t rank_v = 0;
+template <typename _Tp, size_t _Size>
+ inline constexpr size_t rank_v<_Tp[_Size]> = 1 + rank_v<_Tp>;
+template <typename _Tp>
+ inline constexpr size_t rank_v<_Tp[]> = 1 + rank_v<_Tp>;
+
template <typename _Tp, unsigned _Idx = 0>
- inline constexpr size_t extent_v = extent<_Tp, _Idx>::value;
+ inline constexpr size_t extent_v = 0;
+template <typename _Tp, size_t _Size>
+ inline constexpr size_t extent_v<_Tp[_Size], 0> = _Size;
+template <typename _Tp, unsigned _Idx, size_t _Size>
+ inline constexpr size_t extent_v<_Tp[_Size], _Idx> = extent_v<_Tp, _Idx - 1>;
+template <typename _Tp>
+ inline constexpr size_t extent_v<_Tp[], 0> = 0;
+template <typename _Tp, unsigned _Idx>
+ inline constexpr size_t extent_v<_Tp[], _Idx> = extent_v<_Tp, _Idx - 1>;
+
#ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME
template <typename _Tp, typename _Up>
inline constexpr bool is_same_v = __is_same(_Tp, _Up);
@@ -3276,7 +3215,7 @@ template <typename _Tp, typename _Up>
inline constexpr bool is_same_v = std::is_same<_Tp, _Up>::value;
#endif
template <typename _Base, typename _Derived>
- inline constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value;
+ inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived);
template <typename _From, typename _To>
inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
template<typename _Fn, typename... _Args>
@@ -3314,16 +3253,19 @@ template<typename _Ret, typename _Fn, typename... _Args>
#ifdef _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE
# define __cpp_lib_is_aggregate 201703L
- /// is_aggregate
+ /// is_aggregate - true if the type is an aggregate.
/// @since C++17
template<typename _Tp>
struct is_aggregate
: bool_constant<__is_aggregate(remove_cv_t<_Tp>)>
{ };
- /// @ingroup variable_templates
+ /** is_aggregate_v - true if the type is an aggregate.
+ * @ingroup variable_templates
+ * @since C++17
+ */
template<typename _Tp>
- inline constexpr bool is_aggregate_v = is_aggregate<_Tp>::value;
+ inline constexpr bool is_aggregate_v = __is_aggregate(remove_cv_t<_Tp>);
#endif
#endif // C++17
@@ -3396,30 +3338,36 @@ template<typename _Ret, typename _Fn, typename... _Args>
#define __cpp_lib_bounded_array_traits 201902L
/// True for a type that is an array of known bound.
+ /// @ingroup variable_templates
/// @since C++20
template<typename _Tp>
- struct is_bounded_array
- : public __is_array_known_bounds<_Tp>
- { };
+ inline constexpr bool is_bounded_array_v = false;
+
+ template<typename _Tp, size_t _Size>
+ inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true;
/// True for a type that is an array of unknown bound.
+ /// @ingroup variable_templates
/// @since C++20
template<typename _Tp>
- struct is_unbounded_array
- : public __is_array_unknown_bounds<_Tp>
- { };
+ inline constexpr bool is_unbounded_array_v = false;
- /// @ingroup variable_templates
+ template<typename _Tp>
+ inline constexpr bool is_unbounded_array_v<_Tp[]> = true;
+
+ /// True for a type that is an array of known bound.
/// @since C++20
template<typename _Tp>
- inline constexpr bool is_bounded_array_v
- = is_bounded_array<_Tp>::value;
+ struct is_bounded_array
+ : public bool_constant<is_bounded_array_v<_Tp>>
+ { };
- /// @ingroup variable_templates
+ /// True for a type that is an array of unknown bound.
/// @since C++20
template<typename _Tp>
- inline constexpr bool is_unbounded_array_v
- = is_unbounded_array<_Tp>::value;
+ struct is_unbounded_array
+ : public bool_constant<is_unbounded_array_v<_Tp>>
+ { };
#if __has_builtin(__is_layout_compatible)
@@ -3486,20 +3434,11 @@ template<typename _Ret, typename _Fn, typename... _Args>
template<typename _Tp>
requires __is_enum(_Tp)
- && requires(_Tp __t) { __t = __t; } // fails if incomplete
+ && requires(remove_cv_t<_Tp> __t) { __t = __t; } // fails if incomplete
struct is_scoped_enum<_Tp>
: bool_constant<!requires(_Tp __t, void(*__f)(int)) { __f(__t); }>
{ };
- // FIXME remove this partial specialization and use remove_cv_t<_Tp> above
- // when PR c++/99968 is fixed.
- template<typename _Tp>
- requires __is_enum(_Tp)
- && requires(_Tp __t) { __t = __t; } // fails if incomplete
- struct is_scoped_enum<const _Tp>
- : bool_constant<!requires(_Tp __t, void(*__f)(int)) { __f(__t); }>
- { };
-
/// @ingroup variable_templates
/// @since C++23
template<typename _Tp>
diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc
index 8ed61a6..abc4124 100644
--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -611,10 +611,12 @@ namespace
void
print_raw(PrintContext& ctx, const char* str, ptrdiff_t nbc = -1)
{
- if (nbc >= 0)
- ctx._M_column += fprintf(stderr, "%.*s", (int)nbc, str);
- else
- ctx._M_column += fprintf(stderr, "%s", str);
+ if (nbc != 0)
+ {
+ ctx._M_column += (nbc > 0)
+ ? fprintf(stderr, "%.*s", (int)nbc, str)
+ : fprintf(stderr, "%s", str);
+ }
}
void
@@ -680,7 +682,7 @@ namespace
pos += 2; // advance past "__"
if (memcmp(pos, cxx1998, 9) == 0)
- pos += 9; // advance part "cxx1998::"
+ pos += 9; // advance past "cxx1998::"
str = pos;
}
@@ -1093,6 +1095,58 @@ namespace
void
print_string(PrintContext& ctx, const char* str, ptrdiff_t nbc)
{ print_string(ctx, str, nbc, nullptr, 0); }
+
+#if _GLIBCXX_HAVE_STACKTRACE
+ int
+ print_backtrace(void* data, __UINTPTR_TYPE__ pc, const char* filename,
+ int lineno, const char* function)
+ {
+ const int bufsize = 64;
+ char buf[bufsize];
+
+ PrintContext& ctx = *static_cast<PrintContext*>(data);
+
+ int written = __builtin_sprintf(buf, "%p ", (void*)pc);
+ print_word(ctx, buf, written);
+
+ int ret = 0;
+ if (function)
+ {
+ int status;
+ char* demangled_name =
+ __cxxabiv1::__cxa_demangle(function, NULL, NULL, &status);
+ if (status == 0)
+ pretty_print(ctx, demangled_name, &print_raw);
+ else
+ print_word(ctx, function);
+
+ free(demangled_name);
+ ret = strstr(function, "main") ? 1 : 0;
+ }
+
+ print_literal(ctx, "\n");
+
+ if (filename)
+ {
+ bool wordwrap = false;
+ swap(wordwrap, ctx._M_wordwrap);
+ print_word(ctx, filename);
+
+ if (lineno)
+ {
+ written = __builtin_sprintf(buf, ":%u\n", lineno);
+ print_word(ctx, buf, written);
+ }
+ else
+ print_literal(ctx, "\n");
+ swap(wordwrap, ctx._M_wordwrap);
+ }
+ else
+ print_literal(ctx, "???:0\n");
+
+ return ret;
+ }
+#endif
}
namespace __gnu_debug
@@ -1139,6 +1193,17 @@ namespace __gnu_debug
print_literal(ctx, "\n");
}
+#if _GLIBCXX_HAVE_STACKTRACE
+ if (_M_backtrace_state)
+ {
+ print_literal(ctx, "Backtrace:\n");
+ _M_backtrace_full(
+ _M_backtrace_state, 1, print_backtrace, nullptr, &ctx);
+ ctx._M_first_line = true;
+ print_literal(ctx, "\n");
+ }
+#endif
+
print_literal(ctx, "Error: ");
// Print the error message
diff --git a/libstdc++-v3/src/libbacktrace/Makefile.am b/libstdc++-v3/src/libbacktrace/Makefile.am
index 0f11435..52d8f81 100644
--- a/libstdc++-v3/src/libbacktrace/Makefile.am
+++ b/libstdc++-v3/src/libbacktrace/Makefile.am
@@ -60,6 +60,7 @@ libstdc___libbacktrace_la_SHORTNAME = $(obj_prefix)
libstdc___libbacktrace_la_SOURCES = \
atomic.c \
+ backtrace.c \
dwarf.c \
fileline.c \
posix.c \
diff --git a/libstdc++-v3/src/libbacktrace/Makefile.in b/libstdc++-v3/src/libbacktrace/Makefile.in
index 7545894..5c6b4dd 100644
--- a/libstdc++-v3/src/libbacktrace/Makefile.in
+++ b/libstdc++-v3/src/libbacktrace/Makefile.in
@@ -181,10 +181,10 @@ am__uninstall_files_from_dir = { \
am__installdirs = "$(DESTDIR)$(toolexeclibdir)"
LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
am_libstdc___libbacktrace_la_OBJECTS = $(obj_prefix)-atomic.lo \
- $(obj_prefix)-dwarf.lo $(obj_prefix)-fileline.lo \
- $(obj_prefix)-posix.lo $(obj_prefix)-sort.lo \
- $(obj_prefix)-simple.lo $(obj_prefix)-state.lo \
- $(obj_prefix)-cp-demangle.lo
+ $(obj_prefix)-backtrace.lo $(obj_prefix)-dwarf.lo \
+ $(obj_prefix)-fileline.lo $(obj_prefix)-posix.lo \
+ $(obj_prefix)-sort.lo $(obj_prefix)-simple.lo \
+ $(obj_prefix)-state.lo $(obj_prefix)-cp-demangle.lo
libstdc___libbacktrace_la_OBJECTS = \
$(am_libstdc___libbacktrace_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -507,6 +507,7 @@ obj_prefix = std_stacktrace
libstdc___libbacktrace_la_SHORTNAME = $(obj_prefix)
libstdc___libbacktrace_la_SOURCES = \
atomic.c \
+ backtrace.c \
dwarf.c \
fileline.c \
posix.c \
@@ -647,6 +648,9 @@ distclean-compile:
$(obj_prefix)-atomic.lo: atomic.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstdc___libbacktrace_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $(obj_prefix)-atomic.lo `test -f 'atomic.c' || echo '$(srcdir)/'`atomic.c
+$(obj_prefix)-backtrace.lo: backtrace.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstdc___libbacktrace_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $(obj_prefix)-backtrace.lo `test -f 'backtrace.c' || echo '$(srcdir)/'`backtrace.c
+
$(obj_prefix)-dwarf.lo: dwarf.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstdc___libbacktrace_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $(obj_prefix)-dwarf.lo `test -f 'dwarf.c' || echo '$(srcdir)/'`dwarf.c
diff --git a/libstdc++-v3/src/libbacktrace/backtrace-rename.h b/libstdc++-v3/src/libbacktrace/backtrace-rename.h
index 7a59f16..79bdef6 100644
--- a/libstdc++-v3/src/libbacktrace/backtrace-rename.h
+++ b/libstdc++-v3/src/libbacktrace/backtrace-rename.h
@@ -4,6 +4,7 @@
#define backtrace_create_state __glibcxx_backtrace_create_state
#define backtrace_dwarf_add __glibcxx_backtrace_dwarf_add
#define backtrace_free __glibcxx_backtrace_free
+#define backtrace_full __glibcxx_backtrace_full
#define backtrace_get_view __glibcxx_backtrace_get_view
#define backtrace_initialize __glibcxx_backtrace_initialize
#define backtrace_open __glibcxx_backtrace_open
diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/1.cc b/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/1.cc
index f454fc2..d48d5c1 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/1.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/1.cc
@@ -22,23 +22,46 @@
#include <system_error>
#include <testsuite_error.h>
+namespace adl
+{
+ struct Error { };
+
+ const Error err;
+
+ struct category : std::error_category
+ {
+ const char* name() const noexcept override { return "adl"; }
+ std::string message(int) const { return ""; }
+ };
+
+ const category cat;
+
+ std::error_code
+ make_error_code(Error) { return std::error_code(999, cat); }
+}
+
+template<> struct std::is_error_code_enum<adl::Error> : std::true_type { };
+
int main()
{
- // 1
+ // 1 error_code()
std::error_code e1;
VERIFY( e1.value() == 0 );
VERIFY( e1.category() == std::system_category() );
- // 2
+ // 2 error_code(int, const error_category&)
const __gnu_test::test_category cat;
std::error_code e2(e1.value(), cat);
VERIFY( e2.value() == e1.value() );
VERIFY( e2.category() == cat );
- // 3
+ // 3 error_code(const error_code&)
std::error_code e3(std::make_error_code(std::errc::operation_not_supported));
VERIFY( e3.value() == int(std::errc::operation_not_supported) );
VERIFY( e3.category() == std::generic_category() );
- return 0;
+ // 4 error_code(ErrorCodeEnum)
+ std::error_code e4(adl::err);
+ VERIFY( e4.value() == 999 );
+ VERIFY( e4.category() == adl::cat );
}
diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/1.cc b/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/1.cc
index 1e039c4..c353b02 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/1.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/1.cc
@@ -21,23 +21,48 @@
#include <system_error>
#include <testsuite_error.h>
+namespace adl
+{
+ struct Error { };
+
+ const Error err;
+
+ struct category : std::error_category
+ {
+ const char* name() const noexcept override { return "adl"; }
+ std::string message(int) const { return ""; }
+ };
+
+ const category cat;
+
+ std::error_condition
+ make_error_condition(Error) { return std::error_condition(999, cat); }
+}
+
+template<> struct std::is_error_condition_enum<adl::Error> : std::true_type { };
+
void test01()
{
- // 1
+ // 1 error_condition()
std::error_condition e1;
VERIFY( e1.value() == 0 );
VERIFY( e1.category() == std::generic_category() );
- // 2
+ // 2 error_condition(int, const error_category&)
const __gnu_test::test_category cat;
std::error_condition e2(e1.value(), cat);
VERIFY( e2.value() == e1.value() );
VERIFY( e2.category() == cat );
- // 3
+ // 3 error_condition(const error_condition&)
std::error_condition e3(std::errc::operation_not_supported);
VERIFY( e3.value() == int(std::errc::operation_not_supported) );
VERIFY( e3.category() == std::generic_category() );
+
+ // 4 error_condition(ErrorConditionEnum)
+ std::error_condition e4(adl::err);
+ VERIFY( e4.value() == 999 );
+ VERIFY( e4.category() == adl::cat );
}
int main()
diff --git a/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc b/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc
index af6e72d..c5179b6 100644
--- a/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc
+++ b/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc
@@ -58,3 +58,8 @@ static_assert( std::chrono::round<seconds>(2501ms) == 3s );
static_assert( std::chrono::abs(100ms) == 100ms );
static_assert( std::chrono::abs(-100ms) == 100ms );
+
+// LWG 3741. std::chrono::abs(duration) is ill-formed with non-reduced periods
+using D1000 = std::chrono::duration<int, std::ratio<1000, 1000>>;
+static_assert( std::chrono::abs(D1000(-2)) == D1000(2) );
+static_assert( std::is_same_v<decltype(std::chrono::abs(D1000(-2))), D1000> );
diff --git a/libstdc++-v3/testsuite/20_util/logical_traits/requirements/base_classes.cc b/libstdc++-v3/testsuite/20_util/logical_traits/requirements/base_classes.cc
new file mode 100644
index 0000000..9067a3b
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/logical_traits/requirements/base_classes.cc
@@ -0,0 +1,34 @@
+// { dg-do compile { target c++17 } }
+
+#include <type_traits>
+
+template<int> struct T : std::true_type { };
+template<int> struct F : std::false_type { };
+
+// [meta.logical]/5: The specialization conjunction<B_1, ..., B_n> has a
+// public and unambiguous base that is either:
+// - the first type B_i in the list true_type, B_1, ..., B_n for which
+// bool(B_i::value) is false, or
+// - if there is no such B_i, the last type in the list.
+
+static_assert(std::is_base_of_v<std::true_type, std::conjunction<>>);
+static_assert(std::is_base_of_v<T<0>, std::conjunction<T<0>>>);
+static_assert(std::is_base_of_v<F<0>, std::conjunction<F<0>>>);
+static_assert(std::is_base_of_v<T<1>, std::conjunction<T<0>, T<1>>>);
+static_assert(std::is_base_of_v<F<0>, std::conjunction<F<0>, F<1>>>);
+static_assert(std::is_base_of_v<F<0>, std::conjunction<T<0>, F<0>, F<1>>>);
+static_assert(std::is_base_of_v<F<0>, std::conjunction<T<0>, F<0>, T<1>, F<1>>>);
+
+// [meta.logical]/10: The specialization disjunction<B_1, ..., B_n> has a
+// public and unambiguous base that is either:
+// - the first type B_i in the list false_type, B_1, ..., B_n for which
+// bool(B_i::value) is true, or
+// - if there is no such B_i, the last type in the list.
+
+static_assert(std::is_base_of_v<std::false_type, std::disjunction<>>);
+static_assert(std::is_base_of_v<T<0>, std::disjunction<T<0>>>);
+static_assert(std::is_base_of_v<F<0>, std::disjunction<F<0>>>);
+static_assert(std::is_base_of_v<T<0>, std::disjunction<T<0>, T<1>>>);
+static_assert(std::is_base_of_v<F<1>, std::disjunction<F<0>, F<1>>>);
+static_assert(std::is_base_of_v<T<0>, std::disjunction<T<0>, F<0>, F<1>>>);
+static_assert(std::is_base_of_v<T<0>, std::disjunction<T<0>, F<0>, T<1>, F<1>>>);
diff --git a/libstdc++-v3/testsuite/20_util/logical_traits/requirements/short_circuit.cc b/libstdc++-v3/testsuite/20_util/logical_traits/requirements/short_circuit.cc
new file mode 100644
index 0000000..ff90f8a
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/logical_traits/requirements/short_circuit.cc
@@ -0,0 +1,55 @@
+// { dg-do compile { target c++17 } }
+
+#include <type_traits>
+
+template<class T> struct A { using type = typename T::type; };
+using invalid = A<void>;
+
+// [meta.logical]/3: For a specialization conjunction<B_1, ..., B_n>, if
+// there is a template type argument B_i for which bool(B_i::value) is false,
+// then instantiating conjunction<B_1, ..., B_n>::value does not require the
+// instantiation of B_j::value for j > i.
+
+static_assert(!std::conjunction_v<std::false_type, invalid>);
+static_assert(!std::conjunction_v<std::false_type, invalid, invalid>);
+static_assert(!std::conjunction_v<std::true_type, std::false_type, invalid>);
+static_assert(!std::conjunction_v<std::true_type, std::false_type, invalid, invalid>);
+static_assert(!std::conjunction_v<std::false_type,
+ std::conjunction<invalid>,
+ std::disjunction<invalid>,
+ std::negation<invalid>>);
+
+// [meta.logical]/8: For a specialization disjunction<B_1, ..., B_n>, if
+// there is a template type argument B_i for which bool(B_i::value) is true,
+// then instantiating disjunction<B_1, ..., B_n>::value does not require the
+// instantiation of B_j::value for j > i.
+
+static_assert(std::disjunction_v<std::true_type, invalid>);
+static_assert(std::disjunction_v<std::true_type, invalid, invalid>);
+static_assert(std::disjunction_v<std::false_type, std::true_type, invalid>);
+static_assert(std::disjunction_v<std::false_type, std::true_type, invalid, invalid>);
+static_assert(std::disjunction_v<std::true_type,
+ std::conjunction<invalid>,
+ std::disjunction<invalid>,
+ std::negation<invalid>>);
+
+#if __GLIBCXX__
+// Also test the corresponding internal traits __and_, __or_ and __not_.
+static_assert(!std::__and_v<std::false_type, invalid>);
+static_assert(!std::__and_v<std::false_type, invalid, invalid>);
+static_assert(!std::__and_v<std::true_type, std::false_type, invalid>);
+static_assert(!std::__and_v<std::true_type, std::false_type, invalid, invalid>);
+static_assert(!std::__and_v<std::false_type,
+ std::__and_<invalid>,
+ std::__or_<invalid>,
+ std::__not_<invalid>>);
+
+static_assert(std::__or_v<std::true_type, invalid>);
+static_assert(std::__or_v<std::true_type, invalid, invalid>);
+static_assert(std::__or_v<std::false_type, std::true_type, invalid>);
+static_assert(std::__or_v<std::false_type, std::true_type, invalid, invalid>);
+static_assert(std::__or_v<std::true_type,
+ std::__and_<invalid>,
+ std::__or_<invalid>,
+ std::__not_<invalid>>);
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc
index 2741510..fd3430c 100644
--- a/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc
+++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-2.cc
@@ -16,7 +16,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 20.6.4 function object return types [func.ret]
+// C++11 20.8.3.4 reference_wrapper invocation [refwrap.invoke]
#include <functional>
struct X
@@ -27,6 +27,7 @@ struct X
void test01()
{
+ // PR libstdc++/48521 std::result_of doesn't work with pointer to member
typedef int (X::*mfp)(int);
typedef int X::*mp;
mfp m = &X::f;
diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-3.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-3.cc
index e4124c9..c25315b 100644
--- a/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-3.cc
+++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-3.cc
@@ -17,7 +17,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 20.8.3.4 reference_wrapper invocation [refwrap.invoke]
+// C++11 20.8.3.4 reference_wrapper invocation [refwrap.invoke]
#include <functional>
struct ABC
@@ -33,4 +33,5 @@ struct Concrete : ABC
Concrete c;
ABC& abc = c;
+// PR libstdc++/57336 Cannot INVOKE a reference_wrapper around an abstract type
auto b = std::cref(abc)();
diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-noexcept.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-noexcept.cc
new file mode 100644
index 0000000..91b5d09
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-noexcept.cc
@@ -0,0 +1,15 @@
+// { dg-do compile { target c++11 } }
+
+// C++11 20.8.3.4 reference_wrapper invocation [refwrap.invoke]
+
+#include <functional>
+
+struct F
+{
+ int operator()() noexcept(true) { return 1; }
+ int operator()() const noexcept(false) { return 2; }
+};
+
+F f;
+static_assert( noexcept(std::ref(f)()) );
+static_assert( ! noexcept(std::cref(f)()) );
diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke.cc
index cd884fe..b2abc81 100644
--- a/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke.cc
+++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke.cc
@@ -17,6 +17,8 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+// C++11 20.8.3.4 reference_wrapper invocation [refwrap.invoke]
+
#include <functional>
#include <type_traits>
#include <testsuite_hooks.h>
diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
index 6044a37..a326d1b 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
@@ -503,7 +503,17 @@ namespace NothrowCopyThrowMoveThrowCopyConversionNothrowMoveConversion
static_assert(!std::is_nothrow_constructible<BT, IT&>::value, "");
static_assert(!std::is_nothrow_constructible<BT, const IT &>::value, "");
static_assert(!std::is_nothrow_constructible<BT, std::tuple<int&>>::value, "");
+#if __cplusplus > 202002L
+ // C++23 extended tuple's constructor overload set as part of P2321R2, after
+ // which its converting constructors more accurately forward the elements
+ // from a non-const tuple lvalue and from a const tuple rvalue. In particular
+ // for the below test we now forward int&& as an rvalue reference instead of
+ // as an lvalue reference, which means we now select the noexcept B(int&&)
+ // ctor instead of the non-noexcept B(const int&) ctor.
+ static_assert(std::is_nothrow_constructible<BT, const std::tuple<int&&>>::value, "");
+#else
static_assert(!std::is_nothrow_constructible<BT, const std::tuple<int&&>>::value, "");
+#endif
static_assert(test_trait::is_nothrow_convertible<int,BT>::value,"");
static_assert(!test_trait::is_nothrow_convertible<const int,BT>::value,"");
@@ -515,7 +525,13 @@ namespace NothrowCopyThrowMoveThrowCopyConversionNothrowMoveConversion
static_assert(!test_trait::is_nothrow_convertible<IT&,BT>::value,"");
static_assert(!test_trait::is_nothrow_convertible<const IT &,BT>::value,"");
static_assert(!test_trait::is_nothrow_convertible<std::tuple<int&>,BT>::value,"");
+#if __cplusplus > 202002L
+ // See the note about P2321R2 above.
+ static_assert(test_trait::is_nothrow_convertible<const std::tuple<int&&>,BT>::value,"");
+#else
static_assert(!test_trait::is_nothrow_convertible<const std::tuple<int&&>,BT>::value,"");
+#endif
+
static_assert(!std::is_nothrow_constructible<BT, B>::value, "");
@@ -528,7 +544,12 @@ namespace NothrowCopyThrowMoveThrowCopyConversionNothrowMoveConversion
static_assert(std::is_nothrow_constructible<BT, BT&>::value, "");
static_assert(std::is_nothrow_constructible<BT, const BT &>::value, "");
static_assert(std::is_nothrow_constructible<BT, std::tuple<B&>>::value, "");
+#if __cplusplus > 202002L
+ // See the note about P2321R2 above.
+ static_assert(!std::is_nothrow_constructible<BT, const std::tuple<B&&>>::value, "");
+#else
static_assert(std::is_nothrow_constructible<BT, const std::tuple<B&&>>::value, "");
+#endif
static_assert(!test_trait::is_nothrow_convertible<B,BT>::value,"");
static_assert(test_trait::is_nothrow_convertible<const B,BT>::value,"");
@@ -540,7 +561,12 @@ namespace NothrowCopyThrowMoveThrowCopyConversionNothrowMoveConversion
static_assert(test_trait::is_nothrow_convertible<BT&,BT>::value,"");
static_assert(test_trait::is_nothrow_convertible<const BT &,BT>::value,"");
static_assert(test_trait::is_nothrow_convertible<std::tuple<B&>,BT>::value,"");
+#if __cplusplus > 202002L
+ // See the note about P2321R2 above.
+ static_assert(!test_trait::is_nothrow_convertible<const std::tuple<B&&>,BT>::value,"");
+#else
static_assert(test_trait::is_nothrow_convertible<const std::tuple<B&&>,BT>::value,"");
+#endif
/* explicit */
static_assert(std::is_nothrow_constructible<DT, int>::value, "");
@@ -553,7 +579,12 @@ namespace NothrowCopyThrowMoveThrowCopyConversionNothrowMoveConversion
static_assert(!std::is_nothrow_constructible<DT, IT&>::value, "");
static_assert(!std::is_nothrow_constructible<DT, const IT &>::value, "");
static_assert(!std::is_nothrow_constructible<DT, std::tuple<int&>>::value, "");
+#if __cplusplus > 202002L
+ // See the note about P2321R2 above.
+ static_assert(std::is_nothrow_constructible<DT, const std::tuple<int&&>>::value, "");
+#else
static_assert(!std::is_nothrow_constructible<DT, const std::tuple<int&&>>::value, "");
+#endif
static_assert(!std::is_nothrow_constructible<DT, D>::value, "");
static_assert(std::is_nothrow_constructible<DT,const D>::value, "");
@@ -565,7 +596,12 @@ namespace NothrowCopyThrowMoveThrowCopyConversionNothrowMoveConversion
static_assert(std::is_nothrow_constructible<DT, DT&>::value, "");
static_assert(std::is_nothrow_constructible<DT, const DT &>::value, "");
static_assert(std::is_nothrow_constructible<DT, std::tuple<D&>>::value, "");
+#if __cplusplus > 202002L
+ // See note about P2321R2 above.
+ static_assert(!std::is_nothrow_constructible<DT, const std::tuple<D&&>>::value, "");
+#else
static_assert(std::is_nothrow_constructible<DT, const std::tuple<D&&>>::value, "");
+#endif
static_assert(!test_trait::is_nothrow_convertible<DT,DT>::value,"");
static_assert(test_trait::is_nothrow_convertible<const DT,DT>::value,"");
@@ -884,7 +920,12 @@ namespace ThrowMoveNothrowConversion
static_assert(std::is_nothrow_constructible<DT, IT&>::value, "");
static_assert(std::is_nothrow_constructible<DT, const IT &>::value, "");
static_assert(std::is_nothrow_constructible<DT, std::tuple<int&>>::value, "");
+#if __cplusplus > 202002L
+ // See the note about P2321R2 above.
+ static_assert(!std::is_nothrow_constructible<DT, const std::tuple<int&&>>::value, "");
+#else
static_assert(std::is_nothrow_constructible<DT, const std::tuple<int&&>>::value, "");
+#endif
static_assert(test_trait::is_nothrow_convertible<DT,DT>::value,"");
static_assert(test_trait::is_nothrow_convertible<D,DT>::value,"");
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc
index 45af457..1ae4d3d 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc
@@ -175,7 +175,7 @@ void test01()
sz03 = str02.size();
sz04 = str02.length();
VERIFY( sz03 == sz04 );
- str02.c_str();
+ (void) str02.c_str();
sz03 = str02.size();
sz04 = str02.length();
VERIFY( sz03 == sz04 );
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc
index 244a795..1da273b 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc
@@ -74,15 +74,15 @@ void test01()
sz01 = str01.size();
sz02 = str01.length();
VERIFY( sz01 == sz02 );
- str01.c_str();
+ (void) str01.c_str();
sz01 = str01.size();
sz02 = str01.length();
VERIFY( sz01 == sz02 );
sz01 = str01.length();
- str01.c_str();
+ (void) str01.c_str();
str011 = str01 + "_addendum_";
- str01.c_str();
+ (void) str01.c_str();
sz02 = str01.length();
VERIFY( sz01 == sz02 );
sz02 = str011.length();
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc
index 5cb682e..6f03e34 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc
@@ -71,15 +71,15 @@ void test01()
sz01 = str01.size();
sz02 = str01.length();
VERIFY( sz01 == sz02 );
- str01.c_str();
+ (void) str01.c_str();
sz01 = str01.size();
sz02 = str01.length();
VERIFY( sz01 == sz02 );
sz01 = str01.length();
- str01.c_str();
+ (void) str01.c_str();
str011 = str01 + L"_addendum_";
- str01.c_str();
+ (void) str01.c_str();
sz02 = str01.length();
VERIFY( sz01 == sz02 );
sz02 = str011.length();
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/self_move.cc b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/self_move.cc
index d37fe39..ddd9aea 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/self_move.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/self_move.cc
@@ -32,7 +32,7 @@ test(const char* s)
String s3 __attribute__((unused)) = s1;
s1 = std::move(s1);
- s1.begin(); // causes COW string to "leak"
+ (void) s1.begin(); // causes COW string to "leak"
s1 = std::move(s1);
String s4 __attribute__((unused)) = s1;
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/1.cc
index 7fb4323..5a176c0 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/1.cc
@@ -53,7 +53,7 @@ void test01(void)
cref cref3 = str01.at(csz01 - 1);
VERIFY( cref3 == 'a' );
try {
- str01.at(csz01);
+ (void) str01.at(csz01);
VERIFY( false ); // Should not get here, as exception thrown.
}
catch(std::out_of_range& fail) {
@@ -68,7 +68,7 @@ void test01(void)
ref ref3 = str02.at(csz02 - 1);
VERIFY( ref3 == 'a' );
try {
- str02.at(csz02);
+ (void) str02.at(csz02);
VERIFY( false ); // Should not get here, as exception thrown.
}
catch(std::out_of_range& fail) {
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/21674.cc b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/21674.cc
index a5a129b..3ff8d51 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/21674.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/21674.cc
@@ -27,5 +27,5 @@ int main()
{
typedef std::string string_type;
string_type s;
- s[1]; // abort
+ (void) s[1]; // abort
}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/1.cc
index 9bb5dcb..f9a07ab 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/1.cc
@@ -53,7 +53,7 @@ void test01(void)
cref cref3 = str01.at(csz01 - 1);
VERIFY( cref3 == L'a' );
try {
- str01.at(csz01);
+ (void) str01.at(csz01);
VERIFY( false ); // Should not get here, as exception thrown.
}
catch(std::out_of_range& fail) {
@@ -68,7 +68,7 @@ void test01(void)
ref ref3 = str02.at(csz02 - 1);
VERIFY( ref3 == L'a' );
try {
- str02.at(csz02);
+ (void) str02.at(csz02);
VERIFY( false ); // Should not get here, as exception thrown.
}
catch(std::out_of_range& fail) {
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/21674.cc b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/21674.cc
index 974e6b2..fc023a8 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/21674.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/21674.cc
@@ -27,5 +27,5 @@ int main()
{
typedef std::wstring string_type;
string_type s;
- s[1]; // abort
+ (void) s[1]; // abort
}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/lwg2758.cc b/libstdc++-v3/testsuite/21_strings/basic_string/lwg2758.cc
index 45d514b..a9dcd9a 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/lwg2758.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/lwg2758.cc
@@ -40,6 +40,6 @@ int main()
x.replace(0, 3, "foo", 0, 3);
x.replace(0, 3, cs, 0, 3);
x = "bar";
- x.compare(0, 3, "foo", 0, 3);
- x.compare(0, 3, cs, 0, 3);
+ (void) x.compare(0, 3, "foo", 0, 3);
+ (void) x.compare(0, 3, cs, 0, 3);
}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/lwg2946.cc b/libstdc++-v3/testsuite/21_strings/basic_string/lwg2946.cc
index 3cbaf17..6e308ba 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/lwg2946.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/lwg2946.cc
@@ -29,12 +29,12 @@ int main()
s.insert(0, {"abc", 1});
s.replace(0, 1, {"abc", 1});
s.replace(s.begin(), s.begin(), {"abc", 1});
- s.find({"abc", 1});
- s.rfind({"abc", 1});
- s.find_first_of({"abc", 1});
- s.find_last_of({"abc", 1});
- s.find_first_not_of({"abc", 1});
- s.find_last_not_of({"abc", 1});
- s.compare({"abc", 1});
- s.compare(0, 1, {"abc", 1});
+ (void) s.find({"abc", 1});
+ (void) s.rfind({"abc", 1});
+ (void) s.find_first_of({"abc", 1});
+ (void) s.find_last_of({"abc", 1});
+ (void) s.find_first_not_of({"abc", 1});
+ (void) s.find_last_not_of({"abc", 1});
+ (void) s.compare({"abc", 1});
+ (void) s.compare(0, 1, {"abc", 1});
}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/nonnull.cc
new file mode 100644
index 0000000..41bb391
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/nonnull.cc
@@ -0,0 +1,12 @@
+// { dg-options "-std=gnu++23 -Wnonnull -O0 -Wno-unused-result" }
+// { dg-do compile { target c++23 } }
+
+#include <string>
+
+void
+test01(const std::string& s)
+{
+ s.contains((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.contains((char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.contains(nullptr); // { dg-warning "\\\[-Wnonnull" }
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/char.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/char.cc
index cfe18e0..3cf8512 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/char.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/char.cc
@@ -20,7 +20,7 @@
// basic_string ends_with
-#include <string>
+#include <testsuite_string.h>
#include <testsuite_hooks.h>
void
@@ -31,7 +31,7 @@ test01()
const char cstr_suf2[] = ".rgb";
const std::string_view sv_suf2(".rgb");
- const std::string s_test("slugs/slimy.jpg");
+ const __gnu_test::string s_test("slugs/slimy.jpg");
const auto cstr_in_slugs = s_test.ends_with(cstr_suf);
VERIFY( cstr_in_slugs );
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc
new file mode 100644
index 0000000..ba77f01
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc
@@ -0,0 +1,12 @@
+// { dg-options "-std=gnu++20 -Wnonnull -O0 -Wno-unused-result" }
+// { dg-do compile { target c++20 } }
+
+#include <testsuite_string.h>
+
+void
+test01(const __gnu_test::string& s)
+{
+ s.ends_with((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.ends_with((char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.ends_with(nullptr); // { dg-warning "\\\[-Wnonnull" }
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/wchar_t.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/wchar_t.cc
index d27e824..70b522f 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/wchar_t.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/wchar_t.cc
@@ -20,7 +20,7 @@
// basic_string ends_with
-#include <string>
+#include <testsuite_string.h>
#include <testsuite_hooks.h>
void
@@ -31,7 +31,7 @@ test01()
const wchar_t cstr_suf2[] = L".rgb";
const std::wstring_view sv_suf2(L".rgb");
- const std::wstring s_test(L"slugs/slimy.jpg");
+ const __gnu_test::wstring s_test(L"slugs/slimy.jpg");
const auto cstr_in_slugs = s_test.ends_with(cstr_suf);
VERIFY( cstr_in_slugs );
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/char.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/char.cc
index 5c0b3af..dddf51c 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/char.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/char.cc
@@ -20,7 +20,7 @@
// basic_string begins_with
-#include <string>
+#include <testsuite_string.h>
#include <testsuite_hooks.h>
void
@@ -31,7 +31,7 @@ test01()
const char cstr_dir2[] = "worms/";
const std::string_view sv_dir2("worms/");
- const std::string s_test("slugs/slimy.jpg");
+ const __gnu_test::string s_test("slugs/slimy.jpg");
const auto cstr_in_slugs = s_test.starts_with(cstr_dir);
VERIFY( cstr_in_slugs );
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc
new file mode 100644
index 0000000..a023d9e
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc
@@ -0,0 +1,12 @@
+// { dg-options "-std=gnu++20 -Wnonnull -O0 -Wno-unused-result" }
+// { dg-do compile { target c++20 } }
+
+#include <testsuite_string.h>
+
+void
+test01(const __gnu_test::string& s)
+{
+ s.starts_with((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.starts_with((char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.starts_with(nullptr); // { dg-warning "\\\[-Wnonnull" }
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/wchar_t.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/wchar_t.cc
index eda7321..747b23a 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/wchar_t.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/wchar_t.cc
@@ -20,7 +20,7 @@
// basic_string begins_with
-#include <string>
+#include <testsuite_string.h>
#include <testsuite_hooks.h>
void
@@ -31,7 +31,7 @@ test01()
const wchar_t cstr_dir2[] = L"worms/";
const std::wstring_view sv_dir2(L"worms/");
- const std::wstring s_test(L"slugs/slimy.jpg");
+ const __gnu_test::wstring s_test(L"slugs/slimy.jpg");
const auto cstr_in_slugs = s_test.starts_with(cstr_dir);
VERIFY( cstr_in_slugs );
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operators/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operators/char/1.cc
index 704d2f6..be3e41a 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/operators/char/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operators/char/1.cc
@@ -35,12 +35,12 @@ int test01(void)
// 2:8-chars_8-chars_
// The following triggers -Wstringop-overread. See PR 103332.
str1 = std::string("8-chars_") + "8-chars_";
- str1.c_str();
+ (void) str1.c_str();
// printf("1:%s\n", str1.c_str());
VERIFY( str1 == "8-chars_8-chars_" );
str2 = str1 + "7-chars";
// printf("2:%s\n", str1.c_str()); //str1 is gone
- str1.c_str();
+ (void) str1.c_str();
VERIFY( str1 == "8-chars_8-chars_" );
return 0;
}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operators/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operators/wchar_t/1.cc
index 4020950..df3ff7c 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/operators/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operators/wchar_t/1.cc
@@ -32,11 +32,11 @@ int test01(void)
// 1:8-chars_8-chars_
// 2:8-chars_8-chars_
str1 = std::wstring(L"8-chars_") + L"8-chars_";
- str1.c_str();
+ (void) str1.c_str();
// wprintf("1:%s\n", str1.c_str());
str2 = str1 + L"7-chars";
// wprintf("2:%s\n", str1.c_str()); //str1 is gone
- str1.c_str();
+ (void) str1.c_str();
return 0;
}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/capacity/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/capacity/1.cc
index 0376d91..3d162c6 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string_view/capacity/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/capacity/1.cc
@@ -137,7 +137,7 @@ test01()
sz03 = str02.size();
sz04 = str02.length();
VERIFY( sz03 == sz04 );
- str02.data();
+ (void) str02.data();
sz03 = str02.size();
sz04 = str02.length();
VERIFY( sz03 == sz04 );
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/1.cc
index 5de62ec..b27e7d7 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/1.cc
@@ -49,7 +49,7 @@ test01()
VERIFY( cref3 == 'a' );
try
{
- str01.at(csz01);
+ (void) str01.at(csz01);
VERIFY( false ); // Should not get here, as exception thrown.
}
catch (std::out_of_range& fail)
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/2.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/2.cc
index e8f9db2..834d3f6 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/2.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/2.cc
@@ -27,5 +27,5 @@ main()
{
typedef std::string_view string_view_type;
string_view_type s;
- s[0]; // abort
+ (void) s[0]; // abort
}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/1.cc
index 9877cd8..e9df872 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/1.cc
@@ -49,7 +49,7 @@ test01()
VERIFY( cref3 == L'a' );
try
{
- str01.at(csz01);
+ (void) str01.at(csz01);
VERIFY( false ); // Should not get here, as exception thrown.
}
catch (std::out_of_range& fail)
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/2.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/2.cc
index 23daa7a..840de84 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/2.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/2.cc
@@ -29,5 +29,5 @@ main()
{
typedef std::wstring_view string_view_type;
string_view_type s;
- s[0]; // abort
+ (void) s[0]; // abort
}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc
new file mode 100644
index 0000000..fafadcc
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc
@@ -0,0 +1,12 @@
+// { dg-options "-std=gnu++23 -Wnonnull -O0 -Wno-unused-result" }
+// { dg-do compile { target c++23 } }
+
+#include <string_view>
+
+void
+test01(std::string_view s)
+{
+ s.contains((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.contains((char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.contains(nullptr); // { dg-warning "\\\[-Wnonnull" }
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc
new file mode 100644
index 0000000..50437bb
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc
@@ -0,0 +1,12 @@
+// { dg-options "-std=gnu++20 -Wnonnull -O0 -Wno-unused-result" }
+// { dg-do compile { target c++20 } }
+
+#include <string_view>
+
+void
+test01(std::string_view s)
+{
+ s.ends_with((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.ends_with((char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.ends_with(nullptr); // { dg-warning "\\\[-Wnonnull" }
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc
new file mode 100644
index 0000000..fedba28a
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc
@@ -0,0 +1,12 @@
+// { dg-options "-std=gnu++20 -Wnonnull -O0 -Wno-unused-result" }
+// { dg-do compile { target c++20 } }
+
+#include <string_view>
+
+void
+test01(std::string_view s)
+{
+ s.starts_with((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.starts_with((char*)nullptr); // { dg-warning "\\\[-Wnonnull" }
+ s.starts_with(nullptr); // { dg-warning "\\\[-Wnonnull" }
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc
new file mode 100644
index 0000000..520788d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc
@@ -0,0 +1,17 @@
+// { dg-do run { xfail *-*-* } }
+// { dg-options "-D_GLIBCXX_DEBUG_BACKTRACE -lstdc++_libbacktrace" }
+// { dg-require-effective-target stacktrace }
+
+#include <debug/vector>
+#include <debug/checks.h>
+
+void test01()
+{
+ __gnu_test::check_assign1<__gnu_debug::vector<int> >();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_sort/4.cc b/libstdc++-v3/testsuite/25_algorithms/stable_sort/4.cc
new file mode 100644
index 0000000..b7bda4e
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/stable_sort/4.cc
@@ -0,0 +1,51 @@
+// { dg-options "-pedantic" }
+// { dg-do compile }
+
+#include <algorithm>
+
+/* This type is reduced from QTypedArrayData::iterator which has an implicit
+ * conversion to its pointer type and a difference type of int.
+ * The expression Iter() + ptrdiff_t(0) is ambiguous with -pedantic because it
+ * could either convert the RHS to int and use Iter::operator+(int)
+ * or it could convert the LHS to pointer and use built-in pointer arithmetic.
+ */
+struct Iter
+{
+ struct value_type { bool operator<(value_type) const; };
+ typedef value_type* pointer;
+ typedef value_type& reference;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef int difference_type;
+
+ reference operator*() const;
+ pointer operator->() const;
+
+ reference operator[](difference_type) const;
+
+ Iter& operator++();
+ Iter& operator--();
+ Iter operator++(int);
+ Iter operator--(int);
+
+ Iter& operator+=(difference_type);
+ Iter& operator-=(difference_type);
+
+ Iter operator+(difference_type) const;
+ Iter operator-(difference_type) const;
+
+ difference_type operator-(Iter) const;
+
+ operator pointer() const; // XXX this causes the ambiguity
+
+ bool operator==(Iter) const;
+ bool operator!=(Iter) const;
+
+ bool operator<(Iter) const;
+};
+
+Iter operator+(Iter::difference_type, Iter);
+
+int main()
+{
+ std::stable_sort(Iter(), Iter());
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/sputbackc/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/sputbackc/char/1.cc
index 1e8c5fd..2296fd1 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/sputbackc/char/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/sputbackc/char/1.cc
@@ -41,18 +41,18 @@ void test04()
// PUT
strb_03.str(str_01); //reset
- strb_03.str().length();
- strb_03.str().length();
+ (void) strb_03.str().length();
+ (void) strb_03.str().length();
// streamsize sputn(const char_typs* s, streamsize n)
// write up to n chars to out_cur from s, returning number assigned
// NB *sputn will happily put '\0' into your stream if you give it a chance*
str_tmp = strb_03.str();
- str_tmp.length();
+ (void) str_tmp.length();
strb_03.sputn("racadabras", 10);//"abracadabras or what?"
- strb_03.str().length();
+ (void) strb_03.str().length();
strb_03.sputn(", i wanna reach out and", 10);
- strb_03.str().length();
+ (void) strb_03.str().length();
str_tmp = strb_02.str();
strb_02.sputn("racadabra", 10);
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/sputbackc/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/sputbackc/wchar_t/1.cc
index 6acc0f24..c44a535 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/sputbackc/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/sputbackc/wchar_t/1.cc
@@ -41,18 +41,18 @@ void test04()
// PUT
strb_03.str(str_01); //reset
- strb_03.str().length();
- strb_03.str().length();
+ (void) strb_03.str().length();
+ (void) strb_03.str().length();
// streamsize sputn(const char_typs* s, streamsize n)
// write up to n chars to out_cur from s, returning number assigned
// NB *sputn will happily put '\0' into your stream if you give it a chance*
str_tmp = strb_03.str();
- str_tmp.length();
+ (void) str_tmp.length();
strb_03.sputn(L"racadabras", 10);//"abracadabras or what?"
- strb_03.str().length();
+ (void) strb_03.str().length();
strb_03.sputn(L", i wanna reach out and", 10);
- strb_03.str().length();
+ (void) strb_03.str().length();
str_tmp = strb_02.str();
strb_02.sputn(L"racadabra", 10);
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/sungetc/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/sungetc/char/1.cc
index 2a3a28b..b4cdb17 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/sungetc/char/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/sungetc/char/1.cc
@@ -41,18 +41,18 @@ void test04()
// PUT
strb_03.str(str_01); //reset
- strb_03.str().length();
- strb_03.str().length();
+ (void) strb_03.str().length();
+ (void) strb_03.str().length();
// streamsize sputn(const char_typs* s, streamsize n)
// write up to n chars to out_cur from s, returning number assigned
// NB *sputn will happily put '\0' into your stream if you give it a chance*
str_tmp = strb_03.str();
- str_tmp.length();
+ (void) str_tmp.length();
strb_03.sputn("racadabras", 10);//"abracadabras or what?"
- strb_03.str().length();
+ (void) strb_03.str().length();
strb_03.sputn(", i wanna reach out and", 10);
- strb_03.str().length();
+ (void) strb_03.str().length();
str_tmp = strb_02.str();
strb_02.sputn("racadabra", 10);
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/sungetc/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/sungetc/wchar_t/1.cc
index 5f20e2c..eb0ae5e 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/sungetc/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/sungetc/wchar_t/1.cc
@@ -41,18 +41,18 @@ void test04()
// PUT
strb_03.str(str_01); //reset
- strb_03.str().length();
- strb_03.str().length();
+ (void) strb_03.str().length();
+ (void) strb_03.str().length();
// streamsize sputn(const char_typs* s, streamsize n)
// write up to n chars to out_cur from s, returning number assigned
// NB *sputn will happily put '\0' into your stream if you give it a chance*
str_tmp = strb_03.str();
- str_tmp.length();
+ (void) str_tmp.length();
strb_03.sputn(L"racadabras", 10);//"abracadabras or what?"
- strb_03.str().length();
+ (void) strb_03.str().length();
strb_03.sputn(L", i wanna reach out and", 10);
- strb_03.str().length();
+ (void) strb_03.str().length();
str_tmp = strb_02.str();
strb_02.sputn(L"racadabra", 10);
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc
new file mode 100644
index 0000000..9829f79
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc
@@ -0,0 +1,110 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do run { target c++23 } }
+
+#include <ranges>
+#include <algorithm>
+#include <utility>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+
+namespace ranges = std::ranges;
+namespace views = std::views;
+
+constexpr bool
+test01()
+{
+ static_assert(ranges::empty(std::array{1, 2, 3} | views::adjacent<0>));
+
+ auto v1 = std::array{1, 2} | views::adjacent<1>;
+ const auto i0 = v1.begin(), i1 = v1.begin() + 1;
+ VERIFY( i0 + 1 - 1 == i0 );
+ VERIFY( i0 < i1 );
+ VERIFY( i1 < v1.end() );
+ VERIFY( i1 - i0 == 1 );
+ VERIFY( i0 - i1 == -1 );
+ VERIFY( v1.end() - i1 == 1 );
+ VERIFY( i1 - v1.end() == -1 );
+ ranges::iter_swap(i0, i1);
+ VERIFY( ranges::equal(std::move(v1) | views::keys, (int[]){2, 1}) );
+
+ int x[] = {1, 2, 3, 4};
+ auto v2 = x | views::pairwise;
+ auto i2 = v2.begin();
+ i2 += 2;
+ i2 -= -1;
+ VERIFY( i2 == v2.end() );
+ VERIFY( ranges::size(v2) == 3 );
+ VERIFY( ranges::size(std::as_const(v2)) == 3 );
+ VERIFY( ranges::equal(v2 | views::keys, (int[]){1, 2, 3}) );
+ VERIFY( ranges::equal(v2 | views::values, (int[]){2, 3, 4}) );
+
+ int y[] = {1, 2, 3, 4, 5};
+ const auto v3 = y | views::adjacent<3>;
+ VERIFY( ranges::size(v3) == 3 );
+ for (unsigned i = 0; i < ranges::size(x); i++)
+ {
+ VERIFY( &std::get<0>(v3[i]) == &y[i] + 0 );
+ VERIFY( &std::get<1>(v3[i]) == &y[i] + 1 );
+ VERIFY( &std::get<2>(v3[i]) == &y[i] + 2 );
+ }
+
+ const auto v5 = y | views::adjacent<5>;
+ VERIFY( ranges::equal(v5, views::single(std::make_tuple(1, 2, 3, 4, 5))) );
+
+ const auto v6 = y | views::adjacent<6>;
+ VERIFY( ranges::empty(v6) );
+
+ const auto v0 = y | views::adjacent<0>;
+ VERIFY( ranges::empty(v0) );
+
+ return true;
+}
+
+constexpr bool
+test02()
+{
+ using __gnu_test::test_input_range;
+ using __gnu_test::test_forward_range;
+ using __gnu_test::test_random_access_range;
+
+ using ty1 = ranges::adjacent_view<views::all_t<test_forward_range<int>>, 2>;
+ static_assert(ranges::forward_range<ty1>);
+ static_assert(!ranges::bidirectional_range<ty1>);
+ static_assert(!ranges::sized_range<ty1>);
+
+ using ty2 = ranges::adjacent_view<views::all_t<test_random_access_range<int>>, 3>;
+ static_assert(ranges::random_access_range<ty2>);
+ static_assert(ranges::sized_range<ty2>);
+
+ return true;
+}
+
+constexpr bool
+test03()
+{
+ auto v = views::iota(0, 4) | views::filter([](auto) { return true; }) | views::pairwise;
+ using ty = decltype(v);
+ static_assert(ranges::forward_range<ty>);
+ static_assert(ranges::common_range<ty>);
+ static_assert(!ranges::sized_range<ty>);
+ VERIFY( v.begin() == v.begin() );
+ VERIFY( v.begin() != v.end() );
+ VERIFY( ranges::next(v.begin(), 3) == v.end() );
+ auto it = v.begin();
+ ++it;
+ it++;
+ VERIFY( ranges::next(it) == v.end() );
+ it--;
+ --it;
+ VERIFY( it == v.begin() );
+
+ return true;
+}
+
+int
+main()
+{
+ static_assert(test01());
+ static_assert(test02());
+ static_assert(test03());
+}
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent_transform/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent_transform/1.cc
new file mode 100644
index 0000000..07f20b7
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent_transform/1.cc
@@ -0,0 +1,106 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do run { target c++23 } }
+
+#include <ranges>
+#include <algorithm>
+#include <utility>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+
+namespace ranges = std::ranges;
+namespace views = std::views;
+
+constexpr bool
+test01()
+{
+ auto v1 = std::array{1, 2, 3} | views::adjacent_transform<1>(std::identity{});
+ VERIFY( ranges::equal(v1, (int[]){1, 2, 3}) );
+ const auto i0 = v1.begin(), i1 = v1.begin() + 1;
+ VERIFY( i0 + 1 - 1 == i0 );
+ VERIFY( i0 < i1 );
+ VERIFY( i1 < v1.end() );
+ VERIFY( i1 - i0 == 1 );
+ VERIFY( i0 - i1 == -1 );
+ VERIFY( v1.end() - i1 == 2 );
+ VERIFY( i1 - v1.end() == -2 );
+ ranges::iter_swap(i0, i1);
+ VERIFY( ranges::equal(std::move(v1), (int[]){2, 1, 3}) );
+
+ auto v2 = std::array{1, -1, 2, -2} | views::pairwise_transform(std::multiplies{});
+ auto i2 = v2.begin();
+ i2 += 1;
+ i2 -= -2;
+ VERIFY( i2 == v2.end() );
+ VERIFY( ranges::size(v2) == 3 );
+ VERIFY( ranges::size(std::as_const(v2)) == 3 );
+ VERIFY( ranges::equal(v2, (int[]){-1, -2, -4}) );
+
+ int y[] = {1, 2, 3, 4, 5, 6};
+ auto v3 = y | views::adjacent_transform<3>([](auto... xs) { return ranges::max({xs...}); });
+ VERIFY( ranges::size(v3) == 4 );
+ VERIFY( ranges::equal(v3, (int[]){3, 4, 5, 6}) );
+
+ const auto v6 = y | views::adjacent_transform<6>([](auto...) { return 0; });
+ VERIFY( ranges::equal(v6, (int[]){0}) );
+
+ const auto v7 = y | views::adjacent_transform<7>([](auto...) { return 0; });
+ VERIFY( ranges::empty(v7) );
+
+ const auto v0 = y | views::adjacent_transform<0>([] { return 0; });
+ VERIFY( ranges::empty(v0) );
+
+ return true;
+}
+
+constexpr bool
+test02()
+{
+ using __gnu_test::test_input_range;
+ using __gnu_test::test_forward_range;
+ using __gnu_test::test_random_access_range;
+
+ using ty1 = ranges::adjacent_transform_view<views::all_t<test_forward_range<int>>,
+ std::plus<>, 2>;
+ static_assert(ranges::forward_range<ty1>);
+ static_assert(!ranges::bidirectional_range<ty1>);
+ static_assert(!ranges::sized_range<ty1>);
+
+ using ty2 = ranges::adjacent_transform_view<views::all_t<test_random_access_range<int>>,
+ decltype([](int, int, int) { return 0;}), 3>;
+ static_assert(ranges::random_access_range<ty2>);
+ static_assert(ranges::sized_range<ty2>);
+
+ return true;
+}
+
+constexpr bool
+test03()
+{
+ auto v = views::iota(0, 4)
+ | views::filter([](auto) { return true; })
+ | views::pairwise_transform(std::plus{});
+ using ty = decltype(v);
+ static_assert(ranges::forward_range<ty>);
+ static_assert(ranges::common_range<ty>);
+ static_assert(!ranges::sized_range<ty>);
+ VERIFY( v.begin() == v.begin() );
+ VERIFY( v.begin() != v.end() );
+ VERIFY( ranges::next(v.begin(), 3) == v.end() );
+ auto it = v.begin();
+ ++it;
+ it++;
+ VERIFY( ranges::next(it) == v.end() );
+ it--;
+ --it;
+ VERIFY( it == v.begin() );
+
+ return true;
+}
+
+int
+main()
+{
+ static_assert(test01());
+ static_assert(test02());
+ static_assert(test03());
+}
diff --git a/libstdc++-v3/testsuite/std/ranges/zip/1.cc b/libstdc++-v3/testsuite/std/ranges/zip/1.cc
new file mode 100644
index 0000000..0113efd
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/zip/1.cc
@@ -0,0 +1,111 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do run { target c++23 } }
+
+#include <ranges>
+#include <algorithm>
+#include <utility>
+#include <vector>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+
+namespace ranges = std::ranges;
+namespace views = std::views;
+
+constexpr bool
+test01()
+{
+ static_assert(ranges::empty(views::zip()));
+ static_assert(ranges::empty(views::empty<int>));
+
+ auto z1 = views::zip(std::array{1, 2});
+ const auto i0 = z1.begin(), i1 = z1.begin() + 1;
+ VERIFY( i0 + 1 - 1 == i0 );
+ VERIFY( i0 < i1 );
+ VERIFY( i1 < z1.end() );
+ VERIFY( i1 - i0 == 1 );
+ VERIFY( i0 - i1 == -1 );
+ VERIFY( z1.end() - i1 == 1 );
+ VERIFY( i1 - z1.end() == -1 );
+ ranges::iter_swap(i0, i1);
+ VERIFY( ranges::equal(std::move(z1) | views::keys, (int[]){2, 1}) );
+
+ auto z2 = views::zip(std::array{1, 2}, std::array{3, 4, 5});
+ auto i2 = z2.begin();
+ i2 += 1;
+ i2 -= -1;
+ VERIFY( i2 == z2.end() );
+ VERIFY( ranges::size(z2) == 2 );
+ VERIFY( ranges::size(std::as_const(z2)) == 2 );
+ VERIFY( z2[0].first == 1 && z2[0].second == 3 );
+ VERIFY( z2[1].first == 2 && z2[1].second == 4 );
+ for (const auto [x, y] : z2)
+ {
+ VERIFY( y - x == 2 );
+ std::swap(x, y);
+ }
+
+ int x[2] = {1, 2}, y[2] = {3, 4}, z[2] = {5, 6};
+ const auto z3 = views::zip(x, y, z);
+ VERIFY( ranges::size(z3) == 2 );
+ for (int i = 0; i < ranges::size(x); i++)
+ {
+ VERIFY( &std::get<0>(z3[i]) == &x[i] );
+ VERIFY( &std::get<1>(z3[i]) == &y[i] );
+ VERIFY( &std::get<2>(z3[i]) == &z[i] );
+ }
+
+ return true;
+}
+
+constexpr bool
+test02()
+{
+ using __gnu_test::test_input_range;
+ using __gnu_test::test_forward_range;
+ using __gnu_test::test_random_access_range;
+
+ using ty1 = ranges::zip_view<views::all_t<test_forward_range<int>>,
+ views::all_t<test_random_access_range<int>>>;
+ static_assert(ranges::forward_range<ty1>);
+ static_assert(!ranges::random_access_range<ty1>);
+ static_assert(!ranges::sized_range<ty1>);
+
+ using ty2 = ranges::zip_view<views::all_t<test_forward_range<int>>,
+ views::all_t<test_input_range<int>>,
+ views::all_t<test_forward_range<int>>>;
+ static_assert(ranges::input_range<ty2>);
+ static_assert(!ranges::forward_range<ty2>);
+ static_assert(!ranges::sized_range<ty2>);
+
+ return true;
+}
+
+constexpr bool
+test03()
+{
+ int u[] = {1, 2, 3, 4}, v[] = {4, 5, 6}, w[] = {7, 8, 9, 10};
+ auto z = views::zip(u | views::filter([](auto) { return true; }), v, w);
+ using ty = decltype(z);
+ static_assert(ranges::forward_range<ty>);
+ static_assert(!ranges::common_range<ty>);
+ static_assert(!ranges::sized_range<ty>);
+ VERIFY( z.begin() == z.begin() );
+ VERIFY( z.begin() != z.end() );
+ VERIFY( ranges::next(z.begin(), 3) == z.end() );
+ auto it = z.begin();
+ ++it;
+ it++;
+ it--;
+ --it;
+ VERIFY( it == z.begin() );
+
+ return true;
+}
+
+int
+main()
+{
+ static_assert(test01());
+ static_assert(test02());
+ static_assert(test03());
+}
diff --git a/libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc b/libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc
new file mode 100644
index 0000000..5ea24c57
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc
@@ -0,0 +1,108 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do run { target c++23 } }
+
+#include <ranges>
+#include <algorithm>
+#include <utility>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+
+namespace ranges = std::ranges;
+namespace views = std::views;
+
+constexpr bool
+test01()
+{
+ static_assert(ranges::empty(views::zip_transform([] { return 0; })));
+
+ auto z1 = views::zip_transform(std::identity{},
+ std::array{1, 2, 3});
+ VERIFY( ranges::equal(z1, (int[]){1, 2, 3}) );
+ const auto i0 = z1.begin(), i1 = z1.begin() + 1;
+ VERIFY( i0 + 1 - 1 == i0 );
+ VERIFY( i0 < i1 );
+ VERIFY( i1 < z1.end() );
+ VERIFY( i1 - i0 == 1 );
+ VERIFY( i0 - i1 == -1 );
+ VERIFY( z1.end() - i1 == 2 );
+ VERIFY( i1 - z1.end() == -2 );
+ ranges::iter_swap(i0, i1);
+ VERIFY( ranges::equal(std::move(z1), (int[]){2, 1, 3}) );
+
+ auto z2 = views::zip_transform(std::multiplies{},
+ std::array{-1, 2},
+ std::array{3, 4, 5});
+ auto i2 = z2.begin();
+ i2 += 1;
+ i2 -= -1;
+ VERIFY( i2 == z2.end() );
+ VERIFY( ranges::size(z2) == 2 );
+ VERIFY( ranges::size(std::as_const(z2)) == 2 );
+ VERIFY( ranges::equal(z2, (int[]){-3, 8}) );
+
+ auto z3 = views::zip_transform([] (auto... xs) { return ranges::max({xs...}); },
+ std::array{1, 6, 7, 0, 0},
+ std::array{2, 5, 9},
+ std::array{3, 4, 8, 0});
+ VERIFY( ranges::size(z3) == 3 );
+ VERIFY( ranges::equal(z3, (int[]){3, 6, 9}) );
+
+ return true;
+}
+
+constexpr bool
+test02()
+{
+ using __gnu_test::test_input_range;
+ using __gnu_test::test_forward_range;
+ using __gnu_test::test_random_access_range;
+
+ using ty1 = ranges::zip_transform_view<std::plus<>,
+ views::all_t<test_forward_range<int>>,
+ views::all_t<test_random_access_range<int>>>;
+ static_assert(ranges::forward_range<ty1>);
+ static_assert(!ranges::random_access_range<ty1>);
+ static_assert(!ranges::sized_range<ty1>);
+
+ using ty2 = ranges::zip_transform_view<decltype([](int, int, int) { return 0; }),
+ views::all_t<test_forward_range<int>>,
+ views::all_t<test_input_range<int>>,
+ views::all_t<test_forward_range<int>>>;
+ static_assert(ranges::input_range<ty2>);
+ static_assert(!ranges::forward_range<ty2>);
+ static_assert(!ranges::sized_range<ty2>);
+
+ return true;
+}
+
+constexpr bool
+test03()
+{
+ int u[] = {1, 2, 3, 4}, v[] = {4, 5, 6};
+ auto z = views::zip_transform(std::plus{},
+ u | views::filter([](auto) { return true; }),
+ v);
+ using ty = decltype(z);
+ static_assert(ranges::forward_range<ty>);
+ static_assert(!ranges::common_range<ty>);
+ static_assert(!ranges::sized_range<ty>);
+ VERIFY( z.begin() == z.begin() );
+ VERIFY( z.begin() != z.end() );
+ VERIFY( ranges::next(z.begin(), 3) == z.end() );
+ auto it = z.begin();
+ ++it;
+ it++;
+ it--;
+ --it;
+ VERIFY( it == z.begin() );
+
+ return true;
+}
+
+int
+main()
+{
+ static_assert(test01());
+ static_assert(test02());
+ static_assert(test03());
+}