public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Aldy Hernandez <aldyh@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc/devel/ranger] libstdc++: Add missing friend declarations in some range adaptors Date: Wed, 17 Jun 2020 19:16:07 +0000 (GMT) [thread overview] Message-ID: <20200617191607.AF4A03956837@sourceware.org> (raw) https://gcc.gnu.org/g:ba49e9eb18730cc71e5ffc302092f87ef6821f24 commit ba49e9eb18730cc71e5ffc302092f87ef6821f24 Author: Patrick Palka <ppalka@redhat.com> Date: Wed Feb 26 12:31:01 2020 -0500 libstdc++: Add missing friend declarations in some range adaptors Some of the range adaptors have distinct constant and non-constant iterator/sentinel types, along with converting constructors that can convert a non-constant iterator/sentinel to a constant iterator/sentinel. This patch adds the missing appropriate friend declarations in order to make these converting constructors well formed. Strictly speaking it seems the friendship relations don't need to go both ways -- we could get away with declaring e.g. friend _Iterator<false>; instead of friend _Iterator<!_Const>; but both reference implementations seem to use the latter symmetric form anyway. libstdc++-v3/ChangeLog: * include/std/ranges (transform_view::_Iterator<_Const>): Befriend _Iterator<!_Const>. (transform_view::_Sentinel<_Const>): Befriend _Sentinel<!_Const>. (take_view::_Sentinel<_Const>): Likewise. (take_while_view::_Sentinel<_Const>): Likewise. (split_view::_OuterIter<_Const>): Befriend _OuterIter<!_Const>. * testsuite/std/ranges/adaptors/split.cc: Augment test. * testsuite/std/ranges/adaptors/take.cc: Augment test. * testsuite/std/ranges/adaptors/take_while.cc: Augment test. * testsuite/std/ranges/adaptors/transform.cc: Augment test. Diff: --- libstdc++-v3/ChangeLog | 11 +++++++++++ libstdc++-v3/include/std/ranges | 8 ++++++++ .../testsuite/std/ranges/adaptors/split.cc | 14 +++++++++++++ libstdc++-v3/testsuite/std/ranges/adaptors/take.cc | 16 +++++++++++++++ .../testsuite/std/ranges/adaptors/take_while.cc | 17 ++++++++++++++++ .../testsuite/std/ranges/adaptors/transform.cc | 23 ++++++++++++++++++++++ 6 files changed, 89 insertions(+) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b3efeae221a..dd28617d8d9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,16 @@ 2020-02-27 Patrick Palka <ppalka@redhat.com> + * include/std/ranges (transform_view::_Iterator<_Const>): Befriend + _Iterator<!_Const>. + (transform_view::_Sentinel<_Const>): Befriend _Sentinel<!_Const>. + (take_view::_Sentinel<_Const>): Likewise. + (take_while_view::_Sentinel<_Const>): Likewise. + (split_view::_OuterIter<_Const>): Befriend _OuterIter<!_Const>. + * testsuite/std/ranges/adaptors/split.cc: Augment test. + * testsuite/std/ranges/adaptors/take.cc: Augment test. + * testsuite/std/ranges/adaptors/take_while.cc: Augment test. + * testsuite/std/ranges/adaptors/transform.cc: Augment test. + * testsuite/25_algorithms/copy/constrained.cc: Don't assume that the base() of a vector<>::iterator is a pointer. * testsuite/25_algorithms/copy_backward/constrained.cc: Likewise. diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index bad89c5b8b0..38d497ec88e 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -1759,6 +1759,7 @@ namespace views requires indirectly_swappable<_Base_iter> { return ranges::iter_swap(__x._M_current, __y._M_current); } + friend _Iterator<!_Const>; friend _Sentinel<_Const>; }; @@ -1811,6 +1812,8 @@ namespace views operator-(const _Sentinel& __y, const _Iterator<_Const>& __x) requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>> { return __y.__distance_from(__x); } + + friend _Sentinel<!_Const>; }; _Vp _M_base = _Vp(); @@ -1916,6 +1919,8 @@ namespace views friend constexpr bool operator==(const _CI& __y, const _Sentinel& __x) { return __y.count() == 0 || __y.base() == __x._M_end; } + + friend _Sentinel<!_Const>; }; _Vp _M_base = _Vp(); @@ -2055,6 +2060,8 @@ namespace views friend constexpr bool operator==(const iterator_t<_Base>& __x, const _Sentinel& __y) { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); } + + friend _Sentinel<!_Const>; }; _Vp _M_base = _Vp(); @@ -2730,6 +2737,7 @@ namespace views operator==(const _OuterIter& __x, default_sentinel_t) { return __x.__at_end(); }; + friend _OuterIter<!_Const>; friend _InnerIter<_Const>; }; diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/split.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/split.cc index 52b015cf0c6..e7556725e4f 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/split.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/split.cc @@ -108,6 +108,19 @@ test05() str | views::filter(not_space_p)) ); } +void +test06() +{ + std::string str = "hello world"; + auto v = str | views::transform(std::identity{}) | views::split(' '); + + // Verify that _Iterator<false> is implicitly convertible to _Iterator<true>. + static_assert(!std::same_as<decltype(ranges::begin(v)), + decltype(ranges::cbegin(v))>); + auto b = ranges::cbegin(v); + b = ranges::begin(v); +} + int main() { @@ -116,4 +129,5 @@ main() test03(); test04(); test05(); + test06(); } diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc index e2d2edbe0a8..c42505b44cb 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc @@ -19,6 +19,7 @@ // { dg-do run { target c++2a } } #include <algorithm> +#include <forward_list> #include <ranges> #include <testsuite_hooks.h> #include <testsuite_iterators.h> @@ -85,6 +86,20 @@ test04() VERIFY( ranges::equal(v | views::take(5), (int[]){1,2,3}) ); } +void +test05() +{ + std::forward_list<int> x = {1,2,3,4,5}; + auto v = x | views::transform(std::negate{}) | views::take(4); + + // Verify that _Sentinel<false> is implicitly convertible to _Sentinel<true>. + static_assert(!ranges::common_range<decltype(v)>); + static_assert(!std::same_as<decltype(ranges::end(v)), + decltype(ranges::cend(v))>); + auto b = ranges::cend(v); + b = ranges::end(v); +} + int main() { @@ -92,4 +107,5 @@ main() test02(); test03(); test04(); + test05(); } diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/take_while.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/take_while.cc index b261ffd1aae..d587127b97e 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/take_while.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/take_while.cc @@ -19,6 +19,7 @@ // { dg-do run { target c++2a } } #include <algorithm> +#include <forward_list> #include <ranges> #include <testsuite_hooks.h> #include <testsuite_iterators.h> @@ -54,9 +55,25 @@ test02() static_assert(ranges::forward_range<R>); } +void +test03() +{ + std::forward_list<int> x = {1,2,3,4,5}; + auto v + = x | views::transform(std::negate{}) | views::take_while(std::identity{}); + + // Verify that _Sentinel<false> is implicitly convertible to _Sentinel<true>. + static_assert(!ranges::common_range<decltype(v)>); + static_assert(!std::same_as<decltype(ranges::end(v)), + decltype(ranges::cend(v))>); + auto b = ranges::cend(v); + b = ranges::end(v); +} + int main() { test01(); test02(); + test03(); } diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc index 178544d6378..c14e36e0cef 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc @@ -100,6 +100,28 @@ test04() } } +void +test05() +{ + int x[] = {1,2,3,4,5}; + auto i = std::counted_iterator(x, 5); + auto r = ranges::subrange{i, std::default_sentinel}; + auto v = r | views::transform(std::negate{}); + + // Verify that _Iterator<false> is implicitly convertible to _Iterator<true>. + static_assert(!std::same_as<decltype(ranges::begin(v)), + decltype(ranges::cbegin(v))>); + auto a = ranges::cbegin(v); + a = ranges::begin(v); + + // Verify that _Sentinel<false> is implicitly convertible to _Sentinel<true>. + static_assert(!ranges::common_range<decltype(v)>); + static_assert(!std::same_as<decltype(ranges::end(v)), + decltype(ranges::cend(v))>); + auto b = ranges::cend(v); + b = ranges::end(v); +} + int main() { @@ -107,4 +129,5 @@ main() test02(); test03(); test04(); + test05(); }
reply other threads:[~2020-06-17 19:16 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200617191607.AF4A03956837@sourceware.org \ --to=aldyh@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).