diff options
Diffstat (limited to 'unsupported/Eigen/CXX11')
-rw-r--r-- | unsupported/Eigen/CXX11/Tensor | 1 | ||||
-rw-r--r-- | unsupported/Eigen/CXX11/src/Tensor/Tensor.h | 75 | ||||
-rw-r--r-- | unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h | 44 | ||||
-rw-r--r-- | unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h | 53 |
4 files changed, 161 insertions, 12 deletions
diff --git a/unsupported/Eigen/CXX11/Tensor b/unsupported/Eigen/CXX11/Tensor index cbe416602..3331ccb55 100644 --- a/unsupported/Eigen/CXX11/Tensor +++ b/unsupported/Eigen/CXX11/Tensor @@ -57,6 +57,7 @@ #endif +#include "src/Tensor/TensorMacros.h" #include "src/Tensor/TensorForwardDeclarations.h" #include "src/Tensor/TensorMeta.h" #include "src/Tensor/TensorDeviceType.h" diff --git a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h index 6c16e0faa..3ac465d24 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h +++ b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h @@ -88,6 +88,15 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexTyp protected: TensorStorage<Scalar, Dimensions, Options> m_storage; +#ifdef EIGEN_HAS_SFINAE + template<typename CustomIndices> + struct isOfNormalIndex{ + static const bool is_array = internal::is_base_of<array<Index, NumIndices>, CustomIndices>::value; + static const bool is_int = NumTraits<CustomIndices>::IsInteger; + static const bool value = is_array | is_int; + }; +#endif + public: // Metadata EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank() const { return NumIndices; } @@ -113,12 +122,24 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexTyp } #endif + // normal indices EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(const array<Index, NumIndices>& indices) const { eigen_internal_assert(checkIndexRange(indices)); return m_storage.data()[linearizedIndex(indices)]; } + // custom indices +#ifdef EIGEN_HAS_SFINAE + template<typename CustomIndices, + EIGEN_SFINAE_ENABLE_IF( !(isOfNormalIndex<CustomIndices>::value) ) + > + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(CustomIndices& indices) const + { + return coeff(internal::customIndices2Array<Index,NumIndices>(indices)); + } +#endif + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const { eigen_internal_assert(index >= 0 && index < size()); @@ -135,12 +156,24 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexTyp } #endif + // normal indices EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(const array<Index, NumIndices>& indices) { eigen_internal_assert(checkIndexRange(indices)); return m_storage.data()[linearizedIndex(indices)]; } + // custom indices +#ifdef EIGEN_HAS_SFINAE + template<typename CustomIndices, + EIGEN_SFINAE_ENABLE_IF( !(isOfNormalIndex<CustomIndices>::value) ) + > + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(CustomIndices& indices) + { + return coeffRef(internal::customIndices2Array<Index,NumIndices>(indices)); + } +#endif + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) { eigen_internal_assert(index >= 0 && index < size()); @@ -178,9 +211,20 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexTyp } #endif + // custom indices +#ifdef EIGEN_HAS_SFINAE + template<typename CustomIndices, + EIGEN_SFINAE_ENABLE_IF( !(isOfNormalIndex<CustomIndices>::value) ) + > + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(CustomIndices& indices) const + { + return coeff(internal::customIndices2Array<Index,NumIndices>(indices)); + } +#endif + + // normal indices EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(const array<Index, NumIndices>& indices) const { - eigen_assert(checkIndexRange(indices)); return coeff(indices); } @@ -228,12 +272,23 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexTyp } #endif + // normal indices EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(const array<Index, NumIndices>& indices) { - eigen_assert(checkIndexRange(indices)); return coeffRef(indices); } + // custom indices +#ifdef EIGEN_HAS_SFINAE + template<typename CustomIndices, + EIGEN_SFINAE_ENABLE_IF( !(isOfNormalIndex<CustomIndices>::value) ) + > + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(CustomIndices& indices) + { + return coeffRef(internal::customIndices2Array<Index,NumIndices>(indices)); + } +#endif + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(Index index) { eigen_assert(index >= 0 && index < size()); @@ -295,6 +350,7 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexTyp } #endif + /** Normal Dimension */ inline explicit Tensor(const array<Index, NumIndices>& dimensions) : m_storage(internal::array_prod(dimensions), dimensions) { @@ -341,7 +397,7 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexTyp } #ifdef EIGEN_HAS_VARIADIC_TEMPLATES - template<typename... IndexTypes> EIGEN_DEVICE_FUNC + template<typename... IndexTypes> EIGEN_DEVICE_FUNC void resize(Index firstDimension, IndexTypes... otherDimensions) { // The number of dimensions used to resize a tensor must be equal to the rank of the tensor. @@ -350,6 +406,7 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexTyp } #endif + /** Normal Dimension */ EIGEN_DEVICE_FUNC void resize(const array<Index, NumIndices>& dimensions) { std::size_t i; @@ -367,6 +424,7 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexTyp #endif } + // Why this overload, DSizes is derived from array ??? // EIGEN_DEVICE_FUNC void resize(const DSizes<Index, NumIndices>& dimensions) { array<Index, NumIndices> dims; for (std::size_t i = 0; i < NumIndices; ++i) { @@ -375,6 +433,17 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexTyp resize(dims); } + /** Custom Dimension */ +#ifdef EIGEN_HAS_SFINAE + template<typename CustomDimension, + EIGEN_SFINAE_ENABLE_IF( !(isOfNormalIndex<CustomDimension>::value) ) + > + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(CustomDimension& dimensions) + { + resize(internal::customIndices2Array<Index,NumIndices>(dimensions)); + } +#endif + #ifndef EIGEN_EMULATE_CXX11_META_H template <typename std::ptrdiff_t... Indices> EIGEN_DEVICE_FUNC diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h new file mode 100644 index 000000000..6d9cc4f38 --- /dev/null +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h @@ -0,0 +1,44 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 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_TENSOR_META_MACROS_H +#define EIGEN_CXX11_TENSOR_TENSOR_META_MACROS_H + + +/** use this macro in sfinae selection in templated functions + * + * template<typename T, + * typename std::enable_if< isBanana<T>::value , int >::type = 0 + * > + * void foo(){} + * + * becomes => + * + * template<typename TopoType, + * SFINAE_ENABLE_IF( isBanana<T>::value ) + * > + * void foo(){} + */ + +#ifdef EIGEN_HAS_VARIADIC_TEMPLATES +#define EIGEN_HAS_SFINAE +#endif + +#define EIGEN_SFINAE_ENABLE_IF( __condition__ ) \ + typename internal::enable_if< ( __condition__ ) , int >::type = 0 + + +#if defined(EIGEN_HAS_CONSTEXPR) +#define EIGEN_CONSTEXPR constexpr +#else +#define EIGEN_CONSTEXPR +#endif + + +#endif diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h index 7dfa04760..07735fa5f 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h @@ -32,14 +32,6 @@ template <> struct max_n_1<0> { }; - - -#if defined(EIGEN_HAS_CONSTEXPR) -#define EIGEN_CONSTEXPR constexpr -#else -#define EIGEN_CONSTEXPR -#endif - // Tuple mimics std::pair but works on e.g. nvcc. template <typename U, typename V> struct Tuple { public: @@ -83,7 +75,50 @@ bool operator!=(const Tuple<U, V>& x, const Tuple<U, V>& y) { return !(x == y); } -#undef EIGEN_CONSTEXPR + + +#ifdef EIGEN_HAS_SFINAE +namespace internal{ + + template<typename IndexType, Index... Is> + EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array<Index, sizeof...(Is)> customIndices2Array(IndexType& idx, numeric_list<Index, Is...>) { + return { idx[Is]... }; + } + + /** Make an array (for index/dimensions) out of a custom index */ + template<typename Index, int NumIndices, typename IndexType> + EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array<Index, NumIndices> customIndices2Array(IndexType& idx) { + return customIndices2Array(idx, typename gen_numeric_list<Index, NumIndices>::type{}); + } + + + template <typename B, typename D> + struct is_base_of + { + + typedef char (&yes)[1]; + typedef char (&no)[2]; + + template <typename BB, typename DD> + struct Host + { + operator BB*() const; + operator DD*(); + }; + + template<typename T> + static yes check(D*, T); + static no check(B*, int); + + static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes); + }; + +} +#endif + + } // namespace Eigen |