emlabcpp
modern opinionated embedded C++ library
view.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "./types.h"
27 
28 #include <span>
29 
30 namespace emlabcpp
31 {
32 
39 template < typename Iterator, typename EndIterator = Iterator >
40 class view
41 {
42  Iterator begin_;
43  EndIterator end_;
44 
45 public:
48  using reverse_iterator = std::reverse_iterator< Iterator >;
49  using iterator = Iterator;
50  using difference_type = typename std::iterator_traits< Iterator >::difference_type;
51  using size_type = std::size_t;
52 
53  constexpr view() = default;
54 
56  template < range_container_with_iter< iterator > Cont >
57  constexpr view( Cont& cont )
58  : begin_( std::begin( cont ) )
59  , end_( std::end( cont ) )
60  {
61  }
62 
64  template < range_container_with_iter< iterator > Cont >
65  constexpr view( Cont const& cont )
66  : begin_( std::begin( cont ) )
67  , end_( std::end( cont ) )
68  {
69  }
70 
71  template < data_container_with_iter< iterator > Cont >
72  requires( !range_container_with_iter< Cont, iterator > )
73  constexpr view( Cont& cont )
74  : begin_( std::data( cont ) )
75  , end_( begin_ + std::size( cont ) )
76  {
77  }
78 
79  template < data_container_with_iter< iterator > Cont >
80  requires( !range_container_with_iter< Cont, iterator > )
81  constexpr view( Cont const& cont )
82  : begin_( std::data( cont ) )
83  , end_( begin_ + std::size( cont ) )
84  {
85  }
86 
88  constexpr view( Iterator begin, EndIterator end )
89  : begin_( std::move( begin ) )
90  , end_( std::move( end ) )
91  {
92  }
93 
94  template <
95  std::convertible_to< Iterator > OtherIterator,
96  std::convertible_to< EndIterator > OtherEndIterator >
98  : begin_( other.begin() )
99  , end_( other.end() )
100  {
101  }
102 
104  [[nodiscard]] constexpr Iterator begin() const
105  {
106  return begin_;
107  }
108 
110  [[nodiscard]] constexpr EndIterator end() const
111  {
112  return end_;
113  }
114 
116  [[nodiscard]] constexpr decltype( auto ) operator[]( size_type const i ) const
117  {
118  return *( begin_ + static_cast< difference_type >( i ) );
119  }
120 
122  [[nodiscard]] constexpr reverse_iterator rbegin() const
123  {
124  return reverse_iterator{ end_ };
125  }
126 
129  [[nodiscard]] constexpr reverse_iterator rend() const
130  {
131  return reverse_iterator{ begin_ };
132  }
133 
135  [[nodiscard]] constexpr size_type size() const
136  {
137  return static_cast< std::size_t >( std::ranges::distance( begin(), end() ) );
138  }
139 
141  [[nodiscard]] constexpr bool empty() const
142  {
143  return begin() == end();
144  }
145 
147  [[nodiscard]] constexpr value_type const& front() const
148  {
149  return *begin_;
150  }
151 
153  [[nodiscard]] constexpr value_type const& back() const
154  {
155  return *std::prev( end_ );
156  }
157 
158  operator std::span< value_type >()
159  {
160  return std::span{ begin(), end() };
161  }
162 };
163 
164 template < typename IteratorLh, typename IteratorRh >
165 constexpr bool operator==( view< IteratorLh > const& lh, view< IteratorRh > const& rh )
166 {
167  if ( lh.size() != rh.size() )
168  return false;
169 
170  IteratorLh lhiter = lh.begin();
171  IteratorRh rhiter = rh.begin();
172 
173  for ( ; lhiter != lh.end(); ++lhiter, ++rhiter )
174  if ( *lhiter != *rhiter )
175  return false;
176  return true;
177 }
178 
179 template < typename IteratorLh, typename IteratorRh >
180 constexpr bool operator!=( view< IteratorLh > const& lh, view< IteratorRh > const& rh )
181 {
182  return !( lh == rh );
183 }
184 
186 template < range_container Container >
187 view( Container& cont ) -> view< iterator_of_t< Container > >;
188 
190 template < typename Iter >
191 struct impl::is_view< view< Iter > > : std::true_type
192 {
193 };
194 
197 template < typename Iter >
198 constexpr view< Iter > view_n( Iter begin, std::size_t const n )
199 {
200  auto end = std::next(
201  begin, static_cast< typename std::iterator_traits< Iter >::difference_type >( n ) );
202  return view< Iter >{ std::move( begin ), end };
203 }
204 
205 template < data_container Container >
206 constexpr auto data_view( Container& cont )
207 {
208  return view_n( std::data( cont ), std::size( cont ) );
209 }
210 
214 template < range_container Container >
215 constexpr view< iterator_of_t< Container > > trim_view( Container& cont, float const r )
216 {
217  std::size_t const step = std::size( cont ) * ( 1.f - r ) / 2.f;
218  return { std::begin( cont ) + step, std::end( cont ) - step };
219 }
220 
222 constexpr auto
223 reversed( referenceable_container auto& container ) -> view< decltype( std::rbegin( container ) ) >
224 {
225  return { std::rbegin( container ), std::rend( container ) };
226 }
227 
228 template < typename Iterator, typename EndIterator >
230 {
232  bool first = true;
233  for ( value_type const& item : output ) {
234  if ( !first )
235  w( ',' );
236  w( item );
237  first = false;
238  }
239 }
240 
241 #ifdef EMLABCPP_USE_OSTREAM
242 
243 template < typename Iterator, typename EndIterator >
244 std::ostream& operator<<( std::ostream& os, view< Iterator, EndIterator > const& iter )
245 {
246  static_assert( ostreamable< typename std::iterator_traits< Iterator >::value_type > );
248  [&os]( auto const& item ) {
249  os << item;
250  },
251  iter );
252  return os;
253 }
254 #endif
255 
256 } // namespace emlabcpp
Generic class to represent view of some container.
Definition: view.h:41
std::size_t size_type
Definition: view.h:51
requires(!range_container_with_iter< Cont, iterator >) const expr view(Cont const &cont)
Definition: view.h:80
constexpr EndIterator end() const
Past the end iterator.
Definition: view.h:110
constexpr Iterator begin() const
Start of the dataset iterator.
Definition: view.h:104
constexpr value_type const & back() const
Returns last value of the range.
Definition: view.h:153
requires(!range_container_with_iter< Cont, iterator >) const expr view(Cont &cont)
Definition: view.h:72
constexpr view(Cont const &cont)
constructor from Container, uses begin/end of the container
Definition: view.h:65
constexpr value_type const & front() const
Returns first value of the range.
Definition: view.h:147
Iterator iterator
Definition: view.h:49
constexpr view(view< OtherIterator, OtherEndIterator > other)
Definition: view.h:97
std::reverse_iterator< Iterator > reverse_iterator
Definition: view.h:48
constexpr view(Cont &cont)
constructor from Container, uses begin/end of the container
Definition: view.h:57
typename std::iterator_traits< Iterator >::difference_type difference_type
Definition: view.h:50
constexpr view()=default
constexpr reverse_iterator rend() const
Returns iterator to the element before first element, that can go in reverse.
Definition: view.h:129
constexpr view(Iterator begin, EndIterator end)
constructor from the iterators that should internally be stored
Definition: view.h:88
constexpr reverse_iterator rbegin() const
Returns iterator to the last element that goes in reverse.
Definition: view.h:122
typename std::iterator_traits< Iterator >::value_type value_type
standard public usings for container
Definition: view.h:47
constexpr bool empty() const
View is empty if both iterators are equal.
Definition: view.h:141
constexpr size_type size() const
Size of the view over dataset uses std::ranges::distance() to tell the size.
Definition: view.h:135
hdr_state next(hdr_state cs) noexcept
Definition: page.h:43
std::variant< int64_t, float, bool, string_buffer > value_type
Definition: base.h:51
MIT License.
Definition: impl.h:31
length distance
Definition: physical_quantity.h:129
std::size_t size_type
Definition: static_storage.h:105
constexpr pointer data() noexcept
Returns pointer to first item of the storage.
Definition: static_storage.h:108
constexpr auto reversed(referenceable_container auto &container) -> view< decltype(std::rbegin(container)) >
Returns view to the Container in reverse order.
Definition: view.h:223
constexpr view< iterator_of_t< Container > > trim_view(Container &cont, float const r)
Creates the view over over Container, where we ignore first r*size/2 items and last r*size/2 items.
Definition: view.h:215
view(Container &cont) -> view< iterator_of_t< Container > >
The container deduction guide uses iterator_of_t.
constexpr view< Iter > view_n(Iter begin, std::size_t const n)
Creates view over 'n' items of dataset starting at 'begin' This does not check validity of the range!
Definition: view.h:198
T value_type
Definition: static_storage.h:100
constexpr auto data_view(Container &cont)
Definition: view.h:206
concept ostreamable
Definition: concepts.h:164
concept container
Definition: concepts.h:93
concept referenceable_container
Definition: concepts.h:96
constexpr bool operator!=(pose const &x, pose const &y)
negation of operator== between poses
Definition: pose.h:99
std::ostream & operator<<(std::ostream &os, string_buffer< N > const &sb)
Definition: string_buffer.h:112
void string_serialize_view(auto &&w, view< Iterator, EndIterator > const &output)
Definition: view.h:229
constexpr bool operator==(pose const &x, pose const &y)
compares poses on their position and orientation
Definition: pose.h:93
Definition: base.h:67