[libcxx-commits] [PATCH] D117044: [libc++] [ranges] Implement ranges::cdata
Arthur O'Dwyer via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jan 11 19:13:42 PST 2022
Quuxplusone marked 3 inline comments as done.
Quuxplusone added inline comments.
================
Comment at: libcxx/include/__ranges/data.h:76
+
+namespace ranges {
+namespace __cdata {
----------------
var-const wrote:
> Is there any reason to close the `ranges` namespace above and then reopen it here?
https://reviews.llvm.org/D89057#inline-1117677
(Also consistency with all the other CPOs at this point, but then, I wrote them ;))
================
Comment at: libcxx/include/__ranges/data.h:78
+namespace __cdata {
+ struct __fn {
+ template <class _Tp>
----------------
var-const wrote:
> I think we agreed to only indent inside `__cpo` namespaces, so this struct should not have any extra indentation.
True, we did. But I guess I only took that as far as reverting the indentation in `uninitialized_foo`; I didn't actually go //remove// the existing indentation in `begin`/`end`/`cbegin`/etc. This was copied from `cbegin`. I'll go remove that existing indentation tomorrow, unless someone else objects before then (which will certainly give me enough of an excuse to avoid doing it, again ;))
================
Comment at: libcxx/include/__ranges/data.h:83-85
+ noexcept(noexcept(ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t))))
+ -> decltype( ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)))
+ { return ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)); }
----------------
philnik wrote:
> The standard only says `static_cast<const T&>()`, but that doesn't make much sense, so I'm guessing that's a wording defect?
Serendipitously, Casey Carter emphasized the answer [just today in D116991](https://reviews.llvm.org/D116991#inline-1119857). The standard uses `T` to refer to the "type" of the expression, which is never a reference type (although it may be cv-qualified). On paper, you can have an lvalue expression of type `const int`, but you //can't// have an lvalue expression of type `const int&`. So when in libc++ we take a parameter of declared type `_Tp&&`, that corresponds to a paper expression E of "type" `remove_reference_t<_Tp>`.
TLDR the standard is correct as written; the trick is that its notion of "type `T`" is not the same as our `_Tp` here.
================
Comment at: libcxx/include/__ranges/data.h:84
+ noexcept(noexcept(ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t))))
+ -> decltype( ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)))
+ { return ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)); }
----------------
var-const wrote:
> Question: would `decltype(auto)` work here?
No, because we need SFINAE.
This is the "you must write it three times" idiom; see Vittorio Romeo's 2017 lightning talk https://www.youtube.com/watch?v=I3T4lePH-yA
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D117044/new/
https://reviews.llvm.org/D117044
More information about the libcxx-commits
mailing list