Nui
range.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <nui/feature_test.hpp>
6 
7 #include <iterator>
8 #include <utility>
9 
10 #ifdef NUI_HAS_STD_RANGES
11 # include <ranges>
12 #endif
13 
14 namespace Nui
15 {
16  template <typename ObservedValue>
18  {
19  public:
20  using ObservedType = ObservedValue;
21 
22  static constexpr bool isRandomAccess = ObservedType::isRandomAccess;
23 
24  template <typename ObservedValueT>
25  requires std::is_same_v<std::decay_t<ObservedValueT>, std::decay_t<ObservedValueT>>
26  explicit constexpr ObservedRange(ObservedValueT&& observedValues)
27  : observedValue_{std::forward<Detail::ObservedAddMutableReference_t<ObservedValue>>(observedValues)}
28  {}
29 
31  {
32  return observedValue_;
33  }
35  requires(!std::is_const_v<ObservedValue>)
36  {
37  return observedValue_;
38  }
39 
40  private:
42  };
43 
44  template <typename CopyableRangeLike, typename... ObservedValues>
46  {
47  public:
48  UnoptimizedRange(ObservedValueCombinator<ObservedValues...>&& observedValues, CopyableRangeLike&& rangeLike)
49  : observedValues_{std::move(observedValues)}
50  , rangeLike_{std::move(rangeLike)}
51  {}
52  UnoptimizedRange(CopyableRangeLike&& rangeLike)
53  requires(sizeof...(ObservedValues) == 0)
54  : observedValues_{}
55  , rangeLike_{std::move(rangeLike)}
56  {}
57 
58  auto begin() const
59  {
60  return rangeLike_.begin();
61  }
62  auto end() const
63  {
64  return rangeLike_.end();
65  }
66 
67  ObservedValueCombinator<ObservedValues...> const& underlying() const
68  {
69  return observedValues_;
70  }
71  ObservedValueCombinator<ObservedValues...>& underlying()
72  {
73  return observedValues_;
74  }
75 
76  private:
77  ObservedValueCombinator<ObservedValues...> observedValues_;
78  CopyableRangeLike rangeLike_;
79  };
80 
81  template <typename ObservedValue>
82  requires(IsObserved<ObservedValue>)
83  ObservedRange<ObservedValue> range(ObservedValue& observedValues)
84  {
85  return ObservedRange<ObservedValue>{observedValues};
86  }
87 
88  template <typename ObservedValue>
89  requires(IsObserved<ObservedValue>)
90  ObservedRange<const ObservedValue> range(ObservedValue const& observedValues)
91  {
92  return ObservedRange<const ObservedValue>{observedValues};
93  }
94 
95  template <typename ContainerT, typename... Observed>
96  UnoptimizedRange<IteratorAccessor<ContainerT const>, std::decay_t<Detail::ObservedAddReference_t<Observed>>...>
97  range(ContainerT const& container, Observed&&... observed)
98  {
99  return UnoptimizedRange<
101  std::decay_t<Detail::ObservedAddReference_t<Observed>>...>{
102  ObservedValueCombinator{std::forward<Detail::ObservedAddReference_t<Observed>>(observed)...},
104  };
105  }
106 
107  template <typename ContainerT, typename... Observed>
108  UnoptimizedRange<IteratorAccessor<ContainerT>, std::decay_t<Detail::ObservedAddReference_t<Observed>>...>
109  range(ContainerT& container, Observed&&... observed)
110  {
111  return UnoptimizedRange<
113  std::decay_t<Detail::ObservedAddReference_t<Observed>>...>{
114  ObservedValueCombinator{std::forward<Detail::ObservedAddReference_t<Observed>>(observed)...},
115  IteratorAccessor<ContainerT>{container},
116  };
117  }
118 
119  template <typename ContainerT>
121  {
123  IteratorAccessor<ContainerT>{container},
124  };
125  }
126 
127  template <typename ContainerT>
129  {
132  };
133  }
134 
135 #ifdef NUI_HAS_STD_RANGES
136  template <typename T, typename... Observed>
137  UnoptimizedRange<
138  std::ranges::subrange<std::ranges::iterator_t<T const>>,
139  std::decay_t<Detail::ObservedAddReference_t<Observed>>...>
140  range(T const& container, Observed&&... observed)
141  {
142  return UnoptimizedRange<
143  std::ranges::subrange<std::ranges::iterator_t<T const>>,
144  std::decay_t<Detail::ObservedAddReference_t<Observed>>...>{
145  ObservedValueCombinator{std::forward<Detail::ObservedAddReference_t<Observed>>(observed)...},
146  std::ranges::subrange<std::ranges::iterator_t<T const>>{
147  std::ranges::begin(container), std::ranges::end(container)},
148  };
149  }
150 #endif
151 
152  template <typename ContainerT>
153  constexpr auto ObservedContainer<ContainerT>::map(auto&& function) const
154  {
155  return std::pair<ObservedRange<Observed<ContainerT>>, std::decay_t<decltype(function)>>{
156  ObservedRange<Observed<ContainerT>>{static_cast<Observed<ContainerT> const&>(*this)},
157  std::forward<std::decay_t<decltype(function)>>(function),
158  };
159  }
160 
161  template <typename ContainerT>
162  constexpr auto ObservedContainer<ContainerT>::map(auto&& function)
163  {
164  return std::pair<ObservedRange<Observed<ContainerT>>, std::decay_t<decltype(function)>>{
166  std::forward<std::decay_t<decltype(function)>>(function),
167  };
168  }
169 }
Definition: iterator_accessor.hpp:9
constexpr auto map(auto &&function) const
Definition: range.hpp:153
Definition: range.hpp:18
Detail::ObservedAddMutableReference_t< ObservedValue > underlying() requires(!std
Definition: range.hpp:34
static constexpr bool isRandomAccess
Definition: range.hpp:22
requires constexpr std::is_same_v< std::decay_t< ObservedValueT >, std::decay_t< ObservedValueT > > ObservedRange(ObservedValueT &&observedValues)
Definition: range.hpp:26
Detail::ObservedAddReference_t< ObservedValue > underlying() const
Definition: range.hpp:30
ObservedValue ObservedType
Definition: range.hpp:20
Definition: observed_value_combinator.hpp:160
Definition: observed_value.hpp:1202
Definition: range.hpp:46
CopyableRangeLike rangeLike_
Definition: range.hpp:78
UnoptimizedRange(ObservedValueCombinator< ObservedValues... > &&observedValues, CopyableRangeLike &&rangeLike)
Definition: range.hpp:48
UnoptimizedRange(CopyableRangeLike &&rangeLike) requires(sizeof...(ObservedValues)
typename ObservedAddReference< std::decay_t< T > >::type ObservedAddReference_t
Definition: observed_value.hpp:1545
typename ObservedAddMutableReference< std::remove_reference_t< T > >::type ObservedAddMutableReference_t
Definition: observed_value.hpp:1547
Definition: file_dialog.hpp:6
UnoptimizedRange< IteratorAccessor< ContainerT const >, std::decay_t< Detail::ObservedAddReference_t< Observed > >... > range(ContainerT const &container, Observed &&... observed)
Definition: range.hpp:97
ObservedValueCombinator(ObservedValues &&...) -> ObservedValueCombinator< std::decay_t< Detail::ObservedAddReference_t< ObservedValues >>... >
requires(IsObservedLike< ObservedValues > &&...) ObservedValueCombinator< std
Definition: observed_value_combinator.hpp:191