aboutsummaryrefslogtreecommitdiffhomepage
path: root/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
blob: 33670e36e5bc3fbe74b0de35de52b8381f9b332f (plain)
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
127
128
129
// 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/.

#ifndef EIGEN_CXX11_TENSOR_TENSORSTORAGE_H
#define EIGEN_CXX11_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

namespace Eigen {

/** \internal
  *
  * \class TensorStorage
  * \ingroup CXX11_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, int Options_, typename FixedDimensions>
class TensorStorage<T, FixedDimensions, Options_>
{
 private:
  static const std::size_t Size = FixedDimensions::total_size;

  EIGEN_ALIGN_DEFAULT T m_data[Size];
  FixedDimensions m_dimensions;

 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; }

  EIGEN_DEVICE_FUNC
  EIGEN_STRONG_INLINE const FixedDimensions& dimensions() const { return m_dimensions; }

  EIGEN_DEVICE_FUNC
  EIGEN_STRONG_INLINE DenseIndex size() const { return m_dimensions.TotalSize(); }
};


// pure dynamic
template<typename T, int Options_, typename IndexType, std::size_t NumIndices_>
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_DEVICE_FUNC TensorStorage(internal::constructor_without_unaligned_array_assert)
      : m_data(0), m_dimensions(internal::template repeat<NumIndices_, Index>(0)) {}
    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 }

    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() { 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
          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_CXX11_TENSOR_TENSORSTORAGE_H