1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
// SPDX-License-Identifier: LGPL-3.0-or-later
// Author: Kristian Lytje
#pragma once
#include <array>
#include <vector>
#if SAFE_MATH
#include <utility/Exceptions.h>
#endif
namespace ausaxs::container {
template <typename T, int N, int M, int L>
class ArrayContainer3D {
public:
constexpr ArrayContainer3D() noexcept = default;
/**
* @brief Get the value at index i, j, k.
*/
T& operator()(int i, int j, int k) {return data[k + L*(j + M*i)];}
/**
* @brief Get the value at index i, j, k.
*/
const T& operator()(int i, int j, int k) const {return data[k + L*(j + M*i)];}
/**
* @brief Get the value at index i, j, k.
*/
T& index(int i, int j, int k) {return operator()(i, j, k);}
/**
* @brief Get the value at index i, j, k.
*/
const T& index(int i, int j, int k) const {return operator()(i, j, k);}
/**
* @brief Get an iterator to the beginning of the vector at index i, j.
*/
const typename std::vector<T>::const_iterator begin(int i, int j) const {
#if SAFE_MATH
if (i >= static_cast<int>(N) || j >= static_cast<int>(M)) {
throw except::out_of_bounds(
"ArrayContainer3D::begin: Index out of bounds "
"(" + std::to_string(N) + ", " + std::to_string(M) + ") <= "
"(" + std::to_string(i) + ", " + std::to_string(j) + ")"
);
}
#endif
return data.begin() + L*(j + M*i);
}
/**
* @brief Get an iterator to the end of the vector at index i, j.
*/
const typename std::vector<T>::const_iterator end(int i, int j) const {
#if SAFE_MATH
if (i >= static_cast<int>(N) || j >= static_cast<int>(M)) {
throw except::out_of_bounds(
"ArrayContainer3D::end: Index out of bounds "
"(" + std::to_string(N) + ", " + std::to_string(M) + ") <= "
"(" + std::to_string(i) + ", " + std::to_string(j) + ")"
);
}
#endif
return data.begin() + L*(j + M*i) + L;
}
/**
* @brief Get an iterator to the beginning of the vector at index i, j.
*/
typename std::vector<T>::iterator begin(int i, int j) {
#if SAFE_MATH
if (i >= static_cast<int>(N) || j >= static_cast<int>(M)) {
throw except::out_of_bounds(
"ArrayContainer3D::begin: Index out of bounds "
"(" + std::to_string(N) + ", " + std::to_string(M) + ") <= "
"(" + std::to_string(i) + ", " + std::to_string(j) + ")"
);
}
#endif
return data.begin() + L*(j + M*i);
}
/**
* @brief Get an iterator to the end of the vector at index i, j.
*/
typename std::vector<T>::iterator end(int i, int j) {
#if SAFE_MATH
if (i >= static_cast<int>(N) || j >= static_cast<int>(M)) {
throw except::out_of_bounds(
"ArrayContainer3D::end: Index out of bounds "
"(" + std::to_string(N) + ", " + std::to_string(M) + ") <= "
"(" + std::to_string(i) + ", " + std::to_string(j) + ")"
);
}
#endif
return data.begin() + L*(j + M*i) + L;
}
/**
* @brief Get an iterator to the beginning of the entire container.
*/
const typename std::vector<T>::const_iterator begin() const {return data.begin();}
/**
* @brief Get an iterator to the end of the entire container.
*/
const typename std::vector<T>::const_iterator end() const {return data.end();}
/**
* @brief Get an iterator to the beginning of the entire container.
*/
typename std::vector<T>::iterator begin() {return data.begin();}
/**
* @brief Get an iterator to the end of the entire container.
*/
typename std::vector<T>::iterator end() {return data.end();}
protected:
std::array<T, N*M*L> data;
};
}
|