From 723ef5a937dbab5e7a35761fd7f0ff0c76849340 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 12 Sep 2022 11:31:11 +0200 Subject: libstdc++: Outline the overlapping case of string _M_replace into a separate function [PR105329] The following patch is partially a workaround for bogus warnings when the compiler isn't able to fold _M_disjunct call into constant false, but also an optimization attempt - assuming _M_disjunct (__s) is rare, the patch should shrink code size for the common case and use library or for non-standard instantiations an out of line function to handle the rare case. 2022-09-12 Jakub Jelinek PR tree-optimization/105329 * acinclude.m4 (libtool_VERSION): Change to 6:31:0. * config/abi/pre/gnu.ver (GLIBCXX_3.4.21): Don't export std::basic_string methods with name length of 15. (GLIBCXX_3.4.31): Export std::basic_string::_M_replace_cold. * testsuite/util/testsuite_abi.cc (check_version): Handle GLIBCXX_3.4.31. * include/bits/basic_string.h (std::basic_string::_M_replace_cold): Declare. * include/bits/basic_string.tcc (std::basic_string::_M_replace_cold): Define and export even for C++20. (std::basic_string::_M_replace): Use __builtin_expect, outline the overlapping case to _M_replace_cold. * configure: Regenerated. --- libstdc++-v3/acinclude.m4 | 2 +- libstdc++-v3/config/abi/pre/gnu.ver | 6 ++- libstdc++-v3/configure | 2 +- libstdc++-v3/include/bits/basic_string.h | 4 ++ libstdc++-v3/include/bits/basic_string.tcc | 70 +++++++++++++++++----------- libstdc++-v3/testsuite/util/testsuite_abi.cc | 3 +- 6 files changed, 56 insertions(+), 31 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index e3cc3a8..9aa81e1 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -3821,7 +3821,7 @@ changequote([,])dnl fi # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=6:30:0 +libtool_VERSION=6:31:0 # Everything parsed; figure out what files and settings to use. case $enable_symvers in diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 9b80a31..7f30377 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -1736,7 +1736,7 @@ GLIBCXX_3.4.21 { _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE12_M*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE13*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE14_M_replace_aux*; - _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE1[568-9]*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE1[68-9]*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE2at*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE3end*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE4back*; @@ -2444,6 +2444,10 @@ GLIBCXX_3.4.30 { } GLIBCXX_3.4.29; +GLIBCXX_3.4.31 { + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE15_M_replace_cold*; +} GLIBCXX_3.4.30; + # Symbols in the support library (libsupc++) have their own tag. CXXABI_1.3 { diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 1772eef..07916d1 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -69034,7 +69034,7 @@ $as_echo "$as_me: WARNING: === Symbol versioning will be disabled." >&2;} fi # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=6:30:0 +libtool_VERSION=6:31:0 # Everything parsed; figure out what files and settings to use. case $enable_symvers in diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 0df64ea..cd24419 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -2504,6 +2504,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, _CharT __c); + __attribute__((__noinline__, __noclone__, __cold__)) void + _M_replace_cold(pointer __p, size_type __len1, const _CharT* __s, + const size_type __len2, const size_type __how_much); + _GLIBCXX20_CONSTEXPR basic_string& _M_replace(size_type __pos, size_type __len1, const _CharT* __s, diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 4563c61..710c2df 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -471,6 +471,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + __attribute__((__noinline__, __noclone__, __cold__)) void + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_cold(pointer __p, size_type __len1, const _CharT* __s, + const size_type __len2, const size_type __how_much) + { + // Work in-place. + if (__len2 && __len2 <= __len1) + this->_S_move(__p, __s, __len2); + if (__how_much && __len1 != __len2) + this->_S_move(__p + __len2, __p + __len1, __how_much); + if (__len2 > __len1) + { + if (__s + __len2 <= __p + __len1) + this->_S_move(__p, __s, __len2); + else if (__s >= __p + __len1) + { + // Hint to middle end that __p and __s overlap + // (PR 98465). + const size_type __poff = (__s - __p) + (__len2 - __len1); + this->_S_copy(__p, __p + __poff, __len2); + } + else + { + const size_type __nleft = (__p + __len1) - __s; + this->_S_move(__p, __s, __nleft); + this->_S_copy(__p + __nleft, __p + __len2, __len2 - __nleft); + } + } + } + + template _GLIBCXX20_CONSTEXPR basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: @@ -500,7 +531,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } else #endif - if (_M_disjunct(__s)) + if (__builtin_expect(_M_disjunct(__s), true)) { if (__how_much && __len1 != __len2) this->_S_move(__p + __len2, __p + __len1, __how_much); @@ -508,32 +539,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION this->_S_copy(__p, __s, __len2); } else - { - // Work in-place. - if (__len2 && __len2 <= __len1) - this->_S_move(__p, __s, __len2); - if (__how_much && __len1 != __len2) - this->_S_move(__p + __len2, __p + __len1, __how_much); - if (__len2 > __len1) - { - if (__s + __len2 <= __p + __len1) - this->_S_move(__p, __s, __len2); - else if (__s >= __p + __len1) - { - // Hint to middle end that __p and __s overlap - // (PR 98465). - const size_type __poff = (__s - __p) + (__len2 - __len1); - this->_S_copy(__p, __p + __poff, __len2); - } - else - { - const size_type __nleft = (__p + __len1) - __s; - this->_S_move(__p, __s, __nleft); - this->_S_copy(__p + __nleft, __p + __len2, - __len2 - __nleft); - } - } - } + _M_replace_cold(__p, __len1, __s, __len2, __how_much); } else this->_M_mutate(__pos, __len1, __s, __len2); @@ -1000,6 +1006,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // to ensure the definition in libstdc++.so is unique (PR 86138). extern template basic_string::size_type basic_string::_Rep::_S_empty_rep_storage[]; +# elif _GLIBCXX_EXTERN_TEMPLATE > 0 + // Export _M_replace_cold even for C++20. + extern template void + basic_string::_M_replace_cold(char *, size_type, const char*, + const size_type, const size_type); # endif extern template @@ -1021,6 +1032,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION # elif ! _GLIBCXX_USE_CXX11_ABI extern template basic_string::size_type basic_string::_Rep::_S_empty_rep_storage[]; +# elif _GLIBCXX_EXTERN_TEMPLATE > 0 + // Export _M_replace_cold even for C++20. + extern template void + basic_string::_M_replace_cold(wchar_t*, size_type, const wchar_t*, + const size_type, const size_type); # endif extern template diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc index 5c83835..09bd00e 100644 --- a/libstdc++-v3/testsuite/util/testsuite_abi.cc +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -211,6 +211,7 @@ check_version(symbol& test, bool added) known_versions.push_back("GLIBCXX_3.4.28"); known_versions.push_back("GLIBCXX_3.4.29"); known_versions.push_back("GLIBCXX_3.4.30"); + known_versions.push_back("GLIBCXX_3.4.31"); known_versions.push_back("GLIBCXX_LDBL_3.4.29"); known_versions.push_back("GLIBCXX_IEEE128_3.4.29"); known_versions.push_back("GLIBCXX_IEEE128_3.4.30"); @@ -247,7 +248,7 @@ check_version(symbol& test, bool added) test.version_status = symbol::incompatible; // Check that added symbols are added in the latest pre-release version. - bool latestp = (test.version_name == "GLIBCXX_3.4.30" + bool latestp = (test.version_name == "GLIBCXX_3.4.31" // XXX remove next line when baselines have been regenerated. || test.version_name == "GLIBCXX_IEEE128_3.4.30" || test.version_name == "CXXABI_1.3.13" -- cgit v1.1 From c092d894265f3db590585804c30c1ae3cb7b3773 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 12 Sep 2022 12:02:29 +0100 Subject: libstdc++: Fix comments in tests to match code libstdc++-v3/ChangeLog: * testsuite/19_diagnostics/error_code/cons/lwg3629.cc: Fix comments. * testsuite/19_diagnostics/error_condition/cons/lwg3629.cc: Likewise. --- libstdc++-v3/testsuite/19_diagnostics/error_code/cons/lwg3629.cc | 4 ++-- libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/lwg3629.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/lwg3629.cc b/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/lwg3629.cc index b1e0b7f..70fa5e8 100644 --- a/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/lwg3629.cc +++ b/libstdc++-v3/testsuite/19_diagnostics/error_code/cons/lwg3629.cc @@ -39,10 +39,10 @@ template<> struct std::is_error_code_enum : std::true_type { }; // ::make_error_code(E1) should not be found by name lookup. std::error_code e1( user::E1{} ); // { dg-error "here" } -// std::make_error_code(errc) should not be found by name lookup. +// std::make_error_code(future_errc) should not be found by name lookup. std::error_code e2( user::E2{} ); // { dg-error "here" } -// std::make_error_code(future_errc) should not be found by name lookup. +// std::make_error_code(errc) should not be found by name lookup. std::error_code e3( user::E3{} ); // { dg-error "here" } // { dg-error "use of deleted function" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/lwg3629.cc b/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/lwg3629.cc index e34b53d..562a99a 100644 --- a/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/lwg3629.cc +++ b/libstdc++-v3/testsuite/19_diagnostics/error_condition/cons/lwg3629.cc @@ -39,10 +39,10 @@ template<> struct std::is_error_condition_enum : std::true_type { }; // ::make_error_condition(E1) should not be found by name lookup. std::error_condition e1( user::E1{} ); // { dg-error "here" } -// std::make_error_condition(errc) should not be found by name lookup. +// std::make_error_condition(future_errc) should not be found by name lookup. std::error_condition e2( user::E2{} ); // { dg-error "here" } -// std::make_error_condition(future_errc) should not be found by name lookup. +// std::make_error_condition(errc) should not be found by name lookup. std::error_condition e3( user::E3{} ); // { dg-error "here" } // { dg-error "use of deleted function" "" { target *-*-* } 0 } -- cgit v1.1 From db19cfdac8ede93172aecc58612171c239c993ad Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Mon, 12 Sep 2022 15:05:04 -0400 Subject: libstdc++: Add already-accepted testcase [PR106320] Although PR106320 affected only the 10 and 11 branches, and the testcase from there is already correctly accepted on trunk and the 12 branch, we still should add the testcase to trunk/12 too for inter-branch consistency. PR libstdc++/106320 libstdc++-v3/ChangeLog: * testsuite/std/ranges/adaptors/join.cc (test13): New test. --- libstdc++-v3/testsuite/std/ranges/adaptors/join.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc index 8986f71..530ab66 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc @@ -205,6 +205,18 @@ test12() }(); } +void +test13() +{ + // PR libstdc++/106320 + auto l = std::views::transform([](auto x) { + return x | std::views::transform([i=0](auto y) { + return y; + }); + }); + std::vector> v{{5, 6, 7}}; + v | l | std::views::join; +} int main() { @@ -220,4 +232,5 @@ main() test10(); test11(); test12(); + test13(); } -- cgit v1.1 From b5f09bd766008fe11aa35ccaa4038f7b09e3492e Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Tue, 13 Sep 2022 00:18:20 +0000 Subject: Daily bump. --- libstdc++-v3/ChangeLog | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2e15013..5ee6860 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,32 @@ +2022-09-12 Patrick Palka + + PR libstdc++/106320 + * testsuite/std/ranges/adaptors/join.cc (test13): New test. + +2022-09-12 Jonathan Wakely + + * testsuite/19_diagnostics/error_code/cons/lwg3629.cc: Fix + comments. + * testsuite/19_diagnostics/error_condition/cons/lwg3629.cc: + Likewise. + +2022-09-12 Jakub Jelinek + + PR tree-optimization/105329 + * acinclude.m4 (libtool_VERSION): Change to 6:31:0. + * config/abi/pre/gnu.ver (GLIBCXX_3.4.21): Don't export + std::basic_string methods with name length of 15. + (GLIBCXX_3.4.31): Export std::basic_string::_M_replace_cold. + * testsuite/util/testsuite_abi.cc (check_version): Handle + GLIBCXX_3.4.31. + * include/bits/basic_string.h (std::basic_string::_M_replace_cold): + Declare. + * include/bits/basic_string.tcc (std::basic_string::_M_replace_cold): + Define and export even for C++20. + (std::basic_string::_M_replace): Use __builtin_expect, outline + the overlapping case to _M_replace_cold. + * configure: Regenerated. + 2022-09-09 Jonathan Wakely * include/bits/atomic_base.h (__atomic_impl::__compare_exchange): -- cgit v1.1 From edf6fe7800369136c1a8ddcaf75a042a3a938c84 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Tue, 13 Sep 2022 10:41:47 -0400 Subject: libstdc++: Avoid -Wparentheses warning with debug iterators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I noticed compiling e.g. std/ranges/adaptors/join.cc with -D_GLIBCXX_DEBUG -Wsystem-headers -Wall gives the warning: gcc/libstdc++-v3/include/debug/safe_iterator.h:477:9: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses] libstdc++-v3/ChangeLog: * include/debug/safe_iterator.h (_GLIBCXX_DEBUG_VERIFY_OPERANDS): Add parentheses to avoid -Wparentheses warning. --- libstdc++-v3/include/debug/safe_iterator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index 33f7a86..117dc93 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -40,7 +40,7 @@ #endif #define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \ - _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular() \ + _GLIBCXX_DEBUG_VERIFY((!_Lhs._M_singular() && !_Rhs._M_singular()) \ || (_Lhs._M_value_initialized() \ && _Rhs._M_value_initialized()), \ _M_message(_BadMsgId) \ -- cgit v1.1 From 7aa80c82ecf3a320faca276b22b4a4286bbebacf Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Tue, 13 Sep 2022 11:18:07 -0400 Subject: libstdc++: Implement LWG 3569 changes to join_view::_Iterator libstdc++-v3/ChangeLog: * include/std/ranges (join_view::_Iterator::_M_satisfy): Adjust resetting _M_inner as per LWG 3569. (join_view::_Iterator::_M_inner): Wrap in std::optional as per LWG 3569. (join_view::_Iterator::_Iterator): Relax constraints as per LWG 3569. (join_view::_Iterator::operator*): Adjust as per LWG 3569. (join_view::_Iterator::operator->): Likewise. (join_view::_Iterator::operator++): Likewise. (join_view::_Iterator::operator--): Likewise. (join_view::_Iterator::iter_move): Likewise. (join_view::_Iterator::iter_swap): Likewise. * testsuite/std/ranges/adaptors/join.cc (test14): New test. --- libstdc++-v3/include/std/ranges | 28 ++++++++++------------ libstdc++-v3/testsuite/std/ranges/adaptors/join.cc | 17 +++++++++++++ 2 files changed, 30 insertions(+), 15 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 20eb4e8..6297ce7 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -2746,7 +2746,7 @@ namespace views::__adaptor } if constexpr (_S_ref_is_glvalue) - _M_inner = _Inner_iter(); + _M_inner.reset(); } static constexpr auto @@ -2769,7 +2769,7 @@ namespace views::__adaptor using _Inner_iter = join_view::_Inner_iter<_Const>; _Outer_iter _M_outer = _Outer_iter(); - _Inner_iter _M_inner = _Inner_iter(); + optional<_Inner_iter> _M_inner; _Parent* _M_parent = nullptr; public: @@ -2780,9 +2780,7 @@ namespace views::__adaptor = common_type_t, range_difference_t>>; - _Iterator() requires (default_initializable<_Outer_iter> - && default_initializable<_Inner_iter>) - = default; + _Iterator() requires default_initializable<_Outer_iter> = default; constexpr _Iterator(_Parent* __parent, _Outer_iter __outer) @@ -2801,7 +2799,7 @@ namespace views::__adaptor constexpr decltype(auto) operator*() const - { return *_M_inner; } + { return **_M_inner; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3500. join_view::iterator::operator->() is bogus @@ -2809,7 +2807,7 @@ namespace views::__adaptor operator->() const requires __detail::__has_arrow<_Inner_iter> && copyable<_Inner_iter> - { return _M_inner; } + { return *_M_inner; } constexpr _Iterator& operator++() @@ -2820,7 +2818,7 @@ namespace views::__adaptor else return *_M_parent->_M_inner; }(); - if (++_M_inner == ranges::end(__inner_range)) + if (++*_M_inner == ranges::end(__inner_range)) { ++_M_outer; _M_satisfy(); @@ -2850,9 +2848,9 @@ namespace views::__adaptor { if (_M_outer == ranges::end(_M_parent->_M_base)) _M_inner = ranges::end(*--_M_outer); - while (_M_inner == ranges::begin(*_M_outer)) - _M_inner = ranges::end(*--_M_outer); - --_M_inner; + while (*_M_inner == ranges::begin(*_M_outer)) + *_M_inner = ranges::end(*--_M_outer); + --*_M_inner; return *this; } @@ -2879,14 +2877,14 @@ namespace views::__adaptor friend constexpr decltype(auto) iter_move(const _Iterator& __i) - noexcept(noexcept(ranges::iter_move(__i._M_inner))) - { return ranges::iter_move(__i._M_inner); } + noexcept(noexcept(ranges::iter_move(*__i._M_inner))) + { return ranges::iter_move(*__i._M_inner); } friend constexpr void iter_swap(const _Iterator& __x, const _Iterator& __y) - noexcept(noexcept(ranges::iter_swap(__x._M_inner, __y._M_inner))) + noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner))) requires indirectly_swappable<_Inner_iter> - { return ranges::iter_swap(__x._M_inner, __y._M_inner); } + { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); } friend _Iterator; template friend struct _Sentinel; diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc index 530ab66..afc11d4 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -217,6 +218,21 @@ test13() std::vector> v{{5, 6, 7}}; v | l | std::views::join; } + +void +test14() +{ + // LWG 3569: join_view fails to support ranges of ranges with + // non-default_initializable iterators + auto ss = std::istringstream{"1 2 3"}; + auto v = views::single(views::istream(ss)); + using inner = ranges::range_reference_t; + static_assert(ranges::input_range + && !ranges::forward_range + && !std::default_initializable>); + VERIFY( ranges::equal(v | views::join, (int[]){1, 2, 3}) ); +} + int main() { @@ -233,4 +249,5 @@ main() test11(); test12(); test13(); + test14(); } -- cgit v1.1 From 5d84a4418aa962a715dc74998fea2a7de9d4042c Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Tue, 13 Sep 2022 11:18:14 -0400 Subject: libstdc++: Implement ranges::chunk_view from P2442R1 This also implements the LWG 3707, 3710 and 3712 changes to chunk_view. libstdc++-v3/ChangeLog: * include/std/ranges (__detail::__div_ceil): Define. (chunk_view): Define. (chunk_view::_OuterIter): Define. (chunk_view::_OuterIter::value_type): Define. (chunk_view::_InnerIter): Define. (chunk_view<_Vp>): Define partial specialization for forward ranges. (enable_borrowed_range): Define. (chunk_view<_Vp>::_Iterator): Define. (views::__detail::__can_chunk_view): Define. (views::_Chunk, views::chunk): Define. * testsuite/std/ranges/adaptors/chunk/1.cc: New test. --- libstdc++-v3/include/std/ranges | 537 +++++++++++++++++++++ .../testsuite/std/ranges/adaptors/chunk/1.cc | 80 +++ 2 files changed, 617 insertions(+) create mode 100644 libstdc++-v3/testsuite/std/ranges/adaptors/chunk/1.cc (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 6297ce7..da23568 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -5776,6 +5776,543 @@ namespace views::__adaptor inline constexpr auto pairwise_transform = adjacent_transform<2>; } + + namespace __detail + { + template + constexpr _Tp __div_ceil(_Tp __num, _Tp __denom) + { + _Tp __r = __num / __denom; + if (__num % __denom) + ++__r; + return __r; + } + } + + template + requires input_range<_Vp> + class chunk_view : public view_interface> + { + _Vp _M_base; + range_difference_t<_Vp> _M_n; + range_difference_t<_Vp> _M_remainder = 0; + __detail::__non_propagating_cache> _M_current; + + class _OuterIter; + class _InnerIter; + + public: + constexpr explicit + chunk_view(_Vp __base, range_difference_t<_Vp> __n) + : _M_base(std::move(__base)), _M_n(__n) + { __glibcxx_assert(__n >= 0); } + + constexpr _Vp + base() const & requires copy_constructible<_Vp> + { return _M_base; } + + constexpr _Vp + base() && + { return std::move(_M_base); } + + constexpr _OuterIter + begin() + { + _M_current = ranges::begin(_M_base); + _M_remainder = _M_n; + return _OuterIter(*this); + } + + constexpr default_sentinel_t + end() const noexcept + { return default_sentinel; } + + constexpr auto + size() requires sized_range<_Vp> + { + return __detail::__to_unsigned_like(__detail::__div_ceil + (ranges::distance(_M_base), _M_n)); + } + + constexpr auto + size() const requires sized_range + { + return __detail::__to_unsigned_like(__detail::__div_ceil + (ranges::distance(_M_base), _M_n)); + } + }; + + template + chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view>; + + template + requires input_range<_Vp> + class chunk_view<_Vp>::_OuterIter + { + chunk_view* _M_parent; + + constexpr explicit + _OuterIter(chunk_view& __parent) noexcept + : _M_parent(std::__addressof(__parent)) + { } + + friend chunk_view; + + public: + using iterator_concept = input_iterator_tag; + using difference_type = range_difference_t<_Vp>; + + struct value_type; + + _OuterIter(_OuterIter&&) = default; + _OuterIter& operator=(_OuterIter&&) = default; + + constexpr value_type + operator*() const + { + __glibcxx_assert(*this != default_sentinel); + return value_type(*_M_parent); + } + + constexpr _OuterIter& + operator++() + { + __glibcxx_assert(*this != default_sentinel); + ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder, + ranges::end(_M_parent->_M_base)); + _M_parent->_M_remainder = _M_parent->_M_n; + return *this; + } + + constexpr void + operator++(int) + { ++*this; } + + friend constexpr bool + operator==(const _OuterIter& __x, default_sentinel_t) + { + return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base) + && __x._M_parent->_M_remainder != 0; + } + + friend constexpr difference_type + operator-(default_sentinel_t, const _OuterIter& __x) + requires sized_sentinel_for, iterator_t<_Vp>> + { + const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current; + + if (__dist < __x._M_parent->_M_remainder) + return __dist == 0 ? 0 : 1; + + return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder, + __x._M_parent->_M_n); + } + + friend constexpr difference_type + operator-(const _OuterIter& __x, default_sentinel_t __y) + requires sized_sentinel_for, iterator_t<_Vp>> + { return -(__y - __x); } + }; + + template + requires input_range<_Vp> + struct chunk_view<_Vp>::_OuterIter::value_type : view_interface + { + private: + chunk_view* _M_parent; + + constexpr explicit + value_type(chunk_view& __parent) noexcept + : _M_parent(std::__addressof(__parent)) + { } + + friend _OuterIter; + + public: + constexpr _InnerIter + begin() const noexcept + { return _InnerIter(*_M_parent); } + + constexpr default_sentinel_t + end() const noexcept + { return default_sentinel; } + + constexpr auto + size() const + requires sized_sentinel_for, iterator_t<_Vp>> + { + return __detail::__to_unsigned_like + (ranges::min(_M_parent->_M_remainder, + ranges::end(_M_parent->_M_base) - *_M_parent->_M_current)); + } + }; + + template + requires input_range<_Vp> + class chunk_view<_Vp>::_InnerIter + { + chunk_view* _M_parent; + + constexpr explicit + _InnerIter(chunk_view& __parent) noexcept + : _M_parent(std::__addressof(__parent)) + { } + + friend _OuterIter::value_type; + + public: + using iterator_concept = input_iterator_tag; + using difference_type = range_difference_t<_Vp>; + using value_type = range_value_t<_Vp>; + + _InnerIter(_InnerIter&&) = default; + _InnerIter& operator=(_InnerIter&&) = default; + + constexpr const iterator_t<_Vp>& + base() const & + { return *_M_parent->_M_current; } + + constexpr range_reference_t<_Vp> + operator*() const + { + __glibcxx_assert(*this != default_sentinel); + return **_M_parent->_M_current; + } + + constexpr _InnerIter& + operator++() + { + __glibcxx_assert(*this != default_sentinel); + ++*_M_parent->_M_current; + if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base)) + _M_parent->_M_remainder = 0; + else + --_M_parent->_M_remainder; + return *this; + } + + constexpr void + operator++(int) + { ++*this; } + + friend constexpr bool + operator==(const _InnerIter& __x, default_sentinel_t) noexcept + { return __x._M_parent->_M_remainder == 0; } + + friend constexpr difference_type + operator-(default_sentinel_t, const _InnerIter& __x) + requires sized_sentinel_for, iterator_t<_Vp>> + { + return ranges::min(__x._M_parent->_M_remainder, + ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current); + } + + friend constexpr difference_type + operator-(const _InnerIter& __x, default_sentinel_t __y) + requires sized_sentinel_for, iterator_t<_Vp>> + { return -(__y - __x); } + }; + + template + requires forward_range<_Vp> + class chunk_view<_Vp> : public view_interface> + { + _Vp _M_base; + range_difference_t<_Vp> _M_n; + template class _Iterator; + + public: + constexpr explicit + chunk_view(_Vp __base, range_difference_t<_Vp> __n) + : _M_base(std::move(__base)), _M_n(__n) + { __glibcxx_assert(__n > 0); } + + constexpr _Vp + base() const & requires copy_constructible<_Vp> + { return _M_base; } + + constexpr _Vp + base() && + { return std::move(_M_base); } + + constexpr auto + begin() requires (!__detail::__simple_view<_Vp>) + { return _Iterator(this, ranges::begin(_M_base)); } + + constexpr auto + begin() const requires forward_range + { return _Iterator(this, ranges::begin(_M_base)); } + + constexpr auto + end() requires (!__detail::__simple_view<_Vp>) + { + if constexpr (common_range<_Vp> && sized_range<_Vp>) + { + auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n; + return _Iterator(this, ranges::end(_M_base), __missing); + } + else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>) + return _Iterator(this, ranges::end(_M_base)); + else + return default_sentinel; + } + + constexpr auto + end() const requires forward_range + { + if constexpr (common_range && sized_range) + { + auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n; + return _Iterator(this, ranges::end(_M_base), __missing); + } + else if constexpr (common_range && !bidirectional_range) + return _Iterator(this, ranges::end(_M_base)); + else + return default_sentinel; + } + + constexpr auto + size() requires sized_range<_Vp> + { + return __detail::__to_unsigned_like(__detail::__div_ceil + (ranges::distance(_M_base), _M_n)); + } + + constexpr auto + size() const requires sized_range + { + return __detail::__to_unsigned_like(__detail::__div_ceil + (ranges::distance(_M_base), _M_n)); + } + }; + + template + inline constexpr bool enable_borrowed_range> + = forward_range<_Vp> && enable_borrowed_range<_Vp>; + + template + requires forward_range<_Vp> + template + class chunk_view<_Vp>::_Iterator + { + using _Parent = __detail::__maybe_const_t<_Const, chunk_view>; + using _Base = __detail::__maybe_const_t<_Const, _Vp>; + + iterator_t<_Base> _M_current = iterator_t<_Base>(); + sentinel_t<_Base> _M_end = sentinel_t<_Base>(); + range_difference_t<_Base> _M_n = 0; + range_difference_t<_Base> _M_missing = 0; + + constexpr + _Iterator(_Parent* __parent, iterator_t<_Base> __current, + range_difference_t<_Base> __missing = 0) + : _M_current(__current), _M_end(ranges::end(__parent->_M_base)), + _M_n(__parent->_M_n), _M_missing(__missing) + { } + + static auto + _S_iter_cat() + { + 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 chunk_view; + + public: + using iterator_category = input_iterator_tag; + using iterator_concept = decltype(_S_iter_cat()); + using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n)); + using difference_type = range_difference_t<_Base>; + + _Iterator() = default; + + constexpr _Iterator(_Iterator __i) + requires _Const + && convertible_to, iterator_t<_Base>> + && convertible_to, sentinel_t<_Base>> + : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)), + _M_n(__i._M_n), _M_missing(__i._M_missing) + { } + + constexpr iterator_t<_Base> + base() const + { return _M_current; } + + constexpr value_type + operator*() const + { + __glibcxx_assert(_M_current != _M_end); + return views::take(subrange(_M_current, _M_end), _M_n); + } + + constexpr _Iterator& + operator++() + { + __glibcxx_assert(_M_current != _M_end); + _M_missing = ranges::advance(_M_current, _M_n, _M_end); + return *this; + } + + constexpr _Iterator + operator++(int) + { + auto __tmp = *this; + ++*this; + return __tmp; + } + + constexpr _Iterator& + operator--() requires bidirectional_range<_Base> + { + ranges::advance(_M_current, _M_missing - _M_n); + _M_missing = 0; + 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> + { + if (__x > 0) + { + __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1)); + _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end); + } + else if (__x < 0) + { + ranges::advance(_M_current, _M_n * __x + _M_missing); + _M_missing = 0; + } + return *this; + } + + constexpr _Iterator& + operator-=(difference_type __x) + requires random_access_range<_Base> + { return *this += -__x; } + + constexpr value_type + operator[](difference_type __n) const + requires random_access_range<_Base> + { return *(*this + __n); } + + friend constexpr bool + operator==(const _Iterator& __x, const _Iterator& __y) + { return __x._M_current == __y._M_current; } + + friend constexpr bool + operator==(const _Iterator& __x, default_sentinel_t) + { return __x._M_current == __x._M_end; } + + friend constexpr bool + operator<(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + { return __x._M_current > __y._M_current; } + + 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> + { return __x._M_current <=> __y._M_current; } + + 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>> + { + return (__x._M_current - __y._M_current + + __x._M_missing - __y._M_missing) / __x._M_n; + } + + friend constexpr difference_type + operator-(default_sentinel_t __y, const _Iterator& __x) + requires sized_sentinel_for, iterator_t<_Base>> + { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); } + + friend constexpr difference_type + operator-(const _Iterator& __x, default_sentinel_t __y) + requires sized_sentinel_for, iterator_t<_Base>> + { return -(__y - __x); } + }; + + namespace views + { + namespace __detail + { + template + concept __can_chunk_view + = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); }; + } + + struct _Chunk : __adaptor::_RangeAdaptor<_Chunk> + { + template> + requires __detail::__can_chunk_view<_Range, _Dp> + constexpr auto + operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const + { return chunk_view(std::forward<_Range>(__r), __n); } + + using __adaptor::_RangeAdaptor<_Chunk>::operator(); + static constexpr int _S_arity = 2; + static constexpr bool _S_has_simple_extra_args = true; + }; + + inline constexpr _Chunk chunk; + } #endif // C++23 } // namespace ranges diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/chunk/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/chunk/1.cc new file mode 100644 index 0000000..125c88e --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/chunk/1.cc @@ -0,0 +1,80 @@ +// { dg-options "-std=gnu++23" } +// { dg-do run { target c++23 } } + +#include +#include +#include +#include +#include + +namespace ranges = std::ranges; +namespace views = std::views; + +constexpr bool +test01() +{ + int x[] = {1, 2, 3, 4, 5}; + + auto v2 = x | views::chunk(2); + const auto i0 = v2.begin(), i1 = v2.begin() + 1; + VERIFY( i0 + 1 - 1 == i0 ); + VERIFY( i0 < i1 ); + VERIFY( i1 < v2.end() ); + VERIFY( i1 - i0 == 1 ); + VERIFY( i0 - i1 == -1 ); + VERIFY( v2.end() - i1 == 2 ); + VERIFY( i1 - v2.end() == -2 ); + auto i2 = v2.begin(); + i2 += 2; + i2 -= -1; + VERIFY( i2 == v2.end() ); + VERIFY( ranges::size(v2) == 3 ); + VERIFY( ranges::equal(v2, (std::initializer_list[]){{1, 2}, {3, 4}, {5}}, + ranges::equal) ); + + auto v1 = x | views::chunk(1); + VERIFY( ranges::size(v1) == ranges::size(x) ); + for (auto [r, n] : views::zip(v1, x)) + { + VERIFY( ranges::size(r) == 1 ); + VERIFY( *r.begin() == n ); + } + + auto v5 = x | views::chunk(5); + VERIFY( ranges::size(v5) == 1 ); + VERIFY( ranges::equal(v5[0], (int[]){1, 2, 3, 4, 5}) ); + + auto v10 = x | views::chunk(10); + VERIFY( ranges::size(v10) == 1 ); + VERIFY( ranges::equal(v10[0], (int[]){1, 2, 3, 4, 5}) ); + + return true; +} + +template +void +test02() +{ + int x[] = {1, 2, 3, 4, 5, 6, 7, 8}; + wrapper rx(x); + auto v = rx | views::chunk(3); + auto i = ranges::begin(v); + VERIFY( ranges::equal(*i, (int[]){1, 2, 3}) ); + ++i; + VERIFY( ranges::equal(*i, (int[]){4, 5, 6}) ); + ++i; + VERIFY( ranges::equal(*i, (int[]){7, 8}) ); + i++; + VERIFY( i == ranges::end(v) ); + + for (int i = 1; i <= 10; ++i) + VERIFY( ranges::equal(wrapper(x) | views::chunk(i) | views::join, x) ); +} + +int +main() +{ + static_assert(test01()); + test02<__gnu_test::test_input_range>(); + test02<__gnu_test::test_forward_range>(); +} -- cgit v1.1 From 7d7e2149cdb6b0c37e01df7745cb551fbed317f6 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Tue, 13 Sep 2022 11:18:16 -0400 Subject: libstdc++: Implement ranges::slide_view from P2442R1 This also implements the LWG 3711 and 3712 changes to slide_view. libstdc++-v3/ChangeLog: * include/std/ranges (__detail::__slide_caches_nothing): Define. (__detail::__slide_caches_last): Define. (__detail::__slide_caches_first): Define. (slide_view): Define. (enable_borrowed_range): Define. (slide_view::_Iterator): Define. (slide_view::_Sentinel): Define. (views::__detail::__can_slide_view): Define. (views::_Slide, views::slide): Define. * testsuite/std/ranges/adaptors/slide/1.cc: New test. --- libstdc++-v3/include/std/ranges | 363 +++++++++++++++++++++ .../testsuite/std/ranges/adaptors/slide/1.cc | 105 ++++++ 2 files changed, 468 insertions(+) create mode 100644 libstdc++-v3/testsuite/std/ranges/adaptors/slide/1.cc (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index da23568..44a4df8 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -6313,6 +6313,369 @@ namespace views::__adaptor inline constexpr _Chunk chunk; } + + namespace __detail + { + template + concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>; + + template + concept __slide_caches_last + = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>; + + template + concept __slide_caches_first + = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>; + } + + template + requires view<_Vp> + class slide_view : public view_interface> + { + _Vp _M_base; + range_difference_t<_Vp> _M_n; + [[no_unique_address]] + __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>, + __detail::_CachedPosition<_Vp>> _M_cached_begin; + [[no_unique_address]] + __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>, + __detail::_CachedPosition<_Vp>> _M_cached_end; + + template class _Iterator; + class _Sentinel; + + public: + constexpr explicit + slide_view(_Vp __base, range_difference_t<_Vp> __n) + : _M_base(std::move(__base)), _M_n(__n) + { __glibcxx_assert(__n > 0); } + + constexpr auto + begin() requires (!(__detail::__simple_view<_Vp> + && __detail::__slide_caches_nothing)) + { + if constexpr (__detail::__slide_caches_first<_Vp>) + { + iterator_t<_Vp> __it; + if (_M_cached_begin._M_has_value()) + __it = _M_cached_begin._M_get(_M_base); + else + { + __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base)); + _M_cached_begin._M_set(_M_base, __it); + } + return _Iterator(ranges::begin(_M_base), std::move(__it), _M_n); + } + else + return _Iterator(ranges::begin(_M_base), _M_n); + } + + constexpr auto + begin() const requires __detail::__slide_caches_nothing + { return _Iterator(ranges::begin(_M_base), _M_n); } + + constexpr auto + end() requires (!(__detail::__simple_view<_Vp> + && __detail::__slide_caches_nothing)) + { + if constexpr (__detail::__slide_caches_nothing<_Vp>) + return _Iterator(ranges::begin(_M_base) + range_difference_t<_Vp>(size()), + _M_n); + else if constexpr (__detail::__slide_caches_last<_Vp>) + { + iterator_t<_Vp> __it; + if (_M_cached_end._M_has_value()) + __it = _M_cached_end._M_get(_M_base); + else + { + __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base)); + _M_cached_end._M_set(_M_base, __it); + } + return _Iterator(std::move(__it), _M_n); + } + else if constexpr (common_range<_Vp>) + return _Iterator(ranges::end(_M_base), ranges::end(_M_base), _M_n); + else + return _Sentinel(ranges::end(_M_base)); + } + + constexpr auto + end() const requires __detail::__slide_caches_nothing + { return begin() + range_difference_t(size()); } + + constexpr auto + size() requires sized_range<_Vp> + { + auto __sz = ranges::distance(_M_base) - _M_n + 1; + if (__sz < 0) + __sz = 0; + return __detail::__to_unsigned_like(__sz); + } + + constexpr auto + size() const requires sized_range + { + auto __sz = ranges::distance(_M_base) - _M_n + 1; + if (__sz < 0) + __sz = 0; + return __detail::__to_unsigned_like(__sz); + } + }; + + template + slide_view(_Range&&, range_difference_t<_Range>) -> slide_view>; + + template + inline constexpr bool enable_borrowed_range> + = enable_borrowed_range<_Vp>; + + template + requires view<_Vp> + template + class slide_view<_Vp>::_Iterator + { + using _Base = __detail::__maybe_const_t<_Const, _Vp>; + static constexpr bool _S_last_elt_present + = __detail::__slide_caches_first<_Base>; + + iterator_t<_Base> _M_current = iterator_t<_Base>(); + [[no_unique_address]] + __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>> + _M_last_elt = decltype(_M_last_elt)(); + range_difference_t<_Base> _M_n = 0; + + constexpr + _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n) + requires (!_S_last_elt_present) + : _M_current(__current), _M_n(__n) + { } + + constexpr + _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt, + range_difference_t<_Base> __n) + requires _S_last_elt_present + : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n) + { } + + 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 slide_view; + friend slide_view::_Sentinel; + + public: + using iterator_category = input_iterator_tag; + using iterator_concept = decltype(_S_iter_concept()); + using value_type = decltype(views::counted(_M_current, _M_n)); + using difference_type = range_difference_t<_Base>; + + _Iterator() = default; + + constexpr + _Iterator(_Iterator __i) + requires _Const && convertible_to, iterator_t<_Base>> + : _M_current(std::move(__i._M_current)), _M_n(__i._M_n) + { } + + constexpr auto + operator*() const + { return views::counted(_M_current, _M_n); } + + constexpr _Iterator& + operator++() + { + ++_M_current; + if constexpr (_S_last_elt_present) + ++_M_last_elt; + return *this; + } + + constexpr _Iterator + operator++(int) + { + auto __tmp = *this; + ++*this; + return __tmp; + } + + constexpr _Iterator& + operator--() requires bidirectional_range<_Base> + { + --_M_current; + if constexpr (_S_last_elt_present) + --_M_last_elt; + 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_current += __x; + if constexpr (_S_last_elt_present) + _M_last_elt += __x; + return *this; + } + + constexpr _Iterator& + operator-=(difference_type __x) + requires random_access_range<_Base> + { + _M_current -= __x; + if constexpr (_S_last_elt_present) + _M_last_elt -= __x; + return *this; + } + + constexpr auto + operator[](difference_type __n) const + requires random_access_range<_Base> + { return views::counted(_M_current + __n, _M_n); } + + friend constexpr bool + operator==(const _Iterator& __x, const _Iterator& __y) + { + if constexpr (_S_last_elt_present) + return __x._M_last_elt == __y._M_last_elt; + else + return __x._M_current == __y._M_current; + } + + friend constexpr bool + operator<(const _Iterator& __x, const _Iterator& __y) + requires random_access_range<_Base> + { return __x._M_current < __y._M_current; } + + 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> + { return __x._M_current <=> __y._M_current; } + + 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>> + { + if constexpr (_S_last_elt_present) + return __x._M_last_elt - __y._M_last_elt; + else + return __x._M_current - __y._M_current; + } + }; + + template + requires view<_Vp> + class slide_view<_Vp>::_Sentinel + { + sentinel_t<_Vp> _M_end = sentinel_t<_Vp>(); + + constexpr explicit + _Sentinel(sentinel_t<_Vp> __end) + : _M_end(__end) + { } + + friend slide_view; + + public: + _Sentinel() = default; + + friend constexpr bool + operator==(const _Iterator& __x, const _Sentinel& __y) + { return __x._M_last_elt == __y._M_end; } + + friend constexpr range_difference_t<_Vp> + operator-(const _Iterator& __x, const _Sentinel& __y) + requires sized_sentinel_for, iterator_t<_Vp>> + { return __x._M_last_elt - __y._M_end; } + + friend constexpr range_difference_t<_Vp> + operator-(const _Sentinel& __y, const _Iterator& __x) + requires sized_sentinel_for, iterator_t<_Vp>> + { return __y._M_end -__x._M_last_elt; } + }; + + namespace views + { + namespace __detail + { + template + concept __can_slide_view + = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); }; + } + + struct _Slide : __adaptor::_RangeAdaptor<_Slide> + { + template> + requires __detail::__can_slide_view<_Range, _Dp> + constexpr auto + operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const + { return slide_view(std::forward<_Range>(__r), __n); } + + using __adaptor::_RangeAdaptor<_Slide>::operator(); + static constexpr int _S_arity = 2; + static constexpr bool _S_has_simple_extra_args = true; + }; + + inline constexpr _Slide slide; + } #endif // C++23 } // namespace ranges diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/slide/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/slide/1.cc new file mode 100644 index 0000000..9856042 --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/slide/1.cc @@ -0,0 +1,105 @@ +// { dg-options "-std=gnu++23" } +// { dg-do run { target c++23 } } + +#include +#include +#include +#include +#include + +namespace ranges = std::ranges; +namespace views = std::views; + +constexpr bool +test01() +{ + auto v1 = std::array{1, 2} | views::slide(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 ); + VERIFY( ranges::equal(std::move(v1) | views::join, (int[]){1, 2}) ); + + int x[] = {1, 2, 3, 4}; + auto v2 = x | views::slide(2); + 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, (std::initializer_list[]){{1, 2}, {2, 3}, {3, 4}}, + ranges::equal) ); + + int y[] = {1, 2, 3, 4, 5}; + const auto v3 = y | views::slide(3); + VERIFY( ranges::size(v3) == 3 ); + for (unsigned i = 0; i < ranges::size(x); i++) + { + VERIFY( &v3[i][0] == &y[i] + 0 ); + VERIFY( &v3[i][1] == &y[i] + 1 ); + VERIFY( &v3[i][2] == &y[i] + 2 ); + } + + const auto v5 = y | views::slide(5); + VERIFY( ranges::size(v5) == 1 ); + VERIFY( ranges::equal(v5 | views::join, y) ); + + const auto v6 = y | views::slide(6); + VERIFY( ranges::empty(v6) ); + + 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::slide_view>>; + static_assert(ranges::forward_range); + static_assert(!ranges::bidirectional_range); + static_assert(!ranges::sized_range); + + using ty2 = ranges::slide_view>>; + static_assert(ranges::random_access_range); + static_assert(ranges::sized_range); + + return true; +} + +constexpr bool +test03() +{ + auto v = views::iota(0, 4) | views::filter([](auto) { return true; }) | views::slide(2); + using ty = decltype(v); + static_assert(ranges::forward_range); + static_assert(ranges::common_range); + static_assert(!ranges::sized_range); + 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()); +} -- cgit v1.1 From 1995a0227d2602718fd0b283a8c7050fdfc701fb Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 14 Sep 2022 00:18:07 +0000 Subject: Daily bump. --- libstdc++-v3/ChangeLog | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 5ee6860..4f8d8e0 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,52 @@ +2022-09-13 Patrick Palka + + * include/std/ranges (__detail::__slide_caches_nothing): Define. + (__detail::__slide_caches_last): Define. + (__detail::__slide_caches_first): Define. + (slide_view): Define. + (enable_borrowed_range): Define. + (slide_view::_Iterator): Define. + (slide_view::_Sentinel): Define. + (views::__detail::__can_slide_view): Define. + (views::_Slide, views::slide): Define. + * testsuite/std/ranges/adaptors/slide/1.cc: New test. + +2022-09-13 Patrick Palka + + * include/std/ranges (__detail::__div_ceil): Define. + (chunk_view): Define. + (chunk_view::_OuterIter): Define. + (chunk_view::_OuterIter::value_type): Define. + (chunk_view::_InnerIter): Define. + (chunk_view<_Vp>): Define partial specialization for forward + ranges. + (enable_borrowed_range): Define. + (chunk_view<_Vp>::_Iterator): Define. + (views::__detail::__can_chunk_view): Define. + (views::_Chunk, views::chunk): Define. + * testsuite/std/ranges/adaptors/chunk/1.cc: New test. + +2022-09-13 Patrick Palka + + * include/std/ranges (join_view::_Iterator::_M_satisfy): + Adjust resetting _M_inner as per LWG 3569. + (join_view::_Iterator::_M_inner): Wrap in std::optional + as per LWG 3569. + (join_view::_Iterator::_Iterator): Relax constraints as + per LWG 3569. + (join_view::_Iterator::operator*): Adjust as per LWG 3569. + (join_view::_Iterator::operator->): Likewise. + (join_view::_Iterator::operator++): Likewise. + (join_view::_Iterator::operator--): Likewise. + (join_view::_Iterator::iter_move): Likewise. + (join_view::_Iterator::iter_swap): Likewise. + * testsuite/std/ranges/adaptors/join.cc (test14): New test. + +2022-09-13 Patrick Palka + + * include/debug/safe_iterator.h (_GLIBCXX_DEBUG_VERIFY_OPERANDS): + Add parentheses to avoid -Wparentheses warning. + 2022-09-12 Patrick Palka PR libstdc++/106320 -- cgit v1.1 From 93257ed603d72b58bb2616da5b63c4c6737f424b Mon Sep 17 00:00:00 2001 From: Philipp Fent Date: Tue, 6 Sep 2022 23:24:29 +0200 Subject: libstdc++: Add pretty printer for std::stringstreams To display (o-,i-)stringstreams in the common case, we just print the underlying stringbuf, without the many ios_base members. In the unconventional case that the underlying streambuf was redirected, we report the redirected target. Signed-off-by: Philipp Fent libstdc++-v3/ChangeLog: * python/libstdcxx/v6/printers.py (access_streambuf_ptrs): New helper function. (StdStringBufPrinter, StdStringStreamPrinter): New printers. (build_libstdcxx_dictionary): Register stringstream printers. * testsuite/libstdc++-prettyprinters/debug.cc: Check string streams. * testsuite/libstdc++-prettyprinters/simple.cc: Likewise. * testsuite/libstdc++-prettyprinters/simple11.cc: Likewise. --- libstdc++-v3/python/libstdcxx/v6/printers.py | 56 ++++++++++++++++++++++ .../testsuite/libstdc++-prettyprinters/debug.cc | 15 ++++++ .../testsuite/libstdc++-prettyprinters/simple.cc | 15 ++++++ .../testsuite/libstdc++-prettyprinters/simple11.cc | 15 ++++++ 4 files changed, 101 insertions(+) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index d70c8d5..bd4289c 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -969,6 +969,57 @@ class StdStringPrinter: def display_hint (self): return 'string' +def access_streambuf_ptrs(streambuf): + "Access the streambuf put area pointers" + pbase = streambuf['_M_out_beg'] + pptr = streambuf['_M_out_cur'] + egptr = streambuf['_M_in_end'] + return pbase, pptr, egptr + +class StdStringBufPrinter: + "Print a std::basic_stringbuf" + + def __init__(self, _, val): + self.val = val + + def to_string(self): + (pbase, pptr, egptr) = access_streambuf_ptrs(self.val) + # Logic from basic_stringbuf::_M_high_mark() + if pptr: + if not egptr or pptr > egptr: + return pbase.string(length = pptr - pbase) + else: + return pbase.string(length = egptr - pbase) + return self.val['_M_string'] + + def display_hint(self): + return 'string' + +class StdStringStreamPrinter: + "Print a std::basic_stringstream" + + def __init__(self, typename, val): + self.val = val + self.typename = typename + + # Check if the stream was redirected: + # This is essentially: val['_M_streambuf'] == val['_M_stringbuf'].address + # However, GDB can't resolve the virtual inheritance, so we do that manually + basetype = [f.type for f in val.type.fields() if f.is_base_class][0] + gdb.set_convenience_variable('__stream', val.cast(basetype).address) + self.streambuf = gdb.parse_and_eval('$__stream->rdbuf()') + self.was_redirected = self.streambuf != val['_M_stringbuf'].address + + def to_string(self): + if self.was_redirected: + return "%s redirected to %s" % (self.typename, self.streambuf.dereference()) + return self.val['_M_stringbuf'] + + def display_hint(self): + if self.was_redirected: + return None + return 'string' + class Tr1HashtableIterator(Iterator): def __init__ (self, hashtable): self.buckets = hashtable['_M_buckets'] @@ -2232,6 +2283,11 @@ def build_libstdcxx_dictionary (): libstdcxx_printer.add_version('std::', 'initializer_list', StdInitializerListPrinter) libstdcxx_printer.add_version('std::', 'atomic', StdAtomicPrinter) + libstdcxx_printer.add_version('std::', 'basic_stringbuf', StdStringBufPrinter) + libstdcxx_printer.add_version('std::__cxx11::', 'basic_stringbuf', StdStringBufPrinter) + for sstream in ('istringstream', 'ostringstream', 'stringstream'): + libstdcxx_printer.add_version('std::', 'basic_' + sstream, StdStringStreamPrinter) + libstdcxx_printer.add_version('std::__cxx11::', 'basic_' + sstream, StdStringStreamPrinter) # std::regex components libstdcxx_printer.add_version('std::__detail::', '_State', diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc index 98bbc18..3c61955 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -110,6 +111,20 @@ main() __gnu_cxx::slist::iterator slliter = sll.begin(); // { dg-final { note-test slliter {47} } } + std::stringstream sstream; + sstream << "abc"; +// { dg-final { note-test sstream "\"abc\"" } } + std::stringstream ssin("input", std::ios::in); +// { dg-final { note-test ssin "\"input\"" } } + std::istringstream ssin2("input"); +// { dg-final { note-test ssin2 "\"input\"" } } + std::ostringstream ssout; + ssout << "out"; +// { dg-final { note-test ssout "\"out\"" } } + std::stringstream redirected("xxx"); + static_cast&>(redirected).rdbuf(sstream.rdbuf()); +// { dg-final { regexp-test redirected {std::.*stringstream redirected to .*} } } + std::cout << "\n"; return 0; // Mark SPOT } diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc index 1f85775..1609ae2 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -169,6 +170,20 @@ main() __gnu_cxx::slist::iterator slliter0; // { dg-final { note-test slliter0 {non-dereferenceable iterator for __gnu_cxx::slist} } } + std::stringstream sstream; + sstream << "abc"; +// { dg-final { note-test sstream "\"abc\"" } } + std::stringstream ssin("input", std::ios::in); +// { dg-final { note-test ssin "\"input\"" } } + std::istringstream ssin2("input"); +// { dg-final { note-test ssin2 "\"input\"" } } + std::ostringstream ssout; + ssout << "out"; +// { dg-final { note-test ssout "\"out\"" } } + std::stringstream redirected("xxx"); + static_cast&>(redirected).rdbuf(sstream.rdbuf()); +// { dg-final { regexp-test redirected {std::.*stringstream redirected to .*} } } + std::cout << "\n"; return 0; // Mark SPOT } diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc index 6f21675..a4b82e3 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -162,6 +163,20 @@ main() __gnu_cxx::slist::iterator slliter0; // { dg-final { note-test slliter0 {non-dereferenceable iterator for __gnu_cxx::slist} } } + std::stringstream sstream; + sstream << "abc"; +// { dg-final { note-test sstream "\"abc\"" } } + std::stringstream ssin("input", std::ios::in); +// { dg-final { note-test ssin "\"input\"" } } + std::istringstream ssin2("input"); +// { dg-final { note-test ssin2 "\"input\"" } } + std::ostringstream ssout; + ssout << "out"; +// { dg-final { note-test ssout "\"out\"" } } + std::stringstream redirected("xxx"); + static_cast&>(redirected).rdbuf(sstream.rdbuf()); +// { dg-final { regexp-test redirected {std::.*stringstream redirected to .*} } } + std::cout << "\n"; return 0; // Mark SPOT } -- cgit v1.1 From 8b1bc3051bd68ce193a8612fa3b1a65c0353b5b0 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 14 Sep 2022 13:48:25 +0100 Subject: libstdc++: Document LWG 1203 API change in manual libstdc++-v3/ChangeLog: * doc/xml/manual/intro.xml: Document LWG 1203. * doc/html/*: Regenerate. --- libstdc++-v3/doc/html/manual/bugs.html | 3 +++ libstdc++-v3/doc/html/manual/debug_mode_using.html | 7 ++++++- libstdc++-v3/doc/html/manual/using_macros.html | 5 +++++ libstdc++-v3/doc/xml/manual/intro.xml | 6 ++++++ 4 files changed, 20 insertions(+), 1 deletion(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html index 38594a9..384fe8d 100644 --- a/libstdc++-v3/doc/html/manual/bugs.html +++ b/libstdc++-v3/doc/html/manual/bugs.html @@ -357,6 +357,9 @@ More algorithms that throw away information

