00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00031
00032
00033
00034
00035
00036
00037 #ifdef _MSC_VER
00038 # pragma once
00039 # pragma warning( push )
00040 # pragma warning( disable : 4100 4786 )
00041 #endif // _MSC_VER
00042
00043 #ifndef _EXMAT_EXPTMP_H
00044 #define _EXMAT_EXPTMP_H
00045
00046 #include "loki/HierarchyGenerators.h"
00047 #include "Expression.h"
00048 #include "ExpTree.h"
00049 #include "Tag2Exp.h"
00050
00051 #include <iostream>
00052 #include <vector>
00053 #include <deque>
00054
00055 #include "SIMD/SIMDAlignment.h"
00056
00057
00058 namespace exmat {
00059
00061
00065 template<class Con, unsigned int IsFree_>
00066 struct TmpListEntry : public Con {
00067 typedef Con container_type;
00068 enum {
00069 IsFree = IsFree_
00070 };
00071 };
00072
00074
00079 template<class TL, class TC, size_t Index_, size_t TarIndex_>
00080 struct GetTmp {
00081 private:
00082 template<unsigned int Index>
00083 struct DefaultTmp {
00084 typedef typename ::Loki::TL::TypeAt<TTYPENAME TL::tmp_list, Index>::Result return_type;
00085 template<class TmpList> static EXMAT_INLINE2
00086 return_type&
00087 GetTmpAt(::Loki::Tuple<TmpList>& obj, TC& tCon) {
00088 return ::Loki::Field<Index>(obj);
00089 }
00090 };
00091 template<unsigned int Index>
00092 struct TarConTmp {
00093 typedef TC return_type;
00094 template<class TmpList> static EXMAT_INLINE2
00095 return_type&
00096 GetTmpAt(::Loki::Tuple<TmpList>& obj, TC& tCon) {
00097 return tCon;
00098 }
00099 };
00100 public:
00101 typedef typename IF<
00102 (Index_ == TarIndex_),
00103 TarConTmp<Index_>,
00104 DefaultTmp<Index_>
00105 >::RET RET;
00106 };
00107
00109
00112 template<class TmpList, int Index>
00113 class ReleaseTmpAt {
00114 struct NullT{
00115 typedef ::Loki::NullType container_type;
00116 };
00117 typedef typename ::Loki::TL::TypeAtNonStrict<TmpList, (unsigned int)Index, NullT>::Result TA;
00118 typedef typename TA::container_type container_type;
00119 typedef TmpListEntry<container_type, true> FreeT;
00120 public:
00121 typedef typename ::Loki::TL::ReplaceAt<TmpList, Index, FreeT>::Result RET;
00122 };
00123
00125
00129 template<class DyTmpCon>
00130 struct DynamicTmpList {
00131 EXMAT_INLINE1 DynamicTmpList() {
00132
00133 ConList.reserve(10);
00134 AvlList.reserve(10);
00135 FreeList.reserve(10);
00136 }
00138
00139 EXMAT_INLINE1 DyTmpCon& CastToCon() {
00140 size_t i;
00141 if(AccessQue.size() >= 3) {
00142 i = AccessQue.front();
00143 AccessQue.pop_front();
00144 AccessQue.push_back(i);
00145 }
00146 i = AccessQue.front();
00147 AccessQue.pop_front();
00148 FreeList.push_back(i);
00149
00150
00151 return ConList[i];
00152 }
00153 EXMAT_INLINE2 operator DyTmpCon&() {
00154 return CastToCon();
00155 }
00156 EXMAT_INLINE2 operator const DyTmpCon&() {
00157 return CastToCon();
00158 }
00160
00161 template<class Exp> EXMAT_INLINE2
00162 DyTmpCon& AssignNoAna(const Exp& A) {
00163 return (this->assign(A));
00164 }
00165
00166 template<class Exp> EXMAT_INLINE1
00167 DynamicTmpList<DyTmpCon>& operator=(const Exp& A) {
00168 this->assign(A);
00169 return *this;
00170 }
00171
00172
00173 template<class Exp> EXMAT_INLINE2
00174 DyTmpCon& assign(const Exp& A) {
00175 int idx = -1;
00176 size_t i;
00177
00178 for(i=0; i<ConList.size(); ++i) {
00179 if(!AvlList[i] || ConList[i].rows() != A.rows() || ConList[i].cols() != A.cols())
00180 continue;
00181 ConList[i] = A;
00182
00183 AvlList[i] = false;
00184 AccessQue.push_back(i);
00185 idx = int(i);
00186 break;
00187 }
00188
00189 if(idx == -1) {
00190 AccessQue.push_back(ConList.size());
00191 idx = ConList.size();
00192 ConList.push_back(DyTmpCon(A));
00193 AvlList.push_back(false);
00194
00195 }
00196
00197
00198 for(i=0; i<FreeList.size(); ++i)
00199 AvlList[FreeList[i]] = true;
00200 FreeList.clear();
00201
00202 return ConList[idx];
00203 }
00204
00205 void print() {
00206 int i;
00207 for(i=0; i<AvlList.size(); ++i)
00208 std::cout << AvlList[i] << ", ";
00209 std::cout << std::endl;
00210 for(i=0; i<AccessQue.size(); ++i)
00211 std::cout << AccessQue[i] << ", ";
00212 std::cout << std::endl;
00213 for(i=0; i<FreeList.size(); ++i)
00214 std::cout << FreeList[i] << ", ";
00215 std::cout << std::endl;
00216 std::cout << std::endl;
00217 }
00218 std::vector<DyTmpCon> ConList;
00219 std::vector<bool> AvlList;
00220 std::deque<size_t> AccessQue;
00221 std::vector<size_t> FreeList;
00222 };
00223
00224 namespace PNS {
00226
00231 template<class TList>
00232 struct ReplaceTmp
00233 {
00234 private:
00235 typedef typename TList::Head Head;
00236 typedef typename TList::Tail Tail;
00237
00238 typedef typename Head::container_type container_type;
00239 enum {
00240 IsStaticRow = (container_type::ROWS > 0),
00241 IsStaticCol = (container_type::COLS > 0),
00242 IsLeftRowVec = (container_type::ROWS == 1),
00243 IsLeftColVec = (container_type::COLS == 1)
00244 };
00245 typedef typename IF<
00246 !IsStaticRow || !IsStaticCol,
00247 DynamicTmpList<container_type>,
00248 container_type
00249 >::RET replacing_type;
00250 public:
00252 typedef Loki::Typelist<replacing_type, typename ReplaceTmp<Tail>::Result> Result;
00253 };
00254
00256 template <>
00257 struct ReplaceTmp<Loki::NullType> {
00259 typedef Loki::NullType Result;
00260 };
00261 };
00262
00263
00265
00268 template<class TmpList>
00269 struct TmpInstance : public ::Loki::Tuple<TmpList> {
00270 typedef TmpList tmp_list;
00271 EXMAT_INLINE2 TmpInstance() {}
00272 };
00273
00274
00275
00276 template<class Exp, class TmpList, class TarConType, class ForceUseTmp,
00277 int IsRootNode=false, bool NeedTmp_=false>
00278 struct TmpAnalyserUnaNode;
00279 template<class Exp, class TmpList, class TarConType, class ForceUseTmp,
00280 int IsRootNode=false, bool NeedTmp_=false>
00281 struct TmpAnalyserBinNode;
00282
00283
00285
00289 template<class Exp_, class TmpList, class TarConType, class ForceUseTmp, int IsRootNode, bool NeedTmp_>
00290 struct TmpAnalyserUnaNode {
00291 typedef Exp_ Exp;
00292 enum {
00294 IsCBin = IsDerivedFrom<typename Exp::super_type,BinExpTag>::RET,
00296 IsCUna = IsDerivedFrom<typename Exp::super_type,UnaExpTag>::RET,
00298 IsCLeaf = (!IsCBin && !IsCUna),
00300 CNeedTmp = false,
00302 IsDynamicTmp = (Exp::ROWS == 0) || (Exp::COLS == 0),
00303 IsTarConDynamic = (TarConType::ROWS == 0 || TarConType::COLS == 0)
00304 };
00305
00306 typedef typename Exp::exp_tag exp_tag;
00308 typedef typename IF<
00309 IsRootNode == int(true),
00310 TarConType,
00311 TTYPENAME Exp::temp_type
00312 >::RET temp_type;
00313
00314 private:
00315 typedef TmpListEntry<temp_type, true> E1;
00316 typedef typename IF<
00317 IsDynamicTmp,
00318 TmpListEntry<temp_type, true>,
00319 TmpListEntry<temp_type, false>
00320 >::RET E2;
00321 public:
00322
00324 typedef typename IF<
00325 IsCLeaf,
00326 LeafeNode<typename Exp::super_type>,
00327 typename IF<
00328 IsCUna,
00329 TmpAnalyserUnaNode<typename Exp::super_type, TmpList, TarConType, ForceUseTmp>,
00330 TmpAnalyserBinNode<typename Exp::super_type, TmpList, TarConType, ForceUseTmp>
00331 >::RET>::RET child;
00332
00333 private:
00334 typedef typename IF<
00335 IsCLeaf,
00336 TmpList,
00337 typename IF<
00338 IsCUna,
00339 TTYPENAME child::tmp_list,
00340 TTYPENAME child::tmp_list
00341 >::RET>::RET cTL;
00342 public:
00343
00347 typedef typename IF<
00348 NeedTmp_,
00349 temp_type,
00350 Mat<
00351 #if (HAVE_TT_PARAMETER)
00352 TTYPENAME RefillUnaExp<TTYPENAME Exp::rep_type,
00353 #else
00354 TTYPENAME Tag2UnaExp<exp_tag,
00355 #endif
00356 TTYPENAME child::node_exp::rep_type,
00357 TTYPENAME Exp::extra_param_type
00358 >::RET,
00359 EmptyErrorChecker
00360 >
00361 >::RET node_exp;
00362
00363 private:
00364
00365 enum {
00367 PreTmpIndex = ::Loki::TL::IndexOf<cTL, E1>::value
00368 };
00369 typedef typename IF<
00370 PreTmpIndex == -1,
00371
00372 typename ::Loki::TL::Append<cTL, E2>::Result,
00373
00374 typename ::Loki::TL::ReplaceAt<cTL, PreTmpIndex, E2>::Result
00375 >::RET PreRed_list;
00376 public:
00377
00378 enum {
00379 CTmpIndex = child::TmpIndex,
00380 TmpIndex =
00381 IsRootNode && IsTarConDynamic ?
00382 0 :
00383 !NeedTmp_ && !IsRootNode?
00384 -1 : (
00385
00386 (PreTmpIndex == -1) ?
00387
00388 ::Loki::TL::Length<PreRed_list>::value-1 :
00389
00390 PreTmpIndex
00391 )
00392 };
00393
00394 private:
00395
00396 typedef typename ReleaseTmpAt<PreRed_list, CTmpIndex>::RET CRed_list;
00397 public:
00398
00400 typedef typename IF<
00401 NeedTmp_, CRed_list, cTL
00402 >::RET tmp_list;
00403
00404
00406 template<class Tag> static void print(Tag) {
00407 child::print(TTYPENAME child::exp_tag());
00408 std::cout << Tag::name() << ", to index: " << TmpIndex << std::endl;
00409 }
00410
00412
00416
00417 template<class TInst, class TargetCon, class TarConIndex> EXMAT_INLINE2
00418 static const node_exp& getNodeObj(const Exp& exp, TInst& tmpInst,
00419 TargetCon& tCon, Int2Type<0+2*1>, TarConIndex)
00420 {
00421 enum {
00422 TIdx = TarConIndex::RET
00423 };
00424 typedef Mat<
00425 #if (HAVE_TT_PARAMETER)
00426 TTYPENAME RefillUnaExp<TTYPENAME Exp::rep_type,
00427 #else
00428 TTYPENAME Tag2UnaExp<exp_tag,
00429 #endif
00430 TTYPENAME child::node_exp::rep_type,
00431 TTYPENAME Exp::extra_param_type
00432 >::RET,
00433 EmptyErrorChecker
00434 > expT;
00435 typedef typename GetTmp<TInst, TargetCon, TmpIndex, TIdx>::RET GT;
00436 typedef typename GT::return_type RT;
00437
00438
00439 return *((const node_exp*)(&
00440 GT::GetTmpAt(tmpInst, tCon).AssignNoAna(expT(
00441 exp,
00442 child::getNodeObj(
00443 *((const typename child::Exp*)(&exp.rep)),
00444 tmpInst, tCon,
00445 Int2Type<IsCLeaf+2*CNeedTmp>(), TarConIndex())
00446 ))
00447 ));
00448 }
00449
00450 template<class TInst, class TargetCon, class TarConIndex> EXMAT_INLINE2
00451 static const node_exp getNodeObj(const Exp& exp, TInst& tmpInst,
00452 TargetCon& tCon, Int2Type<0+2*0>, TarConIndex)
00453 {
00454 return node_exp(
00455 exp,
00456 child::getNodeObj(
00457 *((const typename child::Exp*)(&exp.rep)),
00458 tmpInst, tCon,
00459 Int2Type<IsCLeaf+2*CNeedTmp>(), TarConIndex())
00460 );
00461 }
00463
00465 template<class TInst, class TargetCon, class TarConIndex> EXMAT_INLINE2
00466 static void ass_root(const Exp& exp, TInst& tmpInst,
00467 TargetCon& tCon, TarConIndex)
00468 {
00469 tCon.AssignNoAna(
00470 getNodeObj(exp, tmpInst, tCon, Int2Type<0+2*0>(), TarConIndex())
00471 );
00472 }
00473 };
00474
00475
00477
00481 template<class Exp_, class TmpList, class TarConType, class ForceUseTmp, int IsRootNode, bool NeedTmp_>
00482 struct TmpAnalyserBinNode {
00483 typedef Exp_ Exp;
00484 enum {
00486 Forced = ForceUseTmp::RET,
00488 IsLinearExp = Exp::IsLinear,
00489 IsLLinear = Exp::left_type::IsLinear,
00490 IsRLinear = Exp::right_type::IsLinear,
00491 IsSIMDExp = IsDerivedFrom<Exp,SIMDTag>::RET,
00492 IsLCon = (Exp::left_type::EXPLevel == 0),
00493 IsRCon = (Exp::right_type::EXPLevel == 0),
00495 IsLBin = IsDerivedFrom<typename Exp::left_type,BinExpTag>::RET,
00497 IsRBin = IsDerivedFrom<typename Exp::right_type,BinExpTag>::RET,
00499 IsLUna = IsDerivedFrom<typename Exp::left_type,UnaExpTag>::RET,
00501 IsRUna = IsDerivedFrom<typename Exp::right_type,UnaExpTag>::RET,
00502 IsLSIMD = IsDerivedFrom<typename Exp::left_type,SIMDTag>::RET,
00503 IsRSIMD = IsDerivedFrom<typename Exp::right_type,SIMDTag>::RET,
00505 LNeedTmp =
00506 Forced ? IsLBin : (
00507 (!IsLinearExp && Exp::COLS!=1) ||
00508 (IsSIMDExp && !IsLinearExp) || (IsLSIMD && !IsLLinear)
00509 ) && (!IsLCon),
00511 RNeedTmp =
00512 Forced ? IsRBin : (
00513 (!IsLinearExp) ||
00514 (IsSIMDExp && !IsLinearExp) || (IsRSIMD && !IsRLinear)
00515 ) && (!IsRCon),
00517 IsLLeaf =
00518 Forced ? IsLCon :
00519 (Exp::left_type::IsLinearRecursive && !LNeedTmp) || (!IsLUna && !IsLBin),
00521 IsRLeaf =
00522 Forced ? IsRCon :
00523 (Exp::right_type::IsLinearRecursive && !RNeedTmp) || (!IsRUna && !IsRBin),
00525 IsDynamicTmp = (Exp::ROWS == 0) || (Exp::COLS == 0),
00526 IsTarConDynamic = (TarConType::ROWS == 0 || TarConType::COLS == 0)
00527 };
00528
00529 typedef typename Exp::exp_tag exp_tag;
00531 typedef typename IF<
00532 IsRootNode == int(true),
00533 TarConType,
00534 TTYPENAME Exp::temp_type
00535 >::RET temp_type;
00536
00537 private:
00538 typedef TmpListEntry<temp_type, true> E1;
00539 typedef typename IF<
00540 IsDynamicTmp,
00541 TmpListEntry<temp_type, true>,
00542 TmpListEntry<temp_type, false>
00543 >::RET E2;
00544 public:
00545
00547 typedef typename IF<
00548 IsLLeaf,
00549 LeafeNode<typename Exp::left_type>,
00550 typename IF<
00551 IsLUna,
00552 TmpAnalyserUnaNode<typename Exp::left_type, TmpList, TarConType, ForceUseTmp, false, LNeedTmp>,
00553 TmpAnalyserBinNode<typename Exp::left_type, TmpList, TarConType, ForceUseTmp, false, LNeedTmp>
00554 >::RET>::RET left_child;
00555
00556 private:
00557 typedef typename IF<
00558 IsLLeaf,
00559 TmpList,
00560 typename IF<
00561 IsLUna,
00562 TTYPENAME left_child::tmp_list,
00563 TTYPENAME left_child::tmp_list
00564 >::RET>::RET lTL;
00565 public:
00566
00568 typedef typename IF<
00569 IsRLeaf,
00570 LeafeNode<typename Exp::right_type>,
00571 typename IF<
00572 IsRUna,
00573 TmpAnalyserUnaNode<typename Exp::right_type, lTL, TarConType, ForceUseTmp, false, RNeedTmp>,
00574 TmpAnalyserBinNode<typename Exp::right_type, lTL, TarConType, ForceUseTmp, false, RNeedTmp>
00575 >::RET>::RET right_child;
00576
00577 private:
00578 typedef typename IF<
00579 IsRLeaf,
00580 lTL,
00581 typename IF<
00582 IsRUna,
00583 TTYPENAME right_child::tmp_list,
00584 TTYPENAME right_child::tmp_list
00585 >::RET>::RET rTL;
00586 public:
00587
00591 typedef typename IF<
00592 NeedTmp_,
00593 temp_type,
00594 Mat<
00595 #if (HAVE_TT_PARAMETER)
00596 TTYPENAME RefillBinExp<TTYPENAME Exp::rep_type,
00597 #else
00598 TTYPENAME Tag2BinExp<exp_tag,
00599 #endif
00600 TTYPENAME left_child::node_exp::rep_type,
00601 TTYPENAME right_child::node_exp::rep_type>::RET,
00602 EmptyErrorChecker
00603 >
00604 >::RET node_exp;
00605
00606 private:
00607
00608 enum {
00610 PreTmpIndex = ::Loki::TL::IndexOf<rTL, E1>::value
00611 };
00612 typedef typename IF<
00613 PreTmpIndex == -1,
00614
00615 typename ::Loki::TL::Append<rTL, E2>::Result,
00616
00617 typename ::Loki::TL::ReplaceAt<rTL, PreTmpIndex, E2>::Result
00618 >::RET PreRed_list;
00619 public:
00620
00621 enum {
00622 LTmpIndex = left_child::TmpIndex,
00623 RTmpIndex = right_child::TmpIndex,
00624 TmpIndex =
00625 IsRootNode && IsTarConDynamic ?
00626 0 :
00627 !NeedTmp_ && !IsRootNode ?
00628 -1 : (
00629
00630 (PreTmpIndex == -1) ?
00631
00632 ::Loki::TL::Length<PreRed_list>::value-1 :
00633
00634 PreTmpIndex
00635 )
00636 };
00637
00638 private:
00639
00640 typedef typename ReleaseTmpAt<PreRed_list, LTmpIndex>::RET LRed_list;
00641
00642 typedef typename ReleaseTmpAt<LRed_list, RTmpIndex>::RET RRed_list;
00643 public:
00644
00646 typedef typename IF<
00647 NeedTmp_, RRed_list, rTL
00648 >::RET tmp_list;
00649
00650
00652 template<class Tag> static void print(Tag) {
00653 left_child::print(TTYPENAME left_child::exp_tag());
00654 right_child::print(TTYPENAME right_child::exp_tag());
00655 std::cout << Tag::name() << ", to index: " << TmpIndex << std::endl;
00656 std::cout << "LNeedTmp: " << LNeedTmp << "\n";
00657 std::cout << "RNeedTmp: " << RNeedTmp << "\n";
00658 std::cout << "IsLLeaf: " << IsLLeaf << "\n";
00659 std::cout << "IsRLeaf: " << IsRLeaf << "\n";
00660
00661 }
00662
00664
00668
00669 template<class TInst, class TargetCon, class TarConIndex> EXMAT_INLINE2
00670 static const node_exp& getNodeObj(const Exp& exp, TInst& tmpInst,
00671 TargetCon& tCon, Int2Type<0+2*1>, TarConIndex)
00672 {
00673 enum {
00674 TIdx = TarConIndex::RET
00675 };
00676 typedef Mat<
00677 #if (HAVE_TT_PARAMETER)
00678 TTYPENAME RefillBinExp<TTYPENAME Exp::rep_type,
00679 #else
00680 TTYPENAME Tag2BinExp<exp_tag,
00681 #endif
00682 TTYPENAME left_child::node_exp::rep_type,
00683 TTYPENAME right_child::node_exp::rep_type>::RET,
00684 EmptyErrorChecker
00685 > expT;
00686 typedef typename GetTmp<TInst, TargetCon, TmpIndex, TIdx>::RET GT;
00687
00688 const typename left_child::node_exp& ln =
00689 left_child::getNodeObj(
00690
00691
00692 *((const typename left_child::Exp*)(&exp.leftOp)),
00693 tmpInst, tCon,
00694 Int2Type<IsLLeaf+2*LNeedTmp>(), TarConIndex());
00695
00696
00697
00698 return *((const node_exp*)(&
00699 GT::GetTmpAt(tmpInst, tCon).AssignNoAna(expT(
00700 ln,
00701 right_child::getNodeObj(
00702 *((const typename right_child::Exp*)(&exp.rightOp)),
00703 tmpInst, tCon,
00704 Int2Type<IsRLeaf+2*RNeedTmp>(), TarConIndex()
00705 )
00706 ))
00707 ));
00708 }
00710 template<class TInst, class TargetCon, class TarConIndex> EXMAT_INLINE2
00711 static const node_exp getNodeObj(const Exp& exp, TInst& tmpInst,
00712 TargetCon& tCon, Int2Type<0+2*0>, TarConIndex)
00713 {
00714
00715 const typename left_child::node_exp& ln =
00716 left_child::getNodeObj(
00717 *((const typename left_child::Exp*)(&exp.leftOp)),
00718 tmpInst, tCon,
00719 Int2Type<IsLLeaf+2*LNeedTmp>(), TarConIndex());
00720 return node_exp(
00721 ln,
00722 right_child::getNodeObj(
00723 *((const typename right_child::Exp*)(&exp.rightOp)),
00724 tmpInst, tCon,
00725 Int2Type<IsRLeaf+2*RNeedTmp>(), TarConIndex()
00726 )
00727 );
00728 }
00730
00732 template<class TInst, class TargetCon, class TarConIndex> EXMAT_INLINE2
00733 static void ass_root(const Exp& exp, TInst& tmpInst,
00734 TargetCon& tCon, TarConIndex)
00735 {
00736 tCon.AssignNoAna(
00737 getNodeObj(exp, tmpInst, tCon, Int2Type<0+2*0>(), TarConIndex())
00738 );
00739 }
00740 };
00741
00745
00746 template<class Exp, class Con, class ErrChk1, class ErrChk2, class ForceUseTmp> EXMAT_INLINE2
00747 static void parseExp_inner(Mat<Con, ErrChk1>& mat,
00748 const Mat<Exp, ErrChk2>& exp, Int2Type<1+2*0>, ForceUseTmp) {
00749 typedef Mat<Con, ErrChk1> TarConType;
00750 enum {
00751
00752 TargetIndex = TmpAnalyserUnaNode<Exp, Loki::NullType, TarConType, ForceUseTmp, true>::TmpIndex,
00753
00754 IsTarConDynamic =
00755 (Con::ROWS == 0 || Con::COLS == 0)
00756 };
00757
00758 typedef TmpListEntry<Mat<Con, EmptyErrorChecker>, false> UnAvailableTarCon;
00759
00760
00761
00762 typedef typename IF<
00763 IsTarConDynamic,
00764 LOKI_TYPELIST_1(UnAvailableTarCon),
00765 Loki::NullType
00766 >::RET tmplist;
00767
00768 typedef typename exmat::PNS::ReplaceTmp<
00769 TTYPENAME TmpAnalyserUnaNode<Exp, tmplist, TarConType, ForceUseTmp, true>::tmp_list
00770 >::Result ReplacedTList;
00771
00772 TmpInstance<ReplacedTList> tmpInstance;
00773
00774
00775 TmpAnalyserUnaNode<Exp, tmplist, TarConType, ForceUseTmp, true>::
00776 ass_root(exp, tmpInstance, mat, Int2Type<TargetIndex>());
00777 }
00778
00780 template<class Exp, class Con, class ErrChk1, class ErrChk2, class ForceUseTmp> EXMAT_INLINE2
00781 static void parseExp_inner(Mat<Con, ErrChk1>& mat,
00782 const Mat<Exp, ErrChk2>& exp, Int2Type<0+2*1>, ForceUseTmp)
00783 {
00784 typedef Mat<Con, ErrChk1> TarConType;
00785 enum {
00786
00787 TargetIndex = TmpAnalyserBinNode<Exp, Loki::NullType, TarConType, ForceUseTmp, true>::TmpIndex,
00788
00789 IsTarConDynamic =
00790 (Con::ROWS == 0 || Con::COLS == 0)
00791 };
00792
00793 typedef TmpListEntry<Mat<Con, EmptyErrorChecker>, false> UnAvailableTarCon;
00794
00795
00796
00797 typedef typename IF<
00798 IsTarConDynamic,
00799 LOKI_TYPELIST_1(UnAvailableTarCon),
00800 Loki::NullType
00801 >::RET tmplist;
00802
00803 typedef typename exmat::PNS::ReplaceTmp<
00804 TTYPENAME TmpAnalyserBinNode<Exp, tmplist, TarConType, ForceUseTmp, true>::tmp_list
00805 >::Result ReplacedTList;
00806
00807 EXMAT_VAR_ALIGN(TmpInstance<ReplacedTList> tmpInstance, EXMAT_SIMD_DEFAULT_ALIGN);
00808
00809
00810 TmpAnalyserBinNode<Exp, tmplist, TarConType, ForceUseTmp, true>::
00811 ass_root(exp, tmpInstance, mat, Int2Type<TargetIndex>());
00812 }
00813
00815 template<class Exp, class Con, class ErrChk1, class ErrChk2, class ForceUseTmp> EXMAT_INLINE2
00816 static void parseExp_inner(Mat<Con, ErrChk1>& mat,
00817 const Mat<Exp, ErrChk2>& exp, Int2Type<0+2*0>, ForceUseTmp)
00818 {
00819 mat.AssignNoAna(exp);
00820 }
00822
00823
00825 template<class Exp, class Con, class ErrChk1, class ErrChk2> EXMAT_INLINE2
00826 static void parseExp(Mat<Con, ErrChk1>& mat, const Mat<Exp, ErrChk2>& exp) {
00827 enum {
00828 IsUna = IsDerivedFrom<Exp,UnaExpTag>::RET,
00829 IsBin = IsDerivedFrom<Exp,BinExpTag>::RET,
00830
00831 IsLinear = Exp::IsLinearRecursive,
00832
00833
00834 ForceUseTmp = false
00835 };
00836 parseExp_inner(mat, exp,
00837 Int2Type<
00838 (IsLinear && !ForceUseTmp) ? 0 :
00839 (IsUna+2*IsBin)
00840 >(),
00841 Int2Type<ForceUseTmp>()
00842 );
00843 }
00844
00845 }
00846
00847 #if _MSC_VER
00848 # pragma warning( pop )
00849 #endif // EXMAT_VC
00850
00851 #endif // _EXMAT_EXPTMP_H