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