common.hpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2014-present
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. #ifndef RANGES_V3_VIEW_COMMON_HPP
  14. #define RANGES_V3_VIEW_COMMON_HPP
  15. #include <type_traits>
  16. #include <range/v3/range_fwd.hpp>
  17. #include <range/v3/iterator/common_iterator.hpp>
  18. #include <range/v3/iterator/concepts.hpp>
  19. #include <range/v3/range/access.hpp>
  20. #include <range/v3/range/concepts.hpp>
  21. #include <range/v3/range/primitives.hpp>
  22. #include <range/v3/range/traits.hpp>
  23. #include <range/v3/utility/static_const.hpp>
  24. #include <range/v3/view/all.hpp>
  25. #include <range/v3/view/interface.hpp>
  26. #include <range/v3/view/view.hpp>
  27. #include <range/v3/detail/prologue.hpp>
  28. namespace ranges
  29. {
  30. /// \addtogroup group-views
  31. /// @{
  32. /// \cond
  33. namespace detail
  34. {
  35. // clang-format off
  36. /// \concept random_access_and_sized_range
  37. /// \brief The \c random_access_and_sized_range concept
  38. template<typename R>
  39. CPP_concept random_access_and_sized_range =
  40. random_access_range<R> && sized_range<R>;
  41. // clang-format on
  42. template<typename R>
  43. using common_view_iterator_t =
  44. meta::if_c<random_access_and_sized_range<R>, iterator_t<R>,
  45. common_iterator_t<iterator_t<R>, sentinel_t<R>>>;
  46. template<typename Rng>
  47. struct is_common_range : meta::bool_<common_range<Rng>>
  48. {};
  49. } // namespace detail
  50. /// \endcond
  51. template<typename Rng, bool = detail::is_common_range<Rng>::value>
  52. struct common_view : view_interface<common_view<Rng>, range_cardinality<Rng>::value>
  53. {
  54. private:
  55. CPP_assert(view_<Rng>);
  56. CPP_assert(!(common_range<Rng> && view_<Rng>));
  57. Rng rng_;
  58. sentinel_t<Rng> end_(std::false_type)
  59. {
  60. return ranges::end(rng_);
  61. }
  62. iterator_t<Rng> end_(std::true_type)
  63. {
  64. return ranges::begin(rng_) + ranges::distance(rng_);
  65. }
  66. template(bool Const = true)(
  67. requires Const AND range<meta::const_if_c<Const, Rng>>)
  68. sentinel_t<meta::const_if_c<Const, Rng>> end_(std::false_type) const
  69. {
  70. return ranges::end(rng_);
  71. }
  72. template(bool Const = true)(
  73. requires Const AND range<meta::const_if_c<Const, Rng>>)
  74. iterator_t<meta::const_if_c<Const, Rng>> end_(std::true_type) const
  75. {
  76. return ranges::begin(rng_) + ranges::distance(rng_);
  77. }
  78. public:
  79. common_view() = default;
  80. explicit common_view(Rng rng)
  81. : rng_(detail::move(rng))
  82. {}
  83. Rng base() const
  84. {
  85. return rng_;
  86. }
  87. detail::common_view_iterator_t<Rng> begin()
  88. {
  89. return detail::common_view_iterator_t<Rng>{ranges::begin(rng_)};
  90. }
  91. detail::common_view_iterator_t<Rng> end()
  92. {
  93. return detail::common_view_iterator_t<Rng>{
  94. end_(meta::bool_<detail::random_access_and_sized_range<Rng>>{})};
  95. }
  96. CPP_auto_member
  97. auto CPP_fun(size)()(
  98. requires sized_range<Rng>)
  99. {
  100. return ranges::size(rng_);
  101. }
  102. template(bool Const = true)(
  103. requires range<meta::const_if_c<Const, Rng>>)
  104. auto begin() const
  105. -> detail::common_view_iterator_t<meta::const_if_c<Const, Rng>>
  106. {
  107. return detail::common_view_iterator_t<meta::const_if_c<Const, Rng>>{
  108. ranges::begin(rng_)};
  109. }
  110. template(bool Const = true)(
  111. requires range<meta::const_if_c<Const, Rng>>)
  112. auto end() const
  113. -> detail::common_view_iterator_t<meta::const_if_c<Const, Rng>>
  114. {
  115. return detail::common_view_iterator_t<meta::const_if_c<Const, Rng>>{
  116. end_(meta::bool_<detail::random_access_and_sized_range<
  117. meta::const_if_c<Const, Rng>>>{})};
  118. }
  119. CPP_auto_member
  120. auto CPP_fun(size)()(const
  121. requires sized_range<Rng const>)
  122. {
  123. return ranges::size(rng_);
  124. }
  125. };
  126. template<typename Rng, bool B>
  127. RANGES_INLINE_VAR constexpr bool enable_borrowed_range<common_view<Rng, B>> = //
  128. enable_borrowed_range<Rng>;
  129. #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
  130. template(typename Rng)(
  131. requires (!common_range<Rng>)) //
  132. common_view(Rng &&)
  133. ->common_view<views::all_t<Rng>>;
  134. #endif
  135. template<typename Rng>
  136. struct common_view<Rng, true> : identity_adaptor<Rng>
  137. {
  138. CPP_assert(common_range<Rng>);
  139. using identity_adaptor<Rng>::identity_adaptor;
  140. };
  141. namespace views
  142. {
  143. struct cpp20_common_fn
  144. {
  145. template(typename Rng)(
  146. requires viewable_range<Rng> AND common_range<Rng>)
  147. all_t<Rng> operator()(Rng && rng) const
  148. {
  149. return all(static_cast<Rng &&>(rng));
  150. }
  151. template(typename Rng)(
  152. requires viewable_range<Rng> AND (!common_range<Rng>)) //
  153. common_view<all_t<Rng>> operator()(Rng && rng) const
  154. {
  155. return common_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
  156. }
  157. };
  158. struct common_fn
  159. {
  160. template(typename Rng)(
  161. requires viewable_range<Rng>)
  162. common_view<all_t<Rng>> operator()(Rng && rng) const
  163. {
  164. return common_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
  165. }
  166. };
  167. /// \relates common_fn
  168. /// \ingroup group-views
  169. RANGES_INLINE_VARIABLE(view_closure<common_fn>, common)
  170. } // namespace views
  171. /// @}
  172. /// \cond
  173. template<typename Rng>
  174. using bounded_view RANGES_DEPRECATED(
  175. "The name bounded_view is deprecated. "
  176. "Please use common_view instead.") = common_view<Rng>;
  177. /// \endcond
  178. namespace views
  179. {
  180. /// \cond
  181. namespace
  182. {
  183. RANGES_DEPRECATED(
  184. "The name views::bounded is deprecated. "
  185. "Please use views::common instead.")
  186. RANGES_INLINE_VAR constexpr auto & bounded = common;
  187. } // namespace
  188. template<typename Rng>
  189. using bounded_t RANGES_DEPRECATED("The name views::bounded_t is deprecated.") =
  190. decltype(common(std::declval<Rng>()));
  191. /// \endcond
  192. } // namespace views
  193. namespace cpp20
  194. {
  195. namespace views
  196. {
  197. RANGES_INLINE_VARIABLE(
  198. ranges::views::view_closure<ranges::views::cpp20_common_fn>, common)
  199. }
  200. template(typename Rng)(
  201. requires view_<Rng> && (!common_range<Rng>)) //
  202. using common_view = ranges::common_view<Rng>;
  203. } // namespace cpp20
  204. } // namespace ranges
  205. #include <range/v3/detail/epilogue.hpp>
  206. #include <range/v3/detail/satisfy_boost_range.hpp>
  207. RANGES_SATISFY_BOOST_RANGE(::ranges::common_view)
  208. #endif