From: Patrick Palka <ppalka@redhat.com>
To: Jonathan Wakely <jwakely@redhat.com>
Cc: Patrick Palka <ppalka@redhat.com>,
gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org
Subject: Re: [PATCH] libstdc++: Implement ranges::join_with_view from P2441R2
Date: Tue, 4 Oct 2022 10:08:57 -0400 (EDT) [thread overview]
Message-ID: <0c8cf283-5dc4-96a4-1bd7-7aa1ab71656f@idea> (raw)
In-Reply-To: <CACb0b4kTi0xng0t9TerTAe_iW5vzNaMfPdbpvT7WdFj+V8DHWA@mail.gmail.com>
On Tue, 4 Oct 2022, Jonathan Wakely wrote:
> On Tue, 4 Oct 2022 at 02:11, Patrick Palka via Libstdc++
> <libstdc++@gcc.gnu.org> wrote:
> >
> > Tested on x86_64-pc-linux-gnu, does this look OK for trunk? FWIW using
>
> OK, thanks.
Thanks a lot, patch committed.
>
> > variant<_PatternIter, _InnerIter> in the implementation means we need to
> > include <variant> from <ranges>, which increases the preprocessed size
> > of <ranges> by 3% (51.5k vs 53k). I suppose that's an acceptable cost?
>
> Yeah, I don't think we want to reimplement a lightweight std::variant,
> because that would just add even more code.
Sounds good.
>
> As I mentioned on IRC, maybe we could optimize the compilation time
> for some of the visitation using P2637R0, but that can be done later.
Ah, I didn't consider the compile time impact of using std::visit.
Since we already use/instantiate std::get elsewhere in the implementation,
what do you think about doing the visitation manually via index() and
std::get like so? Seems to reduce compile time/memory usage for
join_with/1.cc by around 6% and doesn't look too messy since we're
dealing with only two alternatives. (And IIUC this should be equivalent
to std::visit wrt valueless_by_exception handling, since the call to
std::get<1> in each else branch will throw bad_variant_access for us
like std::visit would.)
-- >8 --
Subject: [PATCH] libstdc++: Avoid std::visit in ranges::join_with_view
libstdc++-v3/ChangeLog:
* include/std/ranges (join_with_view::_Iterator::operator*):
Replace use of std::visit with manual visitation.
(join_with_view::_Iterator::operator++): Likewise.
(join_with_view::_Iterator::operator--): Likewise.
(join_with_view::_Iterator::iter_move): Likewise.
(join_with_view::_Iterator::iter_swap): Likewise.
---
libstdc++-v3/include/std/ranges | 47 +++++++++++++++++++++++++--------
1 file changed, 36 insertions(+), 11 deletions(-)
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index d0d6ce61a87..1f821128d2d 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -7165,18 +7165,23 @@ namespace views::__adaptor
_M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
}
- constexpr decltype(auto)
+ constexpr common_reference_t<iter_reference_t<_InnerIter>,
+ iter_reference_t<_PatternIter>>
operator*() const
{
- using reference = common_reference_t<iter_reference_t<_InnerIter>,
- iter_reference_t<_PatternIter>>;
- return std::visit([](auto& __it) -> reference { return *__it; }, _M_inner_it);
+ if (_M_inner_it.index() == 0)
+ return *std::get<0>(_M_inner_it);
+ else
+ return *std::get<1>(_M_inner_it);
}
constexpr _Iterator&
operator++()
{
- std::visit([](auto& __it){ ++__it; }, _M_inner_it);
+ if (_M_inner_it.index() == 0)
+ ++std::get<0>(_M_inner_it);
+ else
+ ++std::get<1>(_M_inner_it);
_M_satisfy();
return *this;
}
@@ -7232,7 +7237,10 @@ namespace views::__adaptor
}
}
- std::visit([](auto& __it){ --__it; }, _M_inner_it);
+ if (_M_inner_it.index() == 0)
+ --std::get<0>(_M_inner_it);
+ else
+ --std::get<1>(_M_inner_it);
return *this;
}
@@ -7253,18 +7261,35 @@ namespace views::__adaptor
&& equality_comparable<_OuterIter> && equality_comparable<_InnerIter>
{ return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
- friend constexpr decltype(auto)
+ friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
+ iter_rvalue_reference_t<_PatternIter>>
iter_move(const _Iterator& __x)
{
- using __rval_ref = common_reference_t<iter_rvalue_reference_t<_InnerIter>,
- iter_rvalue_reference_t<_PatternIter>>;
- return std::visit<__rval_ref>(ranges::iter_move, __x._M_inner_it);
+ if (__x._M_inner_it.index() == 0)
+ return ranges::iter_move(std::get<0>(__x._M_inner_it));
+ else
+ return ranges::iter_move(std::get<1>(__x._M_inner_it));
}
friend constexpr void
iter_swap(const _Iterator& __x, const _Iterator& __y)
requires indirectly_swappable<_InnerIter, _PatternIter>
- { std::visit(ranges::iter_swap, __x._M_inner_it, __y._M_inner_it); }
+ {
+ if (__x._M_inner_it.index() == 0)
+ {
+ if (__y._M_inner_it.index() == 0)
+ ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
+ else
+ ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
+ }
+ else
+ {
+ if (__y._M_inner_it.index() == 0)
+ ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
+ else
+ ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
+ }
+ }
};
template<input_range _Vp, forward_range _Pattern>
--
2.38.0.rc2
next prev parent reply other threads:[~2022-10-04 14:09 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-04 1:11 Patrick Palka
2022-10-04 11:37 ` Jonathan Wakely
2022-10-04 14:08 ` Patrick Palka [this message]
2022-10-04 14:38 ` Jonathan Wakely
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=0c8cf283-5dc4-96a4-1bd7-7aa1ab71656f@idea \
--to=ppalka@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jwakely@redhat.com \
--cc=libstdc++@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: link
Be 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).