[range.adaptor.object] (original) (raw)
25 Ranges library [ranges]
25.7 Range adaptors [range.adaptors]
25.7.2 Range adaptor objects [range.adaptor.object]
A range adaptor closure object is a unary function object that accepts a range argument.
For a range adaptor closure object C and an expression R such thatdecltype((R)) models range, the following expressions are equivalent:C(R)R | C
Given an additional range adaptor closure object D, the expression C | D produces another range adaptor closure object E.
E is a perfect forwarding call wrapper ([func.require]) with the following properties:
- Its target object is an object d of type decay_t<decltype((D))>direct-non-list-initialized with D.
- It has one bound argument entity, an object c of type decay_t<decltype((C))>direct-non-list-initialized with C.
- Its call pattern is d(c(arg)), where arg is the argument used in a function call expression of E.
The expression C | D is well-formed if and only if the initializations of the state entities of E are all well-formed.
Given an object t of type T, where
- t is a unary function object that accepts a range argument,
- T models derived_from<range_adaptor_closure<T>>,
- T has no other base classes of type range_adaptor_closure<U> for any other type U, and
- T does not model range
then the implementation ensures that t is a range adaptor closure object.
The template parameter D for range_adaptor_closuremay be an incomplete type.
If an expression of type cv Dis used as an operand to the | operator,D shall be complete and model derived_from<range_adaptor_closure<D>>.
The behavior of an expression involving an object of type cv Das an operand to the | operator is undefined if overload resolution selects a program-defined operator| function.
If an expression of type cv Uis used as an operand to the | operator, where U has a base class of type range_adaptor_closure<T>for some type T other than U, the behavior is undefined.
The behavior of a program that adds a specialization for range_adaptor_closure is undefined.
If a range adaptor object accepts only one argument, then it is a range adaptor closure object.
If a range adaptor object adaptor accepts more than one argument, then let range be an expression such that decltype((range)) models viewable_range, let args... be arguments such that adaptor(range, args...) is a well-formed expression as specified in the rest of subclause [range.adaptors], and let BoundArgs be a pack that denotes decay_t<decltype((args))>....
The expression adaptor(args...) produces a range adaptor closure object fthat is a perfect forwarding call wrapper ([func.require]) with the following properties:
- Its target object is a copy of adaptor.
- Its bound argument entities bound_args consist of objects of types BoundArgs... direct-non-list-initialized with std::forward<decltype((args))>(args)..., respectively.
- Its call pattern is adaptor(r, bound_args...), where r is the argument used in a function call expression of f.
The expression adaptor(args...) is well-formed if and only if the initialization of the bound argument entities of the result, as specified above, are all well-formed.