From ee38dbf1e6422b3535606fe97e1e9c1a44d035a6 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Tue, 23 Nov 2010 11:11:40 -0500 Subject: [PATCH] Rework nested<> to be cleaner, see bug #76. --- Eigen/src/Core/util/XprHelper.h | 40 ++++++++++++--------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 7dc52e55d..ea43aa91e 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -308,41 +308,29 @@ struct ref_selector */ template::type> struct nested { - // this is a direct port of the logic used when Dynamic was 33331, to make an atomic commit. - enum { - _ScalarReadCost = NumTraits::Scalar>::ReadCost, - ScalarReadCost = _ScalarReadCost == Dynamic ? 33331 : int(_ScalarReadCost), - _CoeffReadCost = int(traits::CoeffReadCost), - CoeffReadCost = _CoeffReadCost == Dynamic ? 33331 : int(_CoeffReadCost), - N = n == Dynamic ? 33331 : n, - CostEval = (N+1) * int(ScalarReadCost), - CostNoEval = (N-1) * int(CoeffReadCost) - }; - - typedef typename conditional< - ( int(traits::Flags) & EvalBeforeNestingBit ) || - ( int(CostEval) <= int(CostNoEval) ), - PlainObject, - typename ref_selector::type - >::type type; - -/* this is what the above logic should be updated to look like: enum { + // for the purpose of this test, to keep it reasonably simple, we arbitrarily choose a value of Dynamic values. + // the choice of 10000 makes it larger than any practical fixed value and even most dynamic values. + // in extreme cases where these assumptions would be wrong, we would still at worst suffer performance issues + // (poor choice of temporaries). + // it's important that this value can still be squared without integer overflowing. + DynamicAsInteger = 10000, ScalarReadCost = NumTraits::Scalar>::ReadCost, + ScalarReadCostAsInteger = ScalarReadCost == Dynamic ? DynamicAsInteger : ScalarReadCost, CoeffReadCost = traits::CoeffReadCost, - CostEval = n == Dynamic || ScalarReadCost == Dynamic ? int(Dynamic) : (n+1) * int(ScalarReadCost), - CostNoEval = n == Dynamic || (CoeffReadCost == Dynamic && n>1) ? int(Dynamic) : (n-1) * int(CoeffReadCost) + CoeffReadCostAsInteger = CoeffReadCost == Dynamic ? DynamicAsInteger : CoeffReadCost, + NAsInteger = n == Dynamic ? int(DynamicAsInteger) : n, + CostEvalAsInteger = (NAsInteger+1) * ScalarReadCostAsInteger + CoeffReadCostAsInteger, + CostNoEvalAsInteger = NAsInteger * CoeffReadCostAsInteger }; typedef typename conditional< - ( int(traits::Flags) & EvalBeforeNestingBit ) || - ( int(CostNoEval) == Dynamic ? true - : int(CostEval) == Dynamic ? false - : int(CostEval) <= int(CostNoEval) ), + ( (int(traits::Flags) & EvalBeforeNestingBit) || + int(CostEvalAsInteger) < int(CostNoEvalAsInteger) + ), PlainObject, typename ref_selector::type >::type type; -*/ }; template struct are_flags_consistent