1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2013 Christian Seiler <christian@iwakd.de> 5 // Copyright (C) 2014-2015 Benoit Steiner <benoit.steiner.goog@gmail.com> 6 // 7 // This Source Code Form is subject to the terms of the Mozilla 8 // Public License v. 2.0. If a copy of the MPL was not distributed 9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 10 11 #ifndef EIGEN_CXX11_TENSOR_TENSORSTORAGE_H 12 #define EIGEN_CXX11_TENSOR_TENSORSTORAGE_H 13 14 #ifdef EIGEN_TENSOR_STORAGE_CTOR_PLUGIN 15 #define EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN EIGEN_TENSOR_STORAGE_CTOR_PLUGIN; 16 #else 17 #define EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN 18 #endif 19 20 namespace Eigen { 21 22 /** \internal 23 * 24 * \class TensorStorage 25 * \ingroup CXX11_Tensor_Module 26 * 27 * \brief Stores the data of a tensor 28 * 29 * This class stores the data of fixed-size, dynamic-size or mixed tensors 30 * in a way as compact as possible. 31 * 32 * \sa Tensor 33 */ 34 template<typename T, typename Dimensions, int Options_> class TensorStorage; 35 36 37 // Pure fixed-size storage 38 template<typename T, int Options_, typename FixedDimensions> 39 class TensorStorage<T, FixedDimensions, Options_> 40 { 41 private: 42 static const std::size_t Size = FixedDimensions::total_size; 43 44 // Allocate an array of size at least one to prevent compiler warnings. 45 static const std::size_t MinSize = max_n_1<Size>::size; 46 EIGEN_ALIGN_MAX T m_data[MinSize]; 47 48 FixedDimensions m_dimensions; 49 50 public: 51 EIGEN_DEVICE_FUNC TensorStorage()52 EIGEN_STRONG_INLINE TensorStorage() { 53 } 54 55 EIGEN_DEVICE_FUNC data()56 EIGEN_STRONG_INLINE T *data() { return m_data; } 57 EIGEN_DEVICE_FUNC data()58 EIGEN_STRONG_INLINE const T *data() const { return m_data; } 59 60 EIGEN_DEVICE_FUNC dimensions()61 EIGEN_STRONG_INLINE const FixedDimensions& dimensions() const { return m_dimensions; } 62 63 EIGEN_DEVICE_FUNC size()64 EIGEN_STRONG_INLINE DenseIndex size() const { return m_dimensions.TotalSize(); } 65 }; 66 67 68 // pure dynamic 69 template<typename T, int Options_, typename IndexType, int NumIndices_> 70 class TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_> 71 { 72 public: 73 typedef IndexType Index; 74 typedef DSizes<IndexType, NumIndices_> Dimensions; 75 typedef TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_> Self; 76 TensorStorage()77 EIGEN_DEVICE_FUNC TensorStorage() : m_data(0), m_dimensions() { 78 if (NumIndices_ == 0) { 79 m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(1); 80 } 81 } TensorStorage(internal::constructor_without_unaligned_array_assert)82 EIGEN_DEVICE_FUNC TensorStorage(internal::constructor_without_unaligned_array_assert) 83 : m_data(0), m_dimensions(internal::template repeat<NumIndices_, Index>(0)) {} TensorStorage(Index size,const array<Index,NumIndices_> & dimensions)84 EIGEN_DEVICE_FUNC TensorStorage(Index size, const array<Index, NumIndices_>& dimensions) 85 : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size)), m_dimensions(dimensions) 86 { EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN } 87 88 #if EIGEN_HAS_VARIADIC_TEMPLATES 89 template <typename... DenseIndex> TensorStorage(DenseIndex...indices)90 EIGEN_DEVICE_FUNC TensorStorage(DenseIndex... indices) : m_dimensions(indices...) { 91 m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(internal::array_prod(m_dimensions)); 92 } 93 #endif 94 TensorStorage(const Self & other)95 EIGEN_DEVICE_FUNC TensorStorage(const Self& other) 96 : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(internal::array_prod(other.m_dimensions))) 97 , m_dimensions(other.m_dimensions) 98 { 99 internal::smart_copy(other.m_data, other.m_data+internal::array_prod(other.m_dimensions), m_data); 100 } 101 EIGEN_DEVICE_FUNC Self& operator=(const Self& other) 102 { 103 if (this != &other) { 104 Self tmp(other); 105 this->swap(tmp); 106 } 107 return *this; 108 } 109 ~TensorStorage()110 EIGEN_DEVICE_FUNC ~TensorStorage() { internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, internal::array_prod(m_dimensions)); } swap(Self & other)111 EIGEN_DEVICE_FUNC void swap(Self& other) 112 { numext::swap(m_data,other.m_data); numext::swap(m_dimensions,other.m_dimensions); } 113 dimensions()114 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const {return m_dimensions;} 115 resize(Index size,const array<Index,NumIndices_> & nbDimensions)116 EIGEN_DEVICE_FUNC void resize(Index size, const array<Index, NumIndices_>& nbDimensions) 117 { 118 const Index currentSz = internal::array_prod(m_dimensions); 119 if(size != currentSz) 120 { 121 internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, currentSz); 122 if (size) 123 m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size); 124 else if (NumIndices_ == 0) { 125 m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(1); 126 } 127 else 128 m_data = 0; 129 EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) 130 } 131 m_dimensions = nbDimensions; 132 } 133 data()134 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T *data() { return m_data; } data()135 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T *data() const { return m_data; } 136 size()137 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const { return m_dimensions.TotalSize(); } 138 139 private: 140 T *m_data; 141 Dimensions m_dimensions; 142 }; 143 144 } // end namespace Eigen 145 146 #endif // EIGEN_CXX11_TENSOR_TENSORSTORAGE_H 147