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