Horizon
indirect.hpp
Go to the documentation of this file.
1 // 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 
14 #ifndef RANGES_V3_VIEW_INDIRECT_HPP
15 #define RANGES_V3_VIEW_INDIRECT_HPP
16 
17 #include <iterator>
18 #include <type_traits>
19 #include <utility>
20 
21 #include <meta/meta.hpp>
22 
23 #include <range/v3/range_fwd.hpp>
24 
28 #include <range/v3/utility/static_const.hpp>
30 #include <range/v3/view/view.hpp>
31 
32 #include <range/v3/detail/prologue.hpp>
33 
34 namespace ranges
35 {
38  template<typename Rng>
39  struct indirect_view : view_adaptor<indirect_view<Rng>, Rng>
40  {
41  private:
42  friend range_access;
43 
44  template<bool IsConst>
45  struct adaptor : adaptor_base
46  {
47  friend adaptor<!IsConst>;
48  using CRng = meta::const_if_c<IsConst, Rng>;
49 
50  adaptor() = default;
51  template(bool Other)(
52  requires IsConst && CPP_NOT(Other)) //
53  constexpr adaptor(adaptor<Other>) noexcept
54  {}
55 
56  // clang-format off
57  constexpr auto CPP_auto_fun(read)(iterator_t<CRng> const &it)(const)
58  (
59  return **it
60  )
61  constexpr auto CPP_auto_fun(iter_move)(iterator_t<CRng> const &it)(const)
62  (
63  return ranges::iter_move(*it)
64  )
65  // clang-format on
66  };
67 
68  CPP_member
69  constexpr auto begin_adaptor() noexcept //
70  -> CPP_ret(adaptor<false>)(
71  requires (!simple_view<Rng>()))
72  {
73  return {};
74  }
75  CPP_member
76  constexpr auto begin_adaptor() const noexcept //
77  -> CPP_ret(adaptor<true>)(
78  requires range<Rng const>)
79  {
80  return {};
81  }
82 
83  CPP_member
84  constexpr auto end_adaptor() noexcept //
85  -> CPP_ret(adaptor<false>)(
86  requires (!simple_view<Rng>()))
87  {
88  return {};
89  }
90  CPP_member
91  constexpr auto end_adaptor() const noexcept //
92  -> CPP_ret(adaptor<true>)(
93  requires range<Rng const>)
94  {
95  return {};
96  }
97 
98  public:
99  indirect_view() = default;
100  constexpr explicit indirect_view(Rng rng)
101  : indirect_view::view_adaptor{detail::move(rng)}
102  {}
103  CPP_auto_member
104  constexpr auto CPP_fun(size)()(const //
105  requires sized_range<Rng const>)
106  {
107  return ranges::size(this->base());
108  }
109  CPP_auto_member
110  constexpr auto CPP_fun(size)()(
111  requires sized_range<Rng>)
112  {
113  return ranges::size(this->base());
114  }
115  };
116 
117  template<typename Rng>
118  RANGES_INLINE_VAR constexpr bool enable_borrowed_range<indirect_view<Rng>> = //
119  enable_borrowed_range<Rng>;
120 
121 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
122  template<typename Rng>
123  indirect_view(Rng &&) //
125 #endif
126 
127  namespace views
128  {
129  struct indirect_fn
130  {
131  template(typename Rng)(
132  requires viewable_range<Rng> AND input_range<Rng> AND
133  // We shouldn't need to strip references to test if something
134  // is readable. https://github.com/ericniebler/stl2/issues/594
135  // indirectly_readable<range_reference_t<Rng>>)
136  ((bool)indirectly_readable<range_value_t<Rng>>)) // Cast to bool needed
137  // for GCC (???))
138  constexpr auto operator()(Rng && rng) const
139  {
140  return indirect_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
141  }
142  };
143 
147  } // namespace views
149 } // namespace ranges
150 
151 #include <range/v3/detail/epilogue.hpp>
152 
153 #include <range/v3/detail/satisfy_boost_range.hpp>
154 RANGES_SATISFY_BOOST_RANGE(::ranges::indirect_view)
155 
156 #endif
CPP_concept indirectly_readable
\concept indirectly_readable
Definition: concepts.hpp:147
decltype(begin(declval(Rng &))) iterator_t
Definition: access.hpp:698
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
meta::size_t< L::size()> size
An integral constant wrapper that is the size of the meta::list L.
Definition: meta.hpp:1696
Tiny meta-programming library.
Definition: adaptor.hpp:110
Definition: indirect.hpp:40
Definition: adaptor.hpp:475
Definition: indirect.hpp:130
Definition: view.hpp:178