[libcxx-commits] [libcxx] [libc++][ranges] P2387R3: Pipe support for user-defined range adaptors (PR #89148)

Xiaoyang Liu via libcxx-commits libcxx-commits at lists.llvm.org
Mon Apr 22 09:40:57 PDT 2024


================
@@ -52,15 +54,21 @@ struct __range_adaptor_closure_t : _Fn, __range_adaptor_closure<__range_adaptor_
 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__range_adaptor_closure_t);
 
 template <class _Tp>
-concept _RangeAdaptorClosure = derived_from<remove_cvref_t<_Tp>, __range_adaptor_closure<remove_cvref_t<_Tp>>>;
+_Tp __derived_from_range_adaptor_closure(__range_adaptor_closure<_Tp>*);
 
 template <class _Tp>
+concept _RangeAdaptorClosure = !ranges::range<remove_cvref_t<_Tp>> && requires {
+  { __derived_from_range_adaptor_closure((remove_cvref_t<_Tp>*)nullptr) } -> same_as<remove_cvref_t<_Tp>>;
+};
----------------
xiaoyang-sde wrote:

Thanks for the suggestion! I believe these test cases already cover this subtlety:

```cpp
// `not_derived_from_3` doesn't derive from the correct specialization of `std::ranges::range_adaptor_closure`
struct not_derived_from_3 : std::ranges::range_adaptor_closure<callable> {
  static void operator()(const range_t&) {}
};
static_assert(!RangeAdaptorClosure<not_derived_from_3>);

// `not_derived_from_4` doesn't derive from exactly one `std::ranges::range_adaptor_closure`
struct not_derived_from_4
    : std::ranges::range_adaptor_closure<not_derived_from_4>,
      std::ranges::range_adaptor_closure<callable> {
  static void operator()(const range_t&) {}
};
static_assert(!RangeAdaptorClosure<not_derived_from_4>);
```

https://github.com/llvm/llvm-project/pull/89148


More information about the libcxx-commits mailing list