You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
3.9KB

  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2013-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_INDIRECT_HPP
  14. #define RANGES_V3_VIEW_INDIRECT_HPP
  15. #include <iterator>
  16. #include <type_traits>
  17. #include <utility>
  18. #include <meta/meta.hpp>
  19. #include <range/v3/range_fwd.hpp>
  20. #include <range/v3/range/access.hpp>
  21. #include <range/v3/range/traits.hpp>
  22. #include <range/v3/utility/move.hpp>
  23. #include <range/v3/utility/static_const.hpp>
  24. #include <range/v3/view/adaptor.hpp>
  25. #include <range/v3/view/view.hpp>
  26. namespace ranges
  27. {
  28. /// \addtogroup group-views
  29. /// @{
  30. template<typename Rng>
  31. struct indirect_view : view_adaptor<indirect_view<Rng>, Rng>
  32. {
  33. private:
  34. friend range_access;
  35. template<bool IsConst>
  36. struct adaptor : adaptor_base
  37. {
  38. friend adaptor<!IsConst>;
  39. using CRng = meta::const_if_c<IsConst, Rng>;
  40. adaptor() = default;
  41. CPP_template(bool Other)( //
  42. requires IsConst && (!Other)) constexpr adaptor(adaptor<Other>) noexcept
  43. {}
  44. // clang-format off
  45. constexpr auto CPP_auto_fun(read)(iterator_t<CRng> const &it)(const)
  46. (
  47. return **it
  48. )
  49. constexpr auto CPP_auto_fun(iter_move)(iterator_t<CRng> const &it)(const)
  50. (
  51. return ranges::iter_move(*it)
  52. )
  53. // clang-format on
  54. };
  55. CPP_member
  56. constexpr auto begin_adaptor() noexcept -> CPP_ret(adaptor<false>)( //
  57. requires(!simple_view<Rng>()))
  58. {
  59. return {};
  60. }
  61. CPP_member
  62. constexpr auto begin_adaptor() const noexcept -> CPP_ret(adaptor<true>)( //
  63. requires range<Rng const>)
  64. {
  65. return {};
  66. }
  67. CPP_member
  68. constexpr auto end_adaptor() noexcept -> CPP_ret(adaptor<false>)( //
  69. requires(!simple_view<Rng>()))
  70. {
  71. return {};
  72. }
  73. CPP_member
  74. constexpr auto end_adaptor() const noexcept -> CPP_ret(adaptor<true>)( //
  75. requires range<Rng const>)
  76. {
  77. return {};
  78. }
  79. public:
  80. indirect_view() = default;
  81. explicit constexpr indirect_view(Rng rng)
  82. : indirect_view::view_adaptor{detail::move(rng)}
  83. {}
  84. CPP_member
  85. constexpr auto CPP_fun(size)()(const requires sized_range<Rng const>)
  86. {
  87. return ranges::size(this->base());
  88. }
  89. CPP_member
  90. constexpr auto CPP_fun(size)()(requires sized_range<Rng>)
  91. {
  92. return ranges::size(this->base());
  93. }
  94. };
  95. #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
  96. template<typename Rng>
  97. indirect_view(Rng &&)->indirect_view<views::all_t<Rng>>;
  98. #endif
  99. namespace views
  100. {
  101. struct indirect_fn
  102. {
  103. template<typename Rng>
  104. constexpr auto CPP_fun(operator())(Rng && rng)(
  105. const requires viewable_range<Rng> && input_range<Rng> &&
  106. // We shouldn't need to strip references to test if something
  107. // is readable. https://github.com/ericniebler/stl2/issues/594
  108. // readable<range_reference_t<Rng>>)
  109. ((bool)readable<range_value_t<Rng>>)) // Cast to bool needed for GCC (???)
  110. {
  111. return indirect_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
  112. }
  113. };
  114. /// \relates indirect_fn
  115. /// \ingroup group-views
  116. RANGES_INLINE_VARIABLE(view<indirect_fn>, indirect)
  117. } // namespace views
  118. /// @}
  119. } // namespace ranges
  120. #include <range/v3/detail/satisfy_boost_range.hpp>
  121. RANGES_SATISFY_BOOST_RANGE(::ranges::indirect_view)
  122. #endif