12 #ifndef INCLUDE_MOLASSEMBLER_TEMPLE_ARRAY_H
13 #define INCLUDE_MOLASSEMBLER_TEMPLE_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]...} {}
57 : Array(other, std::make_index_sequence<nItems>{}) {}
66 template<std::size_t ... Inds>
69 std::index_sequence<Inds...>
70 ) :items_ {std::move(other[Inds])...} {}
81 :
Array(std::move(other), std::make_index_sequence<nItems>{}) {}
87 constexpr
Array& operator = (
const Array& other) {
88 for(std::size_t i = 0; i < nItems; ++i) {
89 items_[i] = other.items_[i];
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]);
114 template<
size_t ... Inds>
116 const std::array<T, nItems>& other,
117 std::index_sequence<Inds...>
118 ) :items_ {other[Inds]...} {}
124 constexpr
Array(
const std::array<T, nItems>& other)
125 : Array(other, std::make_index_sequence<nItems>{})
132 template<
typename ...Args>
133 constexpr
Array(Args... args)
134 : items_ {
static_cast<T
>(args)...}
147 constexpr T& operator[] (
const std::size_t index) noexcept {
148 return items_[index];
152 constexpr T&
at(
const std::size_t index) noexcept {
153 return items_[index];
157 constexpr
const T& operator[] (
const std::size_t index)
const noexcept {
158 return items_[index];
162 constexpr
const T&
at(
const std::size_t index)
const noexcept {
163 return items_[index];
170 constexpr
const T& front() const noexcept {
178 constexpr
const T& back() const noexcept {
179 return items_[nItems - 1];
183 constexpr
size_t size() const noexcept {
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]) {
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]) {
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]) {
222 if(items_[i] > other.items_[i]) {
231 constexpr
bool operator > (
const Array& other)
const noexcept {
232 return (other < *
this);
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&;
248 std::size_t initPosition
250 : baseRef_(instance),
251 position_(initPosition)
254 constexpr iterator() =
delete;
255 constexpr iterator(
const iterator& other) noexcept
256 : baseRef_(other.baseRef_),
257 position_(other.position_)
259 constexpr iterator(iterator&& other) noexcept = default;
260 constexpr iterator& operator = (const iterator& other) noexcept {
261 baseRef_ = other.baseRef_;
262 position_ = other.position_;
266 constexpr iterator& operator = (iterator&& other) noexcept = default;
267 ~iterator() = default;
269 constexpr iterator& operator ++ () noexcept {
274 constexpr iterator operator ++ (
int) noexcept {
275 iterator retval = *
this;
280 constexpr iterator& operator --() noexcept {
285 constexpr iterator operator -- (
int) noexcept {
286 iterator retval = *
this;
291 constexpr iterator operator + (
const int increment) noexcept {
292 iterator retval = *
this;
297 constexpr iterator operator - (
const int increment) noexcept {
298 iterator retval = *
this;
303 constexpr iterator& operator += (
const int increment) noexcept {
304 position_ += increment;
308 constexpr iterator& operator -= (
const int increment) noexcept {
309 position_ -= increment;
313 PURITY_WEAK constexpr
int operator - (
const iterator& other)
const noexcept {
315 static_cast<int>(position_)
316 - static_cast<int>(other.position_)
320 PURITY_WEAK constexpr
bool operator == (
const iterator& other)
const noexcept {
322 &baseRef_ == &other.baseRef_
323 && position_ == other.position_
327 PURITY_WEAK constexpr
bool operator != (
const iterator& other)
const noexcept {
333 PURITY_WEAK constexpr reference operator * () const noexcept {
334 return baseRef_[position_];
337 PURITY_WEAK constexpr
bool operator < (
const iterator& other)
const noexcept {
338 return position_ < other.position_;
341 PURITY_WEAK constexpr
bool operator <= (
const iterator& other)
const noexcept {
342 return position_ <= other.position_;
345 PURITY_WEAK constexpr
bool operator > (
const iterator& other)
const noexcept {
346 return position_ > other.position_;
349 PURITY_WEAK constexpr
bool operator >= (
const iterator& other)
const noexcept {
350 return position_ >= other.position_;
355 std::size_t position_;
359 return iterator(*
this, 0);
363 return iterator(*
this, nItems);
371 using iterator_category = std::random_access_iterator_tag;
372 using value_type = T;
373 using difference_type = int;
374 using pointer =
const T*;
375 using reference =
const T&;
378 const Array& instance,
379 std::size_t initPosition
381 : baseRef_(instance),
382 position_(initPosition)
387 : baseRef_(other.baseRef_),
388 position_(other.position_)
392 if(baseRef_ != other.baseRef_) {
393 throw "Trying to assign constIterator to other base Array!";
396 position_ = other.position_;
425 constexpr
const_iterator operator + (
const int increment) noexcept {
431 constexpr
const_iterator operator - (
const int increment) noexcept {
437 constexpr
const_iterator& operator += (
const int increment) noexcept {
438 position_ += increment;
442 constexpr
const_iterator& operator -= (
const int increment) noexcept {
443 position_ -= increment;
447 constexpr
int operator - (
const const_iterator& other)
const noexcept {
449 static_cast<int>(position_)
450 - static_cast<int>(other.position_)
454 constexpr
bool operator == (
const const_iterator& other)
const noexcept {
456 &baseRef_ == &other.baseRef_
457 && position_ == other.position_
461 constexpr
bool operator != (
const const_iterator& other)
const noexcept {
467 constexpr reference operator * ()
const noexcept {
468 return baseRef_[position_];
472 const Array& baseRef_;
473 std::size_t position_;
480 constexpr const_iterator end() const noexcept {
481 return const_iterator(*
this, nItems);
485 constexpr
operator std::array<T, nItems> ()
const {
486 return makeArray_(std::make_index_sequence<nItems>{});
491 return makeArray_(std::make_index_sequence<nItems>{});
497 template<
size_t ... Inds>
498 constexpr std::array<T, nItems> makeArray_(std::index_sequence<Inds...> )
const {
499 return {{items_[Inds]...}};
503 template<
typename T,
typename... Tail>
504 constexpr
auto makeArray(T head, Tail... tail) -> Array<T, 1 +
sizeof...(Tail)> {
506 return { head, tail ... };
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
unsigned size(Shape shape)
Fetch the number of vertices of a shape.
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
Nonmodifiable data iterator.
Definition: Array.h:369
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:490