Molassembler  1.0.0
Molecule graph and conformer library
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Array.h
Go to the documentation of this file.
1 
12 #ifndef INCLUDE_MOLASSEMBLER_TEMPLE_ARRAY_H
13 #define INCLUDE_MOLASSEMBLER_TEMPLE_ARRAY_H
14 
16 
17 #include <cstddef>
18 #include <type_traits>
19 #include <utility>
20 
21 namespace Scine {
22 namespace Molassembler {
23 namespace Temple {
24 
25 template<typename T, size_t nItems>
26 class Array {
27 public:
30  using value_type = T;
32 
35 
42  template<size_t ... Inds>
43  constexpr Array(
44  const Array& other,
45  std::index_sequence<Inds...> /* inds */
46  ) :items_ {other[Inds]...} {}
47 
56  constexpr Array(const Array& other)
57  : Array(other, std::make_index_sequence<nItems>{}) {}
58 
66  template<size_t ... Inds>
67  constexpr Array(
68  Array&& other,
69  std::index_sequence<Inds...> /* inds */
70  ) :items_ {std::move(other[Inds])...} {}
71 
80  constexpr Array(Array&& other) noexcept
81  : Array(std::move(other), std::make_index_sequence<nItems>{}) {}
82 
87  constexpr Array& operator = (const Array& other) {
88  for(std::size_t i = 0; i < nItems; ++i) {
89  items_[i] = other.items_[i];
90  }
91 
92  return *this;
93  }
94 
99  constexpr Array& operator = (Array&& other) noexcept {
100  for(std::size_t i = 0; i < nItems; ++i) {
101  items_[i] = std::move(other.items_[i]);
102  }
103 
104  return *this;
105  }
106 
108  ~Array() = default;
110 
114  template<size_t ... Inds>
115  constexpr Array(
116  const std::array<T, nItems>& other,
117  std::index_sequence<Inds...> /* inds */
118  ) :items_ {other[Inds]...} {}
119 
124  constexpr Array(const std::array<T, nItems>& other)
125  : Array(other, std::make_index_sequence<nItems>{})
126  {}
127 
132  template<typename ...Args>
133  constexpr Array(Args... args)
134  : items_ {static_cast<T>(args)...}
135  {}
137 
140 
147  constexpr T& operator[] (const std::size_t index) noexcept {
148  return items_[index];
149  }
150 
152  constexpr T& at(const std::size_t index) noexcept {
153  return items_[index];
154  }
155 
157  constexpr const T& operator[] (const std::size_t index) const noexcept {
158  return items_[index];
159  }
160 
162  constexpr const T& at(const std::size_t index) const noexcept {
163  return items_[index];
164  }
165 
170  constexpr const T& front() const noexcept {
171  return items_[0];
172  }
173 
178  constexpr const T& back() const noexcept {
179  return items_[nItems - 1];
180  }
182 
183  constexpr size_t size() const noexcept {
184  return nItems;
185  }
186 
191  constexpr bool operator == (const Array& other) const noexcept {
192  for(std::size_t i = 0; i < nItems; ++i) {
193  if(items_[i] != other.items_[i]) {
194  return false;
195  }
196  }
197 
198  return true;
199  }
200 
202  constexpr bool operator != (const Array& other) const noexcept {
203  for(std::size_t i = 0; i < nItems; ++i) {
204  if(items_[i] != other.items_[i]) {
205  return true;
206  }
207  }
208 
209  return false;
210  }
211 
216  constexpr bool operator < (const Array& other) const noexcept {
217  for(std::size_t i = 0; i < nItems; ++i) {
218  if(items_[i] < other.items_[i]) {
219  return true;
220  }
221 
222  if(items_[i] > other.items_[i]) {
223  return false;
224  }
225  }
226 
227  return false;
228  }
229 
231  constexpr bool operator > (const Array& other) const noexcept {
232  return (other < *this);
233  }
234 
238  class iterator {
239  public:
240  using iterator_category = std::random_access_iterator_tag;
241  using value_type = T;
242  using difference_type = int;
243  using pointer = const T*;
244  using reference = T&;
245 
246  constexpr iterator(
247  Array& instance,
248  std::size_t initPosition
249  ) noexcept
250  : baseRef_(instance),
251  position_(initPosition)
252  {}
253 
254  constexpr iterator() = delete;
255  constexpr iterator(const iterator& other) noexcept
256  : baseRef_(other.baseRef_),
257  position_(other.position_)
258  {}
259  constexpr iterator(iterator&& other) noexcept = default;
260  constexpr iterator& operator = (const iterator& other) noexcept {
261  baseRef_ = other.baseRef_;
262  position_ = other.position_;
263 
264  return *this;
265  }
266  constexpr iterator& operator = (iterator&& other) noexcept = default;
267  ~iterator() = default;
268 
269  constexpr iterator& operator ++ () noexcept {
270  position_ += 1;
271  return *this;
272  }
273 
274  constexpr iterator operator ++ (int) noexcept {
275  iterator retval = *this;
276  ++(*this);
277  return retval;
278  }
279 
280  constexpr iterator& operator --() noexcept {
281  position_ -= 1;
282  return *this;
283  }
284 
285  constexpr iterator operator -- (int) noexcept {
286  iterator retval = *this;
287  --(*this);
288  return retval;
289  }
290 
291  constexpr iterator operator + (const int increment) noexcept {
292  iterator retval = *this;
293  retval += increment;
294  return retval;
295  }
296 
297  constexpr iterator operator - (const int increment) noexcept {
298  iterator retval = *this;
299  retval -= increment;
300  return retval;
301  }
302 
303  constexpr iterator& operator += (const int increment) noexcept {
304  position_ += increment;
305  return *this;
306  }
307 
308  constexpr iterator& operator -= (const int increment) noexcept {
309  position_ -= increment;
310  return *this;
311  }
312 
313  PURITY_WEAK constexpr int operator - (const iterator& other) const noexcept {
314  return (
315  static_cast<int>(position_)
316  - static_cast<int>(other.position_)
317  );
318  }
319 
320  PURITY_WEAK constexpr bool operator == (const iterator& other) const noexcept {
321  return (
322  &baseRef_ == &other.baseRef_
323  && position_ == other.position_
324  );
325  }
326 
327  PURITY_WEAK constexpr bool operator != (const iterator& other) const noexcept {
328  return !(
329  *this == other
330  );
331  }
332 
333  PURITY_WEAK constexpr reference operator * () const noexcept {
334  return baseRef_[position_];
335  }
336 
337  private:
338  Array& baseRef_;
339  std::size_t position_;
340  };
341 
342  PURITY_WEAK constexpr iterator begin() noexcept {
343  return iterator(*this, 0);
344  }
345 
346  PURITY_WEAK constexpr iterator end() noexcept {
347  return iterator(*this, nItems);
348  }
349 
354  public:
355  using iterator_category = std::random_access_iterator_tag;
356  using value_type = T;
357  using difference_type = int;
358  using pointer = const T*;
359  using reference = const T&;
360 
361  constexpr explicit const_iterator(
362  const Array& instance,
363  std::size_t initPosition
364  ) noexcept
365  : baseRef_(instance),
366  position_(initPosition)
367  {}
368 
369  constexpr const_iterator() = delete;
370  constexpr const_iterator(const const_iterator& other) noexcept
371  : baseRef_(other.baseRef_),
372  position_(other.position_)
373  {}
374  constexpr const_iterator(const_iterator&& other) noexcept = default;
375  constexpr const_iterator& operator = (const const_iterator& other) {
376  if(baseRef_ != other.baseRef_) {
377  throw "Trying to assign constIterator to other base Array!";
378  }
379 
380  position_ = other.position_;
381 
382  return *this;
383  }
384  constexpr const_iterator& operator = (const_iterator&& other) noexcept = default;
385  ~const_iterator() = default;
386 
387  constexpr const_iterator& operator ++ () noexcept {
388  position_ += 1;
389  return *this;
390  }
391 
392  constexpr const_iterator operator ++ (int) noexcept {
393  const_iterator retval = *this;
394  ++(*this);
395  return retval;
396  }
397 
398  constexpr const_iterator& operator --() noexcept {
399  position_ -= 1;
400  return *this;
401  }
402 
403  constexpr const_iterator operator -- (int) noexcept {
404  const_iterator retval = *this;
405  --(*this);
406  return retval;
407  }
408 
409  constexpr const_iterator operator + (const int increment) noexcept {
410  const_iterator retval = *this;
411  retval += increment;
412  return retval;
413  }
414 
415  constexpr const_iterator operator - (const int increment) noexcept {
416  const_iterator retval = *this;
417  retval -= increment;
418  return retval;
419  }
420 
421  constexpr const_iterator& operator += (const int increment) noexcept {
422  position_ += increment;
423  return *this;
424  }
425 
426  constexpr const_iterator& operator -= (const int increment) noexcept {
427  position_ -= increment;
428  return *this;
429  }
430 
431  constexpr int operator - (const const_iterator& other) const noexcept {
432  return (
433  static_cast<int>(position_)
434  - static_cast<int>(other.position_)
435  );
436  }
437 
438  constexpr bool operator == (const const_iterator& other) const noexcept {
439  return (
440  &baseRef_ == &other.baseRef_
441  && position_ == other.position_
442  );
443  }
444 
445  constexpr bool operator != (const const_iterator& other) const noexcept {
446  return !(
447  *this == other
448  );
449  }
450 
451  constexpr reference operator * () const noexcept {
452  return baseRef_[position_];
453  }
454 
455  private:
456  const Array& baseRef_;
457  std::size_t position_;
458  };
459 
460  constexpr const_iterator begin() const noexcept {
461  return const_iterator(*this, 0);
462  }
463 
464  constexpr const_iterator end() const noexcept {
465  return const_iterator(*this, nItems);
466  }
467 
469  constexpr operator std::array<T, nItems> () const {
470  return makeArray_(std::make_index_sequence<nItems>{});
471  }
472 
474  constexpr std::array<T, nItems> getArray() const {
475  return makeArray_(std::make_index_sequence<nItems>{});
476  }
477 
478 private:
479  T items_[nItems];
480 
481  template<size_t ... Inds>
482  std::array<T, nItems> makeArray_(std::index_sequence<Inds...> /* inds */) {
483  return {{
484  items_[Inds]...
485  }};
486  }
487 };
488 
489 template<typename T, typename... Tail>
490 constexpr auto makeArray(T head, Tail... tail) -> Array<T, 1 + sizeof...(Tail)> {
491  // This way, makeArray must be called with at least one argument
492  return { head, tail ... };
493 }
494 
495 } // namespace Temple
496 } // namespace Molassembler
497 } // namespace Scine
498 
499 #endif
auto at(Container &&container)
Make functor calling at on arguments.
Definition: Functor.h:58
#define PURITY_WEAK
Definition: Preprocessor.h:36
constexpr Array(const std::array< T, nItems > &other, std::index_sequence< Inds...>)
Delegate std::array ctor, using same trick as copy ctor.
Definition: Array.h:115
constexpr Array(const std::array< T, nItems > &other)
Construct from std::array using same trick as copy ctor.
Definition: Array.h:124
constexpr Array(const Array &other)
Copy constructor.
Definition: Array.h:56
unsigned size(const Shape shape)
Fetch the number of vertices of a shape.
Nonmodifiable data iterator.
Definition: Array.h:353
constexpr Array(const Array &other, std::index_sequence< Inds...>)
Helper copy constructor.
Definition: Array.h:43
Functional-style constexpr container algorithms.
constexpr std::array< T, nItems > getArray() const
Explicit conversion to a std::array.
Definition: Array.h:474