[libcxx-commits] [PATCH] D119057: [libc++][ranges] Implement rbegin, rend, crbegin and crend.

Konstantin Varlamov via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Feb 4 23:04:16 PST 2022


var-const added inline comments.


================
Comment at: libcxx/include/__ranges/access.h:260
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
+    requires (sizeof(*__t) != 0) // Disallow incomplete element types.
+  {
----------------
"Otherwise, if `T` is an array type (`[term.array.type]`) and `remove_­all_­extents_­t<T>` is an incomplete type, `ranges​::​rbegin(E)` is ill-formed with no diagnostic required."


================
Comment at: libcxx/include/__ranges/access.h:267
+    requires __member_rbegin<_Tp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rbegin())))
----------------
"Otherwise, if `auto(t.rbegin())` is a valid expression whose type models `input_­or_­output_­iterator`, `ranges​::​rbegin(E)` is expression-equivalent to `auto(t.rbegin())`."


================
Comment at: libcxx/include/__ranges/access.h:275
+    requires __unqualified_rbegin<_Tp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(_LIBCPP_AUTO_CAST(rbegin(__t))))
----------------
"Otherwise, if `T` is a class or enumeration type and `auto(rbegin(t))` is a valid expression whose type models `input_­or_­output_­iterator` with overload resolution performed in a context in which unqualified lookup for `rbegin` finds only the declarations
```
void rbegin(auto&) = delete;
void rbegin(const auto&) = delete;
```
then `ranges​::​rbegin(E)` is expression-equivalent to `auto(rbegin(t))` with overload resolution performed in the above context."


================
Comment at: libcxx/include/__ranges/access.h:283
+    requires __can_reverse<_Tp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(end(__t)))
----------------
"Otherwise, if both ranges​::​begin(t) and ranges​::​end(t) are valid expressions of the same type which models bidirectional_­iterator ([iterator.concept.bidir]), ranges​::​rbegin(E) is expression-equivalent to make_­reverse_­iterator(ranges​::​end(t))."


================
Comment at: libcxx/include/__ranges/access.h:332
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
+    requires (sizeof(*__t) != 0) // Disallow incomplete element types.
+  {
----------------
"Otherwise, if `T` is an array type (`[term.array.type]`) and `remove_­all_­extents_­t<T>` is an incomplete type, `ranges​::​rend(E)` is ill-formed with no diagnostic required."


================
Comment at: libcxx/include/__ranges/access.h:339
+    requires __member_rend<_Tp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rend())))
----------------
"Otherwise, if `auto(t.rend())` is a valid expression whose type models `sentinel_­for<decltype(​ranges​::​rbegin(E))>` then `ranges​::​rend(E)` is expression-equivalent to `auto(t.rend())`."


================
Comment at: libcxx/include/__ranges/access.h:347
+    requires __unqualified_rend<_Tp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(_LIBCPP_AUTO_CAST(rend(__t))))
----------------
"Otherwise, if `T` is a class or enumeration type and `auto(rend(t))` is a valid expression whose type models `sentinel_­for<decltype(ranges​::​rbegin(E))>` with overload resolution performed in a context in which unqualified lookup for `rend` finds only the declarations
```
void rend(auto&) = delete;
void rend(const auto&) = delete;
```
then `ranges​::​rend(E)` is expression-equivalent to `auto(rend(t))` with overload resolution performed in the above context."


================
Comment at: libcxx/include/__ranges/access.h:355
+    requires __can_reverse<_Tp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(end(__t)))
----------------
"Otherwise, if both `ranges​::​begin(t)` and `ranges​::​end(t)` are valid expressions of the same type which models `bidirectional_­iterator` (`[iterator.concept.bidir]`), then `ranges​::​rend(E)` is expression-equivalent to `make_­reverse_­iterator(ranges​::​begin(t))`."


================
Comment at: libcxx/test/std/ranges/range.access/begin.pass.cpp:91
 
-struct BeginMemberFunction {
-  int x;
----------------
I reordered class definitions to be in the order in which they are used in the test function.


================
Comment at: libcxx/test/std/ranges/range.access/rbegin.pass.cpp:1
+//===----------------------------------------------------------------------===//
+//
----------------
Note: these tests are largely copied from `begin.pass.cpp` (same with `rend.pass.cpp`).


================
Comment at: libcxx/test/std/ranges/range.access/rbegin.pass.cpp:301
+
+struct MemberBeginEnd {
+  int b, e;
----------------
Note: these tests (up to and including `testBeginEnd`) are new (same in `rend.pass.cpp`).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D119057/new/

https://reviews.llvm.org/D119057



More information about the libcxx-commits mailing list