Dune Core Modules (unstable)

reservedvector.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 // SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5 #ifndef DUNE_COMMON_RESERVEDVECTOR_HH
6 #define DUNE_COMMON_RESERVEDVECTOR_HH
7 
12 #include <algorithm>
13 #include <array>
14 #include <cassert>
15 #include <iostream>
16 #include <iterator>
17 #include <cstddef>
18 #include <initializer_list>
19 
20 #include <dune/common/hash.hh>
21 
22 #ifdef CHECK_RESERVEDVECTOR
23 #define CHECKSIZE(X) assert(X)
24 #else
25 #define CHECKSIZE(X) {}
26 #endif
27 
28 namespace Dune
29 {
45  template<class T, int n>
47  {
48  using storage_type = std::array<T,n>;
49 
50  public:
51 
55  typedef typename storage_type::value_type value_type;
57  typedef typename storage_type::pointer pointer;
59  typedef typename storage_type::const_pointer const_pointer;
61  typedef typename storage_type::reference reference;
63  typedef typename storage_type::const_reference const_reference;
65  typedef typename storage_type::size_type size_type;
67  typedef typename storage_type::difference_type difference_type;
69  typedef typename storage_type::iterator iterator;
71  typedef typename storage_type::const_iterator const_iterator;
73  typedef std::reverse_iterator<iterator> reverse_iterator;
75  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
76 
82  constexpr ReservedVector()
83  noexcept(std::is_nothrow_default_constructible_v<value_type>)
84  : storage_()
85  , size_(0)
86  {}
87 
89  explicit constexpr ReservedVector(size_type count)
90  noexcept(std::is_nothrow_default_constructible_v<value_type>)
91  : storage_()
92  , size_(count)
93  {
94  assert(count <= n);
95  }
96 
98  constexpr ReservedVector(size_type count, const value_type& value)
99  noexcept(std::is_nothrow_copy_assignable_v<value_type> &&
100  noexcept(ReservedVector(count)))
101  : ReservedVector(count)
102  {
103  for (size_type i=0; i<count; ++i)
104  storage_[i] = value;
105  }
106 
108  template<class InputIt,
109  std::enable_if_t<std::is_convertible_v<typename std::iterator_traits<InputIt>::value_type, value_type>, int> = 0>
110  constexpr ReservedVector(InputIt first, InputIt last)
111  noexcept(std::is_nothrow_copy_assignable_v<value_type> &&
112  noexcept(ReservedVector()))
113  : ReservedVector()
114  {
115  for (size_type i=0; i<n && first!=last; ++i,++size_)
116  storage_[i] = *first++;
117  assert(first == last);
118  }
119 
121  constexpr ReservedVector(std::initializer_list<value_type> const& l)
122  noexcept(std::is_nothrow_copy_assignable_v<value_type> &&
123  noexcept(ReservedVector(l.begin(),l.end())))
124  : ReservedVector(l.begin(),l.end())
125  {}
126 
132  constexpr bool operator== (const ReservedVector& that) const noexcept
133  {
134  if (size() != that.size())
135  return false;
136  for (size_type i=0; i<size(); ++i)
137  if (!(storage_[i]==that.storage_[i]))
138  return false;
139  return true;
140  }
141 
143  constexpr bool operator!= (const ReservedVector& that) const noexcept
144  {
145  return !(*this == that);
146  }
147 
149  constexpr bool operator< (const ReservedVector& that) const noexcept
150  {
151  for (size_type i=0; i<std::min(size(),that.size()); ++i) {
152  if (storage_[i] < that.storage_[i]) return true;
153  if (that.storage_[i] < storage_[i]) return false;
154  }
155  return size() < that.size();
156  }
157 
159  constexpr bool operator> (const ReservedVector& that) const noexcept
160  {
161  return that < *this;
162  }
163 
165  constexpr bool operator<= (const ReservedVector& that) const noexcept
166  {
167  return !(*this > that);
168  }
169 
171  constexpr bool operator>= (const ReservedVector& that) const noexcept
172  {
173  return !(*this < that);
174  }
175 
181  constexpr void clear() noexcept
182  {
183  size_ = 0;
184  }
185 
187  constexpr void resize(size_type s) noexcept
188  {
189  CHECKSIZE(s<=n);
190  size_ = s;
191  }
192 
194  constexpr void push_back(const value_type& t)
195  noexcept(std::is_nothrow_copy_assignable_v<value_type>)
196  {
197  CHECKSIZE(size_<n);
198  storage_[size_++] = t;
199  }
200 
202  constexpr void push_back(value_type&& t)
203  noexcept(std::is_nothrow_move_assignable_v<value_type>)
204  {
205  CHECKSIZE(size_<n);
206  storage_[size_++] = std::move(t);
207  }
208 
210  template<class... Args>
211  reference emplace_back(Args&&... args)
212  noexcept(std::is_nothrow_constructible_v<value_type,decltype(args)...>)
213  {
214  CHECKSIZE(size_<n);
215  value_type* p = &storage_[size_++];
216  // first destroy any previously (default) constructed element at that location
217  p->~value_type();
218  // construct the value_type in place
219  // NOTE: This is not an integral constant expression.
220  // With c++20 we could use std::construct_at
221  ::new (const_cast<void*>(static_cast<const volatile void*>(p)))
222  value_type(std::forward<Args>(args)...);
223  return *p;
224  }
225 
227  constexpr void pop_back() noexcept
228  {
229  if (! empty()) size_--;
230  }
231 
237  constexpr iterator begin() noexcept
238  {
239  return storage_.begin();
240  }
241 
243  constexpr const_iterator begin() const noexcept
244  {
245  return storage_.begin();
246  }
247 
249  constexpr const_iterator cbegin() const noexcept
250  {
251  return storage_.cbegin();
252  }
253 
255  constexpr reverse_iterator rbegin() noexcept
256  {
257  return reverse_iterator{begin()+size()};
258  }
259 
261  constexpr const_reverse_iterator rbegin() const noexcept
262  {
263  return const_reverse_iterator{begin()+size()};
264  }
265 
267  constexpr const_reverse_iterator crbegin() const noexcept
268  {
269  return const_reverse_iterator{begin()+size()};
270  }
271 
273  constexpr iterator end() noexcept
274  {
275  return storage_.begin()+size();
276  }
277 
279  constexpr const_iterator end() const noexcept
280  {
281  return storage_.begin()+size();
282  }
283 
285  constexpr const_iterator cend() const noexcept
286  {
287  return storage_.cbegin()+size();
288  }
289 
291  constexpr reverse_iterator rend() noexcept
292  {
293  return reverse_iterator{begin()};
294  }
295 
297  constexpr const_reverse_iterator rend() const noexcept
298  {
299  return const_reverse_iterator{begin()};
300  }
301 
303  constexpr const_reverse_iterator crend() const noexcept
304  {
305  return const_reverse_iterator{begin()};
306  }
307 
313  constexpr reference at(size_type i)
314  {
315  if (!(i < size()))
316  throw std::out_of_range("Index out of range");
317  return storage_[i];
318  }
319 
321  constexpr const_reference at(size_type i) const
322  {
323  if (!(i < size()))
324  throw std::out_of_range("Index out of range");
325  return storage_[i];
326  }
327 
329  constexpr reference operator[] (size_type i) noexcept
330  {
331  CHECKSIZE(size_>i);
332  return storage_[i];
333  }
334 
336  constexpr const_reference operator[] (size_type i) const noexcept
337  {
338  CHECKSIZE(size_>i);
339  return storage_[i];
340  }
341 
343  constexpr reference front() noexcept
344  {
345  CHECKSIZE(size_>0);
346  return storage_[0];
347  }
348 
350  constexpr const_reference front() const noexcept
351  {
352  CHECKSIZE(size_>0);
353  return storage_[0];
354  }
355 
357  constexpr reference back() noexcept
358  {
359  CHECKSIZE(size_>0);
360  return storage_[size_-1];
361  }
362 
364  constexpr const_reference back() const noexcept
365  {
366  CHECKSIZE(size_>0);
367  return storage_[size_-1];
368  }
369 
371  constexpr pointer data() noexcept
372  {
373  return storage_.data();
374  }
375 
377  constexpr const_pointer data() const noexcept
378  {
379  return storage_.data();
380  }
381 
387  constexpr size_type size() const noexcept
388  {
389  return size_;
390  }
391 
393  constexpr bool empty() const noexcept
394  {
395  return size_==0;
396  }
397 
399  static constexpr size_type capacity() noexcept
400  {
401  return n;
402  }
403 
405  static constexpr size_type max_size() noexcept
406  {
407  return n;
408  }
409 
415  constexpr void fill(const value_type& value)
416  noexcept(std::is_nothrow_copy_assignable_v<value_type>)
417  {
418  for (size_type i=0; i<size(); ++i)
419  storage_[i] = value;
420  }
421 
423  void swap(ReservedVector& other)
424  noexcept(std::is_nothrow_swappable_v<value_type>)
425  {
426  using std::swap;
427  swap(storage_, other.storage_);
428  swap(size_, other.size_);
429  }
430 
434  friend std::ostream& operator<< (std::ostream& s, const ReservedVector& v)
435  {
436  for (size_type i=0; i<v.size(); i++)
437  s << v[i] << " ";
438  return s;
439  }
440 
441  inline friend std::size_t hash_value(const ReservedVector& v) noexcept
442  {
443  return hash_range(v.storage_.data(),v.storage_.data()+v.size_);
444  }
445 
446  private:
447  storage_type storage_;
448  size_type size_;
449  };
450 
451 }
452 
454 
455 #undef CHECKSIZE
456 
457 #endif // DUNE_COMMON_RESERVEDVECTOR_HH
A Vector class with statically reserved memory.
Definition: reservedvector.hh:47
constexpr const_reference front() const noexcept
Returns const reference to first element of vector.
Definition: reservedvector.hh:350
constexpr const_reverse_iterator crend() const noexcept
Returns a const reverse-iterator pointing to the begin of the vector.
Definition: reservedvector.hh:303
constexpr ReservedVector(size_type count) noexcept(std::is_nothrow_default_constructible_v< value_type >)
Constructs the vector with count elements that will be default-initialized.
Definition: reservedvector.hh:89
constexpr void fill(const value_type &value) noexcept(std::is_nothrow_copy_assignable_v< value_type >)
Fill the container with the value.
Definition: reservedvector.hh:415
storage_type::pointer pointer
Pointer to T.
Definition: reservedvector.hh:57
constexpr reverse_iterator rbegin() noexcept
Returns a const reverse-iterator pointing to the end of the vector.
Definition: reservedvector.hh:255
constexpr bool operator<=(const ReservedVector &that) const noexcept
Lexicographically compares the values in the vector this with that
Definition: reservedvector.hh:165
constexpr bool operator>(const ReservedVector &that) const noexcept
Lexicographically compares the values in the vector this with that
Definition: reservedvector.hh:159
constexpr const_reverse_iterator rend() const noexcept
Returns a const reverse-iterator pointing to the begin of the vector.
Definition: reservedvector.hh:297
static constexpr size_type max_size() noexcept
Returns the maximum length of the vector.
Definition: reservedvector.hh:405
constexpr const_reference at(size_type i) const
Returns a const reference to the i'th element.
Definition: reservedvector.hh:321
std::reverse_iterator< iterator > reverse_iterator
Reverse iterator.
Definition: reservedvector.hh:73
constexpr iterator end() noexcept
Returns an iterator pointing to the end of the vector.
Definition: reservedvector.hh:273
constexpr bool operator<(const ReservedVector &that) const noexcept
Lexicographically compares the values in the vector this with that
Definition: reservedvector.hh:149
constexpr size_type size() const noexcept
Returns number of elements in the vector.
Definition: reservedvector.hh:387
constexpr bool empty() const noexcept
Returns true if vector has no elements.
Definition: reservedvector.hh:393
constexpr iterator begin() noexcept
Returns a iterator pointing to the beginning of the vector.
Definition: reservedvector.hh:237
constexpr void push_back(const value_type &t) noexcept(std::is_nothrow_copy_assignable_v< value_type >)
Appends an element to the end of a vector, up to the maximum size n, O(1) time.
Definition: reservedvector.hh:194
constexpr reverse_iterator rend() noexcept
Returns a const reverse-iterator pointing to the begin of the vector.
Definition: reservedvector.hh:291
storage_type::iterator iterator
Iterator used to iterate through a vector.
Definition: reservedvector.hh:69
constexpr const_iterator cbegin() const noexcept
Returns a const_iterator pointing to the beginning of the vector.
Definition: reservedvector.hh:249
std::reverse_iterator< const_iterator > const_reverse_iterator
Const reverse iterator.
Definition: reservedvector.hh:75
constexpr pointer data() noexcept
Returns pointer to the underlying memory.
Definition: reservedvector.hh:371
constexpr const_reference back() const noexcept
Returns const reference to last element of vector.
Definition: reservedvector.hh:364
constexpr bool operator==(const ReservedVector &that) const noexcept
Compares the values in the vector this with that for equality.
Definition: reservedvector.hh:132
constexpr void pop_back() noexcept
Erases the last element of the vector, O(1) time.
Definition: reservedvector.hh:227
storage_type::difference_type difference_type
A signed integral type.
Definition: reservedvector.hh:67
constexpr const_iterator end() const noexcept
Returns a const_iterator pointing to the end of the vector.
Definition: reservedvector.hh:279
constexpr void clear() noexcept
Erases all elements.
Definition: reservedvector.hh:181
constexpr ReservedVector() noexcept(std::is_nothrow_default_constructible_v< value_type >)
Constructs an empty vector.
Definition: reservedvector.hh:82
storage_type::const_iterator const_iterator
Const iterator used to iterate through a vector.
Definition: reservedvector.hh:71
reference emplace_back(Args &&... args) noexcept(std::is_nothrow_constructible_v< value_type, decltype(args)... >)
Appends an element to the end of a vector by constructing it in place.
Definition: reservedvector.hh:211
storage_type::size_type size_type
An unsigned integral type.
Definition: reservedvector.hh:65
constexpr bool operator>=(const ReservedVector &that) const noexcept
Lexicographically compares the values in the vector this with that
Definition: reservedvector.hh:171
storage_type::const_reference const_reference
Const reference to T.
Definition: reservedvector.hh:63
void swap(ReservedVector &other) noexcept(std::is_nothrow_swappable_v< value_type >)
Swap the content with another vector.
Definition: reservedvector.hh:423
constexpr ReservedVector(InputIt first, InputIt last) noexcept(std::is_nothrow_copy_assignable_v< value_type > &&noexcept(ReservedVector()))
Constructs the vector from an iterator range [first,last)
Definition: reservedvector.hh:110
constexpr const_pointer data() const noexcept
Returns const pointer to the underlying memory.
Definition: reservedvector.hh:377
constexpr reference at(size_type i)
Returns reference to the i'th element.
Definition: reservedvector.hh:313
constexpr const_iterator cend() const noexcept
Returns a const_iterator pointing to the end of the vector.
Definition: reservedvector.hh:285
friend std::ostream & operator<<(std::ostream &s, const ReservedVector &v)
Send ReservedVector to an output stream.
Definition: reservedvector.hh:434
constexpr reference back() noexcept
Returns reference to last element of vector.
Definition: reservedvector.hh:357
constexpr const_reverse_iterator rbegin() const noexcept
Returns a const reverse-iterator pointing to the end of the vector.
Definition: reservedvector.hh:261
storage_type::value_type value_type
The type of object, T, stored in the vector.
Definition: reservedvector.hh:55
constexpr const_iterator begin() const noexcept
Returns a const_iterator pointing to the beginning of the vector.
Definition: reservedvector.hh:243
constexpr ReservedVector(size_type count, const value_type &value) noexcept(std::is_nothrow_copy_assignable_v< value_type > &&noexcept(ReservedVector(count)))
Constructs the vector with count copies of elements with value value.
Definition: reservedvector.hh:98
constexpr reference operator[](size_type i) noexcept
Returns reference to the i'th element.
Definition: reservedvector.hh:329
constexpr reference front() noexcept
Returns reference to first element of vector.
Definition: reservedvector.hh:343
storage_type::const_pointer const_pointer
Const pointer to T.
Definition: reservedvector.hh:59
constexpr ReservedVector(std::initializer_list< value_type > const &l) noexcept(std::is_nothrow_copy_assignable_v< value_type > &&noexcept(ReservedVector(l.begin(), l.end())))
Constructs the vector from an initializer list.
Definition: reservedvector.hh:121
constexpr bool operator!=(const ReservedVector &that) const noexcept
Compares the values in the vector this with that for not equality.
Definition: reservedvector.hh:143
constexpr void resize(size_type s) noexcept
Specifies a new size for the vector.
Definition: reservedvector.hh:187
static constexpr size_type capacity() noexcept
Returns current capacity (allocated memory) of the vector.
Definition: reservedvector.hh:399
storage_type::reference reference
Reference to T.
Definition: reservedvector.hh:61
constexpr const_reverse_iterator crbegin() const noexcept
Returns a const reverse-iterator pointing to the end of the vector.
Definition: reservedvector.hh:267
constexpr void push_back(value_type &&t) noexcept(std::is_nothrow_move_assignable_v< value_type >)
Appends an element to the end of a vector by moving the value, up to the maximum size n,...
Definition: reservedvector.hh:202
constexpr auto min
Function object that returns the smaller of the given values.
Definition: hybridutilities.hh:506
Support for calculating hash values of objects.
#define DUNE_DEFINE_HASH(template_args, type)
Defines the required struct specialization to make type hashable via Dune::hash.
Definition: hash.hh:100
#define DUNE_HASH_TYPE(...)
Wrapper macro for the type to be hashed in DUNE_DEFINE_HASH.
Definition: hash.hh:117
#define DUNE_HASH_TEMPLATE_ARGS(...)
Wrapper macro for the template arguments in DUNE_DEFINE_HASH.
Definition: hash.hh:109
Dune namespace.
Definition: alignedallocator.hh:13
std::size_t hash_range(It first, It last)
Hashes all elements in the range [first,last) and returns the combined hash.
Definition: hash.hh:322
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 2, 22:35, 2024)