SPH
StaticArray.h
Go to the documentation of this file.
1 #pragma once
2 
5 #include <initializer_list>
6 
8 
9 const struct EmptyArray {
11 
18 template <typename T, int N, typename TCounter = Size>
19 class StaticArray {
20 private:
21  AlignedStorage<T> data[N];
22  TCounter actSize;
23 
24  using StorageType = WrapReference<T>;
25 
26 public:
29  if (!std::is_trivially_default_constructible<T>::value) {
30  for (TCounter i = 0; i < N; ++i) {
31  data[i].emplace();
32  }
33  }
34  actSize = N;
35  }
36 
42  actSize = 0;
43  }
44 
49  StaticArray(std::initializer_list<StorageType> list) {
50  actSize = 0;
51  SPH_ASSERT(list.size() <= N);
52  for (auto& i : list) {
53  data[actSize++].emplace(i);
54  }
55  }
56 
57  StaticArray(const StaticArray& other) = delete;
58 
60  actSize = 0;
61  for (TCounter i = 0; i < other.size(); ++i) {
62  // move if it contains values, just copy if it contains references
63  data[actSize++].emplace(std::forward<T>(other[i]));
64  }
65  }
66 
69  if (!std::is_trivially_destructible<T>::value) {
70  for (TCounter i = 0; i < actSize; ++i) {
71  data[i].destroy();
72  }
73  }
74  actSize = 0;
75  }
76 
77  StaticArray& operator=(const StaticArray& other) = delete;
78 
82  template <typename U, typename = std::enable_if_t<std::is_default_constructible<T>::value, U>>
84  this->resize(other.size());
85  for (TCounter i = 0; i < other.size(); ++i) {
86  // move if it contains values, just copy if it contains references
87  (*this)[i] = std::forward<T>(other[i]);
88  }
89  return *this;
90  }
91 
98  template <typename U, int M, typename = std::enable_if_t<std::is_lvalue_reference<T>::value, U>>
100  SPH_ASSERT(this->size() == other.size());
101  for (TCounter i = 0; i < other.size(); ++i) {
102  (*this)[i] = std::forward<U>(other[i]);
103  }
104  return *this;
105  }
106 
110  StaticArray clone() const {
111  StaticArray cloned(EMPTY_ARRAY);
112  for (TCounter i = 0; i < actSize; ++i) {
113  cloned.push(data[i].get());
114  }
115  return cloned;
116  }
117 
121  void fill(const T& value) {
122  for (TCounter i = 0; i < actSize; ++i) {
123  data[i].get() = value;
124  }
125  }
126 
128  INLINE T& operator[](const TCounter idx) noexcept {
129  SPH_ASSERT(idx >= 0 && idx < actSize, idx, actSize);
130  return data[idx].get();
131  }
132 
134  INLINE const T& operator[](const TCounter idx) const noexcept {
135  SPH_ASSERT(idx >= 0 && idx < actSize, idx, actSize);
136  return data[idx].get();
137  }
138 
140  INLINE constexpr TCounter maxSize() const noexcept {
141  return N;
142  }
143 
147  INLINE TCounter size() const {
148  return actSize;
149  }
150 
154  INLINE bool empty() const {
155  return actSize == 0;
156  }
157 
161  template <typename U, typename = std::enable_if_t<std::is_constructible<StorageType, U>::value>>
162  INLINE void push(U&& value) {
163  SPH_ASSERT(actSize < N);
164  data[actSize++].emplace(std::forward<U>(value));
165  }
166 
170  INLINE T pop() {
171  SPH_ASSERT(actSize > 0);
172  T value = data[actSize - 1];
173  data[actSize - 1].destroy();
174  actSize--;
175  return value;
176  }
177 
182  void resize(const TCounter newSize) {
183  SPH_ASSERT(unsigned(newSize) <= N);
184  if (!std::is_trivially_default_constructible<T>::value) {
185  if (newSize > actSize) {
186  for (TCounter i = actSize; i < newSize; ++i) {
187  data[i].emplace();
188  }
189  } else {
190  for (TCounter i = newSize; i < actSize; ++i) {
191  data[i].destroy();
192  }
193  }
194  }
195  actSize = newSize;
196  }
197 
199  return Iterator<StorageType>(rawData(), rawData(), rawData() + actSize);
200  }
201 
203  return Iterator<const StorageType>(rawData(), rawData(), rawData() + actSize);
204  }
205 
207  return Iterator<const StorageType>(rawData(), rawData(), rawData() + actSize);
208  }
209 
211  return Iterator<StorageType>(rawData() + actSize, rawData(), rawData() + actSize);
212  }
213 
215  return Iterator<const StorageType>(rawData() + actSize, rawData(), rawData() + actSize);
216  }
217 
219  return Iterator<const StorageType>(rawData() + actSize, rawData(), rawData() + actSize);
220  }
221 
222  operator ArrayView<T>() {
223  return ArrayView<T>(rawData(), actSize);
224  }
225 
226  operator ArrayView<const T>() const {
227  return ArrayView<const T>(rawData(), actSize);
228  }
229 
230  bool operator==(const StaticArray& other) const {
231  if (actSize != other.actSize) {
232  return false;
233  }
234  for (TCounter i = 0; i < actSize; ++i) {
235  if (data[i].get() != other.data[i].get()) {
236  return false;
237  }
238  }
239  return true;
240  }
241 
242  bool operator!=(const StaticArray& other) const {
243  return !(*this == other);
244  }
245 
249  template <typename TStream>
250  friend TStream& operator<<(TStream& stream, const StaticArray& array) {
251  for (const T& t : array) {
252  stream << t << std::endl;
253  }
254  return stream;
255  }
256 
257 private:
258  INLINE StorageType* rawData() {
259  return reinterpret_cast<StorageType*>(data);
260  }
261 
262  INLINE const StorageType* rawData() const {
263  return reinterpret_cast<const StorageType*>(data);
264  }
265 };
266 
271 template <typename T0, typename... TArgs>
272 StaticArray<T0, sizeof...(TArgs) + 1> makeStatic(T0&& t0, TArgs&&... rest) {
273  return StaticArray<T0, sizeof...(TArgs) + 1>({ std::forward<T0>(t0), std::forward<TArgs>(rest)... });
274 }
275 
280 template <typename T0, typename... TArgs>
281 StaticArray<T0&, sizeof...(TArgs) + 1> tie(T0& t0, TArgs&... rest) {
282  return StaticArray<T0&, sizeof...(TArgs) + 1>({ t0, rest... });
283 }
284 
286 template <typename T>
288 
289 
291 template <typename T, Size N>
293 private:
294  T data[N];
295 
296 public:
297  template <typename... TArgs>
298  constexpr ConstexprArray(TArgs&&... args)
299  : data{ std::forward<TArgs>(args)... } {}
300 
301  constexpr const T& operator[](const Size idx) const {
302  return data[idx];
303  }
304 
305  constexpr T& operator[](const Size idx) {
306  return data[idx];
307  }
308 };
309 
Base class for utility wrappers (Optional, Variant, ...)
Simple non-owning view of a container.
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
StaticArray< T0, sizeof...(TArgs)+1 > makeStatic(T0 &&t0, TArgs &&... rest)
Creates a static array from a list of parameters.
Definition: StaticArray.h:272
StaticArray< T0 &, sizeof...(TArgs)+1 > tie(T0 &t0, TArgs &... rest)
Creates a static array from a list of l-value references.
Definition: StaticArray.h:281
NAMESPACE_SPH_BEGIN const struct EmptyArray EMPTY_ARRAY
constexpr int N
typename WrapReferenceType< T >::Type WrapReference
Definition: Traits.h:153
INLINE void emplace(TArgs &&... rest)
constexpr INLINE Type & get() noexcept
Return the reference to the stored value.
INLINE void destroy()
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
Container similar to StaticArray, but with constexpr constructors and getters.
Definition: StaticArray.h:292
constexpr const T & operator[](const Size idx) const
Definition: StaticArray.h:301
constexpr T & operator[](const Size idx)
Definition: StaticArray.h:305
constexpr ConstexprArray(TArgs &&... args)
Definition: StaticArray.h:298
Simple (forward) iterator over continuous array of objects of type T.
Definition: Iterator.h:18
Array with fixed number of allocated elements.
Definition: StaticArray.h:19
INLINE T & operator[](const TCounter idx) noexcept
Returns the element with given index.
Definition: StaticArray.h:128
~StaticArray()
Destructor, destroys all constructed elements in the array.
Definition: StaticArray.h:68
void resize(const TCounter newSize)
Changes size of the array.
Definition: StaticArray.h:182
StaticArray & operator=(StaticArray< U, N > &&other)
Move operator for arrays holding default-constructible types.
Definition: StaticArray.h:83
bool operator!=(const StaticArray &other) const
Definition: StaticArray.h:242
void fill(const T &value)
Assigns a value to all constructed elements of the array.
Definition: StaticArray.h:121
StaticArray & operator=(StaticArray< U, M > &&other)
Special assignment operator for array of references on left-hand side.
Definition: StaticArray.h:99
INLINE Iterator< const StorageType > cbegin() const
Definition: StaticArray.h:206
INLINE Iterator< const StorageType > begin() const
Definition: StaticArray.h:202
StaticArray clone() const
Clones the array, calling copy constructor on all elements.
Definition: StaticArray.h:110
bool operator==(const StaticArray &other) const
Definition: StaticArray.h:230
friend TStream & operator<<(TStream &stream, const StaticArray &array)
Prints content of array to stream.
Definition: StaticArray.h:250
INLINE Iterator< StorageType > end()
Definition: StaticArray.h:210
StaticArray(const StaticArray &other)=delete
INLINE void push(U &&value)
Inserts a value to the end of the array using copy/move constructor.
Definition: StaticArray.h:162
StaticArray(const EmptyArray &)
Initialize an empty array.
Definition: StaticArray.h:41
StaticArray(StaticArray &&other)
Definition: StaticArray.h:59
StaticArray(std::initializer_list< StorageType > list)
Initialize using initializer_list.
Definition: StaticArray.h:49
INLINE Iterator< const StorageType > cend() const
Definition: StaticArray.h:218
constexpr INLINE TCounter maxSize() const noexcept
Returns the maximum allowed size of the array.
Definition: StaticArray.h:140
INLINE Iterator< const StorageType > end() const
Definition: StaticArray.h:214
INLINE const T & operator[](const TCounter idx) const noexcept
Returns the element with given index.
Definition: StaticArray.h:134
StaticArray()
Default constructor, calls default constructor on all elements.
Definition: StaticArray.h:28
INLINE T pop()
Removes and destroys element from the end of the array.
Definition: StaticArray.h:170
INLINE Iterator< StorageType > begin()
Definition: StaticArray.h:198
INLINE TCounter size() const
Returns the current size of the array (number of constructed elements).
Definition: StaticArray.h:147
INLINE bool empty() const
Return true if the array is empty.
Definition: StaticArray.h:154
StaticArray & operator=(const StaticArray &other)=delete
Overload of std::swap for Sph::Array.
Definition: Array.h:578