* [committed] libstdc++: Make non-propagating-cache fully constexpr [PR101263]
@ 2021-10-15 17:30 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2021-10-15 17:30 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 385 bytes --]
libstdc++-v3/ChangeLog:
PR libstdc++/101263
* include/std/ranges (__cached): New wrapper struct.
(__non_propagating_cache): Use __cached for contained value.
(__non_propagating_cache::_M_emplace_deref): Add constexpr. Use
std::construct_at instead of placement new.
* testsuite/std/ranges/adaptors/join.cc: Check constexpr works.
Tested powerpc64le-linux. Committed to trunk.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 3378 bytes --]
commit 2c564e813c0626802e5bfb066c094933d5e6a774
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Fri Oct 15 14:49:21 2021
libstdc++: Make non-propagating-cache fully constexpr [PR101263]
libstdc++-v3/ChangeLog:
PR libstdc++/101263
* include/std/ranges (__cached): New wrapper struct.
(__non_propagating_cache): Use __cached for contained value.
(__non_propagating_cache::_M_emplace_deref): Add constexpr. Use
std::construct_at instead of placement new.
* testsuite/std/ranges/adaptors/join.cc: Check constexpr works.
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 07eae0cf94b..b8de400dfbb 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1159,9 +1159,34 @@ namespace views::__adaptor
// (such as join_view::_M_inner).
};
+ template<typename _Tp>
+ struct __cached
+ {
+ struct _Deref_t { };
+ static constexpr _Deref_t __deref{};
+
+ // Initialize _M_t directly from the result of dereferencing __i.
+ // This avoids any unwanted temporary materialization that would
+ // occur if *__i was bound to a reference before initializing _M_t.
+ template<typename _Iter>
+ constexpr explicit
+ __cached(_Deref_t, _Iter&& __i)
+ : _M_t(*__i)
+ { }
+
+ template<typename... _Args>
+ constexpr explicit
+ __cached(_Args&&... __args)
+ : _M_t(std::forward<_Args>(__args)...)
+ { }
+
+ _Tp _M_t;
+ };
+
template<typename _Tp>
requires is_object_v<_Tp>
- struct __non_propagating_cache<_Tp> : protected _Optional_base<_Tp>
+ struct __non_propagating_cache<_Tp>
+ : protected _Optional_base<__cached<_Tp>>
{
__non_propagating_cache() = default;
@@ -1205,23 +1230,22 @@ namespace views::__adaptor
constexpr _Tp&
operator*() noexcept
- { return this->_M_get(); }
+ { return this->_M_get()._M_t; }
constexpr const _Tp&
operator*() const noexcept
- { return this->_M_get(); }
+ { return this->_M_get()._M_t; }
template<typename _Iter>
- _Tp&
+ constexpr _Tp&
_M_emplace_deref(const _Iter& __i)
{
this->_M_reset();
- // Using _Optional_base::_M_construct to initialize from '*__i'
- // would incur an extra move due to the indirection, so we instead
- // use placement new directly.
- ::new ((void *) std::__addressof(this->_M_payload._M_payload)) _Tp(*__i);
+ // Use the special constructor of __cached<_Tp> that does *__i.
+ std::construct_at(std::__addressof(this->_M_payload._M_payload),
+ std::in_place, __cached<_Tp>::__deref, __i);
this->_M_payload._M_engaged = true;
- return this->_M_get();
+ return **this;
}
};
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
index 50af3fdf729..1ec42381ad2 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
@@ -193,6 +193,18 @@ test11()
;
}
+void
+test12()
+{
+ // PR libstdc++/101263
+ constexpr auto b = [] {
+ auto r = std::views::iota(0, 5)
+ | std::views::lazy_split(0)
+ | std::views::join;
+ return r.begin() != r.end();
+ }();
+}
+
int
main()
{
@@ -207,4 +219,5 @@ main()
test09();
test10();
test11();
+ test12();
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-10-15 17:30 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-15 17:30 [committed] libstdc++: Make non-propagating-cache fully constexpr [PR101263] Jonathan Wakely
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).