common_view.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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. #ifndef _LIBCPP___RANGES_COMMON_VIEW_H
  10. #define _LIBCPP___RANGES_COMMON_VIEW_H
  11. #include <__concepts/constructible.h>
  12. #include <__concepts/copyable.h>
  13. #include <__config>
  14. #include <__iterator/common_iterator.h>
  15. #include <__iterator/iterator_traits.h>
  16. #include <__ranges/access.h>
  17. #include <__ranges/all.h>
  18. #include <__ranges/concepts.h>
  19. #include <__ranges/enable_borrowed_range.h>
  20. #include <__ranges/range_adaptor.h>
  21. #include <__ranges/size.h>
  22. #include <__ranges/view_interface.h>
  23. #include <__utility/forward.h>
  24. #include <__utility/move.h>
  25. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  26. # pragma GCC system_header
  27. #endif
  28. _LIBCPP_PUSH_MACROS
  29. #include <__undef_macros>
  30. _LIBCPP_BEGIN_NAMESPACE_STD
  31. #if _LIBCPP_STD_VER >= 20
  32. namespace ranges {
  33. template <view _View>
  34. requires(!common_range<_View> && copyable<iterator_t<_View>>)
  35. class common_view : public view_interface<common_view<_View>> {
  36. _View __base_ = _View();
  37. public:
  38. _LIBCPP_HIDE_FROM_ABI common_view()
  39. requires default_initializable<_View>
  40. = default;
  41. _LIBCPP_HIDE_FROM_ABI constexpr explicit common_view(_View __v) : __base_(std::move(__v)) {}
  42. _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
  43. requires copy_constructible<_View>
  44. {
  45. return __base_;
  46. }
  47. _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
  48. _LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
  49. if constexpr (random_access_range<_View> && sized_range<_View>)
  50. return ranges::begin(__base_);
  51. else
  52. return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::begin(__base_));
  53. }
  54. _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
  55. requires range<const _View>
  56. {
  57. if constexpr (random_access_range<const _View> && sized_range<const _View>)
  58. return ranges::begin(__base_);
  59. else
  60. return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::begin(__base_));
  61. }
  62. _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
  63. if constexpr (random_access_range<_View> && sized_range<_View>)
  64. return ranges::begin(__base_) + ranges::size(__base_);
  65. else
  66. return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::end(__base_));
  67. }
  68. _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
  69. requires range<const _View>
  70. {
  71. if constexpr (random_access_range<const _View> && sized_range<const _View>)
  72. return ranges::begin(__base_) + ranges::size(__base_);
  73. else
  74. return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::end(__base_));
  75. }
  76. _LIBCPP_HIDE_FROM_ABI constexpr auto size()
  77. requires sized_range<_View>
  78. {
  79. return ranges::size(__base_);
  80. }
  81. _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
  82. requires sized_range<const _View>
  83. {
  84. return ranges::size(__base_);
  85. }
  86. };
  87. template <class _Range>
  88. common_view(_Range&&) -> common_view<views::all_t<_Range>>;
  89. template <class _View>
  90. inline constexpr bool enable_borrowed_range<common_view<_View>> = enable_borrowed_range<_View>;
  91. namespace views {
  92. namespace __common {
  93. struct __fn : __range_adaptor_closure<__fn> {
  94. template <class _Range>
  95. requires common_range<_Range>
  96. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
  97. noexcept(noexcept(views::all(std::forward<_Range>(__range))))
  98. -> decltype(views::all(std::forward<_Range>(__range))) {
  99. return views::all(std::forward<_Range>(__range));
  100. }
  101. template <class _Range>
  102. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
  103. noexcept(noexcept(common_view{std::forward<_Range>(__range)}))
  104. -> decltype(common_view{std::forward<_Range>(__range)}) {
  105. return common_view{std::forward<_Range>(__range)};
  106. }
  107. };
  108. } // namespace __common
  109. inline namespace __cpo {
  110. inline constexpr auto common = __common::__fn{};
  111. } // namespace __cpo
  112. } // namespace views
  113. } // namespace ranges
  114. #endif // _LIBCPP_STD_VER >= 20
  115. _LIBCPP_END_NAMESPACE_STD
  116. _LIBCPP_POP_MACROS
  117. #endif // _LIBCPP___RANGES_COMMON_VIEW_H