From 3a197a60e602ea0cd836438ab717810803dc9074 Mon Sep 17 00:00:00 2001 From: Mehdi Goli Date: Wed, 1 Aug 2018 12:19:14 +0100 Subject: [PATCH 1/2] variadic version of assert which can take a parameter pack as its input. --- Eigen/src/Core/util/Macros.h | 24 +++++++++++++++++++ .../Eigen/CXX11/src/Tensor/TensorMap.h | 2 ++ 2 files changed, 26 insertions(+) diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index b15819f7d..3255b8351 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -1076,4 +1076,28 @@ namespace Eigen { # endif #endif +#ifdef EIGEN_HAS_VARIADIC_TEMPLATES +// Provide a variadic version of assert which can take a parameter pack as its input +// The eigen_assert macro used here might have been redefined to use other macros such as EIGEN_THROW, such as used in Eigen's test suite, therefore this needs to be defined after the other macros. +// Note that this does not provide as nice a string to assert as a straight forward call to eigen_assert, so we add a message to the assert. +#if defined(EIGEN_NO_DEBUG) +#define eigen_variadic_assert(x) +#else +namespace Eigen { +namespace internal { +inline void variadic_assert(const char*) {} +template inline void variadic_assert(const char* message, bool first, Bools ... others) { + eigen_assert(first && message); + variadic_assert(message, others...); + EIGEN_UNUSED_VARIABLE(first); +} +} +} +#define EIGEN_VARIADIC_ASSERT_MESSAGE(x) EIGEN_MAKESTRING(x) " in " __FILE__ ":" EIGEN_MAKESTRING(__LINE__) +#define eigen_variadic_assert(x) \ + do { Eigen::internal::variadic_assert(EIGEN_VARIADIC_ASSERT_MESSAGE(x), x); } while(false); +#endif +#endif + + #endif // EIGEN_MACROS_H diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h index a8e55757e..f69f8f24a 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h @@ -150,6 +150,7 @@ template class MakePoin EIGEN_STRONG_INLINE const Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) const { EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE) + eigen_variadic_assert((Eigen::NumTraits::highest() >= otherIndices)...); if (PlainObjectType::Options&RowMajor) { const Index index = m_dimensions.IndexOfRowMajor(array{{firstIndex, secondIndex, otherIndices...}}); return m_data[index]; @@ -237,6 +238,7 @@ template class MakePoin EIGEN_STRONG_INLINE Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) { static_assert(sizeof...(otherIndices) + 2 == NumIndices || NumIndices == Dynamic, "Number of indices used to access a tensor coefficient must be equal to the rank of the tensor."); + eigen_variadic_assert((Eigen::NumTraits::highest() >= otherIndices)...); const std::size_t NumDims = sizeof...(otherIndices) + 2; if (PlainObjectType::Options&RowMajor) { const Index index = m_dimensions.IndexOfRowMajor(array{{firstIndex, secondIndex, otherIndices...}}); From af96018b499be64ff0b262cafc7b31f1a907b4c8 Mon Sep 17 00:00:00 2001 From: Mehdi Goli Date: Wed, 1 Aug 2018 16:04:44 +0100 Subject: [PATCH 2/2] Using the suggested modification. --- Eigen/src/Core/util/Macros.h | 21 +++++-------------- .../Eigen/CXX11/src/Tensor/TensorMap.h | 4 ++-- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index 3255b8351..f59b93608 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -1077,26 +1077,15 @@ namespace Eigen { #endif #ifdef EIGEN_HAS_VARIADIC_TEMPLATES -// Provide a variadic version of assert which can take a parameter pack as its input -// The eigen_assert macro used here might have been redefined to use other macros such as EIGEN_THROW, such as used in Eigen's test suite, therefore this needs to be defined after the other macros. -// Note that this does not provide as nice a string to assert as a straight forward call to eigen_assert, so we add a message to the assert. -#if defined(EIGEN_NO_DEBUG) -#define eigen_variadic_assert(x) -#else +// The all function is used to enable a variadic version of eigen_assert which can take a parameter pack as its input. namespace Eigen { namespace internal { -inline void variadic_assert(const char*) {} -template inline void variadic_assert(const char* message, bool first, Bools ... others) { - eigen_assert(first && message); - variadic_assert(message, others...); - EIGEN_UNUSED_VARIABLE(first); +bool all(){ return true; } +template +bool all(T t, Ts ... ts){ return t && all(ts...); } + } } -} -#define EIGEN_VARIADIC_ASSERT_MESSAGE(x) EIGEN_MAKESTRING(x) " in " __FILE__ ":" EIGEN_MAKESTRING(__LINE__) -#define eigen_variadic_assert(x) \ - do { Eigen::internal::variadic_assert(EIGEN_VARIADIC_ASSERT_MESSAGE(x), x); } while(false); -#endif #endif diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h index f69f8f24a..d1cc0593f 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h @@ -150,7 +150,7 @@ template class MakePoin EIGEN_STRONG_INLINE const Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) const { EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE) - eigen_variadic_assert((Eigen::NumTraits::highest() >= otherIndices)...); + eigen_assert(internal::all((Eigen::NumTraits::highest() >= otherIndices)...)); if (PlainObjectType::Options&RowMajor) { const Index index = m_dimensions.IndexOfRowMajor(array{{firstIndex, secondIndex, otherIndices...}}); return m_data[index]; @@ -238,7 +238,7 @@ template class MakePoin EIGEN_STRONG_INLINE Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) { static_assert(sizeof...(otherIndices) + 2 == NumIndices || NumIndices == Dynamic, "Number of indices used to access a tensor coefficient must be equal to the rank of the tensor."); - eigen_variadic_assert((Eigen::NumTraits::highest() >= otherIndices)...); + eigen_assert(internal::all((Eigen::NumTraits::highest() >= otherIndices)...)); const std::size_t NumDims = sizeof...(otherIndices) + 2; if (PlainObjectType::Options&RowMajor) { const Index index = m_dimensions.IndexOfRowMajor(array{{firstIndex, secondIndex, otherIndices...}});