Horizon
facade.hpp
Go to the documentation of this file.
1 // 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_FACADE_HPP
14 #define RANGES_V3_VIEW_FACADE_HPP
15 
16 #include <type_traits>
17 #include <utility>
18 
19 #include <meta/meta.hpp>
20 
21 #include <concepts/concepts.hpp>
22 
23 #include <range/v3/range_fwd.hpp>
24 
29 
30 #include <range/v3/detail/prologue.hpp>
31 
32 namespace ranges
33 {
35  namespace detail
36  {
37  template<typename Derived>
38  using begin_cursor_t = detail::decay_t<decltype(
39  range_access::begin_cursor(std::declval<Derived &>()))>;
40 
41  template<typename Derived>
42  using end_cursor_t = detail::decay_t<decltype(
43  range_access::end_cursor(std::declval<Derived &>()))>;
44 
45  template<typename Derived>
46  using facade_iterator_t = basic_iterator<begin_cursor_t<Derived>>;
47 
48  template<typename Derived>
49  using facade_sentinel_t =
50  meta::if_c<same_as<begin_cursor_t<Derived>, end_cursor_t<Derived>>,
51  facade_iterator_t<Derived>, end_cursor_t<Derived>>;
52  } // namespace detail
54 
57 
64  template<typename Derived, cardinality Cardinality>
65  struct view_facade : view_interface<Derived, Cardinality>
66  {
67  protected:
68  friend range_access;
69  struct view_as_cursor : Derived
70  {
71  view_as_cursor() = default;
72  explicit view_as_cursor(Derived const * derived)
73  : Derived(*derived)
74  {}
75  explicit operator bool() = delete;
76  explicit operator bool() const = delete;
77  };
78  // Default implementations
79  constexpr view_as_cursor begin_cursor() const
80  {
81  return view_as_cursor{static_cast<Derived const *>(this)};
82  }
83  constexpr default_sentinel_t end_cursor() const
84  {
85  return {};
86  }
87 
88  public:
94  template(typename D = Derived)(
95  requires same_as<D, Derived>)
96  constexpr auto begin() -> detail::facade_iterator_t<D>
97  {
98  return detail::facade_iterator_t<D>{
99  range_access::begin_cursor(*static_cast<Derived *>(this))};
100  }
102  template(typename D = Derived)(
103  requires same_as<D, Derived>)
104  constexpr auto begin() const -> detail::facade_iterator_t<D const>
105  {
106  return detail::facade_iterator_t<D const>{
107  range_access::begin_cursor(*static_cast<Derived const *>(this))};
108  }
115  template(typename D = Derived)(
116  requires same_as<D, Derived>)
117  constexpr auto end() -> detail::facade_sentinel_t<D>
118  {
119  return static_cast<detail::facade_sentinel_t<D>>(
120  range_access::end_cursor(*static_cast<Derived *>(this)));
121  }
123  template(typename D = Derived)(
124  requires same_as<D, Derived>)
125  constexpr auto end() const -> detail::facade_sentinel_t<D const>
126  {
127  return static_cast<detail::facade_sentinel_t<D const>>(
128  range_access::end_cursor(*static_cast<Derived const *>(this)));
129  }
130  };
131 
133 } // namespace ranges
134 
135 #include <range/v3/detail/epilogue.hpp>
136 
137 #endif
Tiny meta-programming library.
Definition: facade.hpp:70
A utility for constructing a view from a (derived) type that implements begin and end cursors.
Definition: facade.hpp:66
Definition: interface.hpp:129