diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h index 7e8102997..42b411e6f 100644 --- a/Eigen/src/Core/Assign.h +++ b/Eigen/src/Core/Assign.h @@ -437,6 +437,8 @@ template EIGEN_STRONG_INLINE Derived& MatrixBase ::operator=(const MatrixBase& other) { + EIGEN_STATIC_ASSERT((ei_is_same_type::ret), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) return ei_assign_selector::run(derived(), other.derived()); } diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h index 86bebe246..18e81ac1c 100644 --- a/Eigen/src/Core/Dot.h +++ b/Eigen/src/Core/Dot.h @@ -266,6 +266,9 @@ MatrixBase::dot(const MatrixBase& other) const EIGEN_STATIC_ASSERT_VECTOR_ONLY(_Nested) EIGEN_STATIC_ASSERT_VECTOR_ONLY(_OtherNested) EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(_Nested,_OtherNested) + EIGEN_STATIC_ASSERT((ei_is_same_type::ret), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + ei_assert(size() == other.size()); return ei_dot_impl<_Nested, _OtherNested>::run(derived(), other.derived()); diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 7df7ac67b..6587ad3e0 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -30,7 +30,7 @@ *** Forward declarations *** ***************************/ -template +template struct ei_product_coeff_impl; template @@ -94,6 +94,7 @@ template struct ei_product_mode || Rhs::MaxColsAtCompileTime >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD ) && (!(Rhs::IsVectorAtCompileTime && (Lhs::Flags&RowMajorBit) && (!(Lhs::Flags&DirectAccessBit)))) && (!(Lhs::IsVectorAtCompileTime && (!(Rhs::Flags&RowMajorBit)) && (!(Rhs::Flags&DirectAccessBit)))) + && (ei_is_same_type::ret) ? CacheFriendlyProduct : NormalProduct }; }; @@ -120,7 +121,7 @@ struct ei_traits > // clean the nested types: typedef typename ei_cleantype::type _LhsNested; typedef typename ei_cleantype::type _RhsNested; - typedef typename _LhsNested::Scalar Scalar; + typedef typename ei_scalar_product_traits::ReturnType Scalar; enum { LhsCoeffReadCost = _LhsNested::CoeffReadCost, @@ -189,7 +190,7 @@ template class Product typedef ei_product_coeff_impl ScalarCoeffImpl; + _LhsNested, _RhsNested, Scalar> ScalarCoeffImpl; public: @@ -312,29 +313,29 @@ MatrixBase::operator*=(const MatrixBase &other) *** Scalar path - no vectorization *** **************************************/ -template -struct ei_product_coeff_impl +template +struct ei_product_coeff_impl { - EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { - ei_product_coeff_impl::run(row, col, lhs, rhs, res); + ei_product_coeff_impl::run(row, col, lhs, rhs, res); res += lhs.coeff(row, Index) * rhs.coeff(Index, col); } }; -template -struct ei_product_coeff_impl +template +struct ei_product_coeff_impl { - EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { res = lhs.coeff(row, 0) * rhs.coeff(0, col); } }; -template -struct ei_product_coeff_impl +template +struct ei_product_coeff_impl { - EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar& res) + EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar& res) { ei_assert(lhs.cols()>0 && "you are using a non initialized matrix"); res = lhs.coeff(row, 0) * rhs.coeff(0, col); @@ -344,10 +345,10 @@ struct ei_product_coeff_impl }; // prevent buggy user code from causing an infinite recursion -template -struct ei_product_coeff_impl +template +struct ei_product_coeff_impl { - EIGEN_STRONG_INLINE static void run(int, int, const Lhs&, const Rhs&, typename Lhs::Scalar&) {} + EIGEN_STRONG_INLINE static void run(int, int, const Lhs&, const Rhs&, RetScalar&) {} }; /******************************************* @@ -374,16 +375,16 @@ struct ei_product_coeff_vectorized_unroller<0, Lhs, Rhs, PacketScalar> } }; -template -struct ei_product_coeff_impl +template +struct ei_product_coeff_impl { typedef typename Lhs::PacketScalar PacketScalar; enum { PacketSize = ei_packet_traits::size }; - EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { PacketScalar pres; ei_product_coeff_vectorized_unroller::run(row, col, lhs, rhs, pres); - ei_product_coeff_impl::run(row, col, lhs, rhs, res); + ei_product_coeff_impl::run(row, col, lhs, rhs, res); res = ei_predux(pres); } }; @@ -438,8 +439,8 @@ struct ei_product_coeff_vectorized_dyn_selector } }; -template -struct ei_product_coeff_impl +template +struct ei_product_coeff_impl { EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4255128ad..051a73e15 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -157,6 +157,7 @@ ei_add_test(meta) ei_add_test(sizeof) ei_add_test(dynalloc) ei_add_test(nomalloc) +ei_add_test(mixingtypes) ei_add_test(packetmath) ei_add_test(basicstuff) ei_add_test(linearstructure) diff --git a/test/mixingtypes.cpp b/test/mixingtypes.cpp new file mode 100644 index 000000000..ddf1c2b4d --- /dev/null +++ b/test/mixingtypes.cpp @@ -0,0 +1,81 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2008 Benoit Jacob +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#define EIGEN_NO_STATIC_ASSERT // turn static asserts into runtime asserts in order to check them +#include "main.h" + + +template void mixingtypes(int size = SizeAtCompileType) +{ + typedef Matrix Mat_f; + typedef Matrix Mat_d; + typedef Matrix, SizeAtCompileType, SizeAtCompileType> Mat_cf; + typedef Matrix, SizeAtCompileType, SizeAtCompileType> Mat_cd; + typedef Matrix Vec_f; + typedef Matrix Vec_d; + typedef Matrix, SizeAtCompileType, 1> Vec_cf; + typedef Matrix, SizeAtCompileType, 1> Vec_cd; + + Mat_f mf(size,size); + Mat_d md(size,size); + Mat_cf mcf(size,size); + Mat_cd mcd(size,size); + Vec_f vf(size,1); + Vec_d vd(size,1); + Vec_cf vcf(size,1); + Vec_cd vcd(size,1); + + mf+mf; + VERIFY_RAISES_ASSERT(mf+md); + VERIFY_RAISES_ASSERT(mf+mcf); + VERIFY_RAISES_ASSERT(vf=vd); + VERIFY_RAISES_ASSERT(vf+=vd); + VERIFY_RAISES_ASSERT(mcd=md); + + mf*mf; + md*mcd; + mcd*md; + mf*vcf; + mcf*vf; + mcf *= mf; + vcd = md*vcd; + vcf = mcf*vf; + VERIFY_RAISES_ASSERT(mf*md); + VERIFY_RAISES_ASSERT(mcf*mcd); + VERIFY_RAISES_ASSERT(mcf*vcd); + VERIFY_RAISES_ASSERT(vcf = mf*vf); + + vf.dot(vf); + VERIFY_RAISES_ASSERT(vd.dot(vf)); + VERIFY_RAISES_ASSERT(vcf.dot(vf)); // yeah eventually we should allow this but i'm too lazy to make that change now in Dot.h +} // especially as that might be rewritten as cwise product .sum() which would make that automatic. + +void test_mixingtypes() +{ + // check that our operator new is indeed called: + CALL_SUBTEST(mixingtypes<3>()); + CALL_SUBTEST(mixingtypes<4>()); + CALL_SUBTEST(mixingtypes(20)); +}