emlabcpp
modern opinionated embedded C++ library
static_vector.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "./concepts.h"
27 #include "./static_storage.h"
28 #include "./view.h"
29 
30 namespace emlabcpp
31 {
32 
34 template < typename T, std::size_t N >
36 {
37 
38 public:
39  static constexpr std::size_t capacity = N;
40 
41  using value_type = T;
42  using size_type = std::size_t;
43  using reference = T&;
44  using const_reference = T const&;
45  using iterator = T*;
46  using const_iterator = T const*;
47 
48  static_vector() = default;
49 
50  static_vector( static_vector const& other )
51  {
52  copy_from( other );
53  }
54 
55  static_vector( static_vector&& other ) noexcept
56  {
57  move_from( other );
58  other.clear();
59  }
60 
61  static_vector( std::size_t M, T const& item )
62  {
63  M = std::max( M, N );
64  std::uninitialized_fill( begin(), begin() + M, item );
65  }
66 
67  template < std::size_t M >
68  requires( M <= N )
69  explicit static_vector( std::array< T, M > data )
70  {
71  move_from( data );
72  }
73 
75  {
76  if ( this == &other )
77  return *this;
78  clear();
79  copy_from( other );
80  return *this;
81  }
82 
83  static_vector& operator=( static_vector&& other ) noexcept
84  {
85  if ( this == &other )
86  return *this;
87  clear();
88  move_from( other );
89  other.clear();
90  return *this;
91  }
92 
93  template < std::size_t M >
94  requires( M <= N )
95  static_vector& operator=( std::array< T, M > data )
96  {
97  clear();
98  move_from( data );
99  return *this;
100  }
101 
102  void swap( static_vector& other ) noexcept
103  {
104  using std::swap;
105  size_type const shared_n = std::min( size(), other.size() );
106 
107  for ( size_type i = 0; i < shared_n; ++i )
108  swap( storage_[i], other.storage_[i] );
109 
110  if ( size() > other.size() ) {
111  for ( size_type i = shared_n; i < size(); ++i )
112  other.emplace_back( std::move( storage_[i] ) );
113  while ( shared_n != size() )
114  pop_back();
115  } else if ( size() < other.size() ) {
116  for ( size_type i = shared_n; i < other.size(); ++i )
117  emplace_back( std::move( other.storage_[i] ) );
118  while ( shared_n != other.size() )
119  other.pop_back();
120  }
121  }
122 
123  [[nodiscard]] T* data()
124  {
125  return storage_.data();
126  }
127 
128  [[nodiscard]] T const* data() const
129  {
130  return storage_.data();
131  }
132 
133  [[nodiscard]] iterator begin()
134  {
135  return data();
136  }
137 
138  [[nodiscard]] iterator end()
139  {
140  return begin() + size_;
141  }
142 
143  [[nodiscard]] const_iterator begin() const
144  {
145  return data();
146  }
147 
148  [[nodiscard]] const_iterator end() const
149  {
150  return begin() + size_;
151  }
152 
153  [[nodiscard]] reference front()
154  {
155  return storage_[0];
156  }
157 
158  [[nodiscard]] const_reference front() const
159  {
160  return storage_[0];
161  }
162 
163  void push_back( T item )
164  {
165  emplace_back( std::move( item ) );
166  }
167 
168  template < typename... Args >
169  T& emplace_back( Args&&... args )
170  {
171  T& ref = storage_.emplace_item( size_, std::forward< Args >( args )... );
172  size_ += 1;
173  return ref;
174  }
175 
176  [[nodiscard]] T take_back()
177  {
178  T item = std::move( back() );
179  pop_back();
180  return item;
181  }
182 
183  void pop_back()
184  {
185  storage_.delete_item( size_ - 1 );
186  size_ -= 1;
187  }
188 
189  [[nodiscard]] reference back()
190  {
191  return storage_[size_ - 1];
192  }
193 
194  [[nodiscard]] const_reference back() const
195  {
196  return storage_[size_ - 1];
197  }
198 
200 
201  [[nodiscard]] constexpr std::size_t max_size() const
202  {
203  return N;
204  }
205 
206  [[nodiscard]] std::size_t size() const
207  {
208  return size_;
209  }
210 
211  [[nodiscard]] bool empty() const
212  {
213  return size_ == 0;
214  }
215 
216  [[nodiscard]] bool full() const
217  {
218  return size_ == N;
219  }
220 
221  const_reference operator[]( size_type const i ) const
222  {
223  return storage_[i];
224  }
225 
226  reference operator[]( size_type const i )
227  {
228  return storage_[i];
229  }
230 
231  void clear()
232  {
233  purge();
234  }
235 
236  ~static_vector()
237  {
238  purge();
239  }
240 
241 private:
242  static_storage< T, N > storage_;
244 
245  template < typename Container >
246  void copy_from( Container const& cont )
247  {
248  size_ = std::size( cont );
249  std::uninitialized_copy( std::begin( cont ), std::end( cont ), begin() );
250  }
251 
252  template < typename Container >
253  void move_from( Container& cont )
254  {
255  size_ = std::size( cont );
256  std::uninitialized_move( std::begin( cont ), std::end( cont ), begin() );
257  }
258 
260  void purge()
261  {
262  std::destroy_n( begin(), size_ );
263  size_ = 0;
264  }
265 };
266 
267 template < typename T, std::size_t N >
268 [[nodiscard]] auto operator<=>( static_vector< T, N > const& lh, static_vector< T, N > const& rh )
269 {
270  return std::lexicographical_compare_three_way(
271  std::begin( lh ), std::end( lh ), std::begin( rh ), std::end( rh ) );
272 }
273 
274 template < typename T, std::size_t N >
275 [[nodiscard]] bool operator==( static_vector< T, N > const& lh, static_vector< T, N > const& rh )
276 {
277  auto size = std::size( lh );
278  if ( size != std::size( rh ) )
279  return false;
280 
281  for ( std::size_t i = 0; i < size; ++i )
282  if ( lh[i] != rh[i] )
283  return false;
284  return true;
285 }
286 
287 template < typename T, std::size_t N >
288 [[nodiscard]] bool operator!=( static_vector< T, N > const& lh, static_vector< T, N > const& rh )
289 {
290  return !( lh == rh );
291 }
292 
293 template < typename T, std::size_t N >
294 void swap( static_vector< T, N > const& lh, static_vector< T, N > const& rh ) noexcept
295 {
296  lh.swap( rh );
297 }
298 
299 #ifdef EMLABCPP_USE_OSTREAM
301 template < typename T, std::size_t N >
302 std::ostream& operator<<( std::ostream& os, static_vector< T, N > const& vec )
303 {
304  return os << view{ vec };
305 }
306 #endif
307 
308 } // namespace emlabcpp
Data container for up to N elements.
Definition: static_vector.h:36
void purge()
Cleans entire buffer from items.
Definition: static_vector.h:260
T const * const_iterator
Definition: static_vector.h:46
static_vector(static_vector &&other) noexcept
Definition: static_vector.h:55
static_vector & operator=(static_vector const &other)
Definition: static_vector.h:74
void move_from(Container &cont)
Definition: static_vector.h:253
static_vector(std::size_t M, T const &item)
Definition: static_vector.h:61
std::size_t size_type
Definition: static_vector.h:42
void copy_from(Container const &cont)
count of items
Definition: static_vector.h:246
T const & const_reference
Definition: static_vector.h:44
static_vector(static_vector const &other)
Definition: static_vector.h:50
static_vector & operator=(static_vector &&other) noexcept
Definition: static_vector.h:83
requires(M<=N) explicit static_vector(std
Definition: static_vector.h:68
T * iterator
Definition: static_vector.h:45
size_type size_
Definition: static_vector.h:243
static constexpr std::size_t capacity
Definition: static_vector.h:39
T value_type
Definition: static_vector.h:41
requires(M<=N) static_vector &operator
T & reference
Definition: static_vector.h:43
static constexpr std::size_t max_size
Definition: serializer.h:73
MIT License.
Definition: impl.h:31
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 reference operator[](size_type const i) noexcept
Provides a reference to item at position i.
Definition: static_storage.h:136
view(Container &cont) -> view< iterator_of_t< Container > >
The container deduction guide uses iterator_of_t.
Args const & args
Definition: min_max.h:83
void swap(static_vector< T, N > const &lh, static_vector< T, N > const &rh) noexcept
Definition: static_vector.h:294
constexpr Derived max(vec_point_base< Derived, N > const &a, vec_point_base< Derived, N > const &b)
Definition: vec_point_base.h:229
constexpr Derived const & min(vec_point_base< Derived, N > const &a, vec_point_base< Derived, N > const &b)
Definition: vec_point_base.h:236
auto operator<=>(static_circular_buffer< T, N > const &lh, static_circular_buffer< T, N > const &rh)
Definition: static_circular_buffer.h:290
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
N
Definition: static_storage.h:97
constexpr bool operator==(pose const &x, pose const &y)
compares poses on their position and orientation
Definition: pose.h:93