| 83 | namespace array { |
| 84 | template<typename ShapeType_, typename StorageType_> |
| 85 | class ArrayContainer { |
| 86 | public: |
| 87 | using StorageType = StorageType_; |
| 88 | using ShapeType = ShapeType_; |
| 89 | using StrideType = Stride<ShapeType>; |
| 90 | using SizeType = typename ShapeType::SizeType; |
| 91 | using Scalar = typename StorageType::Scalar; |
| 92 | using Packet = typename typetraits::TypeInfo<Scalar>::Packet; |
| 93 | using Backend = typename typetraits::TypeInfo<ArrayContainer>::Backend; |
| 94 | |
| 95 | using DirectSubscriptType = typename detail::SubscriptType<StorageType>::Direct; |
| 96 | using DirectRefSubscriptType = typename detail::SubscriptType<StorageType>::Ref; |
| 97 | |
| 98 | /// Default constructor |
| 99 | ArrayContainer(); |
| 100 | |
| 101 | template<typename T> |
| 102 | LIBRAPID_ALWAYS_INLINE ArrayContainer(const std::initializer_list<T> &data); |
| 103 | |
| 104 | template<typename T> |
| 105 | explicit LIBRAPID_ALWAYS_INLINE ArrayContainer(const std::vector<T> &data); |
| 106 | |
| 107 | // clang-format off |
| 108 | #define SINIT(SUB_TYPE) std::initializer_list<SUB_TYPE> |
| 109 | #define SVEC(SUB_TYPE) std::vector<SUB_TYPE> |
| 110 | |
| 111 | #define ARRAY_FROM_DATA_DEF(TYPE_INIT, TYPE_VEC) \ |
| 112 | LIBRAPID_NODISCARD static LIBRAPID_ALWAYS_INLINE auto fromData(const TYPE_INIT &data) \ |
| 113 | -> ArrayContainer; \ |
| 114 | LIBRAPID_NODISCARD static LIBRAPID_ALWAYS_INLINE auto fromData(const TYPE_VEC &data) \ |
| 115 | -> ArrayContainer |
| 116 | |
| 117 | ARRAY_FROM_DATA_DEF(SINIT(Scalar), SVEC(Scalar)); |
| 118 | ARRAY_FROM_DATA_DEF(SINIT(SINIT(Scalar)), SVEC(SVEC(Scalar))); |
| 119 | ARRAY_FROM_DATA_DEF(SINIT(SINIT(SINIT(Scalar))), SVEC(SVEC(SVEC(Scalar)))); |
| 120 | ARRAY_FROM_DATA_DEF(SINIT(SINIT(SINIT(SINIT(Scalar)))), SVEC(SVEC(SVEC(SVEC(Scalar))))); |
| 121 | ARRAY_FROM_DATA_DEF(SINIT(SINIT(SINIT(SINIT(SINIT(Scalar))))), SVEC(SVEC(SVEC(SVEC(SVEC(Scalar)))))); |
| 122 | ARRAY_FROM_DATA_DEF(SINIT(SINIT(SINIT(SINIT(SINIT(SINIT(Scalar)))))), SVEC(SVEC(SVEC(SVEC(SVEC(SVEC(Scalar))))))); |
| 123 | ARRAY_FROM_DATA_DEF(SINIT(SINIT(SINIT(SINIT(SINIT(SINIT(SINIT(Scalar))))))), SVEC(SVEC(SVEC(SVEC(SVEC(SVEC(SVEC(Scalar)))))))); |
| 124 | ARRAY_FROM_DATA_DEF(SINIT(SINIT(SINIT(SINIT(SINIT(SINIT(SINIT(SINIT(Scalar)))))))), SVEC(SVEC(SVEC(SVEC(SVEC(SVEC(SVEC(SVEC(Scalar))))))))); |
| 125 | |
| 126 | #undef SINIT |
| 127 | #undef SVEC |
| 128 | |
| 129 | // clang-format on |
| 130 | |
| 131 | /// Constructs an array container from a shape |
| 132 | /// \param shape The shape of the array container |
| 133 | LIBRAPID_ALWAYS_INLINE explicit ArrayContainer(const Shape &shape); |
| 134 | LIBRAPID_ALWAYS_INLINE explicit ArrayContainer(const MatrixShape &shape); |
| 135 | LIBRAPID_ALWAYS_INLINE explicit ArrayContainer(const VectorShape &shape); |
| 136 | |
| 137 | /// Create an array container from a shape and a scalar value. The scalar value |
| 138 | /// represents the value the memory is initialized with. \param shape The shape of the |
| 139 | /// array container \param value The value to initialize the memory with |
| 140 | LIBRAPID_ALWAYS_INLINE ArrayContainer(const Shape &shape, const Scalar &value); |
| 141 | LIBRAPID_ALWAYS_INLINE ArrayContainer(const MatrixShape &shape, const Scalar &value); |
| 142 | LIBRAPID_ALWAYS_INLINE ArrayContainer(const VectorShape &shape, const Scalar &value); |