[range.adaptor.object]

# 25 Ranges library [[ranges]](./#ranges)

## 25.7 Range adaptors [[range.adaptors]](range.adaptors#range.adaptor.object)

### 25.7.2 Range adaptor objects [range.adaptor.object]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4206)

A [*range adaptor closure object*](#def:range_adaptor_closure_object) is a unary function object that accepts
a range argument[.](#1.sentence-1)

For
a range adaptor closure object C and an expression R such thatdecltype((R)) models [range](range.range#concept:range "25.4.2 Ranges [range.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[.](#1.sentence-3)

E is a perfect forwarding call wrapper ([[func.require]](func.require#term.perfect.forwarding.call.wrapper "22.10.4 Requirements"))
with the following properties:

- [(1.1)](#1.1)

  Its target object is an object d of type decay_t<decltype((D))> direct-non-list-initialized with D[.](#1.1.sentence-1)

- [(1.2)](#1.2)

  It has one bound argument entity,
an object c of type decay_t<decltype((C))> direct-non-list-initialized with C[.](#1.2.sentence-1)

- [(1.3)](#1.3)

  Its call pattern is d(c(arg)),
where arg is the argument used in
a function call expression of E[.](#1.3.sentence-1)

The expression C | D is well-formed if and only if
the initializations of the state entities of E are all well-formed[.](#1.sentence-5)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4237)

Given an object t of type T, where

- [(2.1)](#2.1)

t is a unary function object that accepts a range argument,

- [(2.2)](#2.2)

T models [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_­from [concept.derived]")<range_adaptor_closure<T>>,

- [(2.3)](#2.3)

T has no other base classes of type range_adaptor_closure<U> for any other type U, and

- [(2.4)](#2.4)

T does not model [range](range.range#concept:range "25.4.2 Ranges [range.range]")

then the implementation ensures
that t is a range adaptor closure object[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4252)

The template parameter D for range_adaptor_closure may be an incomplete type[.](#3.sentence-1)

If an expression of type cv D is used as an operand to the | operator,D shall be complete and
model [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_­from [concept.derived]")<range_adaptor_closure<D>>[.](#3.sentence-2)

The behavior of an expression involving an object of type cv D as an operand to the | operator is undefined
if overload resolution selects a program-defined operator| function[.](#3.sentence-3)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4263)

If an expression of type cv U is 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[.](#4.sentence-1)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4269)

The behavior of a program
that adds a specialization for range_adaptor_closure is undefined[.](#5.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4273)

A [*range adaptor object*](#def:range_adaptor_object) is a
customization point object ([[customization.point.object]](customization.point.object "16.3.3.3.5 Customization Point Object types"))
that accepts a [viewable_range](range.refinements#concept:viewable_range "25.4.6 Other range refinements [range.refinements]") as its first argument and returns a view[.](#6.sentence-1)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4278)

If a range adaptor object accepts only one argument,
then it is a range adaptor closure object[.](#7.sentence-1)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4282)

If a range adaptor object adaptor accepts more than one argument,
then let range be an expression
such that decltype((range)) models [viewable_range](range.refinements#concept:viewable_range "25.4.6 Other range refinements [range.refinements]"),
let args... be arguments
such that adaptor(range, args...) is a well-formed expression
as specified in the rest of subclause [[range.adaptors]](range.adaptors "25.7 Range adaptors"), and
let BoundArgs be a pack
that denotes decay_t<decltype((args))>...[.](#8.sentence-1)

The expression adaptor(args...) produces a range adaptor closure object f that is a perfect forwarding call wrapper ([[func.require]](func.require#term.perfect.forwarding.call.wrapper "22.10.4 Requirements")) with the following properties:

- [(8.1)](#8.1)

  Its target object is a copy of adaptor[.](#8.1.sentence-1)

- [(8.2)](#8.2)

  Its bound argument entities bound_args consist of objects of types BoundArgs... direct-non-list-initialized with std​::​forward<decltype((args))>(args)..., respectively[.](#8.2.sentence-1)

- [(8.3)](#8.3)

  Its call pattern is adaptor(r, bound_args...),
where r is the argument used in a function call expression of f[.](#8.3.sentence-1)

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[.](#8.sentence-3)
