xref: /llvm-project/libcxx/include/__ranges/view_interface.h (revision cf09b7dec463178fbdefc72dc262d209d865c1c9)
15671ff20Szoecarver // -*- C++ -*-
25671ff20Szoecarver //===----------------------------------------------------------------------===//
35671ff20Szoecarver //
45671ff20Szoecarver // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
55671ff20Szoecarver // See https://llvm.org/LICENSE.txt for license information.
65671ff20Szoecarver // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
75671ff20Szoecarver //
85671ff20Szoecarver //===----------------------------------------------------------------------===//
9480cd780SLouis Dionne 
105671ff20Szoecarver #ifndef _LIBCPP___RANGES_VIEW_INTERFACE_H
115671ff20Szoecarver #define _LIBCPP___RANGES_VIEW_INTERFACE_H
125671ff20Szoecarver 
13f87aa19bSLouis Dionne #include <__assert>
147bdf4165SArthur O'Dwyer #include <__concepts/derived_from.h>
157bdf4165SArthur O'Dwyer #include <__concepts/same_as.h>
165671ff20Szoecarver #include <__config>
175671ff20Szoecarver #include <__iterator/concepts.h>
185671ff20Szoecarver #include <__iterator/iterator_traits.h>
195671ff20Szoecarver #include <__iterator/prev.h>
20332da1c2SChristopher Di Bella #include <__memory/pointer_traits.h>
215671ff20Szoecarver #include <__ranges/access.h>
22332da1c2SChristopher Di Bella #include <__ranges/concepts.h>
235671ff20Szoecarver #include <__ranges/empty.h>
24*cf09b7deSXiaoyang Liu #include <__ranges/size.h>
25e0a66116SNikolas Klauser #include <__type_traits/is_class.h>
26e0a66116SNikolas Klauser #include <__type_traits/make_unsigned.h>
27e0a66116SNikolas Klauser #include <__type_traits/remove_cv.h>
285671ff20Szoecarver 
295671ff20Szoecarver #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
305671ff20Szoecarver #  pragma GCC system_header
315671ff20Szoecarver #endif
325671ff20Szoecarver 
335671ff20Szoecarver _LIBCPP_BEGIN_NAMESPACE_STD
345671ff20Szoecarver 
354f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
365671ff20Szoecarver 
375671ff20Szoecarver namespace ranges {
385671ff20Szoecarver 
395671ff20Szoecarver template <class _Derived>
405671ff20Szoecarver   requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
412513b790SJoe Loser class view_interface {
__derived()429783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr _Derived& __derived() noexcept {
4340a6be43SJoe Loser     static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
445671ff20Szoecarver     return static_cast<_Derived&>(*this);
455671ff20Szoecarver   }
465671ff20Szoecarver 
__derived()479783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr _Derived const& __derived() const noexcept {
4840a6be43SJoe Loser     static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
495671ff20Szoecarver     return static_cast<_Derived const&>(*this);
505671ff20Szoecarver   }
515671ff20Szoecarver 
525671ff20Szoecarver public:
535671ff20Szoecarver   template <class _D2 = _Derived>
54d153e7d0SLouis Dionne   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
55*cf09b7deSXiaoyang Liu     requires sized_range<_D2> || forward_range<_D2>
565671ff20Szoecarver   {
57*cf09b7deSXiaoyang Liu     if constexpr (sized_range<_D2>) {
58*cf09b7deSXiaoyang Liu       return ranges::size(__derived()) == 0;
59*cf09b7deSXiaoyang Liu     } else {
605671ff20Szoecarver       return ranges::begin(__derived()) == ranges::end(__derived());
615671ff20Szoecarver     }
62*cf09b7deSXiaoyang Liu   }
635671ff20Szoecarver 
645671ff20Szoecarver   template <class _D2 = _Derived>
65d153e7d0SLouis Dionne   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
66*cf09b7deSXiaoyang Liu     requires sized_range<const _D2> || forward_range<const _D2>
675671ff20Szoecarver   {
68*cf09b7deSXiaoyang Liu     if constexpr (sized_range<const _D2>) {
69*cf09b7deSXiaoyang Liu       return ranges::size(__derived()) == 0;
70*cf09b7deSXiaoyang Liu     } else {
715671ff20Szoecarver       return ranges::begin(__derived()) == ranges::end(__derived());
725671ff20Szoecarver     }
73*cf09b7deSXiaoyang Liu   }
745671ff20Szoecarver 
755671ff20Szoecarver   template <class _D2 = _Derived>
769783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool()
requires(_D2 & __t)777bdf4165SArthur O'Dwyer     requires requires(_D2& __t) { ranges::empty(__t); }
785671ff20Szoecarver   {
795671ff20Szoecarver     return !ranges::empty(__derived());
805671ff20Szoecarver   }
815671ff20Szoecarver 
825671ff20Szoecarver   template <class _D2 = _Derived>
839783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const
requires(const _D2 & __t)847bdf4165SArthur O'Dwyer     requires requires(const _D2& __t) { ranges::empty(__t); }
855671ff20Szoecarver   {
865671ff20Szoecarver     return !ranges::empty(__derived());
875671ff20Szoecarver   }
885671ff20Szoecarver 
895671ff20Szoecarver   template <class _D2 = _Derived>
data()909783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr auto data()
915671ff20Szoecarver     requires contiguous_iterator<iterator_t<_D2>>
925671ff20Szoecarver   {
93ac428df4SNikolas Klauser     return std::to_address(ranges::begin(__derived()));
945671ff20Szoecarver   }
955671ff20Szoecarver 
965671ff20Szoecarver   template <class _D2 = _Derived>
data()979783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
985671ff20Szoecarver     requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
995671ff20Szoecarver   {
100ac428df4SNikolas Klauser     return std::to_address(ranges::begin(__derived()));
1015671ff20Szoecarver   }
1025671ff20Szoecarver 
1035671ff20Szoecarver   template <class _D2 = _Derived>
size()1049783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr auto size()
1057bdf4165SArthur O'Dwyer     requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
1065671ff20Szoecarver   {
107c45f382aSIgor Zhukov     return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
1085671ff20Szoecarver   }
1095671ff20Szoecarver 
1105671ff20Szoecarver   template <class _D2 = _Derived>
size()1119783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
1127bdf4165SArthur O'Dwyer     requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
1135671ff20Szoecarver   {
114c45f382aSIgor Zhukov     return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
1155671ff20Szoecarver   }
1165671ff20Szoecarver 
1175671ff20Szoecarver   template <class _D2 = _Derived>
decltype(auto)1189783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front()
1195671ff20Szoecarver     requires forward_range<_D2>
1205671ff20Szoecarver   {
1211638657dSKonstantin Varlamov     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1229783f28cSLouis Dionne         !empty(), "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
1235671ff20Szoecarver     return *ranges::begin(__derived());
1245671ff20Szoecarver   }
1255671ff20Szoecarver 
1265671ff20Szoecarver   template <class _D2 = _Derived>
decltype(auto)1279783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front() const
1285671ff20Szoecarver     requires forward_range<const _D2>
1295671ff20Szoecarver   {
1301638657dSKonstantin Varlamov     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1319783f28cSLouis Dionne         !empty(), "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
1325671ff20Szoecarver     return *ranges::begin(__derived());
1335671ff20Szoecarver   }
1345671ff20Szoecarver 
1355671ff20Szoecarver   template <class _D2 = _Derived>
decltype(auto)1369783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back()
1375671ff20Szoecarver     requires bidirectional_range<_D2> && common_range<_D2>
1385671ff20Szoecarver   {
1391638657dSKonstantin Varlamov     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1401638657dSKonstantin Varlamov         !empty(), "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
1415671ff20Szoecarver     return *ranges::prev(ranges::end(__derived()));
1425671ff20Szoecarver   }
1435671ff20Szoecarver 
1445671ff20Szoecarver   template <class _D2 = _Derived>
decltype(auto)1459783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back() const
1465671ff20Szoecarver     requires bidirectional_range<const _D2> && common_range<const _D2>
1475671ff20Szoecarver   {
1481638657dSKonstantin Varlamov     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1491638657dSKonstantin Varlamov         !empty(), "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
1505671ff20Szoecarver     return *ranges::prev(ranges::end(__derived()));
1515671ff20Szoecarver   }
1525671ff20Szoecarver 
1535671ff20Szoecarver   template <random_access_range _RARange = _Derived>
decltype(auto)1549783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) {
1555671ff20Szoecarver     return ranges::begin(__derived())[__index];
1565671ff20Szoecarver   }
1575671ff20Szoecarver 
1585671ff20Szoecarver   template <random_access_range _RARange = const _Derived>
decltype(auto)1599783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const {
1605671ff20Szoecarver     return ranges::begin(__derived())[__index];
1615671ff20Szoecarver   }
1625671ff20Szoecarver };
1635671ff20Szoecarver 
1649c52a19eSNikolas Klauser } // namespace ranges
1655671ff20Szoecarver 
1664f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
1675671ff20Szoecarver 
1685671ff20Szoecarver _LIBCPP_END_NAMESPACE_STD
1695671ff20Szoecarver 
1705671ff20Szoecarver #endif // _LIBCPP___RANGES_VIEW_INTERFACE_H
171