Horizon
shared.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Filip Matzner 2017
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_EXPERIMENTAL_VIEW_SHARED_HPP
14 #define RANGES_V3_EXPERIMENTAL_VIEW_SHARED_HPP
15 
16 #include <memory>
17 #include <type_traits>
18 
19 #include <meta/meta.hpp>
20 
25 #include <range/v3/view/all.hpp>
26 
27 #include <range/v3/detail/prologue.hpp>
28 
29 namespace ranges
30 {
33  namespace experimental
34  {
35  template<typename Rng>
36  struct shared_view
37  : view_interface<shared_view<Rng>, range_cardinality<Rng>::value>
38  {
39  private:
40  // shared storage
41  std::shared_ptr<Rng> rng_ptr_;
42 
43  public:
44  shared_view() = default;
45 
46  // construct from a range rvalue
47  explicit shared_view(Rng rng)
48  : rng_ptr_{std::make_shared<Rng>(std::move(rng))}
49  {}
50 
51  // use the stored range's begin and end
52  iterator_t<Rng> begin() const
53  {
54  return ranges::begin(*rng_ptr_);
55  }
56  sentinel_t<Rng> end() const
57  {
58  return ranges::end(*rng_ptr_);
59  }
60 
61  CPP_auto_member
62  auto CPP_fun(size)()(const
63  requires sized_range<Rng>)
64  {
65  return ranges::size(*rng_ptr_);
66  }
67  };
68 
69  template<typename SharedFn>
70  struct shared_closure;
71 
72  struct RANGES_STRUCT_WITH_ADL_BARRIER(shared_closure_base)
73  {
74  // Piping requires viewable_ranges.
75  template(typename Rng, typename SharedFn)(
76  requires range<Rng> AND (!viewable_range<Rng>) AND
77  constructible_from<detail::decay_t<Rng>, Rng>)
78  friend constexpr auto operator|(Rng && rng, shared_closure<SharedFn> vw)
79  {
80  return static_cast<SharedFn &&>(vw)(static_cast<Rng &&>(rng));
81  }
82 
83  template<typename SharedFn, typename Pipeable>
84  friend constexpr auto operator|(shared_closure<SharedFn> sh, Pipeable pipe)
85  -> CPP_broken_friend_ret(shared_closure<composed<Pipeable, SharedFn>>)(
86  requires (is_pipeable_v<Pipeable>))
87  {
88  return shared_closure<composed<Pipeable, SharedFn>>{compose(
89  static_cast<Pipeable &&>(pipe), static_cast<SharedFn &&>(sh))};
90  }
91  };
92 
93  template<typename SharedFn>
95  : shared_closure_base
96  , SharedFn
97  {
98  shared_closure() = default;
99  constexpr explicit shared_closure(SharedFn fn)
100  : SharedFn(static_cast<SharedFn &&>(fn))
101  {}
102  };
103 
104  namespace views
105  {
106  struct shared_fn
107  {
108  template(typename Rng)(
109  requires range<Rng> AND (!viewable_range<Rng>)AND
110  constructible_from<detail::decay_t<Rng>, Rng>)
111  shared_view<detail::decay_t<Rng>> operator()(Rng && rng) const
112  {
113  return shared_view<detail::decay_t<Rng>>{static_cast<Rng &&>(rng)};
114  }
115  };
116 
120  } // namespace views
121  } // namespace experimental
122 
123  template<typename SharedFn>
124  RANGES_INLINE_VAR constexpr bool
125  is_pipeable_v<experimental::shared_closure<SharedFn>> = true;
127 } // namespace ranges
128 
129 #include <range/v3/detail/epilogue.hpp>
130 
131 #endif
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: compose.hpp:33
Definition: shared.hpp:97
Definition: shared.hpp:38
Definition: shared.hpp:107
Definition: interface.hpp:129