blob: 964797613ae1491d47196f6eeb393c983178df56 [file] [log] [blame]
// 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
// IWYU pragma: private
#include "./InternalHeaderCheck.h"
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, 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; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const FixedDimensions dimensions() const { return FixedDimensions(); }
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() {
if (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 if (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_CXX11_TENSOR_TENSORSTORAGE_H