The traditional HP / SGI return type and value is blessed by the resolution of the DR. +

1203: + More useful rvalue stream insertion +

Return the stream as its original type, not the base class.

1339: uninitialized_fill_n should return the end of its range

Return the end of the filled range. diff --git a/libstdc++-v3/doc/html/manual/debug_mode_using.html b/libstdc++-v3/doc/html/manual/debug_mode_using.html index 4deb498..e26d06c 100644 --- a/libstdc++-v3/doc/html/manual/debug_mode_using.html +++ b/libstdc++-v3/doc/html/manual/debug_mode_using.html @@ -9,7 +9,12 @@ units.

By default, error messages are formatted to fit on lines of about 78 characters. The environment variable GLIBCXX_DEBUG_MESSAGE_LENGTH can be used to request a - different length.

Using a Specific Debug Container

When it is not feasible to recompile your entire application, or + different length.

Note that libstdc++ is able to produce backtraces on error. + It requires that you configure libstdc++ build with + --enable-libstdcxx-backtrace=yes. + Use -D_GLIBCXX_DEBUG_BACKTRACE to activate it. + You'll then have to link with libstdc++_libbacktrace static library + (-lstdc++_libbacktrace) to build your application.

Using a Specific Debug Container

When it is not feasible to recompile your entire application, or only specific containers need checking, debugging containers are available as GNU extensions. These debugging containers are functionally equivalent to the standard drop-in containers used in diff --git a/libstdc++-v3/doc/html/manual/using_macros.html b/libstdc++-v3/doc/html/manual/using_macros.html index edbbd03..9823046 100644 --- a/libstdc++-v3/doc/html/manual/using_macros.html +++ b/libstdc++-v3/doc/html/manual/using_macros.html @@ -95,6 +95,11 @@ the debug mode, makes the debug mode extremely picky by making the use of libstdc++ extensions and libstdc++-specific behavior into errors. +

