[libcxx-commits] [PATCH] D142335: [libc++][ranges] Implement `ranges::to`.

Louis Dionne via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 18 13:05:58 PDT 2023


ldionne accepted this revision.
ldionne added a comment.

LGTM with comments. Thanks, I think this is great!



================
Comment at: libcxx/include/__ranges/to.h:164
+    if constexpr (requires { _Container(std::declval<_Range>(), std::declval<_Args>()...); }) {
+      using _Result = decltype( //
+          _Container(std::declval<_Range>(), std::declval<_Args>()...));
----------------
IMO this would fit nicely on a single line. Same below. Or make sure they line up with the `if constexpr` condition.


================
Comment at: libcxx/include/__ranges/to.h:220-221
+      !is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile");
+
+  return __range_adaptor_closure_t(std::__bind_back(__to_nondeduced<_Container>(), std::forward<_Args>(__args)...));
+}
----------------
Would it be reasonable to try using a lambda here? Something like

```
auto __to_func = []<input_range _Range, class... _Args>(_Range&& __range, _Args&&... __args) -> _Container 
 requires requires { ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Args>(__args)...) }
{ return ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Args>(__args)...); };

return __range_adaptor_closure_t(std::__bind_back(__to_func, std::forward<_Args>(__args)...));
```

It's more compact and a bit more localized. Your call.


================
Comment at: libcxx/include/__ranges/to.h:67-69
+template <class _Container, class _Range>
+concept __can_try_convert_without_recursion =  !input_range<_Container> ||
+    convertible_to<range_reference_t<_Range>, range_value_t<_Container>>;
----------------
var-const wrote:
> ldionne wrote:
> > Maybe `__does_not_require_recursive_conversion`? Or `__try_non_recursive_conversion`? Or maybe just inline that in the function below and use an inline `requires`?
> Went with `__try_non_recursive_conversion` (unless you feel strongly about inlining it).
Re-reading it, I think it would be a lot more readable to inline, especially since there's an `else if` with the `input_range<_Container>` constraint.


================
Comment at: libcxx/include/__ranges/to.h:161
+        _Container(std::declval<_Range>(), std::declval<_Args>()...));
+      return (_Result*){};
+
----------------
var-const wrote:
> philnik wrote:
> > ldionne wrote:
> > > 
> > I think adding and removing a pointer is actually more efficient thann using `type_identity`, since adding a pointer and removing it avoids instantiating a new type every time.
> Tagging @ldionne 
IMO `type_identity` is a lot more explicit about what we're doing. Between instantiating `type_identity` and `remove_pointer_t`, I think the difference is negligible.


================
Comment at: libcxx/test/std/ranges/range.utility/range.utility.conv/container.h:1
+//===----------------------------------------------------------------------===//
+//
----------------
Did you `clang-format` this?


================
Comment at: libcxx/test/std/ranges/range.utility/range.utility.conv/to.pass.cpp:13-14
+//   constexpr C to(R&& r, Args&&... args);     // Since C++23
+// template<template<class...> class C, input_range R, class... Args>
+//   constexpr auto to(R&& r, Args&&... args);  // Since C++23
+
----------------
I think this should be removed now.


================
Comment at: libcxx/test/std/ranges/range.utility/range.utility.conv/to.pass.cpp:47
+  // Deliberately not defining `iterator_category` to make sure this class satisfies the `input_iterator` concept but
+  // would fail `derived_from<iterator_category, input_iterator_tag`.
+
----------------



================
Comment at: libcxx/test/std/ranges/range.utility/range.utility.conv/to.pass.cpp:513
+
+constexpr void test_recursive() {
+  using C1 = Container<int, CtrChoice::DirectCtr>;
----------------
Ok I love this! I was looking for something like it.


================
Comment at: libcxx/test/std/ranges/range.utility/range.utility.conv/to_deduction.pass.cpp:12
+// trunk -- `clang-17` should be removed from the failing list once that version of Clang is in the Docker image.
+// XFAIL: clang-16, clang-17, apple-clang-15
+
----------------



================
Comment at: libcxx/test/std/ranges/range.utility/range.utility.conv/to_deduction.pass.cpp:14-15
+
+// template<class C, input_range R, class... Args> requires (!view<C>)
+//   constexpr C to(R&& r, Args&&... args);     // Since C++23
+// template<template<class...> class C, input_range R, class... Args>
----------------
I think this should be removed now.


================
Comment at: libcxx/test/std/ranges/range.utility/range.utility.conv/to_std_containers.pass.cpp:11-14
+// template<class C, input_range R, class... Args> requires (!view<C>)
+//   constexpr C to(R&& r, Args&&... args);     // Since C++23
+// template<template<class...> class C, input_range R, class... Args>
+//   constexpr auto to(R&& r, Args&&... args);  // Since C++23
----------------
Let's update this comment to explain that we are testing general interoperation between std containers. That's what we're doing right?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D142335



More information about the libcxx-commits mailing list