master
  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
 28#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 29#  pragma GCC system_header
 30#endif
 31
 32_LIBCPP_PUSH_MACROS
 33#include <__undef_macros>
 34
 35_LIBCPP_BEGIN_NAMESPACE_STD
 36
 37#if _LIBCPP_STD_VER >= 20
 38
 39namespace ranges {
 40
 41template <view _View>
 42  requires(!common_range<_View> && copyable<iterator_t<_View>>)
 43class common_view : public view_interface<common_view<_View>> {
 44  _View __base_ = _View();
 45
 46public:
 47  _LIBCPP_HIDE_FROM_ABI common_view()
 48    requires default_initializable<_View>
 49  = default;
 50
 51  _LIBCPP_HIDE_FROM_ABI constexpr explicit common_view(_View __v) : __base_(std::move(__v)) {}
 52
 53  _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
 54    requires copy_constructible<_View>
 55  {
 56    return __base_;
 57  }
 58
 59  _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
 60
 61  _LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
 62    if constexpr (random_access_range<_View> && sized_range<_View>)
 63      return ranges::begin(__base_);
 64    else
 65      return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::begin(__base_));
 66  }
 67
 68  _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
 69    requires range<const _View>
 70  {
 71    if constexpr (random_access_range<const _View> && sized_range<const _View>)
 72      return ranges::begin(__base_);
 73    else
 74      return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::begin(__base_));
 75  }
 76
 77  _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
 78    if constexpr (random_access_range<_View> && sized_range<_View>)
 79      return ranges::begin(__base_) + ranges::size(__base_);
 80    else
 81      return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::end(__base_));
 82  }
 83
 84  _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
 85    requires range<const _View>
 86  {
 87    if constexpr (random_access_range<const _View> && sized_range<const _View>)
 88      return ranges::begin(__base_) + ranges::size(__base_);
 89    else
 90      return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::end(__base_));
 91  }
 92
 93  _LIBCPP_HIDE_FROM_ABI constexpr auto size()
 94    requires sized_range<_View>
 95  {
 96    return ranges::size(__base_);
 97  }
 98
 99  _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
100    requires sized_range<const _View>
101  {
102    return ranges::size(__base_);
103  }
104};
105
106template <class _Range>
107common_view(_Range&&) -> common_view<views::all_t<_Range>>;
108
109template <class _View>
110inline constexpr bool enable_borrowed_range<common_view<_View>> = enable_borrowed_range<_View>;
111
112namespace views {
113namespace __common {
114struct __fn : __range_adaptor_closure<__fn> {
115  template <class _Range>
116    requires common_range<_Range>
117  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const noexcept(
118      noexcept(views::all(std::forward<_Range>(__range)))) -> decltype(views::all(std::forward<_Range>(__range))) {
119    return views::all(std::forward<_Range>(__range));
120  }
121
122  template <class _Range>
123  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const noexcept(noexcept(common_view{
124      std::forward<_Range>(__range)})) -> decltype(common_view{std::forward<_Range>(__range)}) {
125    return common_view{std::forward<_Range>(__range)};
126  }
127};
128} // namespace __common
129
130inline namespace __cpo {
131inline constexpr auto common = __common::__fn{};
132} // namespace __cpo
133} // namespace views
134} // namespace ranges
135
136#endif // _LIBCPP_STD_VER >= 20
137
138_LIBCPP_END_NAMESPACE_STD
139
140_LIBCPP_POP_MACROS
141
142#endif // _LIBCPP___RANGES_COMMON_VIEW_H