[view.interface.general] # 25 Ranges library [[ranges]](./#ranges) ## 25.5 Range utilities [[range.utility]](range.utility#view.interface.general) ### 25.5.3 View interface [[view.interface]](view.interface#general) #### 25.5.3.1 General [view.interface.general] [1](#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[.](#1.sentence-1) It is parameterized with the type that is derived from it[.](#1.sentence-2) [🔗](#lib:view_interface) namespace std::ranges {templaterequires is_class_v && [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>class view_interface {private:constexpr D& *derived*() noexcept { // *exposition only*return static_cast(*this); }constexpr const D& *derived*() const noexcept { // *exposition only*return static_cast(*this); }public:constexpr bool empty() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") || [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") {if constexpr ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"))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]") || [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") {if constexpr ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"))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]") {return ranges::cbegin(*derived*()); }constexpr auto cbegin() const requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") {return ranges::cbegin(*derived*()); }constexpr auto cend() requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") {return ranges::cend(*derived*()); }constexpr auto cend() const requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") {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]")> {return to_address(ranges::begin(*derived*())); }constexpr auto data() constrequires [range](range.range#concept:range "25.4.2 Ranges [range.range]") && [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14 Concept contiguous_­iterator [iterator.concept.contiguous]")> {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]") &&[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t> {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]") &&[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t> {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]"); constexpr decltype(auto) front() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"); constexpr decltype(auto) back() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]") && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]"); constexpr decltype(auto) back() constrequires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]") && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]"); 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 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 n) const {return ranges::begin(*derived*())[n]; }};} [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1867) The template parameter D for view_interface may be an incomplete type[.](#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]")> and [view](range.view#concept:view "25.4.5 Views [range.view]")[.](#2.sentence-2)