C++ named requirements: RangeAdaptorClosureObject (since C++20)
Range adaptor closure objects are FunctionObjects that take one viewable_range
(until C++23) range
(since C++23) as its only argument and returns a view
(until C++23). They are callable via the pipe operator: if C is a range adaptor closure object and R is a viewable_range
(until C++23) range
(since C++23), these two expressions are equivalent (both wellformed or illformed):
C(R) R  C
Two range adaptor closure objects can be chained by operator to produce another range adaptor closure object: if C and D are range adaptor closure objects, then C  D is also a range adaptor closure object if it is valid.
The bound arguments of C  D is determined as follows:
 there is a subobject in the result object of the same type (cvqualification discarded) for every subobject in both operands that is a bound argument,
 such a bound argument is directnonlistinitialized with the source subobject in its containing operand, where the source is identically treated as lvalue or rvalue and cvqualified to the operand,
 the result is valid if and only if the initialization of all bound arguments are valid.
The effect and validity of the operator() of the result is determined as follows: given a viewable_range
(until C++23) range
(since C++23) R, these two expressions are equivalent (both wellformed or illformed):
R  C  D // (R  C)  D R  (C  D)
Notes: operator() is unsupported for volatilequalified or constvolatilequalified version of range adaptor object closure types.
Objects whose type is the same as one of the following objects (ignoring cvqualification) are range adaptor closure objects:
 unary range adaptor objects,

(since C++23) 
 the results of binding trailing arguments by range adaptor objects, and
 the results of chaining two range adaptor closure objects by operator.
Let 
(since C++23) 