[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 {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](#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]")> 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]"); constexpr decltype(auto) front() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"); ` [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]") && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]"); constexpr decltype(auto) back() const 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]"); ` [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*()));