12 #ifndef INCLUDE_MOLASSEMBLER_TEMPLE_DYNAMIC_ARRAY_H
13 #define INCLUDE_MOLASSEMBLER_TEMPLE_DYNAMIC_ARRAY_H
18 #include <type_traits>
22 namespace Molassembler {
25 template<
typename T, std::
size_t nItems>
42 template<std::size_t ... Inds>
45 std::index_sequence<Inds...>
46 ) :items_ {other[Inds]...},
59 : DynamicArray(other, std::make_index_sequence<nItems>{}) {}
66 template<std::size_t ... Inds>
69 std::index_sequence<Inds...>
70 ) :items_ {std::move(other[Inds])...},
82 :
DynamicArray(std::move(other), std::make_index_sequence<nItems>{}) {}
89 for(
unsigned i = 0; i < other.count_; ++i) {
90 items_[i] = other.items_[i];
92 count_ = other.count_;
105 for(
unsigned i = 0; i < other.count_; ++i) {
106 items_[i] = std::move(other.items_[i]);
108 count_ = other.count_;
120 template<
typename, std::
size_t>
class ArrayType,
124 const ArrayType<T, N>& other,
125 std::index_sequence<Inds...>
126 ) : items_ {other.at(Inds)...},
132 template<
typename, std::
size_t>
class ArrayType,
135 const ArrayType<T, N>& other,
136 std::enable_if_t<(N <= nItems)>* = 0
137 ) : DynamicArray(other, std::make_index_sequence<N>{})
141 template<
typename ...Args>
143 : items_ {
static_cast<T
>(args)...},
144 count_(
sizeof...(args))
157 constexpr
void push_back(
const T& item) {
158 if(count_ < nItems) {
159 items_[count_] = item;
162 throw "Dynamic array is already full!";
167 constexpr
void push_back(T&& item) {
168 if(count_ < nItems) {
169 items_[count_] = std::move(item);
178 constexpr
void pop_back() {
188 constexpr
void pop_back(
const unsigned numberToPop) {
189 if(count_ > numberToPop) {
190 count_ -= numberToPop;
201 constexpr DynamicArray<T, nItems> splice(
const unsigned fromIndex) {
202 DynamicArray<T, nItems> spliced;
204 for(
unsigned i = fromIndex; i < count_; ++i) {
205 spliced.push_back(std::move(items_[i]));
208 pop_back(count_ - fromIndex);
220 PURITY_WEAK constexpr
bool validIndex(
const unsigned index)
const noexcept {
221 return (index < count_);
242 PURITY_WEAK constexpr T& operator[] (
const unsigned index) noexcept {
244 if(!validIndex(index)) {
248 return items_[index];
252 PURITY_WEAK constexpr
const T& operator[] (
const unsigned index)
const noexcept {
253 if(!validIndex(index)) {
257 return items_[index];
263 return this->operator[](index);
267 PURITY_WEAK constexpr
const T&
at(
const unsigned index)
const noexcept {
269 return this->operator[](index);
284 PURITY_WEAK constexpr
const T& front() const noexcept {
293 constexpr T& back() noexcept {
301 return items_[count_ - 1];
309 PURITY_WEAK constexpr
const T& back() const noexcept {
317 return items_[count_ - 1];
327 constexpr
void clear() {
335 constexpr
void copyIn(
const DynamicArray<T, nItems>& other) {
336 if(other.size() +
size() > nItems) {
337 throw "DynamicArray to be copied in has too many elements to fit!";
340 for(
auto it = other.begin(); it != other.end(); ++it) {
350 constexpr
void insertAt(
351 iterator insertPositionIter,
355 if(insertPositionIter == end()) {
358 moveElementsRightUntil_(insertPositionIter);
361 *insertPositionIter = item;
370 constexpr
void insertAt(
371 iterator insertPositionIter,
375 if(insertPositionIter == end()) {
378 moveElementsRightUntil_(insertPositionIter);
381 *insertPositionIter = std::move(item);
390 constexpr
void removeAt(iterator insertPositionIter) {
391 if(insertPositionIter == end()) {
392 throw "Cannot remove item at end iterator!";
396 auto& leftIter = insertPositionIter;
397 auto rightIter = insertPositionIter + 1;
399 while(rightIter != end()) {
400 *leftIter = std::move(*rightIter);
416 PURITY_WEAK constexpr
bool operator == (
const DynamicArray& other)
const noexcept {
417 if(count_ != other.count_) {
421 for(
unsigned i = 0; i < count_; ++i) {
422 if(items_[i] != other.items_[i]) {
431 PURITY_WEAK constexpr
bool operator != (
const DynamicArray& other)
const noexcept {
432 return !(*
this == other);
439 PURITY_WEAK constexpr
bool operator < (
const DynamicArray& other)
const noexcept {
440 if(count_ < other.count_) {
444 for(
unsigned i = 0; i < count_; ++i) {
445 if(items_[i] < other.items_[i]) {
449 if(items_[i] > other.items_[i]) {
458 PURITY_WEAK constexpr
bool operator > (
const DynamicArray& other)
const noexcept {
459 return (other < *
this);
470 using iterator_category = std::random_access_iterator_tag;
471 using value_type = T;
472 using difference_type = std::ptrdiff_t;
473 using pointer =
const T*;
474 using reference = T&;
476 constexpr
explicit iterator(
477 DynamicArray& instance,
478 unsigned&& initPosition
479 ) : baseRef_(instance),
480 position_(initPosition)
483 constexpr iterator(
const iterator& other)
484 : baseRef_(other.baseRef_),
485 position_(other.position_)
488 constexpr iterator& operator = (
const iterator& other) {
489 baseRef_ = other.baseRef_;
490 position_ = other.position_;
495 constexpr iterator& operator ++ () {
500 constexpr iterator operator ++ (
int) {
501 iterator retval = *
this;
506 constexpr iterator& operator --() {
511 constexpr iterator operator -- (
int) {
512 iterator retval = *
this;
517 constexpr iterator operator + (
const int& increment) {
518 iterator retval = *
this;
523 constexpr iterator operator - (
const int& increment) {
524 iterator retval = *
this;
529 constexpr iterator& operator += (
const int& increment) {
530 position_ += increment;
534 constexpr iterator& operator -= (
const int& increment) {
535 position_ -= increment;
539 PURITY_WEAK constexpr std::ptrdiff_t operator - (
const iterator& other)
const noexcept {
541 static_cast<std::ptrdiff_t>(position_)
542 - static_cast<std::ptrdiff_t>(other.position_)
546 PURITY_WEAK constexpr
bool operator == (
const iterator& other)
const noexcept {
548 &baseRef_ == &other.baseRef_
549 && position_ == other.position_
553 PURITY_WEAK constexpr
bool operator != (
const iterator& other)
const noexcept {
559 PURITY_WEAK constexpr reference operator * () const noexcept {
560 return baseRef_[position_];
564 DynamicArray& baseRef_;
569 return iterator(*
this, 0);
573 return iterator(*
this, count_);
581 const DynamicArray& baseRef_;
585 using iterator_category = std::random_access_iterator_tag;
586 using value_type = T;
587 using difference_type = std::ptrdiff_t;
588 using pointer =
const T*;
589 using reference =
const T&;
592 const DynamicArray& instance,
593 unsigned&& initPosition
594 ) : baseRef_(instance),
595 position_(initPosition)
598 constexpr const_iterator(
const const_iterator& other)
599 : baseRef_(other.baseRef_),
600 position_(other.position_)
603 constexpr const_iterator& operator = (
const const_iterator& other) {
604 if(baseRef_ != other.baseRef_) {
605 throw "Trying to assign const_iterator to other base DynamicArray!";
608 position_ = other.position_;
613 constexpr const_iterator& operator ++ () {
618 constexpr const_iterator operator ++ (
int) {
619 const_iterator retval = *
this;
624 constexpr const_iterator& operator --() {
629 constexpr const_iterator operator -- (
int) {
630 const_iterator retval = *
this;
635 constexpr const_iterator operator + (
const int& increment) {
636 const_iterator retval = *
this;
641 constexpr const_iterator operator - (
const int& increment) {
642 const_iterator retval = *
this;
647 constexpr const_iterator& operator += (
const int& increment) {
648 position_ += increment;
652 constexpr const_iterator& operator -= (
const int& increment) {
653 position_ -= increment;
657 PURITY_WEAK constexpr std::ptrdiff_t operator - (
const const_iterator& other)
const noexcept {
659 static_cast<std::ptrdiff_t>(position_)
660 - static_cast<std::ptrdiff_t>(other.position_)
664 PURITY_WEAK constexpr
bool operator == (
const const_iterator& other)
const noexcept {
666 &baseRef_ == &other.baseRef_
667 && position_ == other.position_
671 PURITY_WEAK constexpr
bool operator != (
const const_iterator& other)
const noexcept {
677 PURITY_WEAK constexpr reference operator * ()
const noexcept {
678 return baseRef_[position_];
686 PURITY_WEAK constexpr const_iterator end() const noexcept {
687 return const_iterator(*
this, count_);
694 PURITY_WEAK constexpr
operator std::array<T, nItems> ()
const noexcept {
695 return makeArray(std::make_index_sequence<nItems>{});
703 std::size_t count_ = 0;
708 template<std::size_t ... Inds>
709 std::array<T, nItems> makeArray(std::index_sequence<Inds...> ) {
715 constexpr
void moveElementsRightUntil_(
const iterator& position) {
722 auto rightIter = end();
724 auto leftIter = rightIter - 1;
726 while(rightIter != position) {
727 *rightIter = std::move(*leftIter);
740 template<
typename, std::
size_t>
class ArrayType,
744 > constexpr DynamicArray<
748 const ArrayType<T, N>& data,
749 BinaryFunction&& equalityComparator
757 for(
auto iter = data.begin(); iter != data.end(); ++iter) {
758 bool foundEqual =
false;
760 for(
auto& group : groups) {
761 if(equalityComparator(*iter, *group.begin())) {
762 group.push_back(*iter);
770 DynamicArray<T, N> {*iter}
778 template<
typename T, std::
size_t N>
779 DynamicArray<T, N> merge(
780 const DynamicArray<T, N>& a,
781 const DynamicArray<T, N>& b
783 if(a.size() + b.size() > N) {
784 throw "DynamicArrays to be merged have too many elements!";
787 DynamicArray<T, N> merged {a};
constexpr DynamicArray(const DynamicArray &other, std::index_sequence< Inds...>)
Helper to the copy constructor.
Definition: DynamicArray.h:43
auto at(Container &&container)
Make functor calling at on arguments.
Definition: Functor.h:58
#define PURITY_WEAK
Definition: Preprocessor.h:36
Definition: DynamicArray.h:26
unsigned size(Shape shape)
Fetch the number of vertices of a shape.
constexpr DynamicArray< DynamicArray< T, N >, N > groupByEquality(const ArrayType< T, N > &data, BinaryFunction &&equalityComparator)
Definition: DynamicArray.h:747
Defines a set of useful preprocessor macros.
constexpr DynamicArray(DynamicArray &&other) noexcept
Move constructor.
Definition: DynamicArray.h:81
constexpr DynamicArray()
Default constructor.
Definition: DynamicArray.h:35
count_(other.count_)
Default constructor.
Definition: DynamicArray.h:71
Nonmodifiable data iterator.
Definition: DynamicArray.h:579
constexpr DynamicArray(const ArrayType< T, N > &other, std::enable_if_t<(N<=nItems)> *=0)
Construct from any size of other array-like classes.
Definition: DynamicArray.h:134
constexpr DynamicArray(const DynamicArray &other)
Copy constructor.
Definition: DynamicArray.h:58
constexpr DynamicArray(const ArrayType< T, N > &other, std::index_sequence< Inds...>)
Construct from any-size array-like container using same trick as copy ctor.
Definition: DynamicArray.h:123