Core: Fix C++14 linkage of metadata constants libeigen/eigen!3357
diff --git a/Eigen/src/Core/util/IntegralConstant.h b/Eigen/src/Core/util/IntegralConstant.h index df347cc..0a80402 100644 --- a/Eigen/src/Core/util/IntegralConstant.h +++ b/Eigen/src/Core/util/IntegralConstant.h
@@ -109,6 +109,11 @@ constexpr VariableAndFixedInt<N> operator()(int val) const { return VariableAndFixedInt<N>(val); } }; +#if EIGEN_COMP_CXXVER < 17 +template <int N> +constexpr int FixedInt<N>::value; +#endif + /** \internal * \class VariableAndFixedInt *
diff --git a/contrib/Eigen/src/EulerAngles/EulerSystem.h b/contrib/Eigen/src/EulerAngles/EulerSystem.h index ca369f3..2c213b6 100644 --- a/contrib/Eigen/src/EulerAngles/EulerSystem.h +++ b/contrib/Eigen/src/EulerAngles/EulerSystem.h
@@ -176,6 +176,15 @@ friend struct internal::eulerangles_assign_impl; }; +#if EIGEN_COMP_CXXVER < 17 +template <int Alpha, int Beta, int Gamma> +constexpr int EulerSystem<Alpha, Beta, Gamma>::AlphaAxis; +template <int Alpha, int Beta, int Gamma> +constexpr int EulerSystem<Alpha, Beta, Gamma>::BetaAxis; +template <int Alpha, int Beta, int Gamma> +constexpr int EulerSystem<Alpha, Beta, Gamma>::GammaAxis; +#endif + #define EIGEN_EULER_SYSTEM_TYPEDEF(A, B, C) typedef EulerSystem<EULER_##A, EULER_##B, EULER_##C> EulerSystem##A##B##C; /** Default XYZ Euler coordinate system.
diff --git a/contrib/Eigen/src/StructuredMatrices/Bccb.h b/contrib/Eigen/src/StructuredMatrices/Bccb.h index e950f57..655c036 100644 --- a/contrib/Eigen/src/StructuredMatrices/Bccb.h +++ b/contrib/Eigen/src/StructuredMatrices/Bccb.h
@@ -651,6 +651,23 @@ } // namespace internal +#if EIGEN_COMP_CXXVER < 17 +template <typename Scalar_, int BlockSize_, int NumBlocks_> +constexpr int Bccb<Scalar_, BlockSize_, NumBlocks_>::RowsAtCompileTime; +template <typename Scalar_, int BlockSize_, int NumBlocks_> +constexpr int Bccb<Scalar_, BlockSize_, NumBlocks_>::ColsAtCompileTime; +template <typename Scalar_, int BlockSize_, int NumBlocks_> +constexpr int Bccb<Scalar_, BlockSize_, NumBlocks_>::MaxRowsAtCompileTime; +template <typename Scalar_, int BlockSize_, int NumBlocks_> +constexpr int Bccb<Scalar_, BlockSize_, NumBlocks_>::MaxColsAtCompileTime; +template <typename Scalar_, int BlockSize_, int NumBlocks_> +constexpr int Bccb<Scalar_, BlockSize_, NumBlocks_>::SizeAtCompileTime; +template <typename Scalar_, int BlockSize_, int NumBlocks_> +constexpr int Bccb<Scalar_, BlockSize_, NumBlocks_>::MaxSizeAtCompileTime; +template <typename Scalar_, int BlockSize_, int NumBlocks_> +constexpr bool Bccb<Scalar_, BlockSize_, NumBlocks_>::IsRowMajor; +#endif + } // namespace Eigen #endif // EIGEN_STRUCTURED_BCCB_H
diff --git a/contrib/Eigen/src/StructuredMatrices/Cauchy.h b/contrib/Eigen/src/StructuredMatrices/Cauchy.h index 9d10bb1..99e52b2 100644 --- a/contrib/Eigen/src/StructuredMatrices/Cauchy.h +++ b/contrib/Eigen/src/StructuredMatrices/Cauchy.h
@@ -462,6 +462,23 @@ } // namespace internal +#if EIGEN_COMP_CXXVER < 17 +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Cauchy<Scalar_, Rows_, Cols_>::RowsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Cauchy<Scalar_, Rows_, Cols_>::ColsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Cauchy<Scalar_, Rows_, Cols_>::MaxRowsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Cauchy<Scalar_, Rows_, Cols_>::MaxColsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Cauchy<Scalar_, Rows_, Cols_>::SizeAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Cauchy<Scalar_, Rows_, Cols_>::MaxSizeAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr bool Cauchy<Scalar_, Rows_, Cols_>::IsRowMajor; +#endif + } // namespace Eigen #endif // EIGEN_STRUCTURED_CAUCHY_H
diff --git a/contrib/Eigen/src/StructuredMatrices/Circulant.h b/contrib/Eigen/src/StructuredMatrices/Circulant.h index 159d892..bb1ebc5 100644 --- a/contrib/Eigen/src/StructuredMatrices/Circulant.h +++ b/contrib/Eigen/src/StructuredMatrices/Circulant.h
@@ -558,6 +558,23 @@ } // namespace internal +#if EIGEN_COMP_CXXVER < 17 +template <typename Scalar_, int Size_> +constexpr int Circulant<Scalar_, Size_>::RowsAtCompileTime; +template <typename Scalar_, int Size_> +constexpr int Circulant<Scalar_, Size_>::ColsAtCompileTime; +template <typename Scalar_, int Size_> +constexpr int Circulant<Scalar_, Size_>::MaxRowsAtCompileTime; +template <typename Scalar_, int Size_> +constexpr int Circulant<Scalar_, Size_>::MaxColsAtCompileTime; +template <typename Scalar_, int Size_> +constexpr int Circulant<Scalar_, Size_>::SizeAtCompileTime; +template <typename Scalar_, int Size_> +constexpr int Circulant<Scalar_, Size_>::MaxSizeAtCompileTime; +template <typename Scalar_, int Size_> +constexpr bool Circulant<Scalar_, Size_>::IsRowMajor; +#endif + } // namespace Eigen #endif // EIGEN_STRUCTURED_CIRCULANT_H
diff --git a/contrib/Eigen/src/StructuredMatrices/DiagonalPlusLowRank.h b/contrib/Eigen/src/StructuredMatrices/DiagonalPlusLowRank.h index ed8c6dd..9dd76f7 100644 --- a/contrib/Eigen/src/StructuredMatrices/DiagonalPlusLowRank.h +++ b/contrib/Eigen/src/StructuredMatrices/DiagonalPlusLowRank.h
@@ -366,6 +366,23 @@ } // namespace internal +#if EIGEN_COMP_CXXVER < 17 +template <typename Scalar_, int Size_, int Rank_> +constexpr int DiagonalPlusLowRank<Scalar_, Size_, Rank_>::RowsAtCompileTime; +template <typename Scalar_, int Size_, int Rank_> +constexpr int DiagonalPlusLowRank<Scalar_, Size_, Rank_>::ColsAtCompileTime; +template <typename Scalar_, int Size_, int Rank_> +constexpr int DiagonalPlusLowRank<Scalar_, Size_, Rank_>::MaxRowsAtCompileTime; +template <typename Scalar_, int Size_, int Rank_> +constexpr int DiagonalPlusLowRank<Scalar_, Size_, Rank_>::MaxColsAtCompileTime; +template <typename Scalar_, int Size_, int Rank_> +constexpr int DiagonalPlusLowRank<Scalar_, Size_, Rank_>::SizeAtCompileTime; +template <typename Scalar_, int Size_, int Rank_> +constexpr int DiagonalPlusLowRank<Scalar_, Size_, Rank_>::MaxSizeAtCompileTime; +template <typename Scalar_, int Size_, int Rank_> +constexpr bool DiagonalPlusLowRank<Scalar_, Size_, Rank_>::IsRowMajor; +#endif + } // namespace Eigen #endif // EIGEN_STRUCTURED_DIAGONAL_PLUS_LOW_RANK_H
diff --git a/contrib/Eigen/src/StructuredMatrices/Hankel.h b/contrib/Eigen/src/StructuredMatrices/Hankel.h index 7bbf12e..65efd15 100644 --- a/contrib/Eigen/src/StructuredMatrices/Hankel.h +++ b/contrib/Eigen/src/StructuredMatrices/Hankel.h
@@ -426,6 +426,27 @@ } // namespace internal +#if EIGEN_COMP_CXXVER < 17 +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Hankel<Scalar_, Rows_, Cols_>::RowsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Hankel<Scalar_, Rows_, Cols_>::ColsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Hankel<Scalar_, Rows_, Cols_>::MaxRowsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Hankel<Scalar_, Rows_, Cols_>::MaxColsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Hankel<Scalar_, Rows_, Cols_>::SizeAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Hankel<Scalar_, Rows_, Cols_>::MaxSizeAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr bool Hankel<Scalar_, Rows_, Cols_>::IsRowMajor; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Hankel<Scalar_, Rows_, Cols_>::GenSizeAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Hankel<Scalar_, Rows_, Cols_>::SolveRowsAtCompileTime; +#endif + } // namespace Eigen #endif // EIGEN_STRUCTURED_HANKEL_H
diff --git a/contrib/Eigen/src/StructuredMatrices/KroneckerOperator.h b/contrib/Eigen/src/StructuredMatrices/KroneckerOperator.h index e796b97..4e83bda 100644 --- a/contrib/Eigen/src/StructuredMatrices/KroneckerOperator.h +++ b/contrib/Eigen/src/StructuredMatrices/KroneckerOperator.h
@@ -1524,6 +1524,23 @@ } // namespace internal +#if EIGEN_COMP_CXXVER < 17 +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerOperator<LhsMatrix, RhsMatrix>::RowsAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerOperator<LhsMatrix, RhsMatrix>::ColsAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerOperator<LhsMatrix, RhsMatrix>::MaxRowsAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerOperator<LhsMatrix, RhsMatrix>::MaxColsAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerOperator<LhsMatrix, RhsMatrix>::SizeAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerOperator<LhsMatrix, RhsMatrix>::MaxSizeAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr bool KroneckerOperator<LhsMatrix, RhsMatrix>::IsRowMajor; +#endif + } // namespace Eigen #endif // EIGEN_STRUCTURED_KRONECKER_OPERATOR_H
diff --git a/contrib/Eigen/src/StructuredMatrices/KroneckerSum.h b/contrib/Eigen/src/StructuredMatrices/KroneckerSum.h index 0ecab69..9302981 100644 --- a/contrib/Eigen/src/StructuredMatrices/KroneckerSum.h +++ b/contrib/Eigen/src/StructuredMatrices/KroneckerSum.h
@@ -955,6 +955,23 @@ } // namespace internal +#if EIGEN_COMP_CXXVER < 17 +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerSum<LhsMatrix, RhsMatrix>::RowsAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerSum<LhsMatrix, RhsMatrix>::ColsAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerSum<LhsMatrix, RhsMatrix>::MaxRowsAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerSum<LhsMatrix, RhsMatrix>::MaxColsAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerSum<LhsMatrix, RhsMatrix>::SizeAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr int KroneckerSum<LhsMatrix, RhsMatrix>::MaxSizeAtCompileTime; +template <typename LhsMatrix, typename RhsMatrix> +constexpr bool KroneckerSum<LhsMatrix, RhsMatrix>::IsRowMajor; +#endif + } // namespace Eigen #endif // EIGEN_STRUCTURED_KRONECKER_SUM_H
diff --git a/contrib/Eigen/src/StructuredMatrices/Toeplitz.h b/contrib/Eigen/src/StructuredMatrices/Toeplitz.h index 01456c8..bea571d 100644 --- a/contrib/Eigen/src/StructuredMatrices/Toeplitz.h +++ b/contrib/Eigen/src/StructuredMatrices/Toeplitz.h
@@ -346,6 +346,23 @@ } // namespace internal +#if EIGEN_COMP_CXXVER < 17 +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Toeplitz<Scalar_, Rows_, Cols_>::RowsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Toeplitz<Scalar_, Rows_, Cols_>::ColsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Toeplitz<Scalar_, Rows_, Cols_>::MaxRowsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Toeplitz<Scalar_, Rows_, Cols_>::MaxColsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Toeplitz<Scalar_, Rows_, Cols_>::SizeAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Toeplitz<Scalar_, Rows_, Cols_>::MaxSizeAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr bool Toeplitz<Scalar_, Rows_, Cols_>::IsRowMajor; +#endif + } // namespace Eigen #endif // EIGEN_STRUCTURED_TOEPLITZ_H
diff --git a/contrib/Eigen/src/StructuredMatrices/Vandermonde.h b/contrib/Eigen/src/StructuredMatrices/Vandermonde.h index b84f1cd..6a56aa0 100644 --- a/contrib/Eigen/src/StructuredMatrices/Vandermonde.h +++ b/contrib/Eigen/src/StructuredMatrices/Vandermonde.h
@@ -640,6 +640,27 @@ } // namespace internal +#if EIGEN_COMP_CXXVER < 17 +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Vandermonde<Scalar_, Rows_, Cols_>::RowsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Vandermonde<Scalar_, Rows_, Cols_>::ColsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Vandermonde<Scalar_, Rows_, Cols_>::MaxRowsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Vandermonde<Scalar_, Rows_, Cols_>::MaxColsAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Vandermonde<Scalar_, Rows_, Cols_>::SizeAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Vandermonde<Scalar_, Rows_, Cols_>::MaxSizeAtCompileTime; +template <typename Scalar_, int Rows_, int Cols_> +constexpr bool Vandermonde<Scalar_, Rows_, Cols_>::IsRowMajor; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Vandermonde<Scalar_, Rows_, Cols_>::NodeOptions; +template <typename Scalar_, int Rows_, int Cols_> +constexpr int Vandermonde<Scalar_, Rows_, Cols_>::Flags; +#endif + } // namespace Eigen #endif // EIGEN_STRUCTURED_VANDERMONDE_H
diff --git a/contrib/Eigen/src/Tensor/Tensor.h b/contrib/Eigen/src/Tensor/Tensor.h index 95014f8..f3c7d29 100644 --- a/contrib/Eigen/src/Tensor/Tensor.h +++ b/contrib/Eigen/src/Tensor/Tensor.h
@@ -376,6 +376,15 @@ } }; +#if EIGEN_COMP_CXXVER < 17 +template <typename Scalar_, int NumIndices_, int Options_, typename IndexType_> +constexpr int Tensor<Scalar_, NumIndices_, Options_, IndexType_>::NumIndices; +template <typename Scalar_, int NumIndices_, int Options_, typename IndexType_> +constexpr int Tensor<Scalar_, NumIndices_, Options_, IndexType_>::Layout; +template <typename Scalar_, int NumIndices_, int Options_, typename IndexType_> +constexpr int Tensor<Scalar_, NumIndices_, Options_, IndexType_>::Options; +#endif + } // end namespace Eigen #endif // EIGEN_TENSOR_TENSOR_H
diff --git a/contrib/Eigen/src/Tensor/TensorCostModel.h b/contrib/Eigen/src/Tensor/TensorCostModel.h index 5cb986a..8b8a7ea 100644 --- a/contrib/Eigen/src/Tensor/TensorCostModel.h +++ b/contrib/Eigen/src/Tensor/TensorCostModel.h
@@ -246,6 +246,25 @@ } }; +#if EIGEN_COMP_CXXVER < 17 +template <typename Device> +constexpr int TensorCostModel<Device>::kDeviceCyclesPerComputeCycle; +template <typename Device> +constexpr int TensorCostModel<Device>::kStartupCycles; +template <typename Device> +constexpr int TensorCostModel<Device>::kPerThreadCycles; +template <typename Device> +constexpr int TensorCostModel<Device>::kTaskSize; +template <typename Device> +constexpr int TensorCostModel<Device>::kMemBandwidthSaturationThreads; +template <typename Device> +constexpr double TensorCostModel<Device>::kMemBoundThreshold; +template <typename Device> +constexpr double TensorCostModel<Device>::kDramThresholdBytes; +template <typename Device> +constexpr double TensorCostModel<Device>::kByteCost; +#endif + } // namespace Eigen #endif // EIGEN_TENSOR_TENSOR_COST_MODEL_H
diff --git a/contrib/Eigen/src/Tensor/TensorDimensions.h b/contrib/Eigen/src/Tensor/TensorDimensions.h index 9de06e7..2ea34f9 100644 --- a/contrib/Eigen/src/Tensor/TensorDimensions.h +++ b/contrib/Eigen/src/Tensor/TensorDimensions.h
@@ -129,6 +129,13 @@ } }; +#if EIGEN_COMP_CXXVER < 17 +template <std::ptrdiff_t... Indices> +constexpr std::ptrdiff_t Sizes<Indices...>::total_size; +template <std::ptrdiff_t... Indices> +constexpr std::ptrdiff_t Sizes<Indices...>::count; +#endif + namespace internal { template <std::ptrdiff_t... Indices> constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::ptrdiff_t array_prod(const Sizes<Indices...>&) { @@ -258,6 +265,11 @@ } }; +#if EIGEN_COMP_CXXVER < 17 +template <typename DenseIndex, int NumDims> +constexpr int DSizes<DenseIndex, NumDims>::count; +#endif + template <typename IndexType, int NumDims> std::ostream& operator<<(std::ostream& os, const DSizes<IndexType, NumDims>& dims) { os << "[";
diff --git a/contrib/Eigen/src/Tensor/TensorFixedSize.h b/contrib/Eigen/src/Tensor/TensorFixedSize.h index ccf9d17..03af104 100644 --- a/contrib/Eigen/src/Tensor/TensorFixedSize.h +++ b/contrib/Eigen/src/Tensor/TensorFixedSize.h
@@ -213,6 +213,15 @@ } }; +#if EIGEN_COMP_CXXVER < 17 +template <typename Scalar_, typename Dimensions_, int Options_, typename IndexType> +constexpr std::size_t TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType>::NumIndices; +template <typename Scalar_, typename Dimensions_, int Options_, typename IndexType> +constexpr int TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType>::Layout; +template <typename Scalar_, typename Dimensions_, int Options_, typename IndexType> +constexpr int TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType>::Options; +#endif + } // end namespace Eigen #endif // EIGEN_TENSOR_TENSOR_FIXED_SIZE_H
diff --git a/contrib/Eigen/src/Tensor/TensorIndexList.h b/contrib/Eigen/src/Tensor/TensorIndexList.h index a236117..1d55f55 100644 --- a/contrib/Eigen/src/Tensor/TensorIndexList.h +++ b/contrib/Eigen/src/Tensor/TensorIndexList.h
@@ -42,6 +42,15 @@ } }; +#if EIGEN_COMP_CXXVER < 17 +template <Index n> +constexpr Index type2index<n>::value; +template <Index f, Index s> +constexpr Index type2indexpair<f, s>::first; +template <Index f, Index s> +constexpr Index type2indexpair<f, s>::second; +#endif + template <Index n> struct NumTraits<type2index<n>> { typedef Index Real;
diff --git a/contrib/Eigen/src/Tensor/TensorMap.h b/contrib/Eigen/src/Tensor/TensorMap.h index 7c35633..edaed0d 100644 --- a/contrib/Eigen/src/Tensor/TensorMap.h +++ b/contrib/Eigen/src/Tensor/TensorMap.h
@@ -185,6 +185,16 @@ Dimensions m_dimensions; }; +#if EIGEN_COMP_CXXVER < 17 +template <typename PlainObjectType, int Options_, template <class> class MakePointer_> +constexpr typename TensorMap<PlainObjectType, Options_, MakePointer_>::Index + TensorMap<PlainObjectType, Options_, MakePointer_>::NumIndices; +template <typename PlainObjectType, int Options_, template <class> class MakePointer_> +constexpr int TensorMap<PlainObjectType, Options_, MakePointer_>::Layout; +template <typename PlainObjectType, int Options_, template <class> class MakePointer_> +constexpr int TensorMap<PlainObjectType, Options_, MakePointer_>::Options; +#endif + } // end namespace Eigen #endif // EIGEN_TENSOR_TENSOR_MAP_H
diff --git a/contrib/Eigen/src/Tensor/TensorRef.h b/contrib/Eigen/src/Tensor/TensorRef.h index 3a36128..052af5f 100644 --- a/contrib/Eigen/src/Tensor/TensorRef.h +++ b/contrib/Eigen/src/Tensor/TensorRef.h
@@ -237,6 +237,13 @@ TensorLazyBaseEvaluator<Dimensions, Scalar>* m_evaluator = nullptr; }; +#if EIGEN_COMP_CXXVER < 17 +template <typename Derived> +constexpr typename TensorRefBase<Derived>::Index TensorRefBase<Derived>::NumIndices; +template <typename Derived> +constexpr int TensorRefBase<Derived>::Layout; +#endif + } // namespace internal /**
diff --git a/contrib/test/EulerAngles.cpp b/contrib/test/EulerAngles.cpp index 20062ce..b5115b9 100644 --- a/contrib/test/EulerAngles.cpp +++ b/contrib/test/EulerAngles.cpp
@@ -302,6 +302,20 @@ VERIFY_IS_APPROX(e.gamma(), gamma); } +// A volatile pointer forces odr-use even when optimization could fold the value. +template <typename T> +T read_through_address(const T& value) { + const T* volatile address = &value; + return *address; +} + +template <typename System> +void eulerangles_axes_odr_use(int alpha, int beta, int gamma) { + VERIFY_IS_EQUAL(read_through_address(System::AlphaAxis), alpha); + VERIFY_IS_EQUAL(read_through_address(System::BetaAxis), beta); + VERIFY_IS_EQUAL(read_through_address(System::GammaAxis), gamma); +} + EIGEN_DECLARE_TEST(EulerAngles) { // Simple cast test EulerAnglesXYZd onesEd(1, 1, 1); @@ -325,6 +339,8 @@ CALL_SUBTEST_6(eulerangles_data_constructor<float>()); CALL_SUBTEST_6(eulerangles_data_constructor<double>()); + CALL_SUBTEST_6((eulerangles_axes_odr_use<EulerSystemXYZ>(1, 2, 3))); + CALL_SUBTEST_6((eulerangles_axes_odr_use<EulerSystem<1, -2, 3>>(1, -2, 3))); // TODO: Add tests for auto diff // TODO: Add tests for complex numbers
diff --git a/contrib/test/structured_matrices.cpp b/contrib/test/structured_matrices.cpp index 313521a..00ff71f 100644 --- a/contrib/test/structured_matrices.cpp +++ b/contrib/test/structured_matrices.cpp
@@ -1542,7 +1542,58 @@ forEachFlushToZeroMode([&](FlushToZeroMode) { check(); }); } +// A volatile pointer forces odr-use even when optimization could fold the value. +template <typename T> +T read_through_address(const T& value) { + const T* volatile address = &value; + return *address; +} + +template <typename Operator> +void structured_metadata_odr_use(int rows, int cols, bool row_major = false) { + const int size = rows == Dynamic || cols == Dynamic ? Dynamic : rows * cols; + VERIFY_IS_EQUAL(read_through_address(Operator::RowsAtCompileTime), rows); + VERIFY_IS_EQUAL(read_through_address(Operator::ColsAtCompileTime), cols); + VERIFY_IS_EQUAL(read_through_address(Operator::MaxRowsAtCompileTime), rows); + VERIFY_IS_EQUAL(read_through_address(Operator::MaxColsAtCompileTime), cols); + VERIFY_IS_EQUAL(read_through_address(Operator::SizeAtCompileTime), size); + VERIFY_IS_EQUAL(read_through_address(Operator::MaxSizeAtCompileTime), size); + VERIFY_IS_EQUAL(read_through_address(Operator::IsRowMajor), row_major); +} + +static void test_structured_metadata_odr_use() { + structured_metadata_odr_use<Bccb<double, 2, 3>>(6, 6); + structured_metadata_odr_use<Bccb<double>>(Dynamic, Dynamic); + structured_metadata_odr_use<Cauchy<double, 4, 3>>(4, 3); + structured_metadata_odr_use<Cauchy<double>>(Dynamic, Dynamic); + structured_metadata_odr_use<Circulant<double, 4>>(4, 4); + structured_metadata_odr_use<Circulant<double>>(Dynamic, Dynamic); + structured_metadata_odr_use<DiagonalPlusLowRank<double, 4, 2>>(4, 4); + structured_metadata_odr_use<DiagonalPlusLowRank<double>>(Dynamic, Dynamic); + structured_metadata_odr_use<Hankel<double, 4, 3>>(4, 3); + structured_metadata_odr_use<Hankel<double>>(Dynamic, Dynamic); + structured_metadata_odr_use<KroneckerOperator<Matrix<double, 2, 3>, Matrix<double, 3, 4>>>(6, 12); + structured_metadata_odr_use<KroneckerOperator<MatrixXd, MatrixXd>>(Dynamic, Dynamic); + structured_metadata_odr_use<KroneckerSum<Matrix2d, Matrix3d>>(6, 6); + structured_metadata_odr_use<KroneckerSum<MatrixXd, MatrixXd>>(Dynamic, Dynamic); + structured_metadata_odr_use<Toeplitz<double, 4, 3>>(4, 3); + structured_metadata_odr_use<Toeplitz<double>>(Dynamic, Dynamic); + structured_metadata_odr_use<Vandermonde<double, 4, 3>>(4, 3); + structured_metadata_odr_use<Vandermonde<double>>(Dynamic, Dynamic); + structured_metadata_odr_use<Vandermonde<double, 1, 3>>(1, 3, true); + VERIFY_IS_EQUAL((read_through_address(Hankel<double, 4, 3>::GenSizeAtCompileTime)), 6); + VERIFY_IS_EQUAL((read_through_address(Hankel<double, 4, 3>::SolveRowsAtCompileTime)), 3); + VERIFY_IS_EQUAL(read_through_address(Hankel<double>::GenSizeAtCompileTime), Dynamic); + VERIFY_IS_EQUAL(read_through_address(Hankel<double>::SolveRowsAtCompileTime), Dynamic); + VERIFY_IS_EQUAL((read_through_address(Vandermonde<double, 4, 3>::NodeOptions)), int(DontAlign)); + VERIFY_IS_EQUAL((read_through_address(Vandermonde<double, 4, 3>::Flags)), 0); + VERIFY_IS_EQUAL(read_through_address(Vandermonde<double>::NodeOptions), int(AutoAlign)); + VERIFY_IS_EQUAL(read_through_address(Vandermonde<double>::Flags), 0); + VERIFY_IS_EQUAL((read_through_address(Vandermonde<double, 1, 3>::Flags)), int(RowMajorBit)); +} + EIGEN_DECLARE_TEST(structured_matrices) { + CALL_SUBTEST_16(test_structured_metadata_odr_use()); for (int i = 0; i < g_repeat; ++i) { // Circulant: direct path (small), FFT path (composite and prime sizes), edge cases. CALL_SUBTEST_1((test_circulant_product<double>(1)));
diff --git a/contrib/test/tensor_cost_model.cpp b/contrib/test/tensor_cost_model.cpp index 58eb996..e54f822 100644 --- a/contrib/test/tensor_cost_model.cpp +++ b/contrib/test/tensor_cost_model.cpp
@@ -47,7 +47,26 @@ } } +// A volatile pointer forces odr-use even when optimization could fold the value. +template <typename T> +T read_through_address(const T& value) { + const T* volatile address = &value; + return *address; +} + +static void test_cost_model_constants_odr_use() { + using Cost = Eigen::TensorCostModel<DefaultDevice>; + VERIFY_IS_EQUAL(read_through_address(Cost::kDeviceCyclesPerComputeCycle), 1); + VERIFY_IS_EQUAL(read_through_address(Cost::kStartupCycles), 25000); + VERIFY_IS_EQUAL(read_through_address(Cost::kPerThreadCycles), 25000); + VERIFY_IS_EQUAL(read_through_address(Cost::kTaskSize), 40000); + VERIFY_IS_EQUAL(read_through_address(Cost::kMemBandwidthSaturationThreads), 4); + VERIFY_IS_EQUAL(read_through_address(Cost::kMemBoundThreshold), 2.0); + VERIFY_IS_EQUAL(read_through_address(Cost::kDramThresholdBytes), 1024.0 * 1024.0); +} + EIGEN_DECLARE_TEST(tensor_cost_model) { + CALL_SUBTEST(test_cost_model_constants_odr_use()); CALL_SUBTEST(test_nullary_zero_bytes_loaded<float>()); CALL_SUBTEST(test_nullary_zero_bytes_loaded<double>()); CALL_SUBTEST(test_nullary_zero_bytes_loaded<int>());
diff --git a/contrib/test/tensor_dimension.cpp b/contrib/test/tensor_dimension.cpp index 4c064e2..60f58f3 100644 --- a/contrib/test/tensor_dimension.cpp +++ b/contrib/test/tensor_dimension.cpp
@@ -91,7 +91,52 @@ VERIFY_RAISES_ASSERT((Eigen::DSizes<std::ptrdiff_t, 3>(2, 3, std::size_t(-1)))); } +// A volatile pointer forces odr-use even when optimization could fold the value. +template <typename T> +T read_through_address(const T& value) { + const T* volatile address = &value; + return *address; +} + +static void test_dimension_constants_odr_use() { + VERIFY_IS_EQUAL((read_through_address(Eigen::Sizes<2, 3>::total_size)), std::ptrdiff_t(6)); + VERIFY_IS_EQUAL((read_through_address(Eigen::Sizes<2, 3>::count)), std::ptrdiff_t(2)); + VERIFY_IS_EQUAL(read_through_address(Eigen::Sizes<>::total_size), std::ptrdiff_t(1)); + VERIFY_IS_EQUAL(read_through_address(Eigen::Sizes<>::count), std::ptrdiff_t(0)); + VERIFY_IS_EQUAL((read_through_address(Eigen::DSizes<Index, 3>::count)), 3); + VERIFY_IS_EQUAL((read_through_address(Eigen::DSizes<int, 0>::count)), 0); +} + +template <typename TensorType> +void tensor_rank_layout_odr_use(int rank, int layout) { + VERIFY_IS_EQUAL(read_through_address(TensorType::NumIndices), rank); + VERIFY_IS_EQUAL(read_through_address(TensorType::Layout), layout); +} + +template <typename TensorType> +void tensor_metadata_odr_use(int rank, int layout, int options) { + tensor_rank_layout_odr_use<TensorType>(rank, layout); + VERIFY_IS_EQUAL(read_through_address(TensorType::Options), options); +} + +static void test_tensor_metadata_odr_use() { + tensor_metadata_odr_use<Tensor<float, 3>>(3, ColMajor, 0); + tensor_metadata_odr_use<Tensor<float, 3, RowMajor, int>>(3, RowMajor, RowMajor); + tensor_metadata_odr_use<Tensor<float, 0>>(0, ColMajor, 0); + tensor_metadata_odr_use<TensorFixedSize<float, Sizes<2, 3>>>(2, ColMajor, 0); + tensor_metadata_odr_use<TensorFixedSize<float, Sizes<2, 3>, RowMajor, int>>(2, RowMajor, RowMajor); + tensor_metadata_odr_use<TensorFixedSize<float, Sizes<>>>(0, ColMajor, 0); + tensor_metadata_odr_use<TensorMap<Tensor<float, 3>>>(3, ColMajor, 0); + tensor_metadata_odr_use<TensorMap<const Tensor<float, 3, RowMajor>, Aligned>>(3, RowMajor, Aligned); + tensor_metadata_odr_use<TensorMap<TensorFixedSize<float, Sizes<2, 3>>>>(2, ColMajor, 0); + tensor_rank_layout_odr_use<TensorRef<Tensor<float, 3>>>(3, ColMajor); + tensor_rank_layout_odr_use<TensorRef<const Tensor<float, 3, RowMajor>>>(3, RowMajor); + tensor_rank_layout_odr_use<TensorRef<TensorFixedSize<float, Sizes<>>>>(0, ColMajor); +} + EIGEN_DECLARE_TEST(tensor_dimension) { + CALL_SUBTEST(test_dimension_constants_odr_use()); + CALL_SUBTEST(test_tensor_metadata_odr_use()); CALL_SUBTEST(test_dynamic_size()); CALL_SUBTEST(test_fixed_size()); CALL_SUBTEST(test_match());
diff --git a/contrib/test/tensor_index_list.cpp b/contrib/test/tensor_index_list.cpp index 4d8156b..12a74b8 100644 --- a/contrib/test/tensor_index_list.cpp +++ b/contrib/test/tensor_index_list.cpp
@@ -452,7 +452,22 @@ VERIFY(dimensions_match(dim1, dim2)); } +// A volatile pointer forces odr-use even when optimization could fold the value. +template <typename T> +T read_through_address(const T& value) { + const T* volatile address = &value; + return *address; +} + +static void test_static_index_odr_use() { + VERIFY_IS_EQUAL(read_through_address(Eigen::type2index<3>::value), Index(3)); + VERIFY_IS_EQUAL(read_through_address(Eigen::type2index<-3>::value), Index(-3)); + VERIFY_IS_EQUAL((read_through_address(Eigen::type2indexpair<1, -2>::first)), Index(1)); + VERIFY_IS_EQUAL((read_through_address(Eigen::type2indexpair<1, -2>::second)), Index(-2)); +} + EIGEN_DECLARE_TEST(tensor_index_list) { + CALL_SUBTEST(test_static_index_odr_use()); CALL_SUBTEST(test_static_index_list()); CALL_SUBTEST(test_type2index_list()); CALL_SUBTEST(test_type2indexpair_list());
diff --git a/test/symbolic_index.cpp b/test/symbolic_index.cpp index 7dbcafe..1981c11 100644 --- a/test/symbolic_index.cpp +++ b/test/symbolic_index.cpp
@@ -71,4 +71,19 @@ } } -EIGEN_DECLARE_TEST(symbolic_index) { CALL_SUBTEST_1(check_symbolic_index()); } +// A volatile pointer forces odr-use even when optimization could fold the value. +template <typename T> +T read_through_address(const T& value) { + const T* volatile address = &value; + return *address; +} + +void check_fixed_int_odr_use() { + VERIFY_IS_EQUAL(read_through_address(internal::FixedInt<3>::value), 3); + VERIFY_IS_EQUAL(read_through_address(internal::FixedInt<-3>::value), -3); +} + +EIGEN_DECLARE_TEST(symbolic_index) { + CALL_SUBTEST_1(check_symbolic_index()); + CALL_SUBTEST_1(check_fixed_int_odr_use()); +}