[PATCH] D134076: RFC - [ADT] Ranges pipe syntax support + SFINAE

James Player via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 16 14:09:19 PDT 2022


jplayer-nv created this revision.
jplayer-nv added a project: LLVM.
Herald added a subscriber: mgorny.
Herald added a project: All.
jplayer-nv requested review of this revision.
Herald added a subscriber: llvm-commits.

Implement the following view adapters (per the C++20 ranges spec):

- views::iota (mostly accurate, mismatched bound type not implemented)
- views::reverse
- views::early_inc (not C++20, but follows the same form as other view adapters)
- views::filter
- views::transform
- views::keys
- views::values
- views::elements
- views::take
- views::drop
- views::take_while
- views::drop_while

All above support both the functional syntax as well as the pipe syntax:

  int Test[] { 1, 2, 3 };
  auto Range1 = views::drop(Test, 1);
  auto Range2 = Test | views::drop(1);

Pipe closures can be stored to named temporaries and applied later:

  auto LT100 = [](auto X){ return X < 100; };
  
  // Store sequence of adapters to a named variable.
  auto Closure = views::take_while(LT100) | views::reverse | views::drop(1);
  
  int Test[]{ 1, 2, 3, 4, 101, 102, 103 };
  
  // Apply closure sequence.
  dbgs() << (Test | Closure) << '\n';
  // Output: { 3, 2, 1 }

Additionally, implemented certain overloads of `std::ranges::to()` from the C++23 spec to enable simplified range to storage conversion:

  int Test[]{1, 2, 3};
  auto Vec = Test | views::reverse | to<SmallVector<int>>();

There are a few other things I would like to add to the `iterator_range` class which I would like to discuss:

- Templated comparison of at least one `iterator_range` parameter.  (I would like to add a non-templated base class to `iterator_range` to make the SFINAE more robust).
- operator<<() overload for `iterator_range`.
- Internally, `iterator_range` should call `adl_begin` + `adl_end` in the container constructor.

Another fix I've applied in this patch is to wrap my callable objects in a template (Callable<T>).  This enables copy assignments for any callable type.  I discovered this in the TOT range adapter code while converting ranges to a `std::deque` on clang 10.  In that implementation, there is a copy-assignment of the input iterator (which breaks TOT code).

Additionally, everywhere `begin` and `end` member functions are called, I think we should call `adl_begin` and `adl_end` to enable C-array support for the ranges code.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134076

Files:
  llvm/include/llvm/ADT/Callable.h
  llvm/include/llvm/ADT/Closure.h
  llvm/include/llvm/ADT/Ranges.h
  llvm/include/llvm/ADT/RangesConcepts.h
  llvm/include/llvm/ADT/STLExtras.h
  llvm/unittests/ADT/CMakeLists.txt
  llvm/unittests/ADT/RangesTest.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D134076.460888.patch
Type: text/x-patch
Size: 85166 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220916/3b66a946/attachment-0001.bin>


More information about the llvm-commits mailing list