commit aca60ecff35837a1af9383cf67ee7d1c0a718b28 Author: Jonathan Wakely Date: Wed Feb 19 12:30:10 2020 +0000 libstdc++: Add ranges_size_t and rename all_view (LWG 3335) * include/bits/range_access.h (range_size_t): Define alias template. * include/std/ranges (all_view): Rename to views::all_t (LWG 3335). * testsuite/std/ranges/adaptors/filter.cc: Adjust to new name. diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9ccba4345d5..f01b78da118 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,9 @@ 2020-02-19 Jonathan Wakely + * include/bits/range_access.h (range_size_t): Define alias template. + * include/std/ranges (all_view): Rename to views::all_t (LWG 3335). + * testsuite/std/ranges/adaptors/filter.cc: Adjust to new name. + * include/std/ranges (filter_view, transform_view, take_view) (join_view, split_view, reverse_view): Remove commented-out converting constructors (LWG 3280). diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h index e2a2c28c7d2..e7a19305d23 100644 --- a/libstdc++-v3/include/bits/range_access.h +++ b/libstdc++-v3/include/bits/range_access.h @@ -905,6 +905,9 @@ namespace ranges concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); }; + template + using range_size_t = decltype(ranges::size(std::declval<_Range&>())); + // [range.refinements] /// A range for which ranges::begin returns an output iterator. diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index cf4c19ffaab..b0806750a08 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -1236,10 +1236,11 @@ namespace views else return subrange{std::forward<_Range>(__r)}; }; - } // namespace views - template - using all_view = decltype(views::all(declval<_Range>())); + template + using all_t = decltype(all(std::declval<_Range>())); + + } // namespace views // XXX: the following algos are copied from ranges_algo.h to avoid a circular // dependency with that header. @@ -1503,7 +1504,7 @@ namespace views }; template - filter_view(_Range&&, _Pred) -> filter_view, _Pred>; + filter_view(_Range&&, _Pred) -> filter_view, _Pred>; namespace views { @@ -1836,7 +1837,7 @@ namespace views }; template - transform_view(_Range&&, _Fp) -> transform_view, _Fp>; + transform_view(_Range&&, _Fp) -> transform_view, _Fp>; namespace views { @@ -1974,7 +1975,7 @@ namespace views template take_view(_Range&&, range_difference_t<_Range>) - -> take_view>; + -> take_view>; namespace views { @@ -2066,7 +2067,7 @@ namespace views template take_while_view(_Range&&, _Pred) - -> take_while_view, _Pred>; + -> take_while_view, _Pred>; namespace views { @@ -2143,7 +2144,7 @@ namespace views template drop_view(_Range&&, range_difference_t<_Range>) - -> drop_view>; + -> drop_view>; namespace views { @@ -2199,7 +2200,7 @@ namespace views template drop_while_view(_Range&&, _Pred) - -> drop_while_view, _Pred>; + -> drop_while_view, _Pred>; namespace views { @@ -2450,7 +2451,7 @@ namespace views // XXX: _M_inner is "present only when !is_reference_v<_InnerRange>" [[no_unique_address]] conditional_t, - all_view<_InnerRange>, __detail::_Empty> _M_inner; + views::all_t<_InnerRange>, __detail::_Empty> _M_inner; public: join_view() = default; @@ -2514,7 +2515,7 @@ namespace views }; template - explicit join_view(_Range&&) -> join_view>; + explicit join_view(_Range&&) -> join_view>; namespace views { @@ -2838,7 +2839,7 @@ namespace views { } template - requires constructible_from<_Vp, all_view<_Range>> + requires constructible_from<_Vp, views::all_t<_Range>> && constructible_from<_Pattern, single_view>> constexpr split_view(_Range&& __r, range_value_t<_Range> __e) @@ -2893,11 +2894,11 @@ namespace views template split_view(_Range&&, _Pred&&) - -> split_view, all_view<_Pred>>; + -> split_view, views::all_t<_Pred>>; template split_view(_Range&&, range_value_t<_Range>) - -> split_view, single_view>>; + -> split_view, single_view>>; namespace views { @@ -2945,7 +2946,7 @@ namespace views /* XXX: LWG 3280 didn't remove this constructor, but I think it should? template requires (!common_range<_Range>) - && constructible_from<_Vp, all_view<_Range>> + && constructible_from<_Vp, views::all_t<_Range>> constexpr explicit common_view(_Range&& __r) : _M_base(views::all(std::forward<_Range>(__r))) @@ -3010,7 +3011,7 @@ namespace views }; template - common_view(_Range&&) -> common_view>; + common_view(_Range&&) -> common_view>; namespace views { @@ -3083,7 +3084,7 @@ namespace views }; template - reverse_view(_Range&&) -> reverse_view>; + reverse_view(_Range&&) -> reverse_view>; namespace views { @@ -3356,10 +3357,10 @@ namespace views }; template - using keys_view = elements_view, 0>; + using keys_view = elements_view, 0>; template - using values_view = elements_view, 1>; + using values_view = elements_view, 1>; namespace views { @@ -3367,7 +3368,8 @@ namespace views inline constexpr __adaptor::_RangeAdaptorClosure elements = [] (_Range&& __r) { - return elements_view, _Nm>{std::forward<_Range>(__r)}; + using _El = elements_view, _Nm>; + return _El{std::forward<_Range>(__r)}; }; inline constexpr __adaptor::_RangeAdaptorClosure keys = elements<0>; diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/filter.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/filter.cc index 4edbf0b657d..4e41232cd5c 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/filter.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/filter.cc @@ -43,7 +43,7 @@ test01() static_assert(!ranges::sized_range); static_assert(ranges::bidirectional_range); static_assert(!ranges::random_access_range); - static_assert(ranges::range>); + static_assert(ranges::range>); VERIFY( ranges::equal(v, (int[]){1,3,5}) ); VERIFY( ranges::equal(v | views::reverse, (int[]){5,3,1}) ); VERIFY( v.pred()(3) == true ); commit 4cc3b275d310dbf5982544cb88c11630349f414c Author: Jonathan Wakely Date: Wed Feb 19 12:26:19 2020 +0000 libstdc++: Remove converting constructors from views (LWG 3280) * include/std/ranges (filter_view, transform_view, take_view) (join_view, split_view, reverse_view): Remove commented-out converting constructors (LWG 3280). diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 5408a89c7fb..9ccba4345d5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,9 @@ 2020-02-19 Jonathan Wakely + * include/std/ranges (filter_view, transform_view, take_view) + (join_view, split_view, reverse_view): Remove commented-out converting + constructors (LWG 3280). + * include/std/memory (uninitialized_construct_using_allocator): Use std::construct_at (LWG 3321). diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 4bfda88c319..cf4c19ffaab 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -1470,17 +1470,6 @@ namespace views : _M_base(std::move(__base)), _M_pred(std::move(__pred)) { } - /* XXX: P3280 removes this constructor - template - requires viewable_range<_Range> - && constructible_from<_Vp, all_view<_Range>> - constexpr - filter_view(_Range&& __r, _Pred __pred) - : _M_base(views::all(std::forward<_Range>(__r))), - _M_pred(std::move(__pred)) - { } - */ - constexpr _Vp base() const& requires copy_constructible<_Vp> { return _M_base; } @@ -1799,17 +1788,6 @@ namespace views : _M_base(std::move(__base)), _M_fun(std::move(__fun)) { } - /* XXX: P3280 removes this constructor - template - requires viewable_range<_Range> - && constructible_from<_Vp, all_view<_Range>> - constexpr - transform_view(_Range&& __r, _Fp __fun) - : _M_base(views::all(std::forward<_Range>(__r))) - { - } - */ - constexpr _Vp base() const& requires copy_constructible<_Vp> { return _M_base ; } @@ -1915,15 +1893,6 @@ namespace views : _M_base(std::move(base)), _M_count(std::move(__count)) { } - /* XXX: P3280 removes this constructor - template - requires constructible_from<_Vp, all_view<_Range>> - constexpr - take_view(_Range&& __r, range_difference_t<_Vp> __count) - : _M_base(views::all(std::forward<_Range>(__r))), _M_count(__count) - { } - */ - constexpr _Vp base() const& requires copy_constructible<_Vp> { return _M_base; } @@ -2491,16 +2460,6 @@ namespace views : _M_base(std::move(__base)) { } - /* XXX: P3280 removes this constructor - template - requires viewable_range<_Range> - && constructible_from<_Vp, all_view<_Range>> - constexpr explicit - join_view(_Range&& __r) - : _M_base(views::all(std::forward<_Range>(__r))) - { } - */ - constexpr _Vp base() const& requires copy_constructible<_Vp> { return _M_base; } @@ -2878,17 +2837,6 @@ namespace views : _M_base(std::move(__base)), _M_pattern(std::move(__pattern)) { } - /* XXX: P3280 removes this constructor - template - requires constructible_from<_Vp, all_view<_Range>> - && constructible_from<_Pattern, all_view<_Pred>> - constexpr - split_view(_Range&& __r, _Pred&& __p) - : _M_base(views::all(std::forward<_Range>(__r))), - _M_pattern(views::all(std::forward<_Pred>(__p))) - { } - */ - template requires constructible_from<_Vp, all_view<_Range>> && constructible_from<_Pattern, single_view>> @@ -2994,14 +2942,15 @@ namespace views : _M_base(std::move(__r)) { } - /* XXX: P3280 doesn't remove this constructor, but I think it should? + /* XXX: LWG 3280 didn't remove this constructor, but I think it should? template - requires (!common_range<_Range>) && constructible_from<_Vp, all_view<_Range>> + requires (!common_range<_Range>) + && constructible_from<_Vp, all_view<_Range>> constexpr explicit common_view(_Range&& __r) : _M_base(views::all(std::forward<_Range>(__r))) { } - */ + */ constexpr _Vp base() const& requires copy_constructible<_Vp> @@ -3092,15 +3041,6 @@ namespace views : _M_base(std::move(__r)) { } - /* XXX: P3280 removes this constructor - template - requires bidirectional_range<_Range> && constructible_from<_Vp, all_view<_Range>> - constexpr explicit - reverse_view(_Range&& __r) - : _M_base(views::all(std::forward<_Range>(__r))) - { } - */ - constexpr _Vp base() const& requires copy_constructible<_Vp> { return _M_base; } commit 5f3641d0c430523d839298a6876f907523811485 Author: Jonathan Wakely Date: Wed Feb 19 12:14:54 2020 +0000 libstdc++: uninitialized_construct_using_allocator should use construct_at (LWG 3321) * include/std/memory (uninitialized_construct_using_allocator): Use std::construct_at (LWG 3321). diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index eb83c632adc..5408a89c7fb 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,8 @@ 2020-02-19 Jonathan Wakely + * include/std/memory (uninitialized_construct_using_allocator): Use + std::construct_at (LWG 3321). + * include/std/memory_resource (polymorphic_allocator::allocate_bytes) (polymorphic_allocator::allocate_object) (polymorphic_allocator::new_object): Add nodiscard attribute (LWG3304). diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory index 14aedb70dac..aaee6e42c1a 100644 --- a/libstdc++-v3/include/std/memory +++ b/libstdc++-v3/include/std/memory @@ -387,9 +387,10 @@ get_pointer_safety() noexcept { return pointer_safety::relaxed; } uninitialized_construct_using_allocator(_Tp* __p, const _Alloc& __a, _Args&&... __args) { - void* __vp = const_cast(static_cast(__p)); - return ::new(__vp) _Tp(std::make_obj_using_allocator<_Tp>(__a, - std::forward<_Args>(__args)...)); + return std::apply([&](auto&&... __xs) { + return std::construct_at(__p, std::forward(__xs)...); + }, std::uses_allocator_construction_args<_Tp>(__a, + std::forward<_Args>(__args)...)); } // @} commit 020a03eec7054adb10396067fab69d0ace00aada Author: Jonathan Wakely Date: Wed Feb 19 12:04:53 2020 +0000 libstdc++: Add nodiscard to polymorphic_allocator members (LWG 3304) * include/std/memory_resource (polymorphic_allocator::allocate_bytes) (polymorphic_allocator::allocate_object) (polymorphic_allocator::new_object): Add nodiscard attribute (LWG3304). diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 045f0badfae..eb83c632adc 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,9 @@ 2020-02-19 Jonathan Wakely + * include/std/memory_resource (polymorphic_allocator::allocate_bytes) + (polymorphic_allocator::allocate_object) + (polymorphic_allocator::new_object): Add nodiscard attribute (LWG3304). + LWG 3379. "safe" in several library names is misleading * include/bits/range_access.h (enable_safe_range): Rename to enable_borrowed_range. diff --git a/libstdc++-v3/include/std/memory_resource b/libstdc++-v3/include/std/memory_resource index 70c56d1d7e6..73f77bdcadf 100644 --- a/libstdc++-v3/include/std/memory_resource +++ b/libstdc++-v3/include/std/memory_resource @@ -178,7 +178,7 @@ namespace pmr { _M_resource->deallocate(__p, __n * sizeof(_Tp), alignof(_Tp)); } #if __cplusplus > 201703L - void* + [[nodiscard]] void* allocate_bytes(size_t __nbytes, size_t __alignment = alignof(max_align_t)) { return _M_resource->allocate(__nbytes, __alignment); } @@ -189,7 +189,7 @@ namespace pmr { _M_resource->deallocate(__p, __nbytes, __alignment); } template - _Up* + [[nodiscard]] _Up* allocate_object(size_t __n = 1) { if ((__detail::__int_limits::max() / sizeof(_Up)) < __n) @@ -204,7 +204,7 @@ namespace pmr { deallocate_bytes(__p, __n * sizeof(_Up), alignof(_Up)); } template - _Up* + [[nodiscard]] _Up* new_object(_CtorArgs&&... __ctor_args) { _Up* __p = allocate_object<_Up>(); commit 15411a6453444ef49940822380e39e6a1d174fac Author: Jonathan Wakely Date: Wed Feb 19 11:54:19 2020 +0000 libstdc++: "safe" in several library names is misleading (LWG 3379) * include/bits/range_access.h (enable_safe_range): Rename to enable_borrowed_range. (__detail::__maybe_safe_range): Rename to __maybe_borrowed_range. (safe_range): Rename to borrowed_range. * include/bits/ranges_algo.h: Adjust to use new names. * include/bits/ranges_algobase.h: Likewise. * include/bits/ranges_uninitialized.h: Likewise. * include/std/ranges: Likewise. (safe_iterator_t): Rename to borrowed_iterator_t. (safe_subrange_t): Rename to borrowed_subrange_t. * include/std/span: Adjust to use new names. * include/std/string_view: Likewise. * include/experimental/string_view: Likewise. * testsuite/std/ranges/access/begin.cc: Likewise. * testsuite/std/ranges/access/cbegin.cc: Likewise. * testsuite/std/ranges/access/cdata.cc: Likewise. * testsuite/std/ranges/access/cend.cc: Likewise. * testsuite/std/ranges/access/crbegin.cc: Likewise. * testsuite/std/ranges/access/crend.cc: Likewise. * testsuite/std/ranges/access/data.cc: Likewise. * testsuite/std/ranges/access/end.cc: Likewise. * testsuite/std/ranges/access/rbegin.cc: Likewise. * testsuite/std/ranges/access/rend.cc: Likewise. * testsuite/std/ranges/safe_range.cc: Likewise. * testsuite/std/ranges/safe_range_types.cc: Likewise. * testsuite/util/testsuite_iterators.h: Likewise. diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index f69507d667f..045f0badfae 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,33 @@ 2020-02-19 Jonathan Wakely + LWG 3379. "safe" in several library names is misleading + * include/bits/range_access.h (enable_safe_range): Rename to + enable_borrowed_range. + (__detail::__maybe_safe_range): Rename to __maybe_borrowed_range. + (safe_range): Rename to borrowed_range. + * include/bits/ranges_algo.h: Adjust to use new names. + * include/bits/ranges_algobase.h: Likewise. + * include/bits/ranges_uninitialized.h: Likewise. + * include/std/ranges: Likewise. + (safe_iterator_t): Rename to borrowed_iterator_t. + (safe_subrange_t): Rename to borrowed_subrange_t. + * include/std/span: Adjust to use new names. + * include/std/string_view: Likewise. + * include/experimental/string_view: Likewise. + * testsuite/std/ranges/access/begin.cc: Likewise. + * testsuite/std/ranges/access/cbegin.cc: Likewise. + * testsuite/std/ranges/access/cdata.cc: Likewise. + * testsuite/std/ranges/access/cend.cc: Likewise. + * testsuite/std/ranges/access/crbegin.cc: Likewise. + * testsuite/std/ranges/access/crend.cc: Likewise. + * testsuite/std/ranges/access/data.cc: Likewise. + * testsuite/std/ranges/access/end.cc: Likewise. + * testsuite/std/ranges/access/rbegin.cc: Likewise. + * testsuite/std/ranges/access/rend.cc: Likewise. + * testsuite/std/ranges/safe_range.cc: Likewise. + * testsuite/std/ranges/safe_range_types.cc: Likewise. + * testsuite/util/testsuite_iterators.h: Likewise. + * include/std/ranges (tuple_element<0, const subrange>) (tuple_element<1, const subrange>): Add partial specializations (LWG 3398). diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h index 8bac0efc6ed..e2a2c28c7d2 100644 --- a/libstdc++-v3/include/bits/range_access.h +++ b/libstdc++-v3/include/bits/range_access.h @@ -344,7 +344,7 @@ namespace ranges inline constexpr bool disable_sized_range = false; template - inline constexpr bool enable_safe_range = false; + inline constexpr bool enable_borrowed_range = false; namespace __detail { @@ -357,16 +357,17 @@ namespace ranges using __make_unsigned_like_t = conditional_t<_MaxDiff, __max_size_type, make_unsigned_t<_Tp>>; - // Part of the constraints of ranges::safe_range + // Part of the constraints of ranges::borrowed_range template - concept __maybe_safe_range - = is_lvalue_reference_v<_Tp> || enable_safe_range>; + concept __maybe_borrowed_range + = is_lvalue_reference_v<_Tp> + || enable_borrowed_range>; } // namespace __detail namespace __cust_access { - using std::ranges::__detail::__maybe_safe_range; + using std::ranges::__detail::__maybe_borrowed_range; using std::__detail::__class_or_enum; template @@ -407,7 +408,7 @@ namespace ranges } public: - template<__maybe_safe_range _Tp> + template<__maybe_borrowed_range _Tp> requires is_array_v> || __member_begin<_Tp> || __adl_begin<_Tp> constexpr auto @@ -459,7 +460,7 @@ namespace ranges } public: - template<__maybe_safe_range _Tp> + template<__maybe_borrowed_range _Tp> requires is_array_v> || __member_end<_Tp> || __adl_end<_Tp> constexpr auto @@ -559,7 +560,7 @@ namespace ranges } public: - template<__maybe_safe_range _Tp> + template<__maybe_borrowed_range _Tp> requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp> constexpr auto operator()(_Tp&& __t) const @@ -616,7 +617,7 @@ namespace ranges } public: - template<__maybe_safe_range _Tp> + template<__maybe_borrowed_range _Tp> requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp> constexpr auto operator()(_Tp&& __t) const @@ -875,9 +876,10 @@ namespace ranges ranges::end(__t); }; - /// [range.range] The safe_range concept. + /// [range.range] The borrowed_range concept. template - concept safe_range = range<_Tp> && __detail::__maybe_safe_range<_Tp>; + concept borrowed_range + = range<_Tp> && __detail::__maybe_borrowed_range<_Tp>; template using iterator_t = decltype(ranges::begin(std::declval<_Range&>())); diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index a69181e12cb..7de1072abf0 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -190,7 +190,7 @@ namespace ranges template, _Proj>> _Fun> - constexpr for_each_result, _Fun> + constexpr for_each_result, _Fun> operator()(_Range&& __r, _Fun __f, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -253,7 +253,7 @@ namespace ranges requires indirect_binary_predicate, _Proj>, const _Tp*> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -281,7 +281,7 @@ namespace ranges template, _Proj>> _Pred> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -309,7 +309,7 @@ namespace ranges template, _Proj>> _Pred> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -345,7 +345,7 @@ namespace ranges typename _Proj1 = identity, typename _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - constexpr safe_iterator_t<_Range1> + constexpr borrowed_iterator_t<_Range1> operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { @@ -536,7 +536,7 @@ namespace ranges typename _Proj1 = identity, typename _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - constexpr safe_subrange_t<_Range1> + constexpr borrowed_subrange_t<_Range1> operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { @@ -625,7 +625,7 @@ namespace ranges typename _Pred = ranges::equal_to, typename _Proj = identity> requires indirectly_comparable, const _Tp*, _Pred, _Proj> - constexpr safe_subrange_t<_Range> + constexpr borrowed_subrange_t<_Range> operator()(_Range&& __r, range_difference_t<_Range> __count, const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) const { @@ -701,7 +701,7 @@ namespace ranges typename _Proj1 = identity, typename _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - constexpr safe_subrange_t<_Range1> + constexpr borrowed_subrange_t<_Range1> operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { @@ -742,7 +742,7 @@ namespace ranges indirect_binary_predicate< projected, _Proj>, projected, _Proj>> _Pred = ranges::equal_to> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -866,7 +866,7 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires indirectly_copyable, _Out> - constexpr copy_if_result, _Out> + constexpr copy_if_result, _Out> operator()(_Range&& __r, _Out __result, _Pred __pred, _Proj __proj = {}) const { @@ -898,8 +898,8 @@ namespace ranges template requires indirectly_swappable, iterator_t<_Range2>> - constexpr swap_ranges_result, - safe_iterator_t<_Range2>> + constexpr swap_ranges_result, + borrowed_iterator_t<_Range2>> operator()(_Range1&& __r1, _Range2&& __r2) const { return (*this)(ranges::begin(__r1), ranges::end(__r1), @@ -961,7 +961,7 @@ namespace ranges requires indirectly_writable<_Out, indirect_result_t<_Fp&, projected, _Proj>>> - constexpr unary_transform_result, _Out> + constexpr unary_transform_result, _Out> operator()(_Range&& __r, _Out __result, _Fp __op, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -998,8 +998,8 @@ namespace ranges indirect_result_t<_Fp&, projected, _Proj1>, projected, _Proj2>>> - constexpr binary_transform_result, - safe_iterator_t<_Range2>, _Out> + constexpr binary_transform_result, + borrowed_iterator_t<_Range2>, _Out> operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Fp __binary_op, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { @@ -1036,7 +1036,7 @@ namespace ranges && indirect_binary_predicate, _Proj>, const _Tp1*> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, const _Tp1& __old_value, const _Tp2& __new_value, _Proj __proj = {}) const @@ -1068,7 +1068,7 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires indirectly_writable, const _Tp&> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const { @@ -1109,7 +1109,7 @@ namespace ranges && indirect_binary_predicate, _Proj>, const _Tp1*> - constexpr replace_copy_result, _Out> + constexpr replace_copy_result, _Out> operator()(_Range&& __r, _Out __result, const _Tp1& __old_value, const _Tp2& __new_value, _Proj __proj = {}) const @@ -1150,7 +1150,7 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires indirectly_copyable, _Out> - constexpr replace_copy_if_result, _Out> + constexpr replace_copy_if_result, _Out> operator()(_Range&& __r, _Out __result, _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const { @@ -1194,7 +1194,7 @@ namespace ranges template requires invocable<_Fp&> && output_range<_Range, invoke_result_t<_Fp&>> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Fp __gen) const { return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__gen)); @@ -1232,7 +1232,7 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires permutable> - constexpr safe_subrange_t<_Range> + constexpr borrowed_subrange_t<_Range> operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -1265,7 +1265,7 @@ namespace ranges && indirect_binary_predicate, _Proj>, const _Tp*> - constexpr safe_subrange_t<_Range> + constexpr borrowed_subrange_t<_Range> operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -1302,7 +1302,7 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires indirectly_copyable, _Out> - constexpr remove_copy_if_result, _Out> + constexpr remove_copy_if_result, _Out> operator()(_Range&& __r, _Out __result, _Pred __pred, _Proj __proj = {}) const { @@ -1344,7 +1344,7 @@ namespace ranges && indirect_binary_predicate, _Proj>, const _Tp*> - constexpr remove_copy_result, _Out> + constexpr remove_copy_result, _Out> operator()(_Range&& __r, _Out __result, const _Tp& __value, _Proj __proj = {}) const { @@ -1383,7 +1383,7 @@ namespace ranges indirect_equivalence_relation< projected, _Proj>> _Comp = ranges::equal_to> requires permutable> - constexpr safe_subrange_t<_Range> + constexpr borrowed_subrange_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -1467,7 +1467,7 @@ namespace ranges || (input_iterator<_Out> && same_as, iter_value_t<_Out>>) || indirectly_copyable_storable, _Out>) - constexpr unique_copy_result, _Out> + constexpr unique_copy_result, _Out> operator()(_Range&& __r, _Out __result, _Comp __comp = {}, _Proj __proj = {}) const { @@ -1519,7 +1519,7 @@ namespace ranges template requires permutable> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r) const { return (*this)(ranges::begin(__r), ranges::end(__r)); @@ -1552,7 +1552,7 @@ namespace ranges template requires indirectly_copyable, _Out> - constexpr reverse_copy_result, _Out> + constexpr reverse_copy_result, _Out> operator()(_Range&& __r, _Out __result) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -1699,7 +1699,7 @@ namespace ranges template requires permutable> - constexpr safe_subrange_t<_Range> + constexpr borrowed_subrange_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __middle) const { return (*this)(ranges::begin(__r), std::move(__middle), @@ -1732,7 +1732,7 @@ namespace ranges template requires indirectly_copyable, _Out> - constexpr rotate_copy_result, _Out> + constexpr rotate_copy_result, _Out> operator()(_Range&& __r, iterator_t<_Range> __middle, _Out __result) const { return (*this)(ranges::begin(__r), std::move(__middle), @@ -1818,7 +1818,7 @@ namespace ranges template requires permutable> && uniform_random_bit_generator> - safe_iterator_t<_Range> + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Gen&& __g) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -1847,7 +1847,7 @@ namespace ranges template requires sortable, _Comp, _Proj> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -1875,7 +1875,7 @@ namespace ranges template requires sortable, _Comp, _Proj> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -1903,7 +1903,7 @@ namespace ranges template requires sortable, _Comp, _Proj> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -1931,7 +1931,7 @@ namespace ranges template requires sortable, _Comp, _Proj> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -1968,7 +1968,7 @@ namespace ranges typename _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -2026,7 +2026,7 @@ namespace ranges template requires sortable, _Comp, _Proj> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -2054,7 +2054,7 @@ namespace ranges template requires sortable, _Comp, _Proj> - safe_iterator_t<_Range> + borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -2095,7 +2095,7 @@ namespace ranges template requires sortable, _Comp, _Proj> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const { @@ -2168,8 +2168,8 @@ namespace ranges && indirect_strict_weak_order<_Comp, projected, _Proj1>, projected, _Proj2>> - constexpr partial_sort_copy_result, - safe_iterator_t<_Range2>> + constexpr partial_sort_copy_result, + borrowed_iterator_t<_Range2>> operator()(_Range1&& __r, _Range2&& __out, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { @@ -2207,7 +2207,7 @@ namespace ranges template, _Proj>> _Comp = ranges::less> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -2270,7 +2270,7 @@ namespace ranges template requires sortable, _Comp, _Proj> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {}, _Proj __proj = {}) const { @@ -2314,7 +2314,7 @@ namespace ranges indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { @@ -2358,7 +2358,7 @@ namespace ranges indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { @@ -2418,7 +2418,7 @@ namespace ranges indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - constexpr safe_subrange_t<_Range> + constexpr borrowed_subrange_t<_Range> operator()(_Range&& __r, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { @@ -2554,7 +2554,7 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires permutable> - constexpr safe_subrange_t<_Range> + constexpr borrowed_subrange_t<_Range> operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -2585,7 +2585,7 @@ namespace ranges indirect_unary_predicate, _Proj>> _Pred> requires permutable> - safe_subrange_t<_Range> + borrowed_subrange_t<_Range> operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -2658,7 +2658,7 @@ namespace ranges _Pred> requires indirectly_copyable, _Out1> && indirectly_copyable, _O2> - constexpr partition_copy_result, _Out1, _O2> + constexpr partition_copy_result, _Out1, _O2> operator()(_Range&& __r, _Out1 out_true, _O2 out_false, _Pred __pred, _Proj __proj = {}) const { @@ -2701,7 +2701,7 @@ namespace ranges template, _Proj>> _Pred> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -2756,8 +2756,8 @@ namespace ranges typename _Proj1 = identity, typename _Proj2 = identity> requires mergeable, iterator_t<_Range2>, _Out, _Comp, _Proj1, _Proj2> - constexpr merge_result, - safe_iterator_t<_Range2>, + constexpr merge_result, + borrowed_iterator_t<_Range2>, _Out> operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Comp __comp = {}, @@ -2791,7 +2791,7 @@ namespace ranges template requires sortable, _Comp, _Proj> - safe_iterator_t<_Range> + borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const { @@ -2906,8 +2906,8 @@ namespace ranges typename _Proj1 = identity, typename _Proj2 = identity> requires mergeable, iterator_t<_Range2>, _Out, _Comp, _Proj1, _Proj2> - constexpr set_union_result, - safe_iterator_t<_Range2>, _Out> + constexpr set_union_result, + borrowed_iterator_t<_Range2>, _Out> operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const @@ -2964,8 +2964,8 @@ namespace ranges typename _Proj1 = identity, typename _Proj2 = identity> requires mergeable, iterator_t<_Range2>, _Out, _Comp, _Proj1, _Proj2> - constexpr set_intersection_result, - safe_iterator_t<_Range2>, _Out> + constexpr set_intersection_result, + borrowed_iterator_t<_Range2>, _Out> operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const @@ -3022,7 +3022,7 @@ namespace ranges typename _Proj1 = identity, typename _Proj2 = identity> requires mergeable, iterator_t<_Range2>, _Out, _Comp, _Proj1, _Proj2> - constexpr set_difference_result, _Out> + constexpr set_difference_result, _Out> operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const @@ -3088,8 +3088,8 @@ namespace ranges typename _Proj1 = identity, typename _Proj2 = identity> requires mergeable, iterator_t<_Range2>, _Out, _Comp, _Proj1, _Proj2> - constexpr set_symmetric_difference_result, - safe_iterator_t<_Range2>, + constexpr set_symmetric_difference_result, + borrowed_iterator_t<_Range2>, _Out> operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Comp __comp = {}, @@ -3343,7 +3343,7 @@ namespace ranges template, _Proj>> _Comp = ranges::less> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -3380,7 +3380,7 @@ namespace ranges template, _Proj>> _Comp = ranges::less> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -3425,7 +3425,7 @@ namespace ranges template, _Proj>> _Comp = ranges::less> - constexpr minmax_element_result> + constexpr minmax_element_result> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -3610,7 +3610,7 @@ namespace ranges template requires sortable, _Comp, _Proj> - constexpr next_permutation_result> + constexpr next_permutation_result> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -3672,7 +3672,7 @@ namespace ranges template requires sortable, _Comp, _Proj> - constexpr prev_permutation_result> + constexpr prev_permutation_result> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return (*this)(ranges::begin(__r), ranges::end(__r), diff --git a/libstdc++-v3/include/bits/ranges_algobase.h b/libstdc++-v3/include/bits/ranges_algobase.h index 7424766f053..807822e99c8 100644 --- a/libstdc++-v3/include/bits/ranges_algobase.h +++ b/libstdc++-v3/include/bits/ranges_algobase.h @@ -310,7 +310,7 @@ namespace ranges template requires indirectly_copyable, _Out> - constexpr copy_result, _Out> + constexpr copy_result, _Out> operator()(_Range&& __r, _Out __result) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -335,7 +335,7 @@ namespace ranges template requires indirectly_movable, _Out> - constexpr move_result, _Out> + constexpr move_result, _Out> operator()(_Range&& __r, _Out __result) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -452,7 +452,7 @@ namespace ranges template requires indirectly_copyable, _Iter> - constexpr copy_backward_result, _Iter> + constexpr copy_backward_result, _Iter> operator()(_Range&& __r, _Iter __result) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -477,7 +477,7 @@ namespace ranges template requires indirectly_movable, _Iter> - constexpr move_backward_result, _Iter> + constexpr move_backward_result, _Iter> operator()(_Range&& __r, _Iter __result) const { return (*this)(ranges::begin(__r), ranges::end(__r), @@ -577,7 +577,7 @@ namespace ranges } template _Range> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, const _Tp& __value) const { return (*this)(ranges::begin(__r), ranges::end(__r), __value); diff --git a/libstdc++-v3/include/bits/ranges_uninitialized.h b/libstdc++-v3/include/bits/ranges_uninitialized.h index 881bf39d5f8..01e1cad646c 100644 --- a/libstdc++-v3/include/bits/ranges_uninitialized.h +++ b/libstdc++-v3/include/bits/ranges_uninitialized.h @@ -88,7 +88,7 @@ namespace ranges template<__detail::__nothrow_input_range _Range> requires destructible> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r) const noexcept; }; @@ -159,7 +159,7 @@ namespace ranges template<__detail::__nothrow_forward_range _Range> requires default_initializable> - safe_iterator_t<_Range> + borrowed_iterator_t<_Range> operator()(_Range&& __r) const { return (*this)(ranges::begin(__r), ranges::end(__r)); @@ -217,7 +217,7 @@ namespace ranges template<__detail::__nothrow_forward_range _Range> requires default_initializable> - safe_iterator_t<_Range> + borrowed_iterator_t<_Range> operator()(_Range&& __r) const { return (*this)(ranges::begin(__r), ranges::end(__r)); @@ -290,8 +290,8 @@ namespace ranges template requires constructible_from, range_reference_t<_IRange>> - uninitialized_copy_result, - safe_iterator_t<_ORange>> + uninitialized_copy_result, + borrowed_iterator_t<_ORange>> operator()(_IRange&& __inr, _ORange&& __outr) const { return (*this)(ranges::begin(__inr), ranges::end(__inr), @@ -377,8 +377,8 @@ namespace ranges template requires constructible_from, range_rvalue_reference_t<_IRange>> - uninitialized_move_result, - safe_iterator_t<_ORange>> + uninitialized_move_result, + borrowed_iterator_t<_ORange>> operator()(_IRange&& __inr, _ORange&& __outr) const { return (*this)(ranges::begin(__inr), ranges::end(__inr), @@ -450,7 +450,7 @@ namespace ranges template<__detail::__nothrow_forward_range _Range, typename _Tp> requires constructible_from, const _Tp&> - safe_iterator_t<_Range> + borrowed_iterator_t<_Range> operator()(_Range&& __r, const _Tp& __x) const { return (*this)(ranges::begin(__r), ranges::end(__r), __x); @@ -531,7 +531,7 @@ namespace ranges template<__detail::__nothrow_input_range _Range> requires destructible> - constexpr safe_iterator_t<_Range> + constexpr borrowed_iterator_t<_Range> __destroy_fn::operator()(_Range&& __r) const noexcept { return (*this)(ranges::begin(__r), ranges::end(__r)); diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view index 4d4615c94e7..439650154ae 100644 --- a/libstdc++-v3/include/experimental/string_view +++ b/libstdc++-v3/include/experimental/string_view @@ -694,11 +694,11 @@ namespace experimental #if __cpp_lib_concepts namespace ranges { - template extern inline const bool enable_safe_range; - // Opt-in to safe_range concept + template extern inline const bool enable_borrowed_range; + // Opt-in to borrowed_range concept template inline constexpr bool - enable_safe_range> + enable_borrowed_range> = true; } #endif diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 4e50206fb61..4bfda88c319 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -93,7 +93,7 @@ namespace ranges /// A range which can be safely converted to a view. template concept viewable_range = range<_Tp> - && (safe_range<_Tp> || view>); + && (borrowed_range<_Tp> || view>); namespace __detail { @@ -294,7 +294,7 @@ namespace ranges } template<__detail::__not_same_as _Rng> - requires safe_range<_Rng> + requires borrowed_range<_Rng> && convertible_to, _It> && convertible_to, _Sent> constexpr @@ -305,7 +305,7 @@ namespace ranges _M_size._M_size = ranges::size(__r); } - template + template requires convertible_to, _It> && convertible_to, _Sent> constexpr @@ -417,14 +417,14 @@ namespace ranges -> subrange, tuple_element_t<1, _Pr>, subrange_kind::sized>; - template + template subrange(_Rng&&) -> subrange, sentinel_t<_Rng>, (sized_range<_Rng> || sized_sentinel_for, iterator_t<_Rng>>) ? subrange_kind::sized : subrange_kind::unsized>; - template + template subrange(_Rng&&, __detail::__make_unsigned_like_t>) -> subrange, sentinel_t<_Rng>, subrange_kind::sized>; @@ -454,7 +454,7 @@ namespace ranges template _Sent, subrange_kind _Kind> inline constexpr bool - enable_safe_range> = true; + enable_borrowed_range> = true; } // namespace ranges @@ -471,14 +471,14 @@ namespace ranges }; template - using safe_iterator_t = conditional_t, - iterator_t<_Range>, - dangling>; + using borrowed_iterator_t = conditional_t, + iterator_t<_Range>, + dangling>; template - using safe_subrange_t = conditional_t, - subrange>, - dangling>; + using borrowed_subrange_t = conditional_t, + subrange>, + dangling>; template requires is_object_v<_Tp> class empty_view @@ -493,7 +493,7 @@ namespace ranges }; template - inline constexpr bool enable_safe_range> = true; + inline constexpr bool enable_borrowed_range> = true; namespace __detail { @@ -919,7 +919,8 @@ namespace ranges iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>; template - inline constexpr bool enable_safe_range> = true; + inline constexpr bool + enable_borrowed_range> = true; namespace views { @@ -1221,7 +1222,7 @@ namespace views ref_view(_Range&) -> ref_view<_Range>; template - inline constexpr bool enable_safe_range> = true; + inline constexpr bool enable_borrowed_range> = true; namespace views { diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index a8c69796e5e..63dc2515b25 100644 --- a/libstdc++-v3/include/std/span +++ b/libstdc++-v3/include/std/span @@ -207,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template requires ranges::contiguous_range<_Range> && ranges::sized_range<_Range> - && (ranges::safe_range<_Range> || is_const_v) + && (ranges::borrowed_range<_Range> || is_const_v) && (!__detail::__is_std_span>::value) && (!__detail::__is_std_array>::value) && (!is_array_v>) @@ -465,11 +465,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace ranges { - template extern inline const bool enable_safe_range; - // Opt-in to safe_range concept + template extern inline const bool enable_borrowed_range; + // Opt-in to borrowed_range concept template inline constexpr bool - enable_safe_range> = true; + enable_borrowed_range> = true; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view index bedad24979e..16687f6c352 100644 --- a/libstdc++-v3/include/std/string_view +++ b/libstdc++-v3/include/std/string_view @@ -727,11 +727,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cpp_lib_concepts namespace ranges { - template extern inline const bool enable_safe_range; - // Opt-in to safe_range concept + template extern inline const bool enable_borrowed_range; + // Opt-in to borrowed_range concept template inline constexpr bool - enable_safe_range> = true; + enable_borrowed_range> = true; } #endif _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/testsuite/std/ranges/access/begin.cc b/libstdc++-v3/testsuite/std/ranges/access/begin.cc index 882dffb4877..b6801552c60 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/begin.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/begin.cc @@ -85,7 +85,7 @@ struct RV // view on an R }; // Allow ranges::begin to work with RV&& -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test03() @@ -102,7 +102,7 @@ test03() VERIFY( std::ranges::begin(c) == begin(c) ); RV v{r}; - // enable_safe_range allows ranges::begin to work for rvalues, + // enable_borrowed_range allows ranges::begin to work for rvalues, // but it will call v.begin() or begin(v) on an lvalue: static_assert(same_as); @@ -132,7 +132,7 @@ struct RR }; // N.B. this is a lie, begin on an RR rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test04() diff --git a/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc index 981f88d3b5d..6e994210c6b 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc @@ -54,7 +54,7 @@ struct RV // view on an R }; // Allow ranges::begin to work with RV&& -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test03() @@ -86,7 +86,7 @@ struct RR }; // N.B. this is a lie, cbegin on an RR rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test04() diff --git a/libstdc++-v3/testsuite/std/ranges/access/cdata.cc b/libstdc++-v3/testsuite/std/ranges/access/cdata.cc index c8489dd1ab9..8e68514bfad 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/cdata.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/cdata.cc @@ -57,7 +57,7 @@ struct R }; // This is a lie, ranges::begin(R&&) returns a dangling iterator. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test03() diff --git a/libstdc++-v3/testsuite/std/ranges/access/cend.cc b/libstdc++-v3/testsuite/std/ranges/access/cend.cc index 4172932118e..f3a00863a78 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/cend.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/cend.cc @@ -60,7 +60,7 @@ struct RV // view on an R }; // Allow ranges::end to work with RV&& -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test03() @@ -98,7 +98,7 @@ struct RR }; // N.B. this is a lie, begin/end on an RR rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test04() diff --git a/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc index 61724c8ba05..50d8eb43e75 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc @@ -40,7 +40,7 @@ struct R1V // view on an R1 }; // Allow ranges::end to work with R1V&& -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test01() @@ -69,7 +69,7 @@ struct R2 }; // N.B. this is a lie, rbegin on an R2 rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test02() diff --git a/libstdc++-v3/testsuite/std/ranges/access/crend.cc b/libstdc++-v3/testsuite/std/ranges/access/crend.cc index 85fecf1221c..4d50f4a0965 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/crend.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/crend.cc @@ -34,7 +34,7 @@ struct R1 }; // N.B. this is a lie, rend on an R1 rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test01() @@ -60,7 +60,7 @@ struct R2 }; // N.B. this is a lie, rend on an R2 rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test02() @@ -85,7 +85,7 @@ struct R3 }; // N.B. this is a lie, rend on an R3 rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test03() diff --git a/libstdc++-v3/testsuite/std/ranges/access/data.cc b/libstdc++-v3/testsuite/std/ranges/access/data.cc index b7f04929f92..bcd564b75c8 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/data.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/data.cc @@ -61,7 +61,7 @@ struct R3 }; // N.B. this is a lie, begin on an R3 rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test03() @@ -69,7 +69,7 @@ test03() R3 r; const R3& c = r; // r.data() can only be used on an lvalue, but ranges::begin(R3&&) is OK - // because R3 satisfies ranges::safe_range. + // because R3 satisfies ranges::borrowed_range. VERIFY( std::ranges::data(std::move(r)) == std::to_address(std::ranges::begin(std::move(r))) ); VERIFY( std::ranges::data(std::move(c)) == std::to_address(std::ranges::begin(std::move(c))) ); } diff --git a/libstdc++-v3/testsuite/std/ranges/access/end.cc b/libstdc++-v3/testsuite/std/ranges/access/end.cc index c3a1028dc14..245f246c517 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/end.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/end.cc @@ -90,7 +90,7 @@ struct RV // view on an R }; // Allow ranges::begin to work with RV&& -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test03() @@ -146,7 +146,7 @@ struct RR }; // N.B. this is a lie, end on an RR rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test04() diff --git a/libstdc++-v3/testsuite/std/ranges/access/rbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/rbegin.cc index e92e5bc69ac..bc49a10a734 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/rbegin.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/rbegin.cc @@ -32,7 +32,7 @@ struct R1 }; // N.B. this is a lie, rbegin on an R1 rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test01() @@ -56,7 +56,7 @@ struct R2 }; // N.B. this is a lie, begin/end on an R2 rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test02() diff --git a/libstdc++-v3/testsuite/std/ranges/access/rend.cc b/libstdc++-v3/testsuite/std/ranges/access/rend.cc index f6909b8340c..e80b5526f84 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/rend.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/rend.cc @@ -34,7 +34,7 @@ struct R1 }; // N.B. this is a lie, rend on an R1 rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test01() @@ -87,7 +87,7 @@ struct R3 }; // N.B. this is a lie, begin/end on an R3 rvalue will return a dangling pointer. -template<> constexpr bool std::ranges::enable_safe_range = true; +template<> constexpr bool std::ranges::enable_borrowed_range = true; void test03() diff --git a/libstdc++-v3/testsuite/std/ranges/safe_range.cc b/libstdc++-v3/testsuite/std/ranges/safe_range.cc index 6e50bf579c3..ec43f7884dc 100644 --- a/libstdc++-v3/testsuite/std/ranges/safe_range.cc +++ b/libstdc++-v3/testsuite/std/ranges/safe_range.cc @@ -21,21 +21,21 @@ #include #include -static_assert( std::ranges::safe_range ); -static_assert( std::ranges::safe_range ); -static_assert( !std::ranges::safe_range ); -static_assert( !std::ranges::safe_range ); +static_assert( std::ranges::borrowed_range ); +static_assert( std::ranges::borrowed_range ); +static_assert( !std::ranges::borrowed_range ); +static_assert( !std::ranges::borrowed_range ); using __gnu_test::test_contiguous_range; -static_assert( !std::ranges::safe_range> ); -static_assert( std::ranges::safe_range&> ); -static_assert( !std::ranges::safe_range&&> ); +static_assert( !std::ranges::borrowed_range> ); +static_assert( std::ranges::borrowed_range&> ); +static_assert( !std::ranges::borrowed_range&&> ); template<> constexpr bool - std::ranges::enable_safe_range> = true; + std::ranges::enable_borrowed_range> = true; -static_assert( std::ranges::safe_range> ); -static_assert( std::ranges::safe_range&> ); -static_assert( std::ranges::safe_range&&> ); +static_assert( std::ranges::borrowed_range> ); +static_assert( std::ranges::borrowed_range&> ); +static_assert( std::ranges::borrowed_range&&> ); diff --git a/libstdc++-v3/testsuite/std/ranges/safe_range_types.cc b/libstdc++-v3/testsuite/std/ranges/safe_range_types.cc index 3f0b52404a1..2835babfd82 100644 --- a/libstdc++-v3/testsuite/std/ranges/safe_range_types.cc +++ b/libstdc++-v3/testsuite/std/ranges/safe_range_types.cc @@ -25,35 +25,35 @@ template constexpr bool -rvalue_is_safe_range() +rvalue_is_borrowed_range() { - using std::ranges::safe_range; + using std::ranges::borrowed_range; - // An lvalue range always models safe_range - static_assert( safe_range ); - static_assert( safe_range ); + // An lvalue range always models borrowed_range + static_assert( borrowed_range ); + static_assert( borrowed_range ); // Result should not depend on addition of const or rvalue-reference. - static_assert( safe_range == safe_range ); - static_assert( safe_range == safe_range ); - static_assert( safe_range == safe_range ); + static_assert( borrowed_range == borrowed_range ); + static_assert( borrowed_range == borrowed_range ); + static_assert( borrowed_range == borrowed_range ); - return std::ranges::safe_range; + return std::ranges::borrowed_range; } -static_assert( rvalue_is_safe_range>() ); -static_assert( rvalue_is_safe_range>() ); -static_assert( rvalue_is_safe_range>() ); -static_assert( rvalue_is_safe_range>() ); +static_assert( rvalue_is_borrowed_range>() ); +static_assert( rvalue_is_borrowed_range>() ); +static_assert( rvalue_is_borrowed_range>() ); +static_assert( rvalue_is_borrowed_range>() ); -static_assert( rvalue_is_safe_range>() ); -static_assert( rvalue_is_safe_range>() ); +static_assert( rvalue_is_borrowed_range>() ); +static_assert( rvalue_is_borrowed_range>() ); -static_assert( ! rvalue_is_safe_range() ); -static_assert( ! rvalue_is_safe_range() ); +static_assert( ! rvalue_is_borrowed_range() ); +static_assert( ! rvalue_is_borrowed_range() ); -static_assert( rvalue_is_safe_range() ); -static_assert( rvalue_is_safe_range() ); +static_assert( rvalue_is_borrowed_range() ); +static_assert( rvalue_is_borrowed_range() ); -static_assert( rvalue_is_safe_range() ); -static_assert( rvalue_is_safe_range() ); +static_assert( rvalue_is_borrowed_range() ); +static_assert( rvalue_is_borrowed_range() ); diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h index 6887d806a31..7b7093919b7 100644 --- a/libstdc++-v3/testsuite/util/testsuite_iterators.h +++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h @@ -765,8 +765,8 @@ namespace __gnu_test = test_sized_range; // test_range and test_sized_range do not own their elements, so they model -// std::ranges::safe_range. This file does not define specializations of -// std::ranges::enable_safe_range, so that individual tests can decide +// std::ranges::borrowed_range. This file does not define specializations of +// std::ranges::enable_borrowed_range, so that individual tests can decide // whether or not to do so. // This is also true for test_container, although only when it has forward // iterators (because output_iterator_wrapper and input_iterator_wrapper are commit fa89adaa979093936d8f148ef5496db05ad308e5 Author: Jonathan Wakely Date: Wed Feb 19 11:37:54 2020 +0000 libstdc++: tuple_element_t is also wrong for const subrange (LWG 3398) * include/std/ranges (tuple_element<0, const subrange>) (tuple_element<1, const subrange>): Add partial specializations (LWG 3398). * testsuite/std/ranges/subrange/tuple_like.cc: New test. diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a8fcd7cb475..f69507d667f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,10 @@ 2020-02-19 Jonathan Wakely + * include/std/ranges (tuple_element<0, const subrange>) + (tuple_element<1, const subrange>): Add partial + specializations (LWG 3398). + * testsuite/std/ranges/subrange/tuple_like.cc: New test. + * include/bits/ranges_algo.h (__find_fn, __find_first_of_fn) (__adjacent_find_fn, __remove_if_fn, __remove_copy_if_fn) (__unique_fn, __unique_copy_fn): Remove redundant conversions to bool. diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index e0eb84748a2..4e50206fb61 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -3193,7 +3193,6 @@ namespace views typename tuple_size<_Tp>::type; requires _Nm < tuple_size_v<_Tp>; typename tuple_element_t<_Nm, _Tp>; - // XXX: we applied P3323 here { std::get<_Nm>(__t) } -> convertible_to&>; }; @@ -3451,6 +3450,14 @@ namespace views struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>> { using type = _Sent; }; + template + struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>> + { using type = _Iter; }; + + template + struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>> + { using type = _Sent; }; + _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // library concepts diff --git a/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc b/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc new file mode 100644 index 00000000000..a3020d21d29 --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc @@ -0,0 +1,52 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +using S1 = std::ranges::subrange; +using S2 = std::ranges::subrange; + +static_assert( std::tuple_size_v == 2 ); +static_assert( std::tuple_size_v == 2 ); + +static_assert( std::same_as, int*> ); +static_assert( std::same_as, int*> ); +// LWG 3398 +static_assert( std::same_as, int*> ); +static_assert( std::same_as, int*> ); + +static_assert( std::same_as, long*> ); +static_assert( std::same_as, void*> ); +// LWG 3398 +static_assert( std::same_as, long*> ); +static_assert( std::same_as, void*> ); + +S1 s1; +static_assert( std::same_as(s1)), int*> ); +static_assert( std::same_as(s1)), int*> ); +const S1 c1; +static_assert( std::same_as(c1)), int*> ); +static_assert( std::same_as(c1)), int*> ); +S2 s2; +static_assert( std::same_as(s2)), long*> ); +static_assert( std::same_as(s2)), void*> ); +const S2 c2; +static_assert( std::same_as(c2)), long*> ); +static_assert( std::same_as(c2)), void*> ); commit a45fb21a10f486f6596b648e2c64bd1c7d808f18 Author: Jonathan Wakely Date: Wed Feb 19 10:40:24 2020 +0000 libstdc++: Remove redundant bool casts in ranges algorithms Some of these casts were added by me the other day, but some were already present. I think they are all redundant following the introduction of the boolean-testable concept in P1964R2. * include/bits/ranges_algo.h (__find_fn, __find_first_of_fn) (__adjacent_find_fn, __remove_if_fn, __remove_copy_if_fn) (__unique_fn, __unique_copy_fn): Remove redundant conversions to bool. diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b60f5c301b4..a8fcd7cb475 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,9 @@ +2020-02-19 Jonathan Wakely + + * include/bits/ranges_algo.h (__find_fn, __find_first_of_fn) + (__adjacent_find_fn, __remove_if_fn, __remove_copy_if_fn) + (__unique_fn, __unique_copy_fn): Remove redundant conversions to bool. + 2020-02-18 Patrick Palka P1983R0 Wording for GB301, US296, US292, US291, and US283 diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index 31b1bf0d448..a69181e12cb 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -244,7 +244,7 @@ namespace ranges const _Tp& __value, _Proj __proj = {}) const { while (__first != __last - && !(bool)(std::__invoke(__proj, *__first) == __value)) + && !(std::__invoke(__proj, *__first) == __value)) ++__first; return __first; } @@ -333,9 +333,9 @@ namespace ranges { for (; __first1 != __last1; ++__first1) for (auto __iter = __first2; __iter != __last2; ++__iter) - if ((bool)std::__invoke(__pred, - std::__invoke(__proj1, *__first1), - std::__invoke(__proj2, *__iter))) + if (std::__invoke(__pred, + std::__invoke(__proj1, *__first1), + std::__invoke(__proj2, *__iter))) return __first1; return __first1; } @@ -730,9 +730,9 @@ namespace ranges auto __next = __first; for (; ++__next != __last; __first = __next) { - if ((bool)std::__invoke(__pred, - std::__invoke(__proj, *__first), - std::__invoke(__proj, *__next))) + if (std::__invoke(__pred, + std::__invoke(__proj, *__first), + std::__invoke(__proj, *__next))) return __first; } return __next; @@ -1219,7 +1219,7 @@ namespace ranges auto __result = __first; ++__first; for (; __first != __last; ++__first) - if (!(bool)std::__invoke(__pred, std::__invoke(__proj, *__first))) + if (!std::__invoke(__pred, std::__invoke(__proj, *__first))) { *__result = std::move(*__first); ++__result; @@ -1289,7 +1289,7 @@ namespace ranges _Pred __pred, _Proj __proj = {}) const { for (; __first != __last; ++__first) - if (!(bool)std::__invoke(__pred, std::__invoke(__proj, *__first))) + if (!std::__invoke(__pred, std::__invoke(__proj, *__first))) { *__result = *__first; ++__result; @@ -1372,9 +1372,9 @@ namespace ranges auto __dest = __first; ++__first; while (++__first != __last) - if (!(bool)std::__invoke(__comp, - std::__invoke(__proj, *__dest), - std::__invoke(__proj, *__first))) + if (!std::__invoke(__comp, + std::__invoke(__proj, *__dest), + std::__invoke(__proj, *__first))) *++__dest = std::move(*__first); return {++__dest, __first}; } @@ -1420,9 +1420,9 @@ namespace ranges auto __next = __first; *__result = *__next; while (++__next != __last) - if (!(bool)std::__invoke(__comp, - std::__invoke(__proj, *__first), - std::__invoke(__proj, *__next))) + if (!std::__invoke(__comp, + std::__invoke(__proj, *__first), + std::__invoke(__proj, *__next))) { __first = __next; *++__result = *__first; @@ -1434,9 +1434,9 @@ namespace ranges { *__result = *__first; while (++__first != __last) - if (!(bool)std::__invoke(__comp, - std::__invoke(__proj, *__result), - std::__invoke(__proj, *__first))) + if (!std::__invoke(__comp, + std::__invoke(__proj, *__result), + std::__invoke(__proj, *__first))) *++__result = *__first; return {std::move(__first), std::move(++__result)}; } commit 73d531205083eaf19934b516b37b1cf4940895c7 Author: Bernd Edlinger Date: Mon Feb 17 17:40:07 2020 +0100 Fix -save-temp leaking files in /tmp And avoid signal handler calling signal unsafe functions, and/or calling unlink with uninitialized memory pointer. 2020-02-19 Bernd Edlinger * collect2.c (c_file, o_file): Make const again. (ldout,lderrout, dump_ld_file): Remove. (tool_cleanup): Avoid calling not signal-safe functions. (maybe_run_lto_and_relink): Avoid possible signal handler access to unintialzed memory (lto_o_files). (main): Avoid leaking temp files in $TMPDIR. Initialize c_file/o_file with concat, which avoids exposing uninitialized memory to signal handler, which calls unlink(!). Avoid calling maybe_unlink when the main function returns, since the atexit handler is already doing this. * collect2.h (dump_ld_file, ldout, lderrout): Remove. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ebeaed89e0..6cd941a5ff8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2020-02-19 Bernd Edlinger + + * collect2.c (c_file, o_file): Make const again. + (ldout,lderrout, dump_ld_file): Remove. + (tool_cleanup): Avoid calling not signal-safe functions. + (maybe_run_lto_and_relink): Avoid possible signal handler + access to unintialzed memory (lto_o_files). + (main): Avoid leaking temp files in $TMPDIR. + Initialize c_file/o_file with concat, which avoids exposing + uninitialized memory to signal handler, which calls unlink(!). + Avoid calling maybe_unlink when the main function returns, + since the atexit handler is already doing this. + * collect2.h (dump_ld_file, ldout, lderrout): Remove. + 2020-02-19 Martin Jambor PR tree-optimization/93776 diff --git a/gcc/collect2.c b/gcc/collect2.c index 502d629141c..f7d9f103ddc 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -205,14 +205,12 @@ bool helpflag; /* true if --help */ static int shared_obj; /* true if -shared */ static int static_obj; /* true if -static */ -static char *c_file; /* .c for constructor/destructor list. */ -static char *o_file; /* .o for constructor/destructor list. */ +static const char *c_file; /* .c for constructor/destructor list. */ +static const char *o_file; /* .o for constructor/destructor list. */ #ifdef COLLECT_EXPORT_LIST static const char *export_file; /* .x for AIX export list. */ #endif static char **lto_o_files; /* Output files for LTO. */ -const char *ldout; /* File for ld stdout. */ -const char *lderrout; /* File for ld stderr. */ static const char *output_file; /* Output file for ld. */ static const char *nm_file_name; /* pathname of nm */ #ifdef LDD_SUFFIX @@ -384,6 +382,10 @@ static void scan_prog_file (const char *, scanpass, scanfilter); void tool_cleanup (bool from_signal) { + /* maybe_unlink may call notice, which is not signal safe. */ + if (from_signal) + verbose = false; + if (c_file != 0 && c_file[0]) maybe_unlink (c_file); @@ -397,20 +399,6 @@ tool_cleanup (bool from_signal) if (lto_o_files) maybe_unlink_list (lto_o_files); - - if (ldout != 0 && ldout[0]) - { - if (!from_signal) - dump_ld_file (ldout, stdout); - maybe_unlink (ldout); - } - - if (lderrout != 0 && lderrout[0]) - { - if (!from_signal) - dump_ld_file (lderrout, stderr); - maybe_unlink (lderrout); - } } static void @@ -476,77 +464,6 @@ extract_string (const char **pp) return XOBFINISH (&temporary_obstack, char *); } -void -dump_ld_file (const char *name, FILE *to) -{ - FILE *stream = fopen (name, "r"); - - if (stream == 0) - return; - while (1) - { - int c; - while (c = getc (stream), - c != EOF && (ISIDNUM (c) || c == '$' || c == '.')) - obstack_1grow (&temporary_obstack, c); - if (obstack_object_size (&temporary_obstack) > 0) - { - const char *word, *p; - char *result; - obstack_1grow (&temporary_obstack, '\0'); - word = XOBFINISH (&temporary_obstack, const char *); - - if (*word == '.') - ++word, putc ('.', to); - p = word; - if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX))) - p += strlen (USER_LABEL_PREFIX); - -#ifdef HAVE_LD_DEMANGLE - result = 0; -#else - if (no_demangle) - result = 0; - else - result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE); -#endif - - if (result) - { - int diff; - fputs (result, to); - - diff = strlen (word) - strlen (result); - while (diff > 0 && c == ' ') - --diff, putc (' ', to); - if (diff < 0 && c == ' ') - { - while (diff < 0 && c == ' ') - ++diff, c = getc (stream); - if (!ISSPACE (c)) - { - /* Make sure we output at least one space, or - the demangled symbol name will run into - whatever text follows. */ - putc (' ', to); - } - } - - free (result); - } - else - fputs (word, to); - - fflush (to); - obstack_free (&temporary_obstack, temporary_firstobj); - } - if (c == EOF) - break; - putc (c, to); - } - fclose (stream); -} - /* Return the kind of symbol denoted by name S. */ static symkind @@ -744,7 +661,10 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst, ++num_files; } - lto_o_files = XNEWVEC (char *, num_files + 1); + /* signal handler may access uninitialized memory + and delete whatever it points to, if lto_o_files + is not allocatted with calloc. */ + lto_o_files = XCNEWVEC (char *, num_files + 1); lto_o_files[num_files] = NULL; start = XOBFINISH (&temporary_obstack, char *); for (i = 0; i < num_files; ++i) @@ -1262,27 +1182,19 @@ main (int argc, char **argv) /* Make temp file names. */ if (save_temps) { - c_file = (char *) xmalloc (strlen (output_file) - + sizeof (".cdtor.c") + 1); - strcpy (c_file, output_file); - strcat (c_file, ".cdtor.c"); - o_file = (char *) xmalloc (strlen (output_file) - + sizeof (".cdtor.o") + 1); - strcpy (o_file, output_file); - strcat (o_file, ".cdtor.o"); + c_file = concat (output_file, ".cdtor.c", NULL); + o_file = concat (output_file, ".cdtor.o", NULL); +#ifdef COLLECT_EXPORT_LIST + export_file = concat (output_file, ".x", NULL); +#endif } else { c_file = make_temp_file (".cdtor.c"); o_file = make_temp_file (".cdtor.o"); - } #ifdef COLLECT_EXPORT_LIST - export_file = make_temp_file (".x"); + export_file = make_temp_file (".x"); #endif - if (!debug) - { - ldout = make_temp_file (".ld"); - lderrout = make_temp_file (".le"); } /* Build the command line to compile the ctor/dtor list. */ *c_ptr++ = c_file_name; @@ -1811,9 +1723,6 @@ main (int argc, char **argv) maybe_unlink (export_file); #endif post_ld_pass (/*temp_file*/false); - - maybe_unlink (c_file); - maybe_unlink (o_file); return 0; } @@ -1912,13 +1821,6 @@ main (int argc, char **argv) scan_prog_file (output_file, PASS_SECOND, SCAN_ALL); #endif - maybe_unlink (c_file); - maybe_unlink (o_file); - -#ifdef COLLECT_EXPORT_LIST - maybe_unlink (export_file); -#endif - return 0; } diff --git a/gcc/collect2.h b/gcc/collect2.h index ab5fcdf0ed8..aa8a03e7d87 100644 --- a/gcc/collect2.h +++ b/gcc/collect2.h @@ -25,12 +25,8 @@ extern struct pex_obj *collect_execute (const char *, char **, const char *, extern int collect_wait (const char *, struct pex_obj *); -extern void dump_ld_file (const char *, FILE *); - extern int file_exists (const char *); -extern const char *ldout; -extern const char *lderrout; extern const char *c_file_name; extern struct obstack temporary_obstack; extern char *temporary_firstobj; commit 51faf07cef9293af544bfacc7d0b320ab90d7d60 Author: Martin Jambor Date: Wed Feb 19 11:13:52 2020 +0100 sra: Do not create zero sized accesses (PR 93776) SRA can get a bit confused with zero-sized accesses like the one in the testcase. Since there is nothing in the access, nothing is scalarized, but we can get order of the structures wrong, which the verifier is not happy about. Fixed by simply ignoring such accesses. 2020-02-19 Martin Jambor PR tree-optimization/93776 * tree-sra.c (create_access): Do not create zero size accesses. (get_access_for_expr): Do not search for zero sized accesses. testsuite/ * gcc.dg/tree-ssa/pr93776.c: New test. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6b53f9a2f07..7ebeaed89e0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-02-19 Martin Jambor + + PR tree-optimization/93776 + * tree-sra.c (create_access): Do not create zero size accesses. + (get_access_for_expr): Do not search for zero sized accesses. + 2020-02-19 Martin Jambor PR tree-optimization/93667 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8033fa0a3bb..df79951b6cc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-02-19 Martin Jambor + + PR tree-optimization/93776 + * gcc.dg/tree-ssa/pr93776.c: New test. + 2020-02-19 Martin Jambor PR tree-optimization/93667 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr93776.c b/gcc/testsuite/gcc.dg/tree-ssa/pr93776.c new file mode 100644 index 00000000000..c407a627718 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr93776.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +struct empty {}; +struct s { int i; }; +struct z +{ + int j; + struct empty e; + struct s s; + int k; +}; + +void bar (struct z); +void baz (int); + +void foo (void) +{ + struct z z, z2; + + z.k = 8; + z2.s.i = 1; + z = z2; + bar (z); + z.e = (struct empty) {}; + baz (z.k); +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 4c7d651e6b9..49f9001f7fb 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -926,6 +926,8 @@ create_access (tree expr, gimple *stmt, bool write) size = max_size; unscalarizable_region = true; } + if (size == 0) + return NULL; if (size < 0) { disqualify_candidate (base, "Encountered an unconstrained access."); @@ -3643,7 +3645,8 @@ get_access_for_expr (tree expr) return NULL; } - if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base))) + if (max_size == 0 + || !bitmap_bit_p (candidate_bitmap, DECL_UID (base))) return NULL; return get_var_base_offset_size_access (base, offset, max_size); commit 665c5bad168ab63629b29ed2ce08ed042c088dc2 Author: Martin Jambor Date: Wed Feb 19 11:08:40 2020 +0100 sra: Avoid totally scalarizing overallping field_decls (PR 93667) [[no_unique_address]] C++ attribute can cause two fields of a RECORD_TYPE overlap, which currently confuses the totally scalarizing code into creating invalid access tree. For GCC 10, I'd like to simply disable total scalarization of types where this happens. For GCC 11 I'll write down a TODO item to enable total scalarization of cases like this where the problematic fields are basically empty - despite having a non-zero size - i.e. when they are just RECORD_TYPEs without any data fields. 2020-02-19 Martin Jambor gcc/ PR tree-optimization/93667 * tree-sra.c (scalarizable_type_p): Return false if record fields do not follow wach other. gcc/testsuite/ PR tree-optimization/93667 * g++.dg/tree-ssa/pr93667.C: New test. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 77c2a9ad810..6b53f9a2f07 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-02-19 Martin Jambor + + PR tree-optimization/93667 + * tree-sra.c (scalarizable_type_p): Return false if record fields + do not follow wach other. + 2020-01-21 Kito Cheng * config/riscv/riscv.c (riscv_output_move) Using fmv.x.w/fmv.w.x diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9b4fe11a6f6..8033fa0a3bb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-02-19 Martin Jambor + + PR tree-optimization/93667 + * g++.dg/tree-ssa/pr93667.C: New test. + 2020-02-19 Hongtao Liu * g++.dg/other/i386-2.C: add -mavx512vbmi2 diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr93667.C b/gcc/testsuite/g++.dg/tree-ssa/pr93667.C new file mode 100644 index 00000000000..d875f53d9ec --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr93667.C @@ -0,0 +1,11 @@ +// { dg-do compile } +// { dg-options "-O2 -std=c++2a" } */ + +struct a {}; +struct b { [[no_unique_address]] a aq; }; +struct c { + int d; + [[no_unique_address]] b e; +}; +c f() {return {};} +void g() { f(); } diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 0cfac0a8192..4c7d651e6b9 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -958,6 +958,9 @@ scalarizable_type_p (tree type, bool const_decl) if (type_contains_placeholder_p (type)) return false; + bool have_predecessor_field = false; + HOST_WIDE_INT prev_pos = 0; + switch (TREE_CODE (type)) { case RECORD_TYPE: @@ -966,6 +969,17 @@ scalarizable_type_p (tree type, bool const_decl) { tree ft = TREE_TYPE (fld); + if (zerop (DECL_SIZE (fld))) + continue; + + HOST_WIDE_INT pos = int_bit_position (fld); + if (have_predecessor_field + && pos <= prev_pos) + return false; + + have_predecessor_field = true; + prev_pos = pos; + if (DECL_BIT_FIELD (fld)) return false;