00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030 #ifdef _MSC_VER
00031 # pragma once
00032 # pragma warning( push )
00033 # pragma warning( disable : 4786 )
00034 #endif // _MSC_VER
00035
00036 #ifndef _EXMAT_ALIAS_ANALYSER_H
00037 #define _EXMAT_ALIAS_ANALYSER_H
00038
00039 #include "ExpTree.h"
00040
00041 namespace exmat {
00042 namespace PNS {
00043
00045 template<class Exp>
00046 class GetAliasTmpType {
00047 enum {
00048 IsUnaExp = IsDerivedFrom<Exp,UnaExpTag>::RET,
00049 IsBinExp = IsDerivedFrom<Exp,BinExpTag>::RET,
00050 IsView = IsDerivedFrom<Exp,ViewTag>::RET,
00051 IsCon = !IsBinExp && !IsView
00052 };
00053 template<class Exp_>
00054 struct Identity {
00055 typedef Exp_ RET;
00056 };
00057 template<class Exp_>
00058 struct TmpHelper {
00059 typedef typename Exp_::temp_type RET;
00060 };
00061 typedef typename IF<
00062 IsCon,
00063 Identity<Exp>,
00064 TmpHelper<Exp>
00065 >::RET PreRET;
00066 public:
00067 typedef typename PreRET::RET RET;
00068 };
00069
00071 template<class Exp>
00072 struct AliasAnalyser {
00073 enum {
00074 IsUnaExp = IsDerivedFrom<Exp,UnaExpTag>::RET,
00075 IsBinExp = IsDerivedFrom<Exp,BinExpTag>::RET,
00076 IsView = IsDerivedFrom<Exp,ViewTag>::RET,
00077 IsCon = !IsBinExp && !IsView
00078 };
00079
00081 template<class T>
00082 struct Helper {
00083 typedef T left_type;
00084 typedef T right_type;
00085 typedef T inner_rep_type;
00086 };
00087
00088 typedef typename IF<
00089 IsBinExp, Exp, Helper<Exp>
00090 >::RET exp_type;
00091
00092 typedef typename IF<
00093 IsView, Exp, Helper<Exp>
00094 >::RET view_type;
00095
00096 enum {
00098 IsLBinExpNode = IsDerivedFrom<typename exp_type::left_type,BinExpTag>::RET,
00100 IsRBinExpNode = IsDerivedFrom<typename exp_type::right_type,BinExpTag>::RET,
00102 IsLViewNode = IsDerivedFrom<typename exp_type::left_type,ViewTag>::RET,
00104 IsRViewNode = IsDerivedFrom<typename exp_type::right_type,ViewTag>::RET,
00106 IsLConNode = (!IsLBinExpNode && !IsLViewNode),
00108 IsRConNode = (!IsRBinExpNode && !IsRViewNode),
00110 IsViewConNode =
00111 !IsDerivedFrom<typename view_type::inner_rep_type,ViewTag>::RET &&
00112 !IsDerivedFrom<typename view_type::inner_rep_type,BinExpTag>::RET
00113 };
00114
00116 template<class LType> EXMAT_INLINE2 static bool
00117 IsAliased(LType& l, const Exp& exp, const Int2Type<true>&, const bool IsNodePathLinear)
00118 {
00119 typedef typename exp_type::left_type lt;
00120 typedef typename exp_type::right_type rt;
00121
00122 typedef typename IF<
00123 IsLConNode, LeafeNode<NullTag>, AliasAnalyser<lt>
00124 >::RET left_child;
00125 typedef typename IF<
00126 IsRConNode, LeafeNode<NullTag>, AliasAnalyser<rt>
00127 >::RET right_child;
00128
00129 const bool LNP = IsNodePathLinear && exp_type::IsLinear;
00130 const bool la = left_child::IsAliased(l, exp.leftOp, LNP);
00131 const bool ra = right_child::IsAliased(l, exp.rightOp, LNP);
00132 return la || ra;
00133 }
00134
00136 template<class LType> EXMAT_INLINE2 static bool
00137 IsAliased(LType& l, const Exp& exp, const Int2Type<false>&, const bool IsNodePathLinear)
00138 {
00139 typedef typename view_type::inner_rep_type vt;
00140 typedef typename IF<
00141 IsViewConNode, LeafeNode<NullTag>, AliasAnalyser<vt>
00142 >::RET child;
00143
00144 const bool LNP = IsNodePathLinear && Exp::IsLinear;
00145 return child::IsAliased(l, exp.rep, LNP);
00146 }
00147
00148 template<class LType, class RType> EXMAT_INLINE2
00149 static bool IsAliased(LType& l, const RType& exp, const bool IsNodePathLinear=true) {
00150 return IsAliased(l, exp, Int2Type<IsBinExp>(), IsNodePathLinear);
00151 }
00152
00153 };
00154
00157 template<class LT, class RT> EXMAT_INLINE2
00158 bool IsAliased_Helper(LT& l, const RT& r, const Int2Type<true>& isCon) {
00159 return false;
00160 }
00161
00163 template<class LT, class RT> EXMAT_INLINE2
00164 bool IsAliased_Helper(LT& l, const RT& r, const Int2Type<false>& isCon) {
00165 return AliasAnalyser<RT>::IsAliased(l, r);
00166 }
00167
00168 template<class LT, class RT> EXMAT_INLINE2
00169 bool IsAliased(LT& l, const RT& r) {
00170
00171
00172 if(IsDerivedFrom<LT,ViewTag>::RET && !LT::IsLinearRecursive)
00173 return true;
00174 enum {
00175 IsBinExp = IsDerivedFrom<RT,BinExpTag>::RET,
00176 IsView = IsDerivedFrom<RT,ViewTag>::RET,
00177 IsCon = (!IsBinExp && ! IsView),
00178
00179 NoNeedAnalysis = IsCon || (LT::IsLinearRecursive && RT::IsLinearRecursive)
00180 };
00181 return IsAliased_Helper(l, r, Int2Type<NoNeedAnalysis>());
00182 }
00183
00184 }
00185 }
00186
00187 #if _MSC_VER
00188 # pragma warning( pop )
00189 #endif // EXMAT_VC
00190
00191 #endif // _EXMAT_ALIAS_ANALYSER_H