1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP___RANGES_COMMON_VIEW_H 11 #define _LIBCPP___RANGES_COMMON_VIEW_H 12 13 #include <__concepts/constructible.h> 14 #include <__concepts/copyable.h> 15 #include <__config> 16 #include <__iterator/common_iterator.h> 17 #include <__iterator/iterator_traits.h> 18 #include <__ranges/access.h> 19 #include <__ranges/all.h> 20 #include <__ranges/concepts.h> 21 #include <__ranges/enable_borrowed_range.h> 22 #include <__ranges/range_adaptor.h> 23 #include <__ranges/size.h> 24 #include <__ranges/view_interface.h> 25 #include <__utility/forward.h> 26 #include <__utility/move.h> 27 #include <type_traits> 28 29 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 30 # pragma GCC system_header 31 #endif 32 33 _LIBCPP_BEGIN_NAMESPACE_STD 34 35 #if _LIBCPP_STD_VER > 17 36 37 namespace ranges { 38 39 template<view _View> 40 requires (!common_range<_View> && copyable<iterator_t<_View>>) 41 class common_view : public view_interface<common_view<_View>> { 42 _View __base_ = _View(); 43 44 public: 45 _LIBCPP_HIDE_FROM_ABI 46 common_view() requires default_initializable<_View> = default; 47 48 _LIBCPP_HIDE_FROM_ABI 49 constexpr explicit common_view(_View __v) : __base_(std::move(__v)) { } 50 51 _LIBCPP_HIDE_FROM_ABI 52 constexpr _View base() const& requires copy_constructible<_View> { return __base_; } 53 54 _LIBCPP_HIDE_FROM_ABI 55 constexpr _View base() && { return std::move(__base_); } 56 57 _LIBCPP_HIDE_FROM_ABI 58 constexpr auto begin() { 59 if constexpr (random_access_range<_View> && sized_range<_View>) 60 return ranges::begin(__base_); 61 else 62 return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::begin(__base_)); 63 } 64 65 _LIBCPP_HIDE_FROM_ABI 66 constexpr auto begin() const requires range<const _View> { 67 if constexpr (random_access_range<const _View> && sized_range<const _View>) 68 return ranges::begin(__base_); 69 else 70 return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::begin(__base_)); 71 } 72 73 _LIBCPP_HIDE_FROM_ABI 74 constexpr auto end() { 75 if constexpr (random_access_range<_View> && sized_range<_View>) 76 return ranges::begin(__base_) + ranges::size(__base_); 77 else 78 return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::end(__base_)); 79 } 80 81 _LIBCPP_HIDE_FROM_ABI 82 constexpr auto end() const requires range<const _View> { 83 if constexpr (random_access_range<const _View> && sized_range<const _View>) 84 return ranges::begin(__base_) + ranges::size(__base_); 85 else 86 return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::end(__base_)); 87 } 88 89 _LIBCPP_HIDE_FROM_ABI 90 constexpr auto size() requires sized_range<_View> { 91 return ranges::size(__base_); 92 } 93 94 _LIBCPP_HIDE_FROM_ABI 95 constexpr auto size() const requires sized_range<const _View> { 96 return ranges::size(__base_); 97 } 98 }; 99 100 template<class _Range> 101 common_view(_Range&&) 102 -> common_view<views::all_t<_Range>>; 103 104 template<class _View> 105 inline constexpr bool enable_borrowed_range<common_view<_View>> = enable_borrowed_range<_View>; 106 107 namespace views { 108 namespace __common { 109 struct __fn : __range_adaptor_closure<__fn> { 110 template<class _Range> 111 requires common_range<_Range> 112 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 113 constexpr auto operator()(_Range&& __range) const 114 noexcept(noexcept(views::all(std::forward<_Range>(__range)))) 115 -> decltype( views::all(std::forward<_Range>(__range))) 116 { return views::all(std::forward<_Range>(__range)); } 117 118 template<class _Range> 119 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 120 constexpr auto operator()(_Range&& __range) const 121 noexcept(noexcept(common_view{std::forward<_Range>(__range)})) 122 -> decltype( common_view{std::forward<_Range>(__range)}) 123 { return common_view{std::forward<_Range>(__range)}; } 124 }; 125 } // namespace __common 126 127 inline namespace __cpo { 128 inline constexpr auto common = __common::__fn{}; 129 } // namespace __cpo 130 } // namespace views 131 } // namespace ranges 132 133 #endif // _LIBCPP_STD_VER > 17 134 135 _LIBCPP_END_NAMESPACE_STD 136 137 #endif // _LIBCPP___RANGES_COMMON_VIEW_H 138