_GLIBCXX_DEBUG_BACKTRACE

+ Undefined by default. Considered only if libstdc++ has been configured with + --enable-libstdcxx-backtrace=yes and if _GLIBCXX_DEBUG + is defined. When defined display backtraces on + debug mode assertions.

_GLIBCXX_PARALLEL

Undefined by default. When defined, compiles user code using the parallel mode. diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index 290e5d3..d341c3e 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -852,6 +852,12 @@ requirements of the license of GCC. by the resolution of the DR. + 1203: + More useful rvalue stream insertion + + Return the stream as its original type, not the base class. + + 1339: uninitialized_fill_n should return the end of its range -- cgit v1.1 From 0bc9aa9c3fcb1f3534575314038661ff111874dd Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 14 Sep 2022 14:03:19 +0100 Subject: libstdc++: Add assertion to std::promise::set_exception (LWG 2276) Without this assertion, the shared state is made ready, but contains neither a value nor an exception. Add an assertion to prevent users from accessing a value that was never initialized in the shared state. libstdc++-v3/ChangeLog: * include/std/future (_State_baseV2::__setter(exception_ptr&, promise&)): Add assertion for LWG 2276 precondition. * testsuite/30_threads/promise/members/set_exception_neg.cc: New test. --- libstdc++-v3/include/std/future | 1 + .../30_threads/promise/members/set_exception_neg.cc | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 libstdc++-v3/testsuite/30_threads/promise/members/set_exception_neg.cc (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index ba1f28c..a1b2d7f 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -559,6 +559,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _Setter<_Res, __exception_ptr_tag> __setter(exception_ptr& __ex, promise<_Res>* __prom) noexcept { + __glibcxx_assert(__ex != nullptr); // LWG 2276 return _Setter<_Res, __exception_ptr_tag>{ __prom, &__ex }; } diff --git a/libstdc++-v3/testsuite/30_threads/promise/members/set_exception_neg.cc b/libstdc++-v3/testsuite/30_threads/promise/members/set_exception_neg.cc new file mode 100644 index 0000000..1666093 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/promise/members/set_exception_neg.cc @@ -0,0 +1,18 @@ +// { dg-options "-D_GLIBCXX_ASSERTIONS" } +// { dg-do run { xfail *-*-* } } +// { dg-additional-options "-pthread" { target pthread } } +// { dg-require-effective-target c++11 } +// { dg-require-gthreads "" } + +// LWG 2276. Missing requirement on std::promise::set_exception + +#include + +int main() +{ + std::promise prom; + auto f = prom.get_future(); + std::exception_ptr p; + prom.set_exception(p); // Preconditions: p is not null + f.get(); +} -- cgit v1.1 From 9a1bc4b463e61cd5bc5f169a08a420aae39a07f6 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 14 Sep 2022 14:16:25 +0100 Subject: libstdc++: Add comment to 17_intro/names.cc test libstdc++-v3/ChangeLog: * testsuite/17_intro/names.cc: Explain why poison pragma can't be used. --- libstdc++-v3/testsuite/17_intro/names.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/testsuite/17_intro/names.cc b/libstdc++-v3/testsuite/17_intro/names.cc index 86fb8f8..82e201c 100644 --- a/libstdc++-v3/testsuite/17_intro/names.cc +++ b/libstdc++-v3/testsuite/17_intro/names.cc @@ -20,6 +20,8 @@ // Define macros for some common variables names that we must not use for // naming variables, parameters etc. in the library. +// N.B. we cannot use '#pragma GCC poison A' because that also prevents using +// these names even as macro arguments, e.g. #define FOO(A) BAR(A) #define A ( #define B ( #define C ( -- cgit v1.1 From 7f1e3d06bb9a39fb42afd4d0ea1a103fe239b1cb Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 14 Sep 2022 15:52:44 +0100 Subject: libstdc++: Add missing header to This is needed for std::nothrow and the nothrow operator new overload, so should be included explicitly. libstdc++-v3/ChangeLog: * include/bits/stl_tempbuf.h: Include . --- libstdc++-v3/include/bits/stl_tempbuf.h | 1 + 1 file changed, 1 insertion(+) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h b/libstdc++-v3/include/bits/stl_tempbuf.h index db7cdb1..82f2dc8 100644 --- a/libstdc++-v3/include/bits/stl_tempbuf.h +++ b/libstdc++-v3/include/bits/stl_tempbuf.h @@ -56,6 +56,7 @@ #ifndef _STL_TEMPBUF_H #define _STL_TEMPBUF_H 1 +#include #include #include -- cgit v1.1 From 0abc63a5ea4550c9e75e81b05a153dfb4b234446 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 14 Sep 2022 19:11:22 +0100 Subject: libstdc++: Add TSan annotations to std::atomic> This adds annotations to std::atomic> to enable TSan to understand the custom locking. Without this, TSan reports data races for accesses to the _M_ptr member, even though those are correctly synchronized using atomic operations on the tagged pointer. libstdc++-v3/ChangeLog: * include/bits/shared_ptr_atomic.h (_GLIBCXX_TSAN_MUTEX_DESTROY) (_GLIBCXX_TSAN_MUTEX_PRE_LOCK, _GLIBCXX_TSAN_MUTEX_POST_LOCK) (_GLIBCXX_TSAN_MUTEX_PRE_UNLOCK, _GLIBCXX_TSAN_MUTEX_POST_UNLOCK) (_GLIBCXX_TSAN_MUTEX_PRE_SIGNAL, _GLIBCXX_TSAN_MUTEX_POST_SIGNAL): Define macros for TSan annotation functions. (_Sp_atomic::_Atomic_count): Add annotations. --- libstdc++-v3/include/bits/shared_ptr_atomic.h | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/bits/shared_ptr_atomic.h b/libstdc++-v3/include/bits/shared_ptr_atomic.h index d4bd712..4580807 100644 --- a/libstdc++-v3/include/bits/shared_ptr_atomic.h +++ b/libstdc++-v3/include/bits/shared_ptr_atomic.h @@ -32,6 +32,30 @@ #include +#if defined _GLIBCXX_TSAN && __has_include() +#include +#define _GLIBCXX_TSAN_MUTEX_DESTROY(X) \ + __tsan_mutex_destroy(X, __tsan_mutex_not_static) +#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X) \ + __tsan_mutex_pre_lock(X, __tsan_mutex_not_static) +#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X) \ + __tsan_mutex_post_lock(X, __tsan_mutex_not_static, 0) +#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) \ + __tsan_mutex_pre_unlock(X, __tsan_mutex_not_static) +#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) \ + __tsan_mutex_post_unlock(X, __tsan_mutex_not_static) +#define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X) __tsan_mutex_pre_signal(X, 0) +#define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X) __tsan_mutex_post_signal(X, 0) +#else +#define _GLIBCXX_TSAN_MUTEX_DESTROY(X) +#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X) +#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X) +#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) +#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) +#define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X) +#define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X) +#endif + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -377,6 +401,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ~_Atomic_count() { auto __val = _M_val.load(memory_order_relaxed); + _GLIBCXX_TSAN_MUTEX_DESTROY(&_M_val); __glibcxx_assert(!(__val & _S_lock_bit)); if (auto __pi = reinterpret_cast(__val)) { @@ -406,6 +431,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __current = _M_val.load(memory_order_relaxed); } + _GLIBCXX_TSAN_MUTEX_PRE_LOCK(&_M_val); + while (!_M_val.compare_exchange_strong(__current, __current | _S_lock_bit, __o, @@ -416,6 +443,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif __current = __current & ~_S_lock_bit; } + _GLIBCXX_TSAN_MUTEX_POST_LOCK(&_M_val); return reinterpret_cast(__current); } @@ -423,7 +451,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void unlock(memory_order __o) const noexcept { + _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val); _M_val.fetch_sub(1, __o); + _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val); } // Swaps the values of *this and __c, and unlocks *this. @@ -434,7 +464,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__o != memory_order_seq_cst) __o = memory_order_release; auto __x = reinterpret_cast(__c._M_pi); + _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val); __x = _M_val.exchange(__x, __o); + _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val); __c._M_pi = reinterpret_cast(__x & ~_S_lock_bit); } @@ -443,20 +475,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void _M_wait_unlock(memory_order __o) const noexcept { + _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val); auto __v = _M_val.fetch_sub(1, memory_order_relaxed); + _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val); _M_val.wait(__v & ~_S_lock_bit, __o); } void notify_one() noexcept { + _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(&_M_val); _M_val.notify_one(); + _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(&_M_val); } void notify_all() noexcept { + _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(&_M_val); _M_val.notify_all(); + _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(&_M_val); } #endif -- cgit v1.1 From ff822367bb638fe43dfd0038fba883a7c4433576 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 15 Sep 2022 00:17:35 +0000 Subject: Daily bump. --- libstdc++-v3/ChangeLog | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4f8d8e0..b20194d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,45 @@ +2022-09-14 Jonathan Wakely + + * include/bits/shared_ptr_atomic.h (_GLIBCXX_TSAN_MUTEX_DESTROY) + (_GLIBCXX_TSAN_MUTEX_PRE_LOCK, _GLIBCXX_TSAN_MUTEX_POST_LOCK) + (_GLIBCXX_TSAN_MUTEX_PRE_UNLOCK, _GLIBCXX_TSAN_MUTEX_POST_UNLOCK) + (_GLIBCXX_TSAN_MUTEX_PRE_SIGNAL, _GLIBCXX_TSAN_MUTEX_POST_SIGNAL): + Define macros for TSan annotation functions. + (_Sp_atomic::_Atomic_count): Add annotations. + +2022-09-14 Jonathan Wakely + + * include/bits/stl_tempbuf.h: Include . + +2022-09-14 Jonathan Wakely + + * testsuite/17_intro/names.cc: Explain why poison pragma can't + be used. + +2022-09-14 Jonathan Wakely + + * include/std/future + (_State_baseV2::__setter(exception_ptr&, promise&)): Add + assertion for LWG 2276 precondition. + * testsuite/30_threads/promise/members/set_exception_neg.cc: + New test. + +2022-09-14 Jonathan Wakely + + * doc/xml/manual/intro.xml: Document LWG 1203. + * doc/html/*: Regenerate. + +2022-09-14 Philipp Fent + + * python/libstdcxx/v6/printers.py (access_streambuf_ptrs): + New helper function. + (StdStringBufPrinter, StdStringStreamPrinter): New printers. + (build_libstdcxx_dictionary): Register stringstream printers. + * testsuite/libstdc++-prettyprinters/debug.cc: Check string + streams. + * testsuite/libstdc++-prettyprinters/simple.cc: Likewise. + * testsuite/libstdc++-prettyprinters/simple11.cc: Likewise. + 2022-09-13 Patrick Palka * include/std/ranges (__detail::__slide_caches_nothing): Define. -- cgit v1.1 From d26bcff991c7d71d5c0c07a0ff1f7494a4e9812b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Dumont?= Date: Wed, 14 Sep 2022 19:11:51 +0200 Subject: libstdc++: [_GLIBCXX_INLINE_VERSION] Cleanup gnu-versioned-namespace.ver Remove expressions for symbols in std::__detail::__8 namespace, they are obsolete since version namespace applies only at std:: level, not at sub-levels. libstdc++-v3/ChangeLog: * config/abi/pre/gnu-versioned-namespace.ver: Remove obsolete std::__detail::__8 symbols. --- libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver index b37199e..06ccaa8 100644 --- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver +++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver @@ -76,20 +76,9 @@ GLIBCXX_8.0 { # locale _ZNSt3__89has_facetINS_*; - # hash - _ZNSt8__detail3__812__prime_listE; - _ZNSt3tr18__detail3__812__prime_listE; - # thread/mutex/condition_variable/future __once_proxy; - # std::__detail::_List_node_base - _ZNSt8__detail3__815_List_node_base7_M_hook*; - _ZNSt8__detail3__815_List_node_base9_M_unhookEv; - _ZNSt8__detail3__815_List_node_base10_M_reverseEv; - _ZNSt8__detail3__815_List_node_base11_M_transfer*; - _ZNSt8__detail3__815_List_node_base4swapER*; - # std::__convert_to_v _ZNSt3__814__convert_to_v*; -- cgit v1.1 From db58fa0b053327acfa42fbe6ca673e6eddd7852b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Dumont?= Date: Wed, 14 Sep 2022 19:14:48 +0200 Subject: libstdc++: [_GLIBCXX_INLINE_VERSION] Fix test dg-prune-output libstdc++-v3/ChangeLog: * testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc: Adapt dg-prune-output to _GLIBCXX_INLINE_VERSION mode. --- .../testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc index fc0b70b..bc66c13 100644 --- a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc +++ b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile { target c++11 } } // { dg-prune-output "must be a complete" } -// { dg-prune-output "'value' is not a member of 'std::is_move_cons" } +// { dg-prune-output "'value' is not a member of 'std::(__8::)?is_move_cons" } // { dg-prune-output "invalid use of incomplete type" } // Copyright (C) 2019-2022 Free Software Foundation, Inc. -- cgit v1.1 From 29b39d4b0e44d350a35e5f25d9faeb9f9aac38e4 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Thu, 15 Sep 2022 13:16:51 -0400 Subject: libstdc++: Implement ranges::chunk_by_view from P2443R1 libstdc++-v3/ChangeLog: * include/bits/ranges_algo.h (__adjacent_find_fn, adjacent_find): Move to ... * include/bits/ranges_util.h: ... here. * include/std/ranges (chunk_by_view): Define. (chunk_by_view::_Iterator): Define. (__detail::__can_chunk_by_view): Define. (_ChunkBy, chunk_by): Define. * testsuite/std/ranges/adaptors/chunk_by/1.cc: New test. --- libstdc++-v3/include/bits/ranges_algo.h | 38 +--- libstdc++-v3/include/bits/ranges_util.h | 38 ++++ libstdc++-v3/include/std/ranges | 193 +++++++++++++++++++++ .../testsuite/std/ranges/adaptors/chunk_by/1.cc | 58 +++++++ 4 files changed, 290 insertions(+), 37 deletions(-) create mode 100644 libstdc++-v3/testsuite/std/ranges/adaptors/chunk_by/1.cc (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index 2a11636..228e10b 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -506,43 +506,7 @@ namespace ranges inline constexpr __find_end_fn find_end{}; - struct __adjacent_find_fn - { - template _Sent, - typename _Proj = identity, - indirect_binary_predicate, - projected<_Iter, _Proj>> _Pred - = ranges::equal_to> - constexpr _Iter - operator()(_Iter __first, _Sent __last, - _Pred __pred = {}, _Proj __proj = {}) const - { - if (__first == __last) - return __first; - auto __next = __first; - for (; ++__next != __last; __first = __next) - { - if (std::__invoke(__pred, - std::__invoke(__proj, *__first), - std::__invoke(__proj, *__next))) - return __first; - } - return __next; - } - - template, _Proj>, - projected, _Proj>> _Pred = ranges::equal_to> - constexpr borrowed_iterator_t<_Range> - operator()(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) const - { - return (*this)(ranges::begin(__r), ranges::end(__r), - std::move(__pred), std::move(__proj)); - } - }; - - inline constexpr __adjacent_find_fn adjacent_find{}; + // adjacent_find is defined in . struct __is_permutation_fn { diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h index bb56dee..85ddea6 100644 --- a/libstdc++-v3/include/bits/ranges_util.h +++ b/libstdc++-v3/include/bits/ranges_util.h @@ -704,6 +704,44 @@ namespace ranges inline constexpr __min_fn min{}; + struct __adjacent_find_fn + { + template _Sent, + typename _Proj = identity, + indirect_binary_predicate, + projected<_Iter, _Proj>> _Pred + = ranges::equal_to> + constexpr _Iter + operator()(_Iter __first, _Sent __last, + _Pred __pred = {}, _Proj __proj = {}) const + { + if (__first == __last) + return __first; + auto __next = __first; + for (; ++__next != __last; __first = __next) + { + if (std::__invoke(__pred, + std::__invoke(__proj, *__first), + std::__invoke(__proj, *__next))) + return __first; + } + return __next; + } + + template, _Proj>, + projected, _Proj>> _Pred = ranges::equal_to> + constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) const + { + return (*this)(ranges::begin(__r), ranges::end(__r), + std::move(__pred), std::move(__proj)); + } + }; + + inline constexpr __adjacent_find_fn adjacent_find{}; + } // namespace ranges using ranges::get; diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 44a4df8..53093a3 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -6676,6 +6676,199 @@ namespace views::__adaptor inline constexpr _Slide slide; } + + template, iterator_t<_Vp>> _Pred> + requires view<_Vp> && is_object_v<_Pred> + class chunk_by_view : public view_interface> + { + _Vp _M_base = _Vp(); + __detail::__box<_Pred> _M_pred = _Pred(); + __detail::_CachedPosition<_Vp> _M_cached_begin; + + constexpr iterator_t<_Vp> + _M_find_next(iterator_t<_Vp> __current) + { + __glibcxx_assert(_M_pred.has_value()); + auto __pred = [this](_Tp&& __x, _Tp&& __y) { + return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Tp>(__y))); + }; + auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred); + return ranges::next(__it, 1, ranges::end(_M_base)); + } + + constexpr iterator_t<_Vp> + _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp> + { + __glibcxx_assert(_M_pred.has_value()); + auto __pred = [this](_Tp&& __x, _Tp&& __y) { + return !bool((*_M_pred)(std::forward<_Tp>(__y), std::forward<_Tp>(__x))); + }; + auto __rbegin = std::make_reverse_iterator(__current); + auto __rend = std::make_reverse_iterator(ranges::begin(_M_base)); + __glibcxx_assert(__rbegin != __rend); + auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base(); + return ranges::prev(__it, 1, ranges::begin(_M_base)); + } + + class _Iterator; + + public: + chunk_by_view() requires (default_initializable<_Vp> + && default_initializable<_Pred>) + = default; + + constexpr explicit + chunk_by_view(_Vp __base, _Pred __pred) + : _M_base(std::move(__base)), _M_pred(std::move(__pred)) + { } + + constexpr _Vp + base() const & requires copy_constructible<_Vp> + { return _M_base; } + + constexpr _Vp + base() && + { return std::move(_M_base); } + + constexpr const _Pred& + pred() const + { return *_M_pred; } + + constexpr _Iterator + begin() + { + __glibcxx_assert(_M_pred.has_value()); + iterator_t<_Vp> __it; + if (_M_cached_begin._M_has_value()) + __it = _M_cached_begin._M_get(_M_base); + else + { + __it = _M_find_next(ranges::begin(_M_base)); + _M_cached_begin._M_set(_M_base, __it); + } + return _Iterator(*this, ranges::begin(_M_base), __it); + } + + constexpr auto + end() + { + if constexpr (common_range<_Vp>) + return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base)); + else + return default_sentinel; + } + }; + + template + chunk_by_view(_Range&&, _Pred) -> chunk_by_view, _Pred>; + + template, iterator_t<_Vp>> _Pred> + requires view<_Vp> && is_object_v<_Pred> + class chunk_by_view<_Vp, _Pred>::_Iterator + { + chunk_by_view* _M_parent = nullptr; + iterator_t<_Vp> _M_current = iterator_t<_Vp>(); + iterator_t<_Vp> _M_next = iterator_t<_Vp>(); + + constexpr + _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next) + : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next) + { } + + static auto + _S_iter_concept() + { + if constexpr (bidirectional_range<_Vp>) + return bidirectional_iterator_tag{}; + else + return forward_iterator_tag{}; + } + + friend chunk_by_view; + + public: + using value_type = subrange>; + using difference_type = range_difference_t<_Vp>; + using iterator_category = input_iterator_tag; + using iterator_concept = decltype(_S_iter_concept()); + + _Iterator() = default; + + constexpr value_type + operator*() const + { + __glibcxx_assert(_M_current != _M_next); + return ranges::subrange(_M_current, _M_next); + } + + constexpr _Iterator& + operator++() + { + __glibcxx_assert(_M_current != _M_next); + _M_current = _M_next; + _M_next = _M_parent->_M_find_next(_M_current); + return *this; + } + + constexpr _Iterator + operator++(int) + { + auto __tmp = *this; + ++*this; + return __tmp; + } + + constexpr _Iterator& + operator--() requires bidirectional_range<_Vp> + { + _M_next = _M_current; + _M_current = _M_parent->_M_find_prev(_M_next); + return *this; + } + + constexpr _Iterator + operator--(int) requires bidirectional_range<_Vp> + { + auto __tmp = *this; + --*this; + return __tmp; + } + + friend constexpr bool + operator==(const _Iterator& __x, const _Iterator& __y) + { return __x._M_current == __y._M_current; } + + friend constexpr bool + operator==(const _Iterator& __x, default_sentinel_t) + { return __x._M_current == __x._M_next; } + }; + + namespace views + { + namespace __detail + { + template + concept __can_chunk_by_view + = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); }; + } + + struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy> + { + template + requires __detail::__can_chunk_by_view<_Range, _Pred> + constexpr auto + operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const + { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); } + + using __adaptor::_RangeAdaptor<_ChunkBy>::operator(); + static constexpr int _S_arity = 2; + static constexpr bool _S_has_simple_extra_args = true; + }; + + inline constexpr _ChunkBy chunk_by; + } #endif // C++23 } // namespace ranges diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/chunk_by/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/chunk_by/1.cc new file mode 100644 index 0000000..d57b127 --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/chunk_by/1.cc @@ -0,0 +1,58 @@ +// { dg-options "-std=gnu++23" } +// { dg-do run { target c++23 } } + +#include +#include +#include +#include +#include + +namespace ranges = std::ranges; +namespace views = std::views; + +constexpr bool +test01() +{ + int x[] = {1, 2, 2, 3, 0, 4, 5, 2}; + auto v = x | views::chunk_by(ranges::less_equal{}); + static_assert(ranges::bidirectional_range + && ranges::common_range); + VERIFY( ranges::equal(v, (std::initializer_list[]){{1, 2, 2, 3}, {0, 4, 5}, {2}}, + ranges::equal) ); + VERIFY( ranges::equal(v | views::reverse, + (std::initializer_list[]){{2}, {0, 4, 5}, {1, 2, 2, 3}}, + ranges::equal) ); + VERIFY( ranges::equal(v | views::join, x) ); + auto i = v.begin(); + auto j = i; + j++; + VERIFY( i == i && i != v.end() ); + VERIFY( j == j && j != v.end() ); + VERIFY( j != i ); + j--; + VERIFY( j == i ); + + return true; +} + +void +test02() +{ + int x[] = {1, 2, 3}; + __gnu_test::test_forward_range rx(x); + auto v = rx | views::chunk_by(ranges::equal_to{}); + static_assert(!ranges::bidirectional_range + && !ranges::common_range); + VERIFY( ranges::equal(v, x | views::transform(views::single), ranges::equal) ); + auto i = v.begin(); + VERIFY( i != v.end() ); + ranges::advance(i, 3); + VERIFY( i == v.end() ); +} + +int +main() +{ + static_assert(test01()); + test02(); +} -- cgit v1.1 From ecbdfa8b314e2c17da17511b86371f552bffd441 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 15 Sep 2022 16:57:30 +0100 Subject: libstdc++: Tweak TSan annotations for std::atomic> Do not use the __tsan_mutex_not_static flag for annotation functions where it's not a valid flag. Also use the try_lock and try_lock_failed flags to more precisely annotate the CAS loop used to acquire a lock. libstdc++-v3/ChangeLog: * include/bits/shared_ptr_atomic.h (_GLIBCXX_TSAN_MUTEX_PRE_LOCK): Replace with ... (_GLIBCXX_TSAN_MUTEX_TRY_LOCK): ... this, add try_lock flag. (_GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED): New macro using try_lock_failed flag (_GLIBCXX_TSAN_MUTEX_POST_LOCK): Rename to ... (_GLIBCXX_TSAN_MUTEX_LOCKED): ... this. (_GLIBCXX_TSAN_MUTEX_PRE_UNLOCK): Remove invalid flag. (_GLIBCXX_TSAN_MUTEX_POST_UNLOCK): Remove invalid flag. (_Sp_atomic::_Atomic_count::lock): Use new macros. --- libstdc++-v3/include/bits/shared_ptr_atomic.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/bits/shared_ptr_atomic.h b/libstdc++-v3/include/bits/shared_ptr_atomic.h index 4580807..55d193d 100644 --- a/libstdc++-v3/include/bits/shared_ptr_atomic.h +++ b/libstdc++-v3/include/bits/shared_ptr_atomic.h @@ -32,24 +32,26 @@ #include +// Annotations for the custom locking in atomic>. #if defined _GLIBCXX_TSAN && __has_include() #include #define _GLIBCXX_TSAN_MUTEX_DESTROY(X) \ __tsan_mutex_destroy(X, __tsan_mutex_not_static) -#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X) \ - __tsan_mutex_pre_lock(X, __tsan_mutex_not_static) -#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X) \ +#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK(X) \ + __tsan_mutex_pre_lock(X, __tsan_mutex_not_static|__tsan_mutex_try_lock) +#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(X) __tsan_mutex_post_lock(X, \ + __tsan_mutex_not_static|__tsan_mutex_try_lock_failed, 0) +#define _GLIBCXX_TSAN_MUTEX_LOCKED(X) \ __tsan_mutex_post_lock(X, __tsan_mutex_not_static, 0) -#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) \ - __tsan_mutex_pre_unlock(X, __tsan_mutex_not_static) -#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) \ - __tsan_mutex_post_unlock(X, __tsan_mutex_not_static) +#define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) __tsan_mutex_pre_unlock(X, 0) +#define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) __tsan_mutex_post_unlock(X, 0) #define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X) __tsan_mutex_pre_signal(X, 0) #define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X) __tsan_mutex_post_signal(X, 0) #else #define _GLIBCXX_TSAN_MUTEX_DESTROY(X) -#define _GLIBCXX_TSAN_MUTEX_PRE_LOCK(X) -#define _GLIBCXX_TSAN_MUTEX_POST_LOCK(X) +#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK(X) +#define _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(X) +#define _GLIBCXX_TSAN_MUTEX_LOCKED(X) #define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) #define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) #define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X) @@ -431,19 +433,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __current = _M_val.load(memory_order_relaxed); } - _GLIBCXX_TSAN_MUTEX_PRE_LOCK(&_M_val); + _GLIBCXX_TSAN_MUTEX_TRY_LOCK(&_M_val); while (!_M_val.compare_exchange_strong(__current, __current | _S_lock_bit, __o, memory_order_relaxed)) { + _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(&_M_val); #if __cpp_lib_atomic_wait __detail::__thread_relax(); #endif __current = __current & ~_S_lock_bit; + _GLIBCXX_TSAN_MUTEX_TRY_LOCK(&_M_val); } - _GLIBCXX_TSAN_MUTEX_POST_LOCK(&_M_val); + _GLIBCXX_TSAN_MUTEX_LOCKED(&_M_val); return reinterpret_cast(__current); } -- cgit v1.1 From d6ccad7641da10d9c5f1f6cfc676d5f5b9d2d126 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 15 Sep 2022 18:21:32 +0100 Subject: libstdc++: Remove unnecessary header from Previously included so that std::copy, std::fill etc. could be used by . But that includes it explicitly now, so that it can be compiled as a header unit. There's no need to include it in , where its purpose isn't obvious. libstdc++-v3/ChangeLog: * include/std/memory: Do not include . --- libstdc++-v3/include/std/memory | 1 - 1 file changed, 1 deletion(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory index 481fa42..20a5502 100644 --- a/libstdc++-v3/include/std/memory +++ b/libstdc++-v3/include/std/memory @@ -60,7 +60,6 @@ * Smart pointers, etc. */ -#include #include #include #include -- cgit v1.1 From d0fc05e86027463eef60ffe16fb8d1fe74acc4e8 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 16 Sep 2022 00:16:53 +0000 Subject: Daily bump. --- libstdc++-v3/ChangeLog | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b20194d..392a522 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,41 @@ +2022-09-15 Jonathan Wakely + + * include/std/memory: Do not include . + +2022-09-15 Jonathan Wakely + + * include/bits/shared_ptr_atomic.h (_GLIBCXX_TSAN_MUTEX_PRE_LOCK): + Replace with ... + (_GLIBCXX_TSAN_MUTEX_TRY_LOCK): ... this, add try_lock flag. + (_GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED): New macro using + try_lock_failed flag + (_GLIBCXX_TSAN_MUTEX_POST_LOCK): Rename to ... + (_GLIBCXX_TSAN_MUTEX_LOCKED): ... this. + (_GLIBCXX_TSAN_MUTEX_PRE_UNLOCK): Remove invalid flag. + (_GLIBCXX_TSAN_MUTEX_POST_UNLOCK): Remove invalid flag. + (_Sp_atomic::_Atomic_count::lock): Use new macros. + +2022-09-15 Patrick Palka + + * include/bits/ranges_algo.h (__adjacent_find_fn, adjacent_find): + Move to ... + * include/bits/ranges_util.h: ... here. + * include/std/ranges (chunk_by_view): Define. + (chunk_by_view::_Iterator): Define. + (__detail::__can_chunk_by_view): Define. + (_ChunkBy, chunk_by): Define. + * testsuite/std/ranges/adaptors/chunk_by/1.cc: New test. + +2022-09-15 François Dumont + + * testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc: + Adapt dg-prune-output to _GLIBCXX_INLINE_VERSION mode. + +2022-09-15 François Dumont + + * config/abi/pre/gnu-versioned-namespace.ver: Remove obsolete std::__detail::__8 + symbols. + 2022-09-14 Jonathan Wakely * include/bits/shared_ptr_atomic.h (_GLIBCXX_TSAN_MUTEX_DESTROY) -- cgit v1.1 From 4c156ead37c0660b11e1f055bcba159ce806c5c8 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 16 Sep 2022 10:16:04 +0100 Subject: libstdc++: Document new libstdc++.so symbol versions libstdc++-v3/ChangeLog: * doc/xml/manual/abi.xml: Document GLIBCXX_3.4.30 and GLIBCXX_3.4.31 versions. * doc/html/manual/abi.html: Regenerate. --- libstdc++-v3/doc/html/manual/abi.html | 2 +- libstdc++-v3/doc/xml/manual/abi.xml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/doc/html/manual/abi.html b/libstdc++-v3/doc/html/manual/abi.html index 82b03fd..1079886 100644 --- a/libstdc++-v3/doc/html/manual/abi.html +++ b/libstdc++-v3/doc/html/manual/abi.html @@ -128,7 +128,7 @@ compatible. GLIBCPP_3.2 for symbols that were introduced in the GCC 3.2.0 release.) If a particular release is not listed, it has the same version labels as the preceding release. -

  • GCC 3.0.0: (Error, not versioned)

  • GCC 3.0.1: (Error, not versioned)

  • GCC 3.0.2: (Error, not versioned)

  • GCC 3.0.3: (Error, not versioned)

  • GCC 3.0.4: (Error, not versioned)

  • GCC 3.1.0: GLIBCPP_3.1, CXXABI_1

  • GCC 3.1.1: GLIBCPP_3.1, CXXABI_1

  • GCC 3.2.0: GLIBCPP_3.2, CXXABI_1.2

  • GCC 3.2.1: GLIBCPP_3.2.1, CXXABI_1.2

  • GCC 3.2.2: GLIBCPP_3.2.2, CXXABI_1.2

  • GCC 3.2.3: GLIBCPP_3.2.2, CXXABI_1.2

  • GCC 3.3.0: GLIBCPP_3.2.2, CXXABI_1.2.1

  • GCC 3.3.1: GLIBCPP_3.2.3, CXXABI_1.2.1

  • GCC 3.3.2: GLIBCPP_3.2.3, CXXABI_1.2.1

  • GCC 3.3.3: GLIBCPP_3.2.3, CXXABI_1.2.1

  • GCC 3.4.0: GLIBCXX_3.4, CXXABI_1.3

  • GCC 3.4.1: GLIBCXX_3.4.1, CXXABI_1.3

  • GCC 3.4.2: GLIBCXX_3.4.2

  • GCC 3.4.3: GLIBCXX_3.4.3

  • GCC 4.0.0: GLIBCXX_3.4.4, CXXABI_1.3.1

  • GCC 4.0.1: GLIBCXX_3.4.5

  • GCC 4.0.2: GLIBCXX_3.4.6

  • GCC 4.0.3: GLIBCXX_3.4.7

  • GCC 4.1.1: GLIBCXX_3.4.8

  • GCC 4.2.0: GLIBCXX_3.4.9

  • GCC 4.3.0: GLIBCXX_3.4.10, CXXABI_1.3.2

  • GCC 4.4.0: GLIBCXX_3.4.11, CXXABI_1.3.3

  • GCC 4.4.1: GLIBCXX_3.4.12, CXXABI_1.3.3

  • GCC 4.4.2: GLIBCXX_3.4.13, CXXABI_1.3.3

  • GCC 4.5.0: GLIBCXX_3.4.14, CXXABI_1.3.4

  • GCC 4.6.0: GLIBCXX_3.4.15, CXXABI_1.3.5

  • GCC 4.6.1: GLIBCXX_3.4.16, CXXABI_1.3.5

  • GCC 4.7.0: GLIBCXX_3.4.17, CXXABI_1.3.6

  • GCC 4.8.0: GLIBCXX_3.4.18, CXXABI_1.3.7

  • GCC 4.8.3: GLIBCXX_3.4.19, CXXABI_1.3.7

  • GCC 4.9.0: GLIBCXX_3.4.20, CXXABI_1.3.8

  • GCC 5.1.0: GLIBCXX_3.4.21, CXXABI_1.3.9

  • GCC 6.1.0: GLIBCXX_3.4.22, CXXABI_1.3.10

  • GCC 7.1.0: GLIBCXX_3.4.23, CXXABI_1.3.11

  • GCC 7.2.0: GLIBCXX_3.4.24, CXXABI_1.3.11

  • GCC 8.1.0: GLIBCXX_3.4.25, CXXABI_1.3.11

  • GCC 9.1.0: GLIBCXX_3.4.26, CXXABI_1.3.12

  • GCC 9.2.0: GLIBCXX_3.4.27, CXXABI_1.3.12

  • GCC 9.3.0: GLIBCXX_3.4.28, CXXABI_1.3.12

  • GCC 10.1.0: GLIBCXX_3.4.28, CXXABI_1.3.12

  • GCC 11.1.0: GLIBCXX_3.4.29, CXXABI_1.3.13

  • Incremental bumping of a compiler pre-defined macro, +

    • GCC 3.0.0: (Error, not versioned)

    • GCC 3.0.1: (Error, not versioned)

    • GCC 3.0.2: (Error, not versioned)

    • GCC 3.0.3: (Error, not versioned)

    • GCC 3.0.4: (Error, not versioned)

    • GCC 3.1.0: GLIBCPP_3.1, CXXABI_1

    • GCC 3.1.1: GLIBCPP_3.1, CXXABI_1

    • GCC 3.2.0: GLIBCPP_3.2, CXXABI_1.2

    • GCC 3.2.1: GLIBCPP_3.2.1, CXXABI_1.2

    • GCC 3.2.2: GLIBCPP_3.2.2, CXXABI_1.2

    • GCC 3.2.3: GLIBCPP_3.2.2, CXXABI_1.2

    • GCC 3.3.0: GLIBCPP_3.2.2, CXXABI_1.2.1

    • GCC 3.3.1: GLIBCPP_3.2.3, CXXABI_1.2.1

    • GCC 3.3.2: GLIBCPP_3.2.3, CXXABI_1.2.1

    • GCC 3.3.3: GLIBCPP_3.2.3, CXXABI_1.2.1

    • GCC 3.4.0: GLIBCXX_3.4, CXXABI_1.3

    • GCC 3.4.1: GLIBCXX_3.4.1, CXXABI_1.3

    • GCC 3.4.2: GLIBCXX_3.4.2

    • GCC 3.4.3: GLIBCXX_3.4.3

    • GCC 4.0.0: GLIBCXX_3.4.4, CXXABI_1.3.1

    • GCC 4.0.1: GLIBCXX_3.4.5

    • GCC 4.0.2: GLIBCXX_3.4.6

    • GCC 4.0.3: GLIBCXX_3.4.7

    • GCC 4.1.1: GLIBCXX_3.4.8

    • GCC 4.2.0: GLIBCXX_3.4.9

    • GCC 4.3.0: GLIBCXX_3.4.10, CXXABI_1.3.2

    • GCC 4.4.0: GLIBCXX_3.4.11, CXXABI_1.3.3

    • GCC 4.4.1: GLIBCXX_3.4.12, CXXABI_1.3.3

    • GCC 4.4.2: GLIBCXX_3.4.13, CXXABI_1.3.3

    • GCC 4.5.0: GLIBCXX_3.4.14, CXXABI_1.3.4

    • GCC 4.6.0: GLIBCXX_3.4.15, CXXABI_1.3.5

    • GCC 4.6.1: GLIBCXX_3.4.16, CXXABI_1.3.5

    • GCC 4.7.0: GLIBCXX_3.4.17, CXXABI_1.3.6

    • GCC 4.8.0: GLIBCXX_3.4.18, CXXABI_1.3.7

    • GCC 4.8.3: GLIBCXX_3.4.19, CXXABI_1.3.7

    • GCC 4.9.0: GLIBCXX_3.4.20, CXXABI_1.3.8

    • GCC 5.1.0: GLIBCXX_3.4.21, CXXABI_1.3.9

    • GCC 6.1.0: GLIBCXX_3.4.22, CXXABI_1.3.10

    • GCC 7.1.0: GLIBCXX_3.4.23, CXXABI_1.3.11

    • GCC 7.2.0: GLIBCXX_3.4.24, CXXABI_1.3.11

    • GCC 8.1.0: GLIBCXX_3.4.25, CXXABI_1.3.11

    • GCC 9.1.0: GLIBCXX_3.4.26, CXXABI_1.3.12

    • GCC 9.2.0: GLIBCXX_3.4.27, CXXABI_1.3.12

    • GCC 9.3.0: GLIBCXX_3.4.28, CXXABI_1.3.12

    • GCC 10.1.0: GLIBCXX_3.4.28, CXXABI_1.3.12

    • GCC 11.1.0: GLIBCXX_3.4.29, CXXABI_1.3.13

    • GCC 12.1.0: GLIBCXX_3.4.30, CXXABI_1.3.13

    • GCC 13.1.0: GLIBCXX_3.4.31, CXXABI_1.3.13

  • Incremental bumping of a compiler pre-defined macro, __GXX_ABI_VERSION. This macro is defined as the version of the compiler v3 ABI, with g++ 3.0 being version 100. This macro will be automatically defined whenever g++ is used (the curious can diff --git a/libstdc++-v3/doc/xml/manual/abi.xml b/libstdc++-v3/doc/xml/manual/abi.xml index c2c0c02..0153395 100644 --- a/libstdc++-v3/doc/xml/manual/abi.xml +++ b/libstdc++-v3/doc/xml/manual/abi.xml @@ -348,6 +348,8 @@ compatible. GCC 9.3.0: GLIBCXX_3.4.28, CXXABI_1.3.12 GCC 10.1.0: GLIBCXX_3.4.28, CXXABI_1.3.12 GCC 11.1.0: GLIBCXX_3.4.29, CXXABI_1.3.13 + GCC 12.1.0: GLIBCXX_3.4.30, CXXABI_1.3.13 + GCC 13.1.0: GLIBCXX_3.4.31, CXXABI_1.3.13 -- cgit v1.1 From 64f9580423eef22b81a7e90be851c81dc6e04778 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 16 Sep 2022 11:36:41 +0100 Subject: libstdc++: Fix Doxygen commands Remove the bogus -D__allocator_base=std::__new_allocator macro definition for Doxygen, because that's an alias template for C++11 and later, not a macro. Fix the @cond/@endcond pair that span the end of an @addtogroup group. Add another @endcond inside the group, and another @cond after it. libstdc++-v3/ChangeLog: * doc/doxygen/user.cfg.in (PREDEFINED): Remove __allocator_base. * include/bits/allocator.h: Fix nesting of Doxygen commands. --- libstdc++-v3/doc/doxygen/user.cfg.in | 1 - libstdc++-v3/include/bits/allocator.h | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in index 57270bd..834ad9e 100644 --- a/libstdc++-v3/doc/doxygen/user.cfg.in +++ b/libstdc++-v3/doc/doxygen/user.cfg.in @@ -2407,7 +2407,6 @@ PREDEFINED = __cplusplus=202002L \ _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED \ _GLIBCXX_HAVE_BUILTIN_LAUNDER \ "_GLIBCXX_DOXYGEN_ONLY(X)=X " \ - __allocator_base=std::__new_allocator \ __exception_ptr=__unspecified__ \ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h index aec0b37..28abf13 100644 --- a/libstdc++-v3/include/bits/allocator.h +++ b/libstdc++-v3/include/bits/allocator.h @@ -265,6 +265,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Tp value_type; template allocator(const allocator<_Up>&) { } }; + /// @endcond /// @} group allocator @@ -278,6 +279,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Undefine. #undef __allocator_base + /// @cond undocumented + // To implement Option 3 of DR 431. template struct __alloc_swap -- cgit v1.1 From 15943285867a6952dbc5a603c434e61bfe32296f Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 16 Sep 2022 11:39:41 +0100 Subject: libstdc++: Remove __alloc_neq helper This class template and partial specialization were added 15 years ago to optimize allocator equality comparisons in std::list. I think it's safe to assume that GCC is now capable of optimizing an inline operator!= that just returns false at least as well as an inline member function that just returns false. libstdc++-v3/ChangeLog: * include/bits/allocator.h (__alloc_neq): Remove. * include/bits/stl_list.h (list::_M_check_equal_allocators): Compare allocators directly, without __alloc_neq. --- libstdc++-v3/include/bits/allocator.h | 17 ----------------- libstdc++-v3/include/bits/stl_list.h | 5 ++--- 2 files changed, 2 insertions(+), 20 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h index 28abf13..c39166e 100644 --- a/libstdc++-v3/include/bits/allocator.h +++ b/libstdc++-v3/include/bits/allocator.h @@ -298,23 +298,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; - // Optimize for stateless allocators. - template - struct __alloc_neq - { - static bool - _S_do_it(const _Alloc&, const _Alloc&) - { return false; } - }; - - template - struct __alloc_neq<_Alloc, false> - { - static bool - _S_do_it(const _Alloc& __one, const _Alloc& __two) - { return __one != __two; } - }; - #if __cplusplus >= 201103L template, diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index b8bd461..a73ca60 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -2026,10 +2026,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 // To implement the splice (and merge) bits of N1599. void - _M_check_equal_allocators(list& __x) _GLIBCXX_NOEXCEPT + _M_check_equal_allocators(const list& __x) _GLIBCXX_NOEXCEPT { - if (std::__alloc_neq:: - _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator())) + if (_M_get_Node_allocator() != __x._M_get_Node_allocator()) __builtin_abort(); } -- cgit v1.1 From 5ad435f2a0d29486c917025dfa239b9b88c35a09 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 16 Sep 2022 14:27:43 +0100 Subject: libstdc++: Do not use nullptr in C++03-compatible code This has to be valid as C++98/C++03. libstdc++-v3/ChangeLog: * include/debug/formatter.h [_GLIBCXX_DEBUG_BACKTRACE] (_Error_formatter): Use 0 as null pointer constant. --- libstdc++-v3/include/debug/formatter.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h index b4b7238..f120163 100644 --- a/libstdc++-v3/include/debug/formatter.h +++ b/libstdc++-v3/include/debug/formatter.h @@ -609,8 +609,7 @@ namespace __gnu_debug , _M_function(__function) #if _GLIBCXX_HAVE_STACKTRACE # ifdef _GLIBCXX_DEBUG_BACKTRACE - , _M_backtrace_state( - __glibcxx_backtrace_create_state(nullptr, 0, nullptr, nullptr)) + , _M_backtrace_state(__glibcxx_backtrace_create_state(0, 0, 0, 0)) , _M_backtrace_full(&__glibcxx_backtrace_full) # else , _M_backtrace_state() -- cgit v1.1 From b6adc6255f527edd50c08c4aacb4ee21df1c349c Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 16 Sep 2022 15:40:06 +0100 Subject: libstdc++: Fix tr1::variate_generator::engine_value_type The tr1/5_numerical_facilities/random/variate_generator/37986.cc test fails for strict -std=c++98 mode because _Adaptor(const _Engine&) is ill-formed in C++98 when _Engine is a reference type. Rather than attempt to make the _Adaptor handle references and pointers, just strip references and pointers from the _Engine type before we adapt it. That removes the need for the _Adaptor<_Engine*> partial specialization and avoids the reference-to-reference problem for c++98 mode. While looking into this I noticed that the TR1 spec requires the variate_generator::engine_value_type to be the underlying engine type, whereas we make it the _Adaptor type that wraps the engine. libstdc++-v3/ChangeLog: * include/tr1/random.h (__detail::_Adaptor::_BEngine): Remove. (__detail::_Adaptor::_M_g): Make public. (__detail::_Adaptor<_Engine*, _Dist>): Remove partial specialization. (variate_generate::_Value): New helper to simplify handling of _Engine* and _Engine& template arguments. (variate_generate::engine_value_type): Define to underlying engine type, not adapted type. (variate_generate::engine()): Return underlying engine instead of adaptor. * testsuite/tr1/5_numerical_facilities/random/variate_generator/37986.cc: Fix comment. * testsuite/tr1/5_numerical_facilities/random/variate_generator/requirements/typedefs.cc: Check member typedefs have the correct types. --- libstdc++-v3/include/tr1/random.h | 115 +++++++-------------- .../random/variate_generator/37986.cc | 2 +- .../variate_generator/requirements/typedefs.cc | 49 +++++++-- 3 files changed, 83 insertions(+), 83 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/tr1/random.h b/libstdc++-v3/include/tr1/random.h index 535f142..6061649 100644 --- a/libstdc++-v3/include/tr1/random.h +++ b/libstdc++-v3/include/tr1/random.h @@ -81,9 +81,8 @@ namespace tr1 template struct _Adaptor { - typedef typename remove_reference<_Engine>::type _BEngine; - typedef typename _BEngine::result_type _Engine_result_type; - typedef typename _Distribution::input_type result_type; + typedef typename _Engine::result_type _Engine_result_type; + typedef typename _Distribution::input_type result_type; public: _Adaptor(const _Engine& __g) @@ -146,72 +145,8 @@ namespace tr1 return __return_value; } - private: _Engine _M_g; }; - - // Specialization for _Engine*. - template - struct _Adaptor<_Engine*, _Distribution> - { - typedef typename _Engine::result_type _Engine_result_type; - typedef typename _Distribution::input_type result_type; - - public: - _Adaptor(_Engine* __g) - : _M_g(__g) { } - - result_type - min() const - { - result_type __return_value; - if (is_integral<_Engine_result_type>::value - && is_integral::value) - __return_value = _M_g->min(); - else - __return_value = result_type(0); - return __return_value; - } - - result_type - max() const - { - result_type __return_value; - if (is_integral<_Engine_result_type>::value - && is_integral::value) - __return_value = _M_g->max(); - else if (!is_integral::value) - __return_value = result_type(1); - else - __return_value = std::numeric_limits::max() - 1; - return __return_value; - } - - result_type - operator()() - { - result_type __return_value; - if (is_integral<_Engine_result_type>::value - && is_integral::value) - __return_value = (*_M_g)(); - else if (!is_integral<_Engine_result_type>::value - && !is_integral::value) - __return_value = result_type((*_M_g)() - _M_g->min()) - / result_type(_M_g->max() - _M_g->min()); - else if (is_integral<_Engine_result_type>::value - && !is_integral::value) - __return_value = result_type((*_M_g)() - _M_g->min()) - / result_type(_M_g->max() - _M_g->min() + result_type(1)); - else - __return_value = ((((*_M_g)() - _M_g->min()) - / (_M_g->max() - _M_g->min())) - * std::numeric_limits::max()); - return __return_value; - } - - private: - _Engine* _M_g; - }; } // namespace __detail /** @@ -223,17 +158,45 @@ namespace tr1 template class variate_generator { - // Concept requirements. - __glibcxx_class_requires(_Engine, _CopyConstructibleConcept) - // __glibcxx_class_requires(_Engine, _EngineConcept) - // __glibcxx_class_requires(_Dist, _EngineConcept) + template + struct _Value + { + typedef _Eng type; + + static const _Eng& + _S_ref(const _Eng& __e) { return __e; } + }; + + template + struct _Value<_Eng*> + { + typedef _Eng type; + + __attribute__((__nonnull__)) + static const _Eng& + _S_ref(const _Eng* __e) { return *__e; } + }; + + template + struct _Value<_Eng&> + { + typedef _Eng type; + + static const _Eng& + _S_ref(const _Eng& __e) { return __e; } + }; public: typedef _Engine engine_type; - typedef __detail::_Adaptor<_Engine, _Dist> engine_value_type; + typedef typename _Value<_Engine>::type engine_value_type; typedef _Dist distribution_type; typedef typename _Dist::result_type result_type; + // Concept requirements. + __glibcxx_class_requires(engine_value_type, _CopyConstructibleConcept) + // __glibcxx_class_requires(_Engine, _EngineConcept) + // __glibcxx_class_requires(_Dist, _EngineConcept) + // tr1:5.1.1 table 5.1 requirement typedef typename __gnu_cxx::__enable_if< is_arithmetic::value, result_type>::__type _IsValidType; @@ -246,7 +209,7 @@ namespace tr1 * the @p _Engine or @p _Dist objects. */ variate_generator(engine_type __eng, distribution_type __dist) - : _M_engine(__eng), _M_dist(__dist) { } + : _M_engine(_Value<_Engine>::_S_ref(__eng)), _M_dist(__dist) { } /** * Gets the next generated value on the distribution. @@ -269,7 +232,7 @@ namespace tr1 */ engine_value_type& engine() - { return _M_engine; } + { return _M_engine._M_g; } /** * Gets a const reference to the underlying uniform random number @@ -277,7 +240,7 @@ namespace tr1 */ const engine_value_type& engine() const - { return _M_engine; } + { return _M_engine._M_g; } /** * Gets a reference to the underlying random distribution. @@ -308,7 +271,7 @@ namespace tr1 { return this->distribution().max(); } private: - engine_value_type _M_engine; + __detail::_Adaptor _M_engine; distribution_type _M_dist; }; diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/37986.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/37986.cc index 5eeccf0..a130947 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/37986.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/37986.cc @@ -21,7 +21,7 @@ #include -// libtsdc++/37986 +// libstdc++/37986 void test01() { std::tr1::mt19937 mt; diff --git a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/requirements/typedefs.cc b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/requirements/typedefs.cc index 0bdb610..a71c8ddf 100644 --- a/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/tr1/5_numerical_facilities/random/variate_generator/requirements/typedefs.cc @@ -23,19 +23,56 @@ #include +template struct require_same; // not defined +template struct require_same { }; + +typedef std::tr1::linear_congruential E; +typedef std::tr1::uniform_int D; + void test01() { - using namespace std::tr1; + typedef std::tr1::variate_generator test_type; + + typedef test_type::engine_type engine_type; + typedef test_type::engine_value_type engine_value_type; + typedef test_type::distribution_type distribution_type; + typedef test_type::result_type result_type; + + require_same check_e; + require_same check_ev; + require_same check_d; + require_same check_r; +} + +void +test02() +{ + typedef std::tr1::variate_generator test_type; - typedef variate_generator - < - linear_congruential, - uniform_int - > test_type; + typedef test_type::engine_type engine_type; + typedef test_type::engine_value_type engine_value_type; + typedef test_type::distribution_type distribution_type; + typedef test_type::result_type result_type; + + require_same check_e; + require_same check_ev; + require_same check_d; + require_same check_r; +} + +void +test03() +{ + typedef std::tr1::variate_generator test_type; typedef test_type::engine_type engine_type; typedef test_type::engine_value_type engine_value_type; typedef test_type::distribution_type distribution_type; typedef test_type::result_type result_type; + + require_same check_e; + require_same check_ev; + require_same check_d; + require_same check_r; } -- cgit v1.1 From 47deb1ef874c078ac51bc1970a3324f5c8002815 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 16 Sep 2022 17:50:21 +0100 Subject: libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref This test was written assuming that std::atomic_ref clears its target's padding on construction, but that could introduce data races. Change the test to store a value after construction and check that its padding is cleared by the store. libstdc++-v3/ChangeLog: * testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc: Store value with non-zero padding bits after construction. --- .../29_atomics/atomic_ref/compare_exchange_padding.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc index 1b1a12d..e9f8a4b 100644 --- a/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc +++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc @@ -20,14 +20,15 @@ int main () { S s; - fill_struct(s); - s.c = 'a'; - s.s = 42; - S ss{ s }; + fill_struct(ss); + ss.c = 'a'; + ss.s = 42; + std::atomic_ref as{ s }; + as.store(ss); auto ts = as.load(); - VERIFY( !compare_struct(ss, ts) ); // padding cleared on construction + VERIFY( !compare_struct(ss, ts) ); // padding cleared on store as.exchange(ss); auto es = as.load(); VERIFY( compare_struct(ts, es) ); // padding cleared on exchange -- cgit v1.1 From d31e19e44009ef645f0a120043c7f84d0450b4c9 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 16 Sep 2022 10:49:54 +0100 Subject: libstdc++: Make more internal headers include their own dependencies This adds required headers to a few internal headers that currently assume their deps will be included first. It's more robust to make them include their own dependencies, so that later refactoring or reuse of those headers in new contexts doesn't break. libstdc++-v3/ChangeLog: * include/bits/stl_algo.h: Include . * include/bits/stl_tempbuf.h: Include headers for __try and __catch macros, std::pair, and __gnu_cxx::__numeric_traits. * include/bits/stream_iterator.h: Include and headers for std::addressof and std::iterator. * include/bits/streambuf_iterator.h: Include header for std::iterator. * include/std/iterator: Do not include . --- libstdc++-v3/include/bits/stl_algo.h | 1 + libstdc++-v3/include/bits/stl_tempbuf.h | 4 +++- libstdc++-v3/include/bits/stream_iterator.h | 3 +++ libstdc++-v3/include/bits/streambuf_iterator.h | 1 + libstdc++-v3/include/std/iterator | 1 - 5 files changed, 8 insertions(+), 2 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 57fa1c1..9cb708a 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -57,6 +57,7 @@ #define _STL_ALGO_H 1 #include +#include #include #include // for _Temporary_buffer #include diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h b/libstdc++-v3/include/bits/stl_tempbuf.h index 82f2dc8..b13aa3b 100644 --- a/libstdc++-v3/include/bits/stl_tempbuf.h +++ b/libstdc++-v3/include/bits/stl_tempbuf.h @@ -57,8 +57,10 @@ #define _STL_TEMPBUF_H 1 #include -#include +#include #include +#include +#include namespace std _GLIBCXX_VISIBILITY(default) { diff --git a/libstdc++-v3/include/bits/stream_iterator.h b/libstdc++-v3/include/bits/stream_iterator.h index 86c5845..0a1362a 100644 --- a/libstdc++-v3/include/bits/stream_iterator.h +++ b/libstdc++-v3/include/bits/stream_iterator.h @@ -32,6 +32,9 @@ #pragma GCC system_header +#include +#include +#include #include namespace std _GLIBCXX_VISIBILITY(default) diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 72344c6..c26ac24 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -33,6 +33,7 @@ #pragma GCC system_header #include +#include #include namespace std _GLIBCXX_VISIBILITY(default) diff --git a/libstdc++-v3/include/std/iterator b/libstdc++-v3/include/std/iterator index 7f8fc50..2da2fb6 100644 --- a/libstdc++-v3/include/std/iterator +++ b/libstdc++-v3/include/std/iterator @@ -61,7 +61,6 @@ #include #include #include -#include #include #include #include -- cgit v1.1 From 7f4c37099a9f2415e00e94379c1206b3e9185c52 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 16 Sep 2022 21:29:44 +0100 Subject: libstdc++: Move allocator-related helpers to The __alloc_swap and __shrink_to_fit_aux helpers are not specific to std::allocator, so don't belong in . This also simplifies enabling for freestanding, as now we can just omit the whole of for freestanding. libstdc++-v3/ChangeLog: * include/bits/alloc_traits.h (__alloc_swap) (__shrink_to_fit_aux): Move here, from ... * include/bits/allocator.h: ... here. * include/ext/alloc_traits.h: Do not include allocator.h. --- libstdc++-v3/include/bits/alloc_traits.h | 48 ++++++++++++++++++++++++++++++ libstdc++-v3/include/bits/allocator.h | 51 -------------------------------- libstdc++-v3/include/ext/alloc_traits.h | 3 -- 3 files changed, 48 insertions(+), 54 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h index f9ca37f..35bdf6e 100644 --- a/libstdc++-v3/include/bits/alloc_traits.h +++ b/libstdc++-v3/include/bits/alloc_traits.h @@ -824,6 +824,54 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @cond undocumented + // To implement Option 3 of DR 431. + template + struct __alloc_swap + { static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } }; + + template + struct __alloc_swap<_Alloc, false> + { + static void + _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT + { + // Precondition: swappable allocators. + if (__one != __two) + swap(__one, __two); + } + }; + +#if __cplusplus >= 201103L + template, + is_nothrow_move_constructible>::value> + struct __shrink_to_fit_aux + { static bool _S_do_it(_Tp&) noexcept { return false; } }; + + template + struct __shrink_to_fit_aux<_Tp, true> + { + _GLIBCXX20_CONSTEXPR + static bool + _S_do_it(_Tp& __c) noexcept + { +#if __cpp_exceptions + try + { + _Tp(__make_move_if_noexcept_iterator(__c.begin()), + __make_move_if_noexcept_iterator(__c.end()), + __c.get_allocator()).swap(__c); + return true; + } + catch(...) + { return false; } +#else + return false; +#endif + } + }; +#endif + /** * Destroy a range of objects using the supplied allocator. For * non-default allocators we do not optimize away invocation of diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h index c39166e..54f5acf 100644 --- a/libstdc++-v3/include/bits/allocator.h +++ b/libstdc++-v3/include/bits/allocator.h @@ -279,57 +279,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Undefine. #undef __allocator_base - /// @cond undocumented - - // To implement Option 3 of DR 431. - template - struct __alloc_swap - { static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } }; - - template - struct __alloc_swap<_Alloc, false> - { - static void - _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT - { - // Precondition: swappable allocators. - if (__one != __two) - swap(__one, __two); - } - }; - -#if __cplusplus >= 201103L - template, - is_nothrow_move_constructible>::value> - struct __shrink_to_fit_aux - { static bool _S_do_it(_Tp&) noexcept { return false; } }; - - template - struct __shrink_to_fit_aux<_Tp, true> - { - _GLIBCXX20_CONSTEXPR - static bool - _S_do_it(_Tp& __c) noexcept - { -#if __cpp_exceptions - try - { - _Tp(__make_move_if_noexcept_iterator(__c.begin()), - __make_move_if_noexcept_iterator(__c.end()), - __c.get_allocator()).swap(__c); - return true; - } - catch(...) - { return false; } -#else - return false; -#endif - } - }; -#endif - /// @endcond - _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/ext/alloc_traits.h b/libstdc++-v3/include/ext/alloc_traits.h index 1d7d959..c9547c7 100644 --- a/libstdc++-v3/include/ext/alloc_traits.h +++ b/libstdc++-v3/include/ext/alloc_traits.h @@ -32,9 +32,6 @@ #pragma GCC system_header # include -#if __cplusplus < 201103L -# include // for __alloc_swap -#endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { -- cgit v1.1 From cf0fded5d837bad590eb091d8a3dc4898872560f Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 15 Sep 2022 21:02:32 +0100 Subject: libstdc++: Add preprocessor conditions for freestanding [PR106953] This adds checks for _GLIBCXX_HOSTED to a number of headers which are not currently installed for freestanding, but need to be for P1642R11 support. For example, needs to be installed for C++23 freestanding mode, but without stream iterators and streambuf iterators. Similarly, needs to be installed, but without std::allocator and std::shared_ptr. This change disables the non-freestanding parts of those headers. libstdc++-v3/ChangeLog: PR libstdc++/106953 * include/backward/auto_ptr.h [!_GLIBCXX_HOSTED]: Do not define shared_ptr members. * include/bits/alloc_traits.h [!_GLIBCXX_HOSTED]: Do not declare std::allocator_traits> specializations for freestanding. * include/bits/memoryfwd.h [!_GLIBCXX_HOSTED] (allocator): Do not declare for freestanding. * include/bits/stl_algo.h [!_GLIBCXX_HOSTED] (stable_partition): Do not define for freestanding. [!_GLIBCXX_HOSTED] (merge, stable_sort): Do not use temporary buffers for freestanding. * include/bits/stl_algobase.h [!_GLIBCXX_HOSTED]: Do not declare streambuf iterators and overloaded algorithms using them. * include/bits/stl_uninitialized.h [!_GLIBCXX_HOSTED]: Do not define specialized overloads for std::allocator. * include/bits/unique_ptr.h [!_GLIBCXX_HOSTED] (make_unique) (make_unique_for_overwrite, operator<<): Do not define for freestanding. * include/c_global/cstdlib [!_GLIBCXX_HOSTED] (_Exit): Declare. Use _GLIBCXX_NOTHROW instead of throw(). * include/debug/assertions.h [!_GLIBCXX_HOSTED]: Ignore _GLIBCXX_DEBUG for freestanding. * include/debug/debug.h [!_GLIBCXX_DEBUG]: Likewise. * include/std/bit [!_GLIBCXX_HOSTED]: Do not use the custom __int_traits if is available. * include/std/functional [!_GLIBCXX_HOSTED]: Do not include headers that aren't valid for freestanding. (boyer_moore_searcher, boyer_moore_horspool_searcher): Do not define for freestanding. * include/std/iterator [!_GLIBCXX_HOSTED]: Do not include headers that aren't valid for freestanding. * include/std/memory [!_GLIBCXX_HOSTED]: Likewise. * include/std/ranges [!_GLIBCXX_HOSTED] (istream_view): Do not define for freestanding. (views::__detail::__is_basic_string_view) [!_GLIBCXX_HOSTED]: Do not define partial specialization for freestanding. --- libstdc++-v3/include/backward/auto_ptr.h | 4 +++- libstdc++-v3/include/bits/alloc_traits.h | 13 ++++++++++++- libstdc++-v3/include/bits/memoryfwd.h | 2 ++ libstdc++-v3/include/bits/stl_algo.h | 25 +++++++++++++++++++------ libstdc++-v3/include/bits/stl_algobase.h | 4 ++++ libstdc++-v3/include/bits/stl_uninitialized.h | 17 +++++++++++++---- libstdc++-v3/include/bits/unique_ptr.h | 14 ++++++++------ libstdc++-v3/include/c_global/cstdlib | 24 ++++++++++++++---------- libstdc++-v3/include/debug/assertions.h | 16 +++++++--------- libstdc++-v3/include/debug/debug.h | 2 +- libstdc++-v3/include/std/bit | 2 +- libstdc++-v3/include/std/functional | 22 ++++++++++++++-------- libstdc++-v3/include/std/iterator | 6 ++++-- libstdc++-v3/include/std/memory | 11 ++++++++--- libstdc++-v3/include/std/ranges | 4 ++++ 15 files changed, 114 insertions(+), 52 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/backward/auto_ptr.h b/libstdc++-v3/include/backward/auto_ptr.h index 184ab40..093db52 100644 --- a/libstdc++-v3/include/backward/auto_ptr.h +++ b/libstdc++-v3/include/backward/auto_ptr.h @@ -300,6 +300,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } _GLIBCXX11_DEPRECATED; #if __cplusplus >= 201103L +#if _GLIBCXX_HOSTED template<_Lock_policy _Lp> template inline @@ -325,13 +326,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline shared_ptr<_Tp>::shared_ptr(std::auto_ptr<_Tp1>&& __r) : __shared_ptr<_Tp>(std::move(__r)) { } +#endif // HOSTED template template inline unique_ptr<_Tp, _Dp>::unique_ptr(auto_ptr<_Up>&& __u) noexcept : _M_t(__u.release(), deleter_type()) { } -#endif +#endif // C++11 #pragma GCC diagnostic pop diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h index 35bdf6e..507e8f1 100644 --- a/libstdc++-v3/include/bits/alloc_traits.h +++ b/libstdc++-v3/include/bits/alloc_traits.h @@ -33,9 +33,11 @@ #include #include #if __cplusplus >= 201103L -# include # include # include +# if _GLIBCXX_HOSTED +# include +# endif #endif namespace std _GLIBCXX_VISIBILITY(default) @@ -402,6 +404,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _S_select(__rhs, 0); } }; +#if _GLIBCXX_HOSTED + #if __cplusplus > 201703L # define __cpp_lib_constexpr_dynamic_alloc 201907L #endif @@ -660,6 +664,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION select_on_container_copy_construction(const allocator_type& __rhs) { return __rhs; } }; +#endif /// @cond undocumented #if __cplusplus < 201703L @@ -774,11 +779,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _Alloc::value_type const&>::type { }; +#if _GLIBCXX_HOSTED // std::allocator<_Tp> just requires CopyConstructible template struct __is_copy_insertable> : is_copy_constructible<_Tp> { }; +#endif // true if _Alloc::value_type is MoveInsertable into containers using _Alloc // (might be wrong if _Alloc::construct exists but is not constrained, @@ -788,11 +795,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type { }; +#if _GLIBCXX_HOSTED // std::allocator<_Tp> just requires MoveConstructible template struct __is_move_insertable> : is_move_constructible<_Tp> { }; +#endif // Trait to detect Allocator-like types. template @@ -893,6 +902,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif } +#if _GLIBCXX_HOSTED template _GLIBCXX20_CONSTEXPR inline void @@ -901,6 +911,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _Destroy(__first, __last); } +#endif /// @endcond _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/bits/memoryfwd.h b/libstdc++-v3/include/bits/memoryfwd.h index 751329c..ae164fa 100644 --- a/libstdc++-v3/include/bits/memoryfwd.h +++ b/libstdc++-v3/include/bits/memoryfwd.h @@ -60,11 +60,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ +#if _GLIBCXX_HOSTED template class allocator; template<> class allocator; +#endif #if __cplusplus >= 201103L /// Declare uses_allocator so it can be specialized in `` etc. diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 9cb708a..e63fe66 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -59,15 +59,17 @@ #include #include #include -#include // for _Temporary_buffer #include #if __cplusplus >= 201103L #include #endif -#if _GLIBCXX_HOSTED && (__cplusplus <= 201103L || _GLIBCXX_USE_DEPRECATED) -#include // for rand +#if _GLIBCXX_HOSTED +# include // for _Temporary_buffer +# if (__cplusplus <= 201103L || _GLIBCXX_USE_DEPRECATED) +# include // for rand +# endif #endif // See concept_check.h for the __glibcxx_*_requires macros. @@ -1492,6 +1494,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) } } +#if _GLIBCXX_HOSTED // partition /// This is a helper function... @@ -1617,6 +1620,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) return std::__stable_partition(__first, __last, __gnu_cxx::__ops::__pred_iter(__pred)); } +#endif // HOSTED /// @cond undocumented @@ -2527,7 +2531,6 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) _ValueType; typedef typename iterator_traits<_BidirectionalIterator>::difference_type _DistanceType; - typedef _Temporary_buffer<_BidirectionalIterator, _ValueType> _TmpBuf; if (__first == __middle || __middle == __last) return; @@ -2535,6 +2538,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) const _DistanceType __len1 = std::distance(__first, __middle); const _DistanceType __len2 = std::distance(__middle, __last); +#if _GLIBCXX_HOSTED + typedef _Temporary_buffer<_BidirectionalIterator, _ValueType> _TmpBuf; // __merge_adaptive will use a buffer for the smaller of // [first,middle) and [middle,last). _TmpBuf __buf(__first, std::min(__len1, __len2)); @@ -2549,6 +2554,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2) std::__merge_adaptive_resize (__first, __middle, __last, __len1, __len2, __buf.begin(), _DistanceType(__buf.size()), __comp); +#else + std::__merge_without_buffer + (__first, __middle, __last, __len1, __len2, __comp); +#endif } /** @@ -4585,7 +4594,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO std::iter_swap(__i, __j); } } -#endif +#endif // HOSTED /** * @brief Shuffle the elements of a sequence using a random number @@ -5017,11 +5026,12 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _ValueType; typedef typename iterator_traits<_RandomAccessIterator>::difference_type _DistanceType; - typedef _Temporary_buffer<_RandomAccessIterator, _ValueType> _TmpBuf; if (__first == __last) return; +#if _GLIBCXX_HOSTED + typedef _Temporary_buffer<_RandomAccessIterator, _ValueType> _TmpBuf; // __stable_sort_adaptive sorts the range in two halves, // so the buffer only needs to fit half the range at once. _TmpBuf __buf(__first, (__last - __first + 1) / 2); @@ -5035,6 +5045,9 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO else std::__stable_sort_adaptive_resize(__first, __last, __buf.begin(), _DistanceType(__buf.size()), __comp); +#else + std::__inplace_stable_sort(__first, __last, __comp); +#endif } /** diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index 84a1f9e..ae898ed 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -442,6 +442,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_CONTAINER +#if _GLIBCXX_HOSTED // Helpers for streambuf iterators (either istream or ostream). // NB: avoid including , relatively large. template @@ -479,6 +480,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER istreambuf_iterator<_CharT, char_traits<_CharT> >, istreambuf_iterator<_CharT, char_traits<_CharT> >, _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*>); +#endif // HOSTED template _GLIBCXX20_CONSTEXPR @@ -574,6 +576,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER return __result; } +#if _GLIBCXX_HOSTED template typename __gnu_cxx::__enable_if< __is_char<_CharT>::__value, _CharT*>::__type @@ -587,6 +590,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER __copy_n_a(istreambuf_iterator<_CharT, char_traits<_CharT> >, _Size, _GLIBCXX_STD_C::_Deque_iterator<_CharT, _CharT&, _CharT*>, bool); +#endif /** * @brief Copies the range [first,last) into result. diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index 7ed69f5..0b32074 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -359,6 +359,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +#if _GLIBCXX_HOSTED template _GLIBCXX20_CONSTEXPR inline _ForwardIterator @@ -371,6 +372,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif return std::uninitialized_copy(__first, __last, __result); } +#endif template @@ -418,6 +420,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +#if _GLIBCXX_HOSTED template _GLIBCXX20_CONSTEXPR inline void @@ -430,6 +433,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif std::uninitialized_fill(__first, __last, __x); } +#endif template @@ -453,6 +457,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +#if _GLIBCXX_HOSTED template _GLIBCXX20_CONSTEXPR @@ -466,7 +471,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif return std::uninitialized_fill_n(__first, __n, __x); } - +#endif // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, // __uninitialized_fill_move, __uninitialized_move_fill. @@ -725,13 +730,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +#if _GLIBCXX_HOSTED template inline void __uninitialized_default_a(_ForwardIterator __first, _ForwardIterator __last, allocator<_Tp>&) { std::__uninitialized_default(__first, __last); } - +#endif // __uninitialized_default_n_a // Fills [first, first + n) with value_types constructed by the allocator @@ -756,6 +762,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +#if _GLIBCXX_HOSTED // __uninitialized_default_n_a specialization for std::allocator, // which ignores the allocator and value-initializes the elements. template @@ -764,6 +771,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, allocator<_Tp>&) { return std::__uninitialized_default_n(__first, __n); } +#endif template struct __uninitialized_default_novalue_1 @@ -1094,6 +1102,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __cur; } +#if _GLIBCXX_HOSTED template _GLIBCXX20_CONSTEXPR inline __enable_if_t::value, _Tp*> @@ -1118,7 +1127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } return __result + __count; } - +#endif template @@ -1136,7 +1145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// @endcond -#endif +#endif // C++11 /// @} group memory diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index e1ad772..1086f40 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -36,9 +36,11 @@ #include #include #include -#if __cplusplus > 201703L +#if __cplusplus >= 202002L # include -# include +# if _GLIBCXX_HOSTED +# include +# endif #endif #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc @@ -1031,7 +1033,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public __uniq_ptr_hash> { }; -#if __cplusplus >= 201402L +#if __cplusplus >= 201402L && _GLIBCXX_HOSTED #define __cpp_lib_make_unique 201304L /// @cond undocumented @@ -1131,9 +1133,9 @@ namespace __detail make_unique_for_overwrite(_Args&&...) = delete; #endif // C++20 -#endif // C++14 +#endif // C++14 && HOSTED -#if __cplusplus > 201703L && __cpp_concepts +#if __cplusplus > 201703L && __cpp_concepts && _GLIBCXX_HOSTED // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2948. unique_ptr does not define operator<< for stream output /// Stream output operator for unique_ptr @@ -1148,7 +1150,7 @@ namespace __detail __os << __p.get(); return __os; } -#endif // C++20 +#endif // C++20 && HOSTED /// @} group pointer_abstractions diff --git a/libstdc++-v3/include/c_global/cstdlib b/libstdc++-v3/include/c_global/cstdlib index 8a832af..0f7362e 100644 --- a/libstdc++-v3/include/c_global/cstdlib +++ b/libstdc++-v3/include/c_global/cstdlib @@ -51,19 +51,23 @@ #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 +#define NULL __null namespace std { - extern "C" void abort(void) throw () _GLIBCXX_NORETURN; - extern "C" int atexit(void (*)(void)) throw (); - extern "C" void exit(int) throw () _GLIBCXX_NORETURN; + extern "C" void abort(void) _GLIBCXX_NOTHROW _GLIBCXX_NORETURN; + extern "C" int atexit(void (*)(void)) _GLIBCXX_NOTHROW; + extern "C" void exit(int) _GLIBCXX_NOTHROW _GLIBCXX_NORETURN; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT - extern "C" int at_quick_exit(void (*)(void)) throw (); + extern "C" int at_quick_exit(void (*)(void)) _GLIBCXX_NOTHROW; # endif # ifdef _GLIBCXX_HAVE_QUICK_EXIT - extern "C" void quick_exit(int) throw() _GLIBCXX_NORETURN; + extern "C" void quick_exit(int) _GLIBCXX_NOTHROW_GLIBCXX_NORETURN; # endif +#if _GLIBCXX_USE_C99_STDLIB + extern "C" void _Exit(int) _GLIBCXX_NOTHROW _GLIBCXX_NORETURN; +#endif #endif } // namespace std @@ -174,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO inline ldiv_t - div(long __i, long __j) { return ldiv(__i, __j); } + div(long __i, long __j) _GLIBCXX_NOTHROW { return ldiv(__i, __j); } #endif @@ -200,7 +204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::lldiv_t; #endif #if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC - extern "C" void (_Exit)(int) throw () _GLIBCXX_NORETURN; + extern "C" void (_Exit)(int) _GLIBCXX_NOTHROW _GLIBCXX_NORETURN; #endif #if !_GLIBCXX_USE_C99_DYNAMIC using ::_Exit; @@ -217,11 +221,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif #if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC - extern "C" long long int (atoll)(const char *) throw (); + extern "C" long long int (atoll)(const char *) _GLIBCXX_NOTHROW; extern "C" long long int - (strtoll)(const char * __restrict, char ** __restrict, int) throw (); + (strtoll)(const char * __restrict, char ** __restrict, int) _GLIBCXX_NOTHROW; extern "C" unsigned long long int - (strtoull)(const char * __restrict, char ** __restrict, int) throw (); + (strtoull)(const char * __restrict, char ** __restrict, int) _GLIBCXX_NOTHROW; #endif #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::atoll; diff --git a/libstdc++-v3/include/debug/assertions.h b/libstdc++-v3/include/debug/assertions.h index 57c0ab2..c3b5ad0 100644 --- a/libstdc++-v3/include/debug/assertions.h +++ b/libstdc++-v3/include/debug/assertions.h @@ -31,14 +31,6 @@ #include -#ifndef _GLIBCXX_DEBUG - -# define _GLIBCXX_DEBUG_ASSERT(_Condition) -# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) -# define _GLIBCXX_DEBUG_ONLY(_Statement) - -#endif - #ifndef _GLIBCXX_ASSERTIONS # define __glibcxx_requires_non_empty_range(_First,_Last) # define __glibcxx_requires_nonempty() @@ -55,7 +47,8 @@ __glibcxx_assert(!this->empty()) #endif -#ifdef _GLIBCXX_DEBUG +#if defined _GLIBCXX_DEBUG && _GLIBCXX_HOSTED + # define _GLIBCXX_DEBUG_ASSERT(_Condition) __glibcxx_assert(_Condition) # ifdef _GLIBCXX_DEBUG_PEDANTIC @@ -65,6 +58,11 @@ # endif # define _GLIBCXX_DEBUG_ONLY(_Statement) _Statement + +#else +# define _GLIBCXX_DEBUG_ASSERT(_Condition) +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +# define _GLIBCXX_DEBUG_ONLY(_Statement) #endif #endif // _GLIBCXX_DEBUG_ASSERTIONS diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h index f423376..78546d7 100644 --- a/libstdc++-v3/include/debug/debug.h +++ b/libstdc++-v3/include/debug/debug.h @@ -61,7 +61,7 @@ namespace __gnu_debug struct _Safe_iterator; } -#ifndef _GLIBCXX_DEBUG +#if ! defined _GLIBCXX_DEBUG || ! _GLIBCXX_HOSTED # define __glibcxx_requires_cond(_Cond,_Msg) # define __glibcxx_requires_valid_range(_First,_Last) diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit index ef19d64..2fd8018 100644 --- a/libstdc++-v3/include/std/bit +++ b/libstdc++-v3/include/std/bit @@ -35,7 +35,7 @@ #include -#if _GLIBCXX_HOSTED +#if _GLIBCXX_HOSTED || __has_include() # include #else # include diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 685a3e1..c4f7588 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -56,18 +56,22 @@ #include #include #include // std::reference_wrapper and _Mem_fn_traits -#include // std::function -#if __cplusplus > 201402L -# include -# include -# include -# include +#if _GLIBCXX_HOSTED +# include // std::function +#endif +#if __cplusplus >= 201703L +# if _GLIBCXX_HOSTED +# include +# include +# include +# endif +# include // std::search #endif #if __cplusplus > 201703L # include # include #endif -#if __cplusplus > 202002L +#if __cplusplus > 202002L && _GLIBCXX_HOSTED # include #endif @@ -238,7 +242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Trait that identifies a bind expression. - * + * * Determines if the given type `_Tp` is a function object that * should be treated as a subexpression when evaluating calls to * function objects returned by `std::bind`. @@ -1117,6 +1121,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple<_ForwardIterator1, _ForwardIterator1, _BinaryPredicate> _M_m; }; +#if _GLIBCXX_HOSTED template struct __boyer_moore_map_base { @@ -1359,6 +1364,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } return std::make_pair(__last, __last); } +#endif // HOSTED #endif // C++17 #endif // C++14 diff --git a/libstdc++-v3/include/std/iterator b/libstdc++-v3/include/std/iterator index 2da2fb6..fb2a47c 100644 --- a/libstdc++-v3/include/std/iterator +++ b/libstdc++-v3/include/std/iterator @@ -61,8 +61,10 @@ #include #include #include -#include -#include +#if _GLIBCXX_HOSTED +# include +# include +#endif #include #if __cplusplus >= 201402L && ! defined _GLIBCXX_DEBUG // PR libstdc++/70303 diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory index 20a5502..3eff121 100644 --- a/libstdc++-v3/include/std/memory +++ b/libstdc++-v3/include/std/memory @@ -60,7 +60,10 @@ * Smart pointers, etc. */ -#include +#include +#if _GLIBCXX_HOSTED +# include +#endif #include #include #include @@ -73,8 +76,10 @@ # include # include # include +# if _GLIBCXX_HOSTED # include # include +# endif #endif #if __cplusplus < 201103L || _GLIBCXX_USE_DEPRECATED @@ -86,7 +91,7 @@ # include #endif -#if __cplusplus >= 201103L && __cplusplus <= 202002L +#if __cplusplus >= 201103L && __cplusplus <= 202002L && _GLIBCXX_HOSTED namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -133,7 +138,7 @@ _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 to C++20 -#if __cplusplus >= 201703L +#if __cplusplus >= 201703L && _GLIBCXX_HOSTED // Parallel STL algorithms # if _PSTL_EXECUTION_POLICIES_DEFINED // If has already been included, pull in implementations diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 53093a3..c2eacde 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -701,6 +701,7 @@ namespace views inline constexpr _Iota iota{}; } // namespace views +#if _GLIBCXX_HOSTED namespace __detail { template @@ -804,6 +805,7 @@ namespace views template inline constexpr _Istream<_Tp> istream; } +#endif // HOSTED // C++20 24.7 [range.adaptors] Range adaptors @@ -2234,9 +2236,11 @@ namespace views::__adaptor template inline constexpr bool __is_basic_string_view = false; +#if _GLIBCXX_HOSTED template inline constexpr bool __is_basic_string_view> = true; +#endif template inline constexpr bool __is_subrange = false; -- cgit v1.1 From 7ee0fa100f0f28d7b88237d520131e07b7b49f0a Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 17 Sep 2022 00:17:20 +0000 Subject: Daily bump. --- libstdc++-v3/ChangeLog | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 392a522..a55293e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,105 @@ +2022-09-16 Jonathan Wakely + + PR libstdc++/106953 + * include/backward/auto_ptr.h [!_GLIBCXX_HOSTED]: Do not define + shared_ptr members. + * include/bits/alloc_traits.h [!_GLIBCXX_HOSTED]: Do not declare + std::allocator_traits> specializations for + freestanding. + * include/bits/memoryfwd.h [!_GLIBCXX_HOSTED] (allocator): Do + not declare for freestanding. + * include/bits/stl_algo.h [!_GLIBCXX_HOSTED] (stable_partition): + Do not define for freestanding. + [!_GLIBCXX_HOSTED] (merge, stable_sort): Do not use temporary + buffers for freestanding. + * include/bits/stl_algobase.h [!_GLIBCXX_HOSTED]: Do not declare + streambuf iterators and overloaded algorithms using them. + * include/bits/stl_uninitialized.h [!_GLIBCXX_HOSTED]: Do not + define specialized overloads for std::allocator. + * include/bits/unique_ptr.h [!_GLIBCXX_HOSTED] (make_unique) + (make_unique_for_overwrite, operator<<): Do not define for + freestanding. + * include/c_global/cstdlib [!_GLIBCXX_HOSTED] (_Exit): Declare. + Use _GLIBCXX_NOTHROW instead of throw(). + * include/debug/assertions.h [!_GLIBCXX_HOSTED]: Ignore + _GLIBCXX_DEBUG for freestanding. + * include/debug/debug.h [!_GLIBCXX_DEBUG]: Likewise. + * include/std/bit [!_GLIBCXX_HOSTED]: Do not use the custom + __int_traits if is available. + * include/std/functional [!_GLIBCXX_HOSTED]: Do not include + headers that aren't valid for freestanding. + (boyer_moore_searcher, boyer_moore_horspool_searcher): Do not + define for freestanding. + * include/std/iterator [!_GLIBCXX_HOSTED]: Do not include + headers that aren't valid for freestanding. + * include/std/memory [!_GLIBCXX_HOSTED]: Likewise. + * include/std/ranges [!_GLIBCXX_HOSTED] (istream_view): Do not + define for freestanding. + (views::__detail::__is_basic_string_view) [!_GLIBCXX_HOSTED]: + Do not define partial specialization for freestanding. + +2022-09-16 Jonathan Wakely + + * include/bits/alloc_traits.h (__alloc_swap) + (__shrink_to_fit_aux): Move here, from ... + * include/bits/allocator.h: ... here. + * include/ext/alloc_traits.h: Do not include allocator.h. + +2022-09-16 Jonathan Wakely + + * include/bits/stl_algo.h: Include . + * include/bits/stl_tempbuf.h: Include headers for __try and + __catch macros, std::pair, and __gnu_cxx::__numeric_traits. + * include/bits/stream_iterator.h: Include and headers + for std::addressof and std::iterator. + * include/bits/streambuf_iterator.h: Include header for + std::iterator. + * include/std/iterator: Do not include . + +2022-09-16 Jonathan Wakely + + * testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc: + Store value with non-zero padding bits after construction. + +2022-09-16 Jonathan Wakely + + * include/tr1/random.h (__detail::_Adaptor::_BEngine): Remove. + (__detail::_Adaptor::_M_g): Make public. + (__detail::_Adaptor<_Engine*, _Dist>): Remove partial + specialization. + (variate_generate::_Value): New helper to simplify handling of + _Engine* and _Engine& template arguments. + (variate_generate::engine_value_type): Define to underlying + engine type, not adapted type. + (variate_generate::engine()): Return underlying engine instead + of adaptor. + * testsuite/tr1/5_numerical_facilities/random/variate_generator/37986.cc: + Fix comment. + * testsuite/tr1/5_numerical_facilities/random/variate_generator/requirements/typedefs.cc: + Check member typedefs have the correct types. + +2022-09-16 Jonathan Wakely + + * include/debug/formatter.h [_GLIBCXX_DEBUG_BACKTRACE] + (_Error_formatter): Use 0 as null pointer constant. + +2022-09-16 Jonathan Wakely + + * include/bits/allocator.h (__alloc_neq): Remove. + * include/bits/stl_list.h (list::_M_check_equal_allocators): + Compare allocators directly, without __alloc_neq. + +2022-09-16 Jonathan Wakely + + * doc/doxygen/user.cfg.in (PREDEFINED): Remove __allocator_base. + * include/bits/allocator.h: Fix nesting of Doxygen commands. + +2022-09-16 Jonathan Wakely + + * doc/xml/manual/abi.xml: Document GLIBCXX_3.4.30 and + GLIBCXX_3.4.31 versions. + * doc/html/manual/abi.html: Regenerate. + 2022-09-15 Jonathan Wakely * include/std/memory: Do not include . -- cgit v1.1