[view.interface]

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

## 25.5 Range utilities [[range.utility]](range.utility#view.interface)

### 25.5.3 View interface [view.interface]

#### [25.5.3.1](#general) General [[view.interface.general]](view.interface.general)

[1](#general-1)

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

The class template view_interface is a helper for defining
view-like types that offer a container-like interface[.](#general-1.sentence-1)

It is
parameterized with the type that is derived from it[.](#general-1.sentence-2)

[ð](#lib:view_interface)

namespace std::ranges {template<class D>requires is_class_v<D> && [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<D, remove_cv_t<D>>class view_interface {private:constexpr D& *derived*() noexcept { // *exposition only*return static_cast<D&>(*this); }constexpr const D& *derived*() const noexcept { // *exposition only*return static_cast<const D&>(*this); }public:constexpr bool empty() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<D> || [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<D> {if constexpr ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<D>)return ranges::size(*derived*()) == 0; elsereturn ranges::begin(*derived*()) == ranges::end(*derived*()); }constexpr bool empty() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const D> || [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const D> {if constexpr ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const D>)return ranges::size(*derived*()) == 0; elsereturn ranges::begin(*derived*()) == ranges::end(*derived*()); }constexpr auto cbegin() requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<D> {return ranges::cbegin(*derived*()); }constexpr auto cbegin() const requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<const D> {return ranges::cbegin(*derived*()); }constexpr auto cend() requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<D> {return ranges::cend(*derived*()); }constexpr auto cend() const requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<const D> {return ranges::cend(*derived*()); }constexpr explicit operator bool()requires requires { ranges::empty(*derived*()); } {return !ranges::empty(*derived*()); }constexpr explicit operator bool() constrequires requires { ranges::empty(*derived*()); } {return !ranges::empty(*derived*()); }constexpr auto data() requires [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14 Concept contiguous_­iterator [iterator.concept.contiguous]")<iterator_t<D>> {return to_address(ranges::begin(*derived*())); }constexpr auto data() constrequires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const D> && [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14 Concept contiguous_­iterator [iterator.concept.contiguous]")<iterator_t<const D>> {return to_address(ranges::begin(*derived*())); }constexpr auto size() requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<D> &&[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<sentinel_t<D>, iterator_t<D>> {return *to-unsigned-like*(ranges::end(*derived*()) - ranges::begin(*derived*())); }constexpr auto size() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const D> &&[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<sentinel_t<const D>, iterator_t<const D>> {return *to-unsigned-like*(ranges::end(*derived*()) - ranges::begin(*derived*())); }constexpr decltype(auto) front() requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<D>; constexpr decltype(auto) front() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const D>; constexpr decltype(auto) back() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<D> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<D>; constexpr decltype(auto) back() constrequires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<const D> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const D>; template<[random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]") R = D>constexpr decltype(auto) operator[](range_difference_t<R> n) {return ranges::begin(*derived*())[n]; }template<[random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]") R = const D>constexpr decltype(auto) operator[](range_difference_t<R> n) const {return ranges::begin(*derived*())[n]; }};}

[2](#general-2)

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

The template parameter D for view_interface may be an
incomplete type[.](#general-2.sentence-1)

Before any member of the resulting specialization ofview_interface other than special member functions
is referenced, D shall be complete, and
model both [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_­from [concept.derived]")<view_interface<D>> and [view](range.view#concept:view "25.4.5 Views [range.view]")[.](#general-2.sentence-2)

#### [25.5.3.2](#members) Members [[view.interface.members]](view.interface.members)

[ð](#lib:front,view_interface)

`constexpr decltype(auto) front() requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<D>;
constexpr decltype(auto) front() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const D>;
`

[1](#members-1)

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

*Hardened preconditions*: !empty() is true[.](#members-1.sentence-1)

[2](#members-2)

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

*Effects*: Equivalent to: return *ranges​::​begin(*derived*());

[ð](#lib:back,view_interface)

`constexpr decltype(auto) back() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<D> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<D>;
constexpr decltype(auto) back() const
  requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<const D> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const D>;
`

[3](#members-3)

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

*Hardened preconditions*: !empty() is true[.](#members-3.sentence-1)

[4](#members-4)

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

*Effects*: Equivalent to: return *ranges​::​prev(ranges​::​end(*derived*()));
