| // This file is part of Eigen, a lightweight C++ template library | |
| // for linear algebra. | |
| // | |
| // Copyright (C) 2013 Christian Seiler <christian@iwakd.de> | |
| // Copyright (C) 2014-2015 Benoit Steiner <benoit.steiner.goog@gmail.com> | |
| // | |
| // This Source Code Form is subject to the terms of the Mozilla | |
| // Public License v. 2.0. If a copy of the MPL was not distributed | |
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| // SPDX-License-Identifier: MPL-2.0 | |
| #ifndef EIGEN_TENSOR_TENSORSTORAGE_H | |
| #define EIGEN_TENSOR_TENSORSTORAGE_H | |
| #ifdef EIGEN_TENSOR_STORAGE_CTOR_PLUGIN | |
| #define EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN EIGEN_TENSOR_STORAGE_CTOR_PLUGIN; | |
| #else | |
| #define EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN | |
| #endif | |
| // IWYU pragma: private | |
| #include "./InternalHeaderCheck.h" | |
| namespace Eigen { | |
| /** \internal | |
| * | |
| * \ingroup Tensor_Module | |
| * | |
| * \brief Stores the data of a tensor | |
| * | |
| * This class stores the data of fixed-size, dynamic-size or mixed tensors | |
| * in a way as compact as possible. | |
| * | |
| * \sa Tensor | |
| */ | |
| template <typename T, typename Dimensions, int Options> | |
| class TensorStorage; | |
| // Pure fixed-size storage | |
| template <typename T, typename FixedDimensions, int Options_> | |
| class TensorStorage { | |
| private: | |
| static constexpr std::size_t Size = FixedDimensions::total_size; | |
| // Allocate an array of size at least one to prevent compiler warnings. | |
| static constexpr std::size_t MinSize = max_n_1<Size>::size; | |
| EIGEN_ALIGN_MAX T m_data[MinSize]; | |
| public: | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorStorage() {} | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T* data() { return m_data; } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T* data() const { return m_data; } | |
| constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const FixedDimensions dimensions() const { return FixedDimensions(); } | |
| constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex size() const { return Size; } | |
| }; | |
| // pure dynamic | |
| template <typename T, typename IndexType, int NumIndices_, int Options_> | |
| class TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_> { | |
| public: | |
| typedef IndexType Index; | |
| typedef DSizes<IndexType, NumIndices_> Dimensions; | |
| typedef TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_> Self; | |
| EIGEN_DEVICE_FUNC TensorStorage() : m_data(0), m_dimensions() { | |
| EIGEN_IF_CONSTEXPR (NumIndices_ == 0) { | |
| m_data = internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(1); | |
| } | |
| } | |
| EIGEN_DEVICE_FUNC TensorStorage(Index size, const array<Index, NumIndices_>& dimensions) | |
| : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size)), m_dimensions(dimensions) { | |
| EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN | |
| } | |
| template <typename... DenseIndex> | |
| EIGEN_DEVICE_FUNC TensorStorage(DenseIndex... indices) : m_dimensions(indices...) { | |
| m_data = internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(internal::array_prod(m_dimensions)); | |
| } | |
| EIGEN_DEVICE_FUNC TensorStorage(const Self& other) | |
| : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>( | |
| internal::array_prod(other.m_dimensions))), | |
| m_dimensions(other.m_dimensions) { | |
| internal::smart_copy(other.m_data, other.m_data + internal::array_prod(other.m_dimensions), m_data); | |
| } | |
| EIGEN_DEVICE_FUNC Self& operator=(const Self& other) { | |
| if (this != &other) { | |
| Self tmp(other); | |
| this->swap(tmp); | |
| } | |
| return *this; | |
| } | |
| EIGEN_DEVICE_FUNC TensorStorage(Self&& other) : TensorStorage() { *this = std::move(other); } | |
| EIGEN_DEVICE_FUNC Self& operator=(Self&& other) { | |
| numext::swap(m_data, other.m_data); | |
| numext::swap(m_dimensions, other.m_dimensions); | |
| return *this; | |
| } | |
| EIGEN_DEVICE_FUNC ~TensorStorage() { | |
| internal::conditional_aligned_delete_auto<T, (Options_ & DontAlign) == 0>(m_data, | |
| internal::array_prod(m_dimensions)); | |
| } | |
| EIGEN_DEVICE_FUNC void swap(Self& other) { | |
| numext::swap(m_data, other.m_data); | |
| numext::swap(m_dimensions, other.m_dimensions); | |
| } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; } | |
| EIGEN_DEVICE_FUNC void resize(Index size, const array<Index, NumIndices_>& nbDimensions) { | |
| const Index currentSz = internal::array_prod(m_dimensions); | |
| if (size != currentSz) { | |
| internal::conditional_aligned_delete_auto<T, (Options_ & DontAlign) == 0>(m_data, currentSz); | |
| if (size) | |
| m_data = internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size); | |
| else EIGEN_IF_CONSTEXPR (NumIndices_ == 0) { | |
| m_data = internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(1); | |
| } else | |
| m_data = 0; | |
| EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) | |
| } | |
| m_dimensions = nbDimensions; | |
| } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T* data() { return m_data; } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T* data() const { return m_data; } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const { return m_dimensions.TotalSize(); } | |
| private: | |
| T* m_data; | |
| Dimensions m_dimensions; | |
| }; | |
| } // end namespace Eigen | |
| #endif // EIGEN_TENSOR_TENSORSTORAGE_H |