unwrap.hpp 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222
  1. // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
  2. // Copyright 2008-2016 National ICT Australia (NICTA)
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // ------------------------------------------------------------------------
  15. //! \addtogroup unwrap
  16. //! @{
  17. // TODO: document the conditions and restrictions for the use of each unwrap variant:
  18. // TODO: unwrap, unwrap_check, quasi_unwrap, partial_unwrap, partial_unwrap_check
  19. template<typename T1>
  20. struct unwrap_default
  21. {
  22. typedef typename T1::elem_type eT;
  23. typedef Mat<eT> stored_type;
  24. inline
  25. unwrap_default(const T1& A)
  26. : M(A)
  27. {
  28. arma_extra_debug_sigprint();
  29. }
  30. const Mat<eT> M;
  31. };
  32. template<typename T1>
  33. struct unwrap_fixed
  34. {
  35. typedef T1 stored_type;
  36. inline explicit
  37. unwrap_fixed(const T1& A)
  38. : M(A)
  39. {
  40. arma_extra_debug_sigprint();
  41. }
  42. const T1& M;
  43. };
  44. template<typename T1, bool condition>
  45. struct unwrap_redirect {};
  46. template<typename T1>
  47. struct unwrap_redirect<T1, false> { typedef unwrap_default<T1> result; };
  48. template<typename T1>
  49. struct unwrap_redirect<T1, true> { typedef unwrap_fixed<T1> result; };
  50. template<typename T1>
  51. struct unwrap : public unwrap_redirect<T1, is_Mat_fixed<T1>::value >::result
  52. {
  53. inline
  54. unwrap(const T1& A)
  55. : unwrap_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
  56. {
  57. }
  58. };
  59. template<typename eT>
  60. struct unwrap< Mat<eT> >
  61. {
  62. typedef Mat<eT> stored_type;
  63. inline
  64. unwrap(const Mat<eT>& A)
  65. : M(A)
  66. {
  67. arma_extra_debug_sigprint();
  68. }
  69. const Mat<eT>& M;
  70. };
  71. template<typename eT>
  72. struct unwrap< Row<eT> >
  73. {
  74. typedef Row<eT> stored_type;
  75. inline
  76. unwrap(const Row<eT>& A)
  77. : M(A)
  78. {
  79. arma_extra_debug_sigprint();
  80. }
  81. const Row<eT>& M;
  82. };
  83. template<typename eT>
  84. struct unwrap< Col<eT> >
  85. {
  86. typedef Col<eT> stored_type;
  87. inline
  88. unwrap(const Col<eT>& A)
  89. : M(A)
  90. {
  91. arma_extra_debug_sigprint();
  92. }
  93. const Col<eT>& M;
  94. };
  95. template<typename out_eT, typename T1, typename T2, typename glue_type>
  96. struct unwrap< mtGlue<out_eT, T1, T2, glue_type> >
  97. {
  98. typedef Mat<out_eT> stored_type;
  99. inline
  100. unwrap(const mtGlue<out_eT, T1, T2, glue_type>& A)
  101. : M(A)
  102. {
  103. arma_extra_debug_sigprint();
  104. }
  105. const Mat<out_eT> M;
  106. };
  107. template<typename out_eT, typename T1, typename op_type>
  108. struct unwrap< mtOp<out_eT, T1, op_type> >
  109. {
  110. typedef Mat<out_eT> stored_type;
  111. inline
  112. unwrap(const mtOp<out_eT, T1, op_type>& A)
  113. : M(A)
  114. {
  115. arma_extra_debug_sigprint();
  116. }
  117. const Mat<out_eT> M;
  118. };
  119. //
  120. //
  121. //
  122. template<typename T1>
  123. struct quasi_unwrap_default
  124. {
  125. typedef typename T1::elem_type eT;
  126. inline
  127. quasi_unwrap_default(const T1& A)
  128. : M(A)
  129. {
  130. arma_extra_debug_sigprint();
  131. }
  132. // NOTE: DO NOT DIRECTLY CHECK FOR ALIASING BY TAKING THE ADDRESS OF THE "M" OBJECT IN ANY quasi_unwrap CLASS !!!
  133. Mat<eT> M;
  134. static const bool is_const = false;
  135. static const bool has_subview = false;
  136. static const bool has_orig_mem = false;
  137. template<typename eT2>
  138. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  139. };
  140. template<typename T1>
  141. struct quasi_unwrap_fixed
  142. {
  143. typedef typename T1::elem_type eT;
  144. inline explicit
  145. quasi_unwrap_fixed(const T1& A)
  146. : M(A)
  147. {
  148. arma_extra_debug_sigprint();
  149. }
  150. const T1& M;
  151. static const bool is_const = true;
  152. static const bool has_subview = false;
  153. static const bool has_orig_mem = true;
  154. template<typename eT2>
  155. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); }
  156. };
  157. template<typename T1, bool condition>
  158. struct quasi_unwrap_redirect {};
  159. template<typename T1>
  160. struct quasi_unwrap_redirect<T1, false> { typedef quasi_unwrap_default<T1> result; };
  161. template<typename T1>
  162. struct quasi_unwrap_redirect<T1, true> { typedef quasi_unwrap_fixed<T1> result; };
  163. template<typename T1>
  164. struct quasi_unwrap : public quasi_unwrap_redirect<T1, is_Mat_fixed<T1>::value >::result
  165. {
  166. typedef typename quasi_unwrap_redirect<T1, is_Mat_fixed<T1>::value >::result quasi_unwrap_extra;
  167. inline
  168. quasi_unwrap(const T1& A)
  169. : quasi_unwrap_extra(A)
  170. {
  171. }
  172. static const bool is_const = quasi_unwrap_extra::is_const;
  173. static const bool has_subview = quasi_unwrap_extra::has_subview;
  174. static const bool has_orig_mem = quasi_unwrap_extra::has_orig_mem;
  175. using quasi_unwrap_extra::M;
  176. using quasi_unwrap_extra::is_alias;
  177. };
  178. template<typename eT>
  179. struct quasi_unwrap< Mat<eT> >
  180. {
  181. inline
  182. quasi_unwrap(const Mat<eT>& A)
  183. : M(A)
  184. {
  185. arma_extra_debug_sigprint();
  186. }
  187. const Mat<eT>& M;
  188. static const bool is_const = true;
  189. static const bool has_subview = false;
  190. static const bool has_orig_mem = true;
  191. template<typename eT2>
  192. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); }
  193. };
  194. template<typename eT>
  195. struct quasi_unwrap< Row<eT> >
  196. {
  197. inline
  198. quasi_unwrap(const Row<eT>& A)
  199. : M(A)
  200. {
  201. arma_extra_debug_sigprint();
  202. }
  203. const Row<eT>& M;
  204. static const bool is_const = true;
  205. static const bool has_subview = false;
  206. static const bool has_orig_mem = true;
  207. template<typename eT2>
  208. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); }
  209. };
  210. template<typename eT>
  211. struct quasi_unwrap< Col<eT> >
  212. {
  213. inline
  214. quasi_unwrap(const Col<eT>& A)
  215. : M(A)
  216. {
  217. arma_extra_debug_sigprint();
  218. }
  219. const Col<eT>& M;
  220. static const bool is_const = true;
  221. static const bool has_subview = false;
  222. static const bool has_orig_mem = true;
  223. template<typename eT2>
  224. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); }
  225. };
  226. template<typename eT>
  227. struct quasi_unwrap< subview<eT> >
  228. {
  229. inline
  230. quasi_unwrap(const subview<eT>& A)
  231. : sv( A )
  232. , M ( A, ((A.aux_row1 == 0) && (A.n_rows == A.m.n_rows)) ) // reuse memory if the subview is a contiguous chunk
  233. {
  234. arma_extra_debug_sigprint();
  235. }
  236. const subview<eT>& sv;
  237. const Mat<eT> M;
  238. static const bool is_const = true;
  239. static const bool has_subview = true;
  240. static const bool has_orig_mem = false; // NOTE: set to false as this is the general case; original memory is only used when the subview is a contiguous chunk
  241. template<typename eT2>
  242. arma_inline bool is_alias(const Mat<eT2>& X) const { return ( ((sv.aux_row1 == 0) && (sv.n_rows == sv.m.n_rows)) ? (void_ptr(&(sv.m)) == void_ptr(&X)) : false ); }
  243. };
  244. template<typename eT>
  245. struct quasi_unwrap< subview_row<eT> >
  246. {
  247. inline
  248. quasi_unwrap(const subview_row<eT>& A)
  249. : M(A)
  250. {
  251. arma_extra_debug_sigprint();
  252. }
  253. Row<eT> M;
  254. static const bool is_const = false;
  255. static const bool has_subview = false;
  256. static const bool has_orig_mem = false;
  257. template<typename eT2>
  258. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  259. };
  260. template<typename eT>
  261. struct quasi_unwrap< subview_col<eT> >
  262. {
  263. inline
  264. quasi_unwrap(const subview_col<eT>& A)
  265. : orig( A.m )
  266. , M ( const_cast<eT*>( A.colptr(0) ), A.n_rows, false, false )
  267. {
  268. arma_extra_debug_sigprint();
  269. }
  270. const Mat<eT>& orig;
  271. const Col<eT> M;
  272. static const bool is_const = true;
  273. static const bool has_subview = true;
  274. static const bool has_orig_mem = true;
  275. template<typename eT2>
  276. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); }
  277. };
  278. template<typename out_eT, typename T1, typename T2, typename glue_type>
  279. struct quasi_unwrap< mtGlue<out_eT, T1, T2, glue_type> >
  280. {
  281. inline
  282. quasi_unwrap(const mtGlue<out_eT, T1, T2, glue_type>& A)
  283. : M(A)
  284. {
  285. arma_extra_debug_sigprint();
  286. }
  287. Mat<out_eT> M;
  288. static const bool is_const = false;
  289. static const bool has_subview = false;
  290. static const bool has_orig_mem = false;
  291. template<typename eT2>
  292. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  293. };
  294. template<typename out_eT, typename T1, typename op_type>
  295. struct quasi_unwrap< mtOp<out_eT, T1, op_type> >
  296. {
  297. inline
  298. quasi_unwrap(const mtOp<out_eT, T1, op_type>& A)
  299. : M(A)
  300. {
  301. arma_extra_debug_sigprint();
  302. }
  303. Mat<out_eT> M;
  304. static const bool is_const = false;
  305. static const bool has_subview = false;
  306. static const bool has_orig_mem = false;
  307. template<typename eT2>
  308. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  309. };
  310. template<typename T1>
  311. struct quasi_unwrap< Op<T1, op_vectorise_col> >
  312. {
  313. typedef typename T1::elem_type eT;
  314. inline
  315. quasi_unwrap(const Op<T1, op_vectorise_col>& A)
  316. : U( A.m )
  317. , M( const_cast<eT*>(U.M.memptr()), U.M.n_elem, 1, false, false )
  318. {
  319. arma_extra_debug_sigprint();
  320. }
  321. const unwrap<T1> U;
  322. const Mat<eT> M;
  323. static const bool is_const = true;
  324. static const bool has_subview = true;
  325. static const bool has_orig_mem = true;
  326. template<typename eT2>
  327. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(U.M)) == void_ptr(&X)); }
  328. };
  329. template<typename eT>
  330. struct quasi_unwrap< Op<Col<eT>, op_strans> >
  331. {
  332. inline
  333. quasi_unwrap(const Op<Col<eT>, op_strans>& A)
  334. : orig(A.m)
  335. , M (const_cast<eT*>(A.m.memptr()), A.m.n_elem, false, false)
  336. {
  337. arma_extra_debug_sigprint();
  338. }
  339. const Col<eT>& orig;
  340. const Row<eT> M;
  341. static const bool is_const = true;
  342. static const bool has_subview = true;
  343. static const bool has_orig_mem = true;
  344. template<typename eT2>
  345. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); }
  346. };
  347. template<typename eT>
  348. struct quasi_unwrap< Op<Row<eT>, op_strans> >
  349. {
  350. inline
  351. quasi_unwrap(const Op<Row<eT>, op_strans>& A)
  352. : orig(A.m)
  353. , M (const_cast<eT*>(A.m.memptr()), A.m.n_elem, false, false)
  354. {
  355. arma_extra_debug_sigprint();
  356. }
  357. const Row<eT>& orig;
  358. const Col<eT> M;
  359. static const bool is_const = true;
  360. static const bool has_subview = true;
  361. static const bool has_orig_mem = true;
  362. template<typename eT2>
  363. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); }
  364. };
  365. template<typename eT>
  366. struct quasi_unwrap< Op<subview_col<eT>, op_strans> >
  367. {
  368. inline
  369. quasi_unwrap(const Op<subview_col<eT>, op_strans>& A)
  370. : orig( A.m.m )
  371. , M ( const_cast<eT*>( A.m.colptr(0) ), A.m.n_rows, false, false )
  372. {
  373. arma_extra_debug_sigprint();
  374. }
  375. const Mat<eT>& orig;
  376. const Row<eT> M;
  377. static const bool is_const = true;
  378. static const bool has_subview = true;
  379. static const bool has_orig_mem = true;
  380. template<typename eT2>
  381. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); }
  382. };
  383. template<typename T1>
  384. struct quasi_unwrap_Col_htrans
  385. {
  386. inline quasi_unwrap_Col_htrans(const T1&) {}
  387. };
  388. template<typename eT>
  389. struct quasi_unwrap_Col_htrans< Op<Col<eT>, op_htrans> >
  390. {
  391. inline
  392. quasi_unwrap_Col_htrans(const Op<Col<eT>, op_htrans>& A)
  393. : orig(A.m)
  394. , M (const_cast<eT*>(A.m.memptr()), A.m.n_elem, false, false)
  395. {
  396. arma_extra_debug_sigprint();
  397. }
  398. const Col<eT>& orig;
  399. const Row<eT> M;
  400. static const bool is_const = true;
  401. static const bool has_subview = true;
  402. static const bool has_orig_mem = true;
  403. template<typename eT2>
  404. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); }
  405. };
  406. template<typename T1, bool condition>
  407. struct quasi_unwrap_Col_htrans_redirect {};
  408. template<typename T1>
  409. struct quasi_unwrap_Col_htrans_redirect<T1, true> { typedef quasi_unwrap_default<T1> result; };
  410. template<typename T1>
  411. struct quasi_unwrap_Col_htrans_redirect<T1, false> { typedef quasi_unwrap_Col_htrans<T1> result; };
  412. template<typename eT>
  413. struct quasi_unwrap< Op<Col<eT>, op_htrans> >
  414. : public quasi_unwrap_Col_htrans_redirect< Op<Col<eT>, op_htrans>, is_cx<eT>::value >::result
  415. {
  416. typedef typename quasi_unwrap_Col_htrans_redirect< Op<Col<eT>, op_htrans>, is_cx<eT>::value >::result quasi_unwrap_Col_htrans_extra;
  417. inline
  418. quasi_unwrap(const Op<Col<eT>, op_htrans>& A)
  419. : quasi_unwrap_Col_htrans_extra(A)
  420. {
  421. }
  422. static const bool is_const = quasi_unwrap_Col_htrans_extra::is_const;
  423. static const bool has_subview = quasi_unwrap_Col_htrans_extra::has_subview;
  424. static const bool has_orig_mem = quasi_unwrap_Col_htrans_extra::has_orig_mem;
  425. using quasi_unwrap_Col_htrans_extra::M;
  426. using quasi_unwrap_Col_htrans_extra::is_alias;
  427. };
  428. template<typename T1>
  429. struct quasi_unwrap_Row_htrans
  430. {
  431. inline quasi_unwrap_Row_htrans(const T1&) {}
  432. };
  433. template<typename eT>
  434. struct quasi_unwrap_Row_htrans< Op<Row<eT>, op_htrans> >
  435. {
  436. inline
  437. quasi_unwrap_Row_htrans(const Op<Row<eT>, op_htrans>& A)
  438. : orig(A.m)
  439. , M (const_cast<eT*>(A.m.memptr()), A.m.n_elem, false, false)
  440. {
  441. arma_extra_debug_sigprint();
  442. }
  443. const Row<eT>& orig;
  444. const Col<eT> M;
  445. static const bool is_const = true;
  446. static const bool has_subview = true;
  447. static const bool has_orig_mem = true;
  448. template<typename eT2>
  449. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); }
  450. };
  451. template<typename T1, bool condition>
  452. struct quasi_unwrap_Row_htrans_redirect {};
  453. template<typename T1>
  454. struct quasi_unwrap_Row_htrans_redirect<T1, true> { typedef quasi_unwrap_default<T1> result; };
  455. template<typename T1>
  456. struct quasi_unwrap_Row_htrans_redirect<T1, false> { typedef quasi_unwrap_Row_htrans<T1> result; };
  457. template<typename eT>
  458. struct quasi_unwrap< Op<Row<eT>, op_htrans> >
  459. : public quasi_unwrap_Row_htrans_redirect< Op<Row<eT>, op_htrans>, is_cx<eT>::value >::result
  460. {
  461. typedef typename quasi_unwrap_Row_htrans_redirect< Op<Row<eT>, op_htrans>, is_cx<eT>::value >::result quasi_unwrap_Row_htrans_extra;
  462. inline
  463. quasi_unwrap(const Op<Row<eT>, op_htrans>& A)
  464. : quasi_unwrap_Row_htrans_extra(A)
  465. {
  466. }
  467. static const bool is_const = quasi_unwrap_Row_htrans_extra::is_const;
  468. static const bool has_subview = quasi_unwrap_Row_htrans_extra::has_subview;
  469. static const bool has_orig_mem = quasi_unwrap_Row_htrans_extra::has_orig_mem;
  470. using quasi_unwrap_Row_htrans_extra::M;
  471. using quasi_unwrap_Row_htrans_extra::is_alias;
  472. };
  473. template<typename T1>
  474. struct quasi_unwrap_subview_col_htrans
  475. {
  476. inline quasi_unwrap_subview_col_htrans(const T1&) {}
  477. };
  478. template<typename eT>
  479. struct quasi_unwrap_subview_col_htrans< Op<subview_col<eT>, op_htrans> >
  480. {
  481. inline
  482. quasi_unwrap_subview_col_htrans(const Op<subview_col<eT>, op_htrans>& A)
  483. : orig(A.m.m)
  484. , M (const_cast<eT*>(A.m.colptr(0)), A.m.n_rows, false, false)
  485. {
  486. arma_extra_debug_sigprint();
  487. }
  488. const Mat<eT>& orig;
  489. const Row<eT> M;
  490. static const bool is_const = true;
  491. static const bool has_subview = true;
  492. static const bool has_orig_mem = true;
  493. template<typename eT2>
  494. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); }
  495. };
  496. template<typename T1, bool condition>
  497. struct quasi_unwrap_subview_col_htrans_redirect {};
  498. template<typename T1>
  499. struct quasi_unwrap_subview_col_htrans_redirect<T1, true> { typedef quasi_unwrap_default<T1> result; };
  500. template<typename T1>
  501. struct quasi_unwrap_subview_col_htrans_redirect<T1, false> { typedef quasi_unwrap_subview_col_htrans<T1> result; };
  502. template<typename eT>
  503. struct quasi_unwrap< Op<subview_col<eT>, op_htrans> >
  504. : public quasi_unwrap_subview_col_htrans_redirect< Op<subview_col<eT>, op_htrans>, is_cx<eT>::value >::result
  505. {
  506. typedef typename quasi_unwrap_subview_col_htrans_redirect< Op<subview_col<eT>, op_htrans>, is_cx<eT>::value >::result quasi_unwrap_subview_col_htrans_extra;
  507. inline
  508. quasi_unwrap(const Op<subview_col<eT>, op_htrans>& A)
  509. : quasi_unwrap_subview_col_htrans_extra(A)
  510. {
  511. }
  512. static const bool is_const = quasi_unwrap_subview_col_htrans_extra::is_const;
  513. static const bool has_subview = quasi_unwrap_subview_col_htrans_extra::has_subview;
  514. static const bool has_orig_mem = quasi_unwrap_subview_col_htrans_extra::has_orig_mem;
  515. using quasi_unwrap_subview_col_htrans_extra::M;
  516. using quasi_unwrap_subview_col_htrans_extra::is_alias;
  517. };
  518. template<typename T1>
  519. struct quasi_unwrap< CubeToMatOp<T1, op_vectorise_cube_col> >
  520. {
  521. typedef typename T1::elem_type eT;
  522. inline
  523. quasi_unwrap(const CubeToMatOp<T1, op_vectorise_cube_col>& A)
  524. : U( A.m )
  525. , M( const_cast<eT*>(U.M.memptr()), U.M.n_elem, 1, false, true )
  526. {
  527. arma_extra_debug_sigprint();
  528. }
  529. const unwrap_cube<T1> U;
  530. const Mat<eT> M;
  531. static const bool is_const = true;
  532. static const bool has_subview = true;
  533. static const bool has_orig_mem = true;
  534. template<typename eT2>
  535. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  536. };
  537. template<typename T1>
  538. struct quasi_unwrap< SpToDOp<T1, op_nonzeros_spmat> >
  539. {
  540. typedef typename T1::elem_type eT;
  541. inline
  542. quasi_unwrap(const SpToDOp<T1, op_nonzeros_spmat>& A)
  543. : U( A.m )
  544. , M( const_cast<eT*>(U.M.values), U.M.n_nonzero, 1, false, true )
  545. {
  546. arma_extra_debug_sigprint();
  547. }
  548. const unwrap_spmat<T1> U;
  549. const Mat<eT> M;
  550. static const bool is_const = true;
  551. static const bool has_subview = true;
  552. static const bool has_orig_mem = true;
  553. template<typename eT2>
  554. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  555. };
  556. //
  557. //
  558. //
  559. template<typename T1>
  560. struct unwrap_check_default
  561. {
  562. typedef typename T1::elem_type eT;
  563. typedef Mat<eT> stored_type;
  564. inline
  565. unwrap_check_default(const T1& A, const Mat<eT>&)
  566. : M(A)
  567. {
  568. arma_extra_debug_sigprint();
  569. }
  570. inline
  571. unwrap_check_default(const T1& A, const bool)
  572. : M(A)
  573. {
  574. arma_extra_debug_sigprint();
  575. }
  576. const Mat<eT> M;
  577. };
  578. template<typename T1>
  579. struct unwrap_check_fixed
  580. {
  581. typedef typename T1::elem_type eT;
  582. typedef T1 stored_type;
  583. inline
  584. unwrap_check_fixed(const T1& A, const Mat<eT>& B)
  585. : M_local( (&A == &B) ? new T1(A) : 0 )
  586. , M ( (&A == &B) ? *M_local : A )
  587. {
  588. arma_extra_debug_sigprint();
  589. }
  590. inline
  591. unwrap_check_fixed(const T1& A, const bool is_alias)
  592. : M_local( is_alias ? new T1(A) : 0 )
  593. , M ( is_alias ? *M_local : A )
  594. {
  595. arma_extra_debug_sigprint();
  596. }
  597. inline
  598. ~unwrap_check_fixed()
  599. {
  600. arma_extra_debug_sigprint();
  601. if(M_local) { delete M_local; }
  602. }
  603. // the order below is important
  604. const T1* M_local;
  605. const T1& M;
  606. };
  607. template<typename T1, bool condition>
  608. struct unwrap_check_redirect {};
  609. template<typename T1>
  610. struct unwrap_check_redirect<T1, false> { typedef unwrap_check_default<T1> result; };
  611. template<typename T1>
  612. struct unwrap_check_redirect<T1, true> { typedef unwrap_check_fixed<T1> result; };
  613. template<typename T1>
  614. struct unwrap_check : public unwrap_check_redirect<T1, is_Mat_fixed<T1>::value >::result
  615. {
  616. inline unwrap_check(const T1& A, const Mat<typename T1::elem_type>& B)
  617. : unwrap_check_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
  618. {
  619. }
  620. inline unwrap_check(const T1& A, const bool is_alias)
  621. : unwrap_check_redirect< T1, is_Mat_fixed<T1>::value >::result(A, is_alias)
  622. {
  623. }
  624. };
  625. template<typename eT>
  626. struct unwrap_check< Mat<eT> >
  627. {
  628. typedef Mat<eT> stored_type;
  629. inline
  630. unwrap_check(const Mat<eT>& A, const Mat<eT>& B)
  631. : M_local( (&A == &B) ? new Mat<eT>(A) : 0 )
  632. , M ( (&A == &B) ? (*M_local) : A )
  633. {
  634. arma_extra_debug_sigprint();
  635. }
  636. inline
  637. unwrap_check(const Mat<eT>& A, const bool is_alias)
  638. : M_local( is_alias ? new Mat<eT>(A) : 0 )
  639. , M ( is_alias ? (*M_local) : A )
  640. {
  641. arma_extra_debug_sigprint();
  642. }
  643. inline
  644. ~unwrap_check()
  645. {
  646. arma_extra_debug_sigprint();
  647. if(M_local) { delete M_local; }
  648. }
  649. // the order below is important
  650. const Mat<eT>* M_local;
  651. const Mat<eT>& M;
  652. };
  653. template<typename eT>
  654. struct unwrap_check< Row<eT> >
  655. {
  656. typedef Row<eT> stored_type;
  657. inline
  658. unwrap_check(const Row<eT>& A, const Mat<eT>& B)
  659. : M_local( (&A == &B) ? new Row<eT>(A) : 0 )
  660. , M ( (&A == &B) ? (*M_local) : A )
  661. {
  662. arma_extra_debug_sigprint();
  663. }
  664. inline
  665. unwrap_check(const Row<eT>& A, const bool is_alias)
  666. : M_local( is_alias ? new Row<eT>(A) : 0 )
  667. , M ( is_alias ? (*M_local) : A )
  668. {
  669. arma_extra_debug_sigprint();
  670. }
  671. inline
  672. ~unwrap_check()
  673. {
  674. arma_extra_debug_sigprint();
  675. if(M_local) { delete M_local; }
  676. }
  677. // the order below is important
  678. const Row<eT>* M_local;
  679. const Row<eT>& M;
  680. };
  681. template<typename eT>
  682. struct unwrap_check< Col<eT> >
  683. {
  684. typedef Col<eT> stored_type;
  685. inline
  686. unwrap_check(const Col<eT>& A, const Mat<eT>& B)
  687. : M_local( (&A == &B) ? new Col<eT>(A) : 0 )
  688. , M ( (&A == &B) ? (*M_local) : A )
  689. {
  690. arma_extra_debug_sigprint();
  691. }
  692. inline
  693. unwrap_check(const Col<eT>& A, const bool is_alias)
  694. : M_local( is_alias ? new Col<eT>(A) : 0 )
  695. , M ( is_alias ? (*M_local) : A )
  696. {
  697. arma_extra_debug_sigprint();
  698. }
  699. inline
  700. ~unwrap_check()
  701. {
  702. arma_extra_debug_sigprint();
  703. if(M_local) { delete M_local; }
  704. }
  705. // the order below is important
  706. const Col<eT>* M_local;
  707. const Col<eT>& M;
  708. };
  709. //
  710. //
  711. //
  712. template<typename T1>
  713. struct unwrap_check_mixed
  714. {
  715. typedef typename T1::elem_type eT1;
  716. template<typename eT2>
  717. inline
  718. unwrap_check_mixed(const T1& A, const Mat<eT2>&)
  719. : M(A)
  720. {
  721. arma_extra_debug_sigprint();
  722. }
  723. //template<typename eT2>
  724. inline
  725. unwrap_check_mixed(const T1& A, const bool)
  726. : M(A)
  727. {
  728. arma_extra_debug_sigprint();
  729. }
  730. const Mat<eT1> M;
  731. };
  732. template<typename eT1>
  733. struct unwrap_check_mixed< Mat<eT1> >
  734. {
  735. template<typename eT2>
  736. inline
  737. unwrap_check_mixed(const Mat<eT1>& A, const Mat<eT2>& B)
  738. : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Mat<eT1>(A) : 0 )
  739. , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A )
  740. {
  741. arma_extra_debug_sigprint();
  742. }
  743. //template<typename eT2>
  744. inline
  745. unwrap_check_mixed(const Mat<eT1>& A, const bool is_alias)
  746. : M_local( is_alias ? new Mat<eT1>(A) : 0 )
  747. , M ( is_alias ? (*M_local) : A )
  748. {
  749. arma_extra_debug_sigprint();
  750. }
  751. inline
  752. ~unwrap_check_mixed()
  753. {
  754. arma_extra_debug_sigprint();
  755. if(M_local) { delete M_local; }
  756. }
  757. // the order below is important
  758. const Mat<eT1>* M_local;
  759. const Mat<eT1>& M;
  760. };
  761. template<typename eT1>
  762. struct unwrap_check_mixed< Row<eT1> >
  763. {
  764. template<typename eT2>
  765. inline
  766. unwrap_check_mixed(const Row<eT1>& A, const Mat<eT2>& B)
  767. : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Row<eT1>(A) : 0 )
  768. , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A )
  769. {
  770. arma_extra_debug_sigprint();
  771. }
  772. //template<typename eT2>
  773. inline
  774. unwrap_check_mixed(const Row<eT1>& A, const bool is_alias)
  775. : M_local( is_alias ? new Row<eT1>(A) : 0 )
  776. , M ( is_alias ? (*M_local) : A )
  777. {
  778. arma_extra_debug_sigprint();
  779. }
  780. inline
  781. ~unwrap_check_mixed()
  782. {
  783. arma_extra_debug_sigprint();
  784. if(M_local) { delete M_local; }
  785. }
  786. // the order below is important
  787. const Row<eT1>* M_local;
  788. const Row<eT1>& M;
  789. };
  790. template<typename eT1>
  791. struct unwrap_check_mixed< Col<eT1> >
  792. {
  793. template<typename eT2>
  794. inline
  795. unwrap_check_mixed(const Col<eT1>& A, const Mat<eT2>& B)
  796. : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Col<eT1>(A) : 0 )
  797. , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A )
  798. {
  799. arma_extra_debug_sigprint();
  800. }
  801. //template<typename eT2>
  802. inline
  803. unwrap_check_mixed(const Col<eT1>& A, const bool is_alias)
  804. : M_local( is_alias ? new Col<eT1>(A) : 0 )
  805. , M ( is_alias ? (*M_local) : A )
  806. {
  807. arma_extra_debug_sigprint();
  808. }
  809. inline
  810. ~unwrap_check_mixed()
  811. {
  812. arma_extra_debug_sigprint();
  813. if(M_local) { delete M_local; }
  814. }
  815. // the order below is important
  816. const Col<eT1>* M_local;
  817. const Col<eT1>& M;
  818. };
  819. //
  820. //
  821. //
  822. template<typename T1>
  823. struct partial_unwrap_default
  824. {
  825. typedef typename T1::elem_type eT;
  826. typedef Mat<eT> stored_type;
  827. inline
  828. partial_unwrap_default(const T1& A)
  829. : M(A)
  830. {
  831. arma_extra_debug_sigprint();
  832. }
  833. arma_inline eT get_val() const { return eT(1); }
  834. template<typename eT2>
  835. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  836. static const bool do_trans = false;
  837. static const bool do_times = false;
  838. const Mat<eT> M;
  839. };
  840. template<typename T1>
  841. struct partial_unwrap_fixed
  842. {
  843. typedef typename T1::elem_type eT;
  844. typedef T1 stored_type;
  845. inline explicit
  846. partial_unwrap_fixed(const T1& A)
  847. : M(A)
  848. {
  849. arma_extra_debug_sigprint();
  850. }
  851. arma_inline eT get_val() const { return eT(1); }
  852. template<typename eT2>
  853. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  854. static const bool do_trans = false;
  855. static const bool do_times = false;
  856. const T1& M;
  857. };
  858. template<typename T1, bool condition>
  859. struct partial_unwrap_redirect {};
  860. template<typename T1>
  861. struct partial_unwrap_redirect<T1, false> { typedef partial_unwrap_default<T1> result; };
  862. template<typename T1>
  863. struct partial_unwrap_redirect<T1, true> { typedef partial_unwrap_fixed<T1> result; };
  864. template<typename T1>
  865. struct partial_unwrap : public partial_unwrap_redirect<T1, is_Mat_fixed<T1>::value >::result
  866. {
  867. inline
  868. partial_unwrap(const T1& A)
  869. : partial_unwrap_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
  870. {
  871. }
  872. };
  873. template<typename eT>
  874. struct partial_unwrap< Mat<eT> >
  875. {
  876. typedef Mat<eT> stored_type;
  877. inline
  878. partial_unwrap(const Mat<eT>& A)
  879. : M(A)
  880. {
  881. arma_extra_debug_sigprint();
  882. }
  883. arma_inline eT get_val() const { return eT(1); }
  884. template<typename eT2>
  885. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  886. static const bool do_trans = false;
  887. static const bool do_times = false;
  888. const Mat<eT>& M;
  889. };
  890. template<typename eT>
  891. struct partial_unwrap< Row<eT> >
  892. {
  893. typedef Row<eT> stored_type;
  894. inline
  895. partial_unwrap(const Row<eT>& A)
  896. : M(A)
  897. {
  898. arma_extra_debug_sigprint();
  899. }
  900. arma_inline eT get_val() const { return eT(1); }
  901. template<typename eT2>
  902. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  903. static const bool do_trans = false;
  904. static const bool do_times = false;
  905. const Row<eT>& M;
  906. };
  907. template<typename eT>
  908. struct partial_unwrap< Col<eT> >
  909. {
  910. typedef Col<eT> stored_type;
  911. inline
  912. partial_unwrap(const Col<eT>& A)
  913. : M(A)
  914. {
  915. arma_extra_debug_sigprint();
  916. }
  917. arma_inline eT get_val() const { return eT(1); }
  918. template<typename eT2>
  919. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  920. static const bool do_trans = false;
  921. static const bool do_times = false;
  922. const Col<eT>& M;
  923. };
  924. template<typename eT>
  925. struct partial_unwrap< subview<eT> >
  926. {
  927. typedef Mat<eT> stored_type;
  928. inline
  929. partial_unwrap(const subview<eT>& A)
  930. : sv( A )
  931. , M ( A, ((A.aux_row1 == 0) && (A.n_rows == A.m.n_rows)) ) // reuse memory if the subview is a contiguous chunk
  932. {
  933. arma_extra_debug_sigprint();
  934. }
  935. arma_inline eT get_val() const { return eT(1); }
  936. template<typename eT2>
  937. arma_inline bool is_alias(const Mat<eT2>& X) const { return ( ((sv.aux_row1 == 0) && (sv.n_rows == sv.m.n_rows)) ? (void_ptr(&(sv.m)) == void_ptr(&X)) : false ); }
  938. static const bool do_trans = false;
  939. static const bool do_times = false;
  940. const subview<eT>& sv;
  941. const Mat<eT> M;
  942. };
  943. template<typename eT>
  944. struct partial_unwrap< subview_col<eT> >
  945. {
  946. typedef Col<eT> stored_type;
  947. inline
  948. partial_unwrap(const subview_col<eT>& A)
  949. : orig( A.m )
  950. , M ( const_cast<eT*>( A.colptr(0) ), A.n_rows, false, false )
  951. {
  952. arma_extra_debug_sigprint();
  953. }
  954. arma_inline eT get_val() const { return eT(1); }
  955. template<typename eT2>
  956. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); }
  957. static const bool do_trans = false;
  958. static const bool do_times = false;
  959. const Mat<eT>& orig;
  960. const Col<eT> M;
  961. };
  962. template<typename eT>
  963. struct partial_unwrap< subview_row<eT> >
  964. {
  965. typedef Row<eT> stored_type;
  966. inline
  967. partial_unwrap(const subview_row<eT>& A)
  968. : M(A)
  969. {
  970. arma_extra_debug_sigprint();
  971. }
  972. arma_inline eT get_val() const { return eT(1); }
  973. template<typename eT2>
  974. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  975. static const bool do_trans = false;
  976. static const bool do_times = false;
  977. const Row<eT> M;
  978. };
  979. template<typename T1>
  980. struct partial_unwrap_htrans_default
  981. {
  982. typedef typename T1::elem_type eT;
  983. typedef Mat<eT> stored_type;
  984. inline
  985. partial_unwrap_htrans_default(const Op<T1, op_htrans>& A)
  986. : M(A.m)
  987. {
  988. arma_extra_debug_sigprint();
  989. }
  990. arma_inline eT get_val() const { return eT(1); }
  991. template<typename eT2>
  992. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  993. static const bool do_trans = true;
  994. static const bool do_times = false;
  995. const Mat<eT> M;
  996. };
  997. template<typename T1>
  998. struct partial_unwrap_htrans_fixed
  999. {
  1000. typedef typename T1::elem_type eT;
  1001. typedef T1 stored_type;
  1002. inline explicit
  1003. partial_unwrap_htrans_fixed(const Op<T1, op_htrans>& A)
  1004. : M(A.m)
  1005. {
  1006. arma_extra_debug_sigprint();
  1007. }
  1008. arma_inline eT get_val() const { return eT(1); }
  1009. template<typename eT2>
  1010. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1011. static const bool do_trans = true;
  1012. static const bool do_times = false;
  1013. const T1& M;
  1014. };
  1015. template<typename T1, bool condition>
  1016. struct partial_unwrap_htrans_redirect {};
  1017. template<typename T1>
  1018. struct partial_unwrap_htrans_redirect<T1, false> { typedef partial_unwrap_htrans_default<T1> result; };
  1019. template<typename T1>
  1020. struct partial_unwrap_htrans_redirect<T1, true> { typedef partial_unwrap_htrans_fixed<T1> result; };
  1021. template<typename T1>
  1022. struct partial_unwrap< Op<T1, op_htrans> > : public partial_unwrap_htrans_redirect<T1, is_Mat_fixed<T1>::value >::result
  1023. {
  1024. inline partial_unwrap(const Op<T1, op_htrans>& A)
  1025. : partial_unwrap_htrans_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
  1026. {
  1027. }
  1028. };
  1029. template<typename eT>
  1030. struct partial_unwrap< Op< Mat<eT>, op_htrans> >
  1031. {
  1032. typedef Mat<eT> stored_type;
  1033. inline
  1034. partial_unwrap(const Op< Mat<eT>, op_htrans>& A)
  1035. : M(A.m)
  1036. {
  1037. arma_extra_debug_sigprint();
  1038. }
  1039. arma_inline eT get_val() const { return eT(1); }
  1040. template<typename eT2>
  1041. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1042. static const bool do_trans = true;
  1043. static const bool do_times = false;
  1044. const Mat<eT>& M;
  1045. };
  1046. template<typename eT>
  1047. struct partial_unwrap< Op< Row<eT>, op_htrans> >
  1048. {
  1049. typedef Row<eT> stored_type;
  1050. inline
  1051. partial_unwrap(const Op< Row<eT>, op_htrans>& A)
  1052. : M(A.m)
  1053. {
  1054. arma_extra_debug_sigprint();
  1055. }
  1056. arma_inline eT get_val() const { return eT(1); }
  1057. template<typename eT2>
  1058. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1059. static const bool do_trans = true;
  1060. static const bool do_times = false;
  1061. const Row<eT>& M;
  1062. };
  1063. template<typename eT>
  1064. struct partial_unwrap< Op< Col<eT>, op_htrans> >
  1065. {
  1066. typedef Col<eT> stored_type;
  1067. inline
  1068. partial_unwrap(const Op< Col<eT>, op_htrans>& A)
  1069. : M(A.m)
  1070. {
  1071. arma_extra_debug_sigprint();
  1072. }
  1073. arma_inline eT get_val() const { return eT(1); }
  1074. template<typename eT2>
  1075. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1076. static const bool do_trans = true;
  1077. static const bool do_times = false;
  1078. const Col<eT>& M;
  1079. };
  1080. template<typename eT>
  1081. struct partial_unwrap< Op< subview_col<eT>, op_htrans> >
  1082. {
  1083. typedef Col<eT> stored_type;
  1084. inline
  1085. partial_unwrap(const Op< subview_col<eT>, op_htrans>& A)
  1086. : orig( A.m.m )
  1087. , M ( const_cast<eT*>( A.m.colptr(0) ), A.m.n_rows, false, false )
  1088. {
  1089. arma_extra_debug_sigprint();
  1090. }
  1091. arma_inline eT get_val() const { return eT(1); }
  1092. template<typename eT2>
  1093. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); }
  1094. static const bool do_trans = true;
  1095. static const bool do_times = false;
  1096. const Mat<eT>& orig;
  1097. const Col<eT> M;
  1098. };
  1099. template<typename eT>
  1100. struct partial_unwrap< Op< subview_row<eT>, op_htrans> >
  1101. {
  1102. typedef Row<eT> stored_type;
  1103. inline
  1104. partial_unwrap(const Op< subview_row<eT>, op_htrans>& A)
  1105. : M(A.m)
  1106. {
  1107. arma_extra_debug_sigprint();
  1108. }
  1109. arma_inline eT get_val() const { return eT(1); }
  1110. template<typename eT2>
  1111. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  1112. static const bool do_trans = true;
  1113. static const bool do_times = false;
  1114. const Row<eT> M;
  1115. };
  1116. template<typename T1>
  1117. struct partial_unwrap_htrans2_default
  1118. {
  1119. typedef typename T1::elem_type eT;
  1120. typedef Mat<eT> stored_type;
  1121. inline
  1122. partial_unwrap_htrans2_default(const Op<T1, op_htrans2>& A)
  1123. : val(A.aux)
  1124. , M (A.m)
  1125. {
  1126. arma_extra_debug_sigprint();
  1127. }
  1128. arma_inline eT get_val() const { return val; }
  1129. template<typename eT2>
  1130. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  1131. static const bool do_trans = true;
  1132. static const bool do_times = true;
  1133. const eT val;
  1134. const Mat<eT> M;
  1135. };
  1136. template<typename T1>
  1137. struct partial_unwrap_htrans2_fixed
  1138. {
  1139. typedef typename T1::elem_type eT;
  1140. typedef T1 stored_type;
  1141. inline explicit
  1142. partial_unwrap_htrans2_fixed(const Op<T1, op_htrans2>& A)
  1143. : val(A.aux)
  1144. , M (A.m)
  1145. {
  1146. arma_extra_debug_sigprint();
  1147. }
  1148. arma_inline eT get_val() const { return val; }
  1149. template<typename eT2>
  1150. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1151. static const bool do_trans = true;
  1152. static const bool do_times = true;
  1153. const eT val;
  1154. const T1& M;
  1155. };
  1156. template<typename T1, bool condition>
  1157. struct partial_unwrap_htrans2_redirect {};
  1158. template<typename T1>
  1159. struct partial_unwrap_htrans2_redirect<T1, false> { typedef partial_unwrap_htrans2_default<T1> result; };
  1160. template<typename T1>
  1161. struct partial_unwrap_htrans2_redirect<T1, true> { typedef partial_unwrap_htrans2_fixed<T1> result; };
  1162. template<typename T1>
  1163. struct partial_unwrap< Op<T1, op_htrans2> > : public partial_unwrap_htrans2_redirect<T1, is_Mat_fixed<T1>::value >::result
  1164. {
  1165. inline partial_unwrap(const Op<T1, op_htrans2>& A)
  1166. : partial_unwrap_htrans2_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
  1167. {
  1168. }
  1169. };
  1170. template<typename eT>
  1171. struct partial_unwrap< Op< Mat<eT>, op_htrans2> >
  1172. {
  1173. typedef Mat<eT> stored_type;
  1174. inline
  1175. partial_unwrap(const Op< Mat<eT>, op_htrans2>& A)
  1176. : val(A.aux)
  1177. , M (A.m)
  1178. {
  1179. arma_extra_debug_sigprint();
  1180. }
  1181. inline eT get_val() const { return val; }
  1182. template<typename eT2>
  1183. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1184. static const bool do_trans = true;
  1185. static const bool do_times = true;
  1186. const eT val;
  1187. const Mat<eT>& M;
  1188. };
  1189. template<typename eT>
  1190. struct partial_unwrap< Op< Row<eT>, op_htrans2> >
  1191. {
  1192. typedef Row<eT> stored_type;
  1193. inline
  1194. partial_unwrap(const Op< Row<eT>, op_htrans2>& A)
  1195. : val(A.aux)
  1196. , M (A.m)
  1197. {
  1198. arma_extra_debug_sigprint();
  1199. }
  1200. inline eT get_val() const { return val; }
  1201. template<typename eT2>
  1202. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1203. static const bool do_trans = true;
  1204. static const bool do_times = true;
  1205. const eT val;
  1206. const Row<eT>& M;
  1207. };
  1208. template<typename eT>
  1209. struct partial_unwrap< Op< Col<eT>, op_htrans2> >
  1210. {
  1211. typedef Col<eT> stored_type;
  1212. inline
  1213. partial_unwrap(const Op< Col<eT>, op_htrans2>& A)
  1214. : val(A.aux)
  1215. , M (A.m)
  1216. {
  1217. arma_extra_debug_sigprint();
  1218. }
  1219. inline eT get_val() const { return val; }
  1220. template<typename eT2>
  1221. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1222. static const bool do_trans = true;
  1223. static const bool do_times = true;
  1224. const eT val;
  1225. const Col<eT>& M;
  1226. };
  1227. template<typename eT>
  1228. struct partial_unwrap< Op< subview_col<eT>, op_htrans2> >
  1229. {
  1230. typedef Col<eT> stored_type;
  1231. inline
  1232. partial_unwrap(const Op< subview_col<eT>, op_htrans2>& A)
  1233. : orig( A.m.m )
  1234. , val ( A.aux )
  1235. , M ( const_cast<eT*>( A.m.colptr(0) ), A.m.n_rows, false, false )
  1236. {
  1237. arma_extra_debug_sigprint();
  1238. }
  1239. inline eT get_val() const { return val; }
  1240. template<typename eT2>
  1241. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); }
  1242. static const bool do_trans = true;
  1243. static const bool do_times = true;
  1244. const Mat<eT>& orig;
  1245. const eT val;
  1246. const Col<eT> M;
  1247. };
  1248. template<typename eT>
  1249. struct partial_unwrap< Op< subview_row<eT>, op_htrans2> >
  1250. {
  1251. typedef Row<eT> stored_type;
  1252. inline
  1253. partial_unwrap(const Op< subview_row<eT>, op_htrans2>& A)
  1254. : val(A.aux)
  1255. , M (A.m )
  1256. {
  1257. arma_extra_debug_sigprint();
  1258. }
  1259. arma_inline eT get_val() const { return val; }
  1260. template<typename eT2>
  1261. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  1262. static const bool do_trans = true;
  1263. static const bool do_times = true;
  1264. const eT val;
  1265. const Row<eT> M;
  1266. };
  1267. template<typename T1>
  1268. struct partial_unwrap_scalar_times_default
  1269. {
  1270. typedef typename T1::elem_type eT;
  1271. typedef Mat<eT> stored_type;
  1272. inline
  1273. partial_unwrap_scalar_times_default(const eOp<T1, eop_scalar_times>& A)
  1274. : val(A.aux)
  1275. , M (A.P.Q)
  1276. {
  1277. arma_extra_debug_sigprint();
  1278. }
  1279. arma_inline eT get_val() const { return val; }
  1280. template<typename eT2>
  1281. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  1282. static const bool do_trans = false;
  1283. static const bool do_times = true;
  1284. const eT val;
  1285. const Mat<eT> M;
  1286. };
  1287. template<typename T1>
  1288. struct partial_unwrap_scalar_times_fixed
  1289. {
  1290. typedef typename T1::elem_type eT;
  1291. typedef T1 stored_type;
  1292. inline explicit
  1293. partial_unwrap_scalar_times_fixed(const eOp<T1, eop_scalar_times>& A)
  1294. : val(A.aux)
  1295. , M (A.P.Q)
  1296. {
  1297. arma_extra_debug_sigprint();
  1298. }
  1299. arma_inline eT get_val() const { return val; }
  1300. template<typename eT2>
  1301. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1302. static const bool do_trans = false;
  1303. static const bool do_times = true;
  1304. const eT val;
  1305. const T1& M;
  1306. };
  1307. template<typename T1, bool condition>
  1308. struct partial_unwrap_scalar_times_redirect {};
  1309. template<typename T1>
  1310. struct partial_unwrap_scalar_times_redirect<T1, false> { typedef partial_unwrap_scalar_times_default<T1> result; };
  1311. template<typename T1>
  1312. struct partial_unwrap_scalar_times_redirect<T1, true> { typedef partial_unwrap_scalar_times_fixed<T1> result; };
  1313. template<typename T1>
  1314. struct partial_unwrap< eOp<T1, eop_scalar_times> > : public partial_unwrap_scalar_times_redirect<T1, is_Mat_fixed<T1>::value >::result
  1315. {
  1316. typedef typename T1::elem_type eT;
  1317. inline
  1318. partial_unwrap(const eOp<T1, eop_scalar_times>& A)
  1319. : partial_unwrap_scalar_times_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
  1320. {
  1321. }
  1322. };
  1323. template<typename eT>
  1324. struct partial_unwrap< eOp<Mat<eT>, eop_scalar_times> >
  1325. {
  1326. typedef Mat<eT> stored_type;
  1327. inline
  1328. partial_unwrap(const eOp<Mat<eT>,eop_scalar_times>& A)
  1329. : val(A.aux)
  1330. , M (A.P.Q)
  1331. {
  1332. arma_extra_debug_sigprint();
  1333. }
  1334. inline eT get_val() const { return val; }
  1335. template<typename eT2>
  1336. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1337. static const bool do_trans = false;
  1338. static const bool do_times = true;
  1339. const eT val;
  1340. const Mat<eT>& M;
  1341. };
  1342. template<typename eT>
  1343. struct partial_unwrap< eOp<Row<eT>, eop_scalar_times> >
  1344. {
  1345. typedef Row<eT> stored_type;
  1346. inline
  1347. partial_unwrap(const eOp<Row<eT>,eop_scalar_times>& A)
  1348. : val(A.aux)
  1349. , M (A.P.Q)
  1350. {
  1351. arma_extra_debug_sigprint();
  1352. }
  1353. inline eT get_val() const { return val; }
  1354. template<typename eT2>
  1355. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1356. static const bool do_trans = false;
  1357. static const bool do_times = true;
  1358. const eT val;
  1359. const Row<eT>& M;
  1360. };
  1361. template<typename eT>
  1362. struct partial_unwrap< eOp<Col<eT>, eop_scalar_times> >
  1363. {
  1364. typedef Col<eT> stored_type;
  1365. inline
  1366. partial_unwrap(const eOp<Col<eT>,eop_scalar_times>& A)
  1367. : val(A.aux)
  1368. , M (A.P.Q)
  1369. {
  1370. arma_extra_debug_sigprint();
  1371. }
  1372. inline eT get_val() const { return val; }
  1373. template<typename eT2>
  1374. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1375. static const bool do_trans = false;
  1376. static const bool do_times = true;
  1377. const eT val;
  1378. const Col<eT>& M;
  1379. };
  1380. template<typename eT>
  1381. struct partial_unwrap< eOp<subview_col<eT>, eop_scalar_times> >
  1382. {
  1383. typedef Col<eT> stored_type;
  1384. inline
  1385. partial_unwrap(const eOp<subview_col<eT>,eop_scalar_times>& A)
  1386. : orig( A.P.Q.m )
  1387. , val ( A.aux )
  1388. , M ( const_cast<eT*>( A.P.Q.colptr(0) ), A.P.Q.n_rows, false, false )
  1389. {
  1390. arma_extra_debug_sigprint();
  1391. }
  1392. arma_inline eT get_val() const { return val; }
  1393. template<typename eT2>
  1394. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); }
  1395. static const bool do_trans = false;
  1396. static const bool do_times = true;
  1397. const Mat<eT>& orig;
  1398. const eT val;
  1399. const Col<eT> M;
  1400. };
  1401. template<typename eT>
  1402. struct partial_unwrap< eOp<subview_row<eT>, eop_scalar_times> >
  1403. {
  1404. typedef Row<eT> stored_type;
  1405. inline
  1406. partial_unwrap(const eOp<subview_row<eT>,eop_scalar_times>& A)
  1407. : val(A.aux)
  1408. , M (A.P.Q)
  1409. {
  1410. arma_extra_debug_sigprint();
  1411. }
  1412. arma_inline eT get_val() const { return val; }
  1413. template<typename eT2>
  1414. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  1415. static const bool do_trans = false;
  1416. static const bool do_times = true;
  1417. const eT val;
  1418. const Row<eT> M;
  1419. };
  1420. template<typename T1>
  1421. struct partial_unwrap_neg_default
  1422. {
  1423. typedef typename T1::elem_type eT;
  1424. typedef Mat<eT> stored_type;
  1425. inline
  1426. partial_unwrap_neg_default(const eOp<T1, eop_neg>& A)
  1427. : M(A.P.Q)
  1428. {
  1429. arma_extra_debug_sigprint();
  1430. }
  1431. arma_inline eT get_val() const { return eT(-1); }
  1432. template<typename eT2>
  1433. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  1434. static const bool do_trans = false;
  1435. static const bool do_times = true;
  1436. const Mat<eT> M;
  1437. };
  1438. template<typename T1>
  1439. struct partial_unwrap_neg_fixed
  1440. {
  1441. typedef typename T1::elem_type eT;
  1442. typedef T1 stored_type;
  1443. inline explicit
  1444. partial_unwrap_neg_fixed(const eOp<T1, eop_neg>& A)
  1445. : M(A.P.Q)
  1446. {
  1447. arma_extra_debug_sigprint();
  1448. }
  1449. arma_inline eT get_val() const { return eT(-1); }
  1450. template<typename eT2>
  1451. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1452. static const bool do_trans = false;
  1453. static const bool do_times = true;
  1454. const T1& M;
  1455. };
  1456. template<typename T1, bool condition>
  1457. struct partial_unwrap_neg_redirect {};
  1458. template<typename T1>
  1459. struct partial_unwrap_neg_redirect<T1, false> { typedef partial_unwrap_neg_default<T1> result; };
  1460. template<typename T1>
  1461. struct partial_unwrap_neg_redirect<T1, true> { typedef partial_unwrap_neg_fixed<T1> result; };
  1462. template<typename T1>
  1463. struct partial_unwrap< eOp<T1, eop_neg> > : public partial_unwrap_neg_redirect<T1, is_Mat_fixed<T1>::value >::result
  1464. {
  1465. typedef typename T1::elem_type eT;
  1466. inline
  1467. partial_unwrap(const eOp<T1, eop_neg>& A)
  1468. : partial_unwrap_neg_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
  1469. {
  1470. }
  1471. };
  1472. template<typename eT>
  1473. struct partial_unwrap< eOp<Mat<eT>, eop_neg> >
  1474. {
  1475. typedef Mat<eT> stored_type;
  1476. inline
  1477. partial_unwrap(const eOp<Mat<eT>,eop_neg>& A)
  1478. : M(A.P.Q)
  1479. {
  1480. arma_extra_debug_sigprint();
  1481. }
  1482. arma_inline eT get_val() const { return eT(-1); }
  1483. template<typename eT2>
  1484. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1485. static const bool do_trans = false;
  1486. static const bool do_times = true;
  1487. const Mat<eT>& M;
  1488. };
  1489. template<typename eT>
  1490. struct partial_unwrap< eOp<Row<eT>, eop_neg> >
  1491. {
  1492. typedef Row<eT> stored_type;
  1493. inline
  1494. partial_unwrap(const eOp<Row<eT>,eop_neg>& A)
  1495. : M(A.P.Q)
  1496. {
  1497. arma_extra_debug_sigprint();
  1498. }
  1499. arma_inline eT get_val() const { return eT(-1); }
  1500. template<typename eT2>
  1501. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1502. static const bool do_trans = false;
  1503. static const bool do_times = true;
  1504. const Row<eT>& M;
  1505. };
  1506. template<typename eT>
  1507. struct partial_unwrap< eOp<Col<eT>, eop_neg> >
  1508. {
  1509. typedef Col<eT> stored_type;
  1510. inline
  1511. partial_unwrap(const eOp<Col<eT>,eop_neg>& A)
  1512. : M(A.P.Q)
  1513. {
  1514. arma_extra_debug_sigprint();
  1515. }
  1516. arma_inline eT get_val() const { return eT(-1); }
  1517. template<typename eT2>
  1518. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); }
  1519. static const bool do_trans = false;
  1520. static const bool do_times = true;
  1521. const Col<eT>& M;
  1522. };
  1523. template<typename eT>
  1524. struct partial_unwrap< eOp<subview_col<eT>, eop_neg> >
  1525. {
  1526. typedef Col<eT> stored_type;
  1527. inline
  1528. partial_unwrap(const eOp<subview_col<eT>,eop_neg>& A)
  1529. : orig( A.P.Q.m )
  1530. , M ( const_cast<eT*>( A.P.Q.colptr(0) ), A.P.Q.n_rows, false, false )
  1531. {
  1532. arma_extra_debug_sigprint();
  1533. }
  1534. arma_inline eT get_val() const { return eT(-1); }
  1535. template<typename eT2>
  1536. arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); }
  1537. static const bool do_trans = false;
  1538. static const bool do_times = true;
  1539. const Mat<eT>& orig;
  1540. const Col<eT> M;
  1541. };
  1542. template<typename eT>
  1543. struct partial_unwrap< eOp<subview_row<eT>, eop_neg> >
  1544. {
  1545. typedef Row<eT> stored_type;
  1546. inline
  1547. partial_unwrap(const eOp<subview_row<eT>,eop_neg>& A)
  1548. : M(A.P.Q)
  1549. {
  1550. arma_extra_debug_sigprint();
  1551. }
  1552. arma_inline eT get_val() const { return eT(-1); }
  1553. template<typename eT2>
  1554. arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
  1555. static const bool do_trans = false;
  1556. static const bool do_times = true;
  1557. const Row<eT> M;
  1558. };
  1559. //
  1560. template<typename T1>
  1561. struct partial_unwrap_check_default
  1562. {
  1563. typedef typename T1::elem_type eT;
  1564. typedef Mat<eT> stored_type;
  1565. inline
  1566. partial_unwrap_check_default(const T1& A, const Mat<eT>&)
  1567. : M(A)
  1568. {
  1569. arma_extra_debug_sigprint();
  1570. }
  1571. arma_inline eT get_val() const { return eT(1); }
  1572. static const bool do_trans = false;
  1573. static const bool do_times = false;
  1574. const Mat<eT> M;
  1575. };
  1576. template<typename T1>
  1577. struct partial_unwrap_check_fixed
  1578. {
  1579. typedef typename T1::elem_type eT;
  1580. typedef T1 stored_type;
  1581. inline explicit
  1582. partial_unwrap_check_fixed(const T1& A, const Mat<eT>& B)
  1583. : M_local( (&A == &B) ? new T1(A) : 0 )
  1584. , M ( (&A == &B) ? (*M_local) : A )
  1585. {
  1586. arma_extra_debug_sigprint();
  1587. }
  1588. inline
  1589. ~partial_unwrap_check_fixed()
  1590. {
  1591. arma_extra_debug_sigprint();
  1592. if(M_local) { delete M_local; }
  1593. }
  1594. arma_inline eT get_val() const { return eT(1); }
  1595. static const bool do_trans = false;
  1596. static const bool do_times = false;
  1597. const T1* M_local;
  1598. const T1& M;
  1599. };
  1600. template<typename T1, bool condition>
  1601. struct partial_unwrap_check_redirect {};
  1602. template<typename T1>
  1603. struct partial_unwrap_check_redirect<T1, false> { typedef partial_unwrap_check_default<T1> result; };
  1604. template<typename T1>
  1605. struct partial_unwrap_check_redirect<T1, true> { typedef partial_unwrap_check_fixed<T1> result; };
  1606. template<typename T1>
  1607. struct partial_unwrap_check : public partial_unwrap_check_redirect<T1, is_Mat_fixed<T1>::value >::result
  1608. {
  1609. typedef typename T1::elem_type eT;
  1610. inline partial_unwrap_check(const T1& A, const Mat<eT>& B)
  1611. : partial_unwrap_check_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
  1612. {
  1613. }
  1614. };
  1615. template<typename eT>
  1616. struct partial_unwrap_check< Mat<eT> >
  1617. {
  1618. typedef Mat<eT> stored_type;
  1619. inline
  1620. partial_unwrap_check(const Mat<eT>& A, const Mat<eT>& B)
  1621. : M_local ( (&A == &B) ? new Mat<eT>(A) : 0 )
  1622. , M ( (&A == &B) ? (*M_local) : A )
  1623. {
  1624. arma_extra_debug_sigprint();
  1625. }
  1626. inline
  1627. ~partial_unwrap_check()
  1628. {
  1629. arma_extra_debug_sigprint();
  1630. if(M_local) { delete M_local; }
  1631. }
  1632. arma_inline eT get_val() const { return eT(1); }
  1633. static const bool do_trans = false;
  1634. static const bool do_times = false;
  1635. // the order below is important
  1636. const Mat<eT>* M_local;
  1637. const Mat<eT>& M;
  1638. };
  1639. template<typename eT>
  1640. struct partial_unwrap_check< Row<eT> >
  1641. {
  1642. typedef Row<eT> stored_type;
  1643. inline
  1644. partial_unwrap_check(const Row<eT>& A, const Mat<eT>& B)
  1645. : M_local ( (&A == &B) ? new Row<eT>(A) : 0 )
  1646. , M ( (&A == &B) ? (*M_local) : A )
  1647. {
  1648. arma_extra_debug_sigprint();
  1649. }
  1650. inline
  1651. ~partial_unwrap_check()
  1652. {
  1653. arma_extra_debug_sigprint();
  1654. if(M_local) { delete M_local; }
  1655. }
  1656. arma_inline eT get_val() const { return eT(1); }
  1657. static const bool do_trans = false;
  1658. static const bool do_times = false;
  1659. // the order below is important
  1660. const Row<eT>* M_local;
  1661. const Row<eT>& M;
  1662. };
  1663. template<typename eT>
  1664. struct partial_unwrap_check< Col<eT> >
  1665. {
  1666. typedef Col<eT> stored_type;
  1667. inline
  1668. partial_unwrap_check(const Col<eT>& A, const Mat<eT>& B)
  1669. : M_local ( (&A == &B) ? new Col<eT>(A) : 0 )
  1670. , M ( (&A == &B) ? (*M_local) : A )
  1671. {
  1672. arma_extra_debug_sigprint();
  1673. }
  1674. inline
  1675. ~partial_unwrap_check()
  1676. {
  1677. arma_extra_debug_sigprint();
  1678. if(M_local) { delete M_local; }
  1679. }
  1680. arma_inline eT get_val() const { return eT(1); }
  1681. static const bool do_trans = false;
  1682. static const bool do_times = false;
  1683. // the order below is important
  1684. const Col<eT>* M_local;
  1685. const Col<eT>& M;
  1686. };
  1687. // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class,
  1688. // NOTE: which relies on partial_unwrap_check to check for aliasing
  1689. template<typename eT>
  1690. struct partial_unwrap_check< subview_col<eT> >
  1691. {
  1692. typedef Col<eT> stored_type;
  1693. inline
  1694. partial_unwrap_check(const subview_col<eT>& A, const Mat<eT>& B)
  1695. : M ( const_cast<eT*>( A.colptr(0) ), A.n_rows, (&(A.m) == &B), false )
  1696. {
  1697. arma_extra_debug_sigprint();
  1698. }
  1699. arma_inline eT get_val() const { return eT(1); }
  1700. static const bool do_trans = false;
  1701. static const bool do_times = false;
  1702. const Col<eT> M;
  1703. };
  1704. template<typename T1>
  1705. struct partial_unwrap_check_htrans_default
  1706. {
  1707. typedef typename T1::elem_type eT;
  1708. typedef Mat<eT> stored_type;
  1709. inline
  1710. partial_unwrap_check_htrans_default(const Op<T1, op_htrans>& A, const Mat<eT>&)
  1711. : M(A.m)
  1712. {
  1713. arma_extra_debug_sigprint();
  1714. }
  1715. arma_inline eT get_val() const { return eT(1); }
  1716. static const bool do_trans = true;
  1717. static const bool do_times = false;
  1718. const Mat<eT> M;
  1719. };
  1720. template<typename T1>
  1721. struct partial_unwrap_check_htrans_fixed
  1722. {
  1723. typedef typename T1::elem_type eT;
  1724. typedef T1 stored_type;
  1725. inline explicit
  1726. partial_unwrap_check_htrans_fixed(const Op<T1, op_htrans>& A, const Mat<eT>& B)
  1727. : M_local( (&(A.m) == &B) ? new T1(A.m) : 0 )
  1728. , M ( (&(A.m) == &B) ? (*M_local) : A.m )
  1729. {
  1730. arma_extra_debug_sigprint();
  1731. }
  1732. inline
  1733. ~partial_unwrap_check_htrans_fixed()
  1734. {
  1735. arma_extra_debug_sigprint();
  1736. if(M_local) { delete M_local; }
  1737. }
  1738. arma_inline eT get_val() const { return eT(1); }
  1739. static const bool do_trans = true;
  1740. static const bool do_times = false;
  1741. const T1* M_local;
  1742. const T1& M;
  1743. };
  1744. template<typename T1, bool condition>
  1745. struct partial_unwrap_check_htrans_redirect {};
  1746. template<typename T1>
  1747. struct partial_unwrap_check_htrans_redirect<T1, false> { typedef partial_unwrap_check_htrans_default<T1> result; };
  1748. template<typename T1>
  1749. struct partial_unwrap_check_htrans_redirect<T1, true> { typedef partial_unwrap_check_htrans_fixed<T1> result; };
  1750. template<typename T1>
  1751. struct partial_unwrap_check< Op<T1, op_htrans> > : public partial_unwrap_check_htrans_redirect<T1, is_Mat_fixed<T1>::value >::result
  1752. {
  1753. typedef typename T1::elem_type eT;
  1754. inline partial_unwrap_check(const Op<T1, op_htrans>& A, const Mat<eT>& B)
  1755. : partial_unwrap_check_htrans_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
  1756. {
  1757. }
  1758. };
  1759. template<typename eT>
  1760. struct partial_unwrap_check< Op< Mat<eT>, op_htrans> >
  1761. {
  1762. typedef Mat<eT> stored_type;
  1763. inline
  1764. partial_unwrap_check(const Op< Mat<eT>, op_htrans>& A, const Mat<eT>& B)
  1765. : M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : 0 )
  1766. , M ( (&A.m == &B) ? (*M_local) : A.m )
  1767. {
  1768. arma_extra_debug_sigprint();
  1769. }
  1770. inline
  1771. ~partial_unwrap_check()
  1772. {
  1773. arma_extra_debug_sigprint();
  1774. if(M_local) { delete M_local; }
  1775. }
  1776. arma_inline eT get_val() const { return eT(1); }
  1777. static const bool do_trans = true;
  1778. static const bool do_times = false;
  1779. // the order below is important
  1780. const Mat<eT>* M_local;
  1781. const Mat<eT>& M;
  1782. };
  1783. template<typename eT>
  1784. struct partial_unwrap_check< Op< Row<eT>, op_htrans> >
  1785. {
  1786. typedef Row<eT> stored_type;
  1787. inline
  1788. partial_unwrap_check(const Op< Row<eT>, op_htrans>& A, const Mat<eT>& B)
  1789. : M_local ( (&A.m == &B) ? new Row<eT>(A.m) : 0 )
  1790. , M ( (&A.m == &B) ? (*M_local) : A.m )
  1791. {
  1792. arma_extra_debug_sigprint();
  1793. }
  1794. inline
  1795. ~partial_unwrap_check()
  1796. {
  1797. arma_extra_debug_sigprint();
  1798. if(M_local) { delete M_local; }
  1799. }
  1800. arma_inline eT get_val() const { return eT(1); }
  1801. static const bool do_trans = true;
  1802. static const bool do_times = false;
  1803. // the order below is important
  1804. const Row<eT>* M_local;
  1805. const Row<eT>& M;
  1806. };
  1807. template<typename eT>
  1808. struct partial_unwrap_check< Op< Col<eT>, op_htrans> >
  1809. {
  1810. typedef Col<eT> stored_type;
  1811. inline
  1812. partial_unwrap_check(const Op< Col<eT>, op_htrans>& A, const Mat<eT>& B)
  1813. : M_local ( (&A.m == &B) ? new Col<eT>(A.m) : 0 )
  1814. , M ( (&A.m == &B) ? (*M_local) : A.m )
  1815. {
  1816. arma_extra_debug_sigprint();
  1817. }
  1818. inline
  1819. ~partial_unwrap_check()
  1820. {
  1821. arma_extra_debug_sigprint();
  1822. if(M_local) { delete M_local; }
  1823. }
  1824. arma_inline eT get_val() const { return eT(1); }
  1825. static const bool do_trans = true;
  1826. static const bool do_times = false;
  1827. // the order below is important
  1828. const Col<eT>* M_local;
  1829. const Col<eT>& M;
  1830. };
  1831. // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class,
  1832. // NOTE: which relies on partial_unwrap_check to check for aliasing
  1833. template<typename eT>
  1834. struct partial_unwrap_check< Op< subview_col<eT>, op_htrans> >
  1835. {
  1836. typedef Col<eT> stored_type;
  1837. inline
  1838. partial_unwrap_check(const Op< subview_col<eT>, op_htrans>& A, const Mat<eT>& B)
  1839. : M ( const_cast<eT*>( A.m.colptr(0) ), A.m.n_rows, (&(A.m.m) == &B), false )
  1840. {
  1841. arma_extra_debug_sigprint();
  1842. }
  1843. arma_inline eT get_val() const { return eT(1); }
  1844. static const bool do_trans = true;
  1845. static const bool do_times = false;
  1846. const Col<eT> M;
  1847. };
  1848. template<typename T1>
  1849. struct partial_unwrap_check_htrans2_default
  1850. {
  1851. typedef typename T1::elem_type eT;
  1852. typedef Mat<eT> stored_type;
  1853. inline
  1854. partial_unwrap_check_htrans2_default(const Op<T1, op_htrans2>& A, const Mat<eT>&)
  1855. : val(A.aux)
  1856. , M (A.m)
  1857. {
  1858. arma_extra_debug_sigprint();
  1859. }
  1860. arma_inline eT get_val() const { return val; }
  1861. static const bool do_trans = true;
  1862. static const bool do_times = true;
  1863. const eT val;
  1864. const Mat<eT> M;
  1865. };
  1866. template<typename T1>
  1867. struct partial_unwrap_check_htrans2_fixed
  1868. {
  1869. typedef typename T1::elem_type eT;
  1870. typedef T1 stored_type;
  1871. inline explicit
  1872. partial_unwrap_check_htrans2_fixed(const Op<T1, op_htrans2>& A, const Mat<eT>& B)
  1873. : val (A.aux)
  1874. , M_local( (&(A.m) == &B) ? new T1(A.m) : 0 )
  1875. , M ( (&(A.m) == &B) ? (*M_local) : A.m )
  1876. {
  1877. arma_extra_debug_sigprint();
  1878. }
  1879. inline
  1880. ~partial_unwrap_check_htrans2_fixed()
  1881. {
  1882. arma_extra_debug_sigprint();
  1883. if(M_local) { delete M_local; }
  1884. }
  1885. arma_inline eT get_val() const { return val; }
  1886. static const bool do_trans = true;
  1887. static const bool do_times = true;
  1888. const eT val;
  1889. const T1* M_local;
  1890. const T1& M;
  1891. };
  1892. template<typename T1, bool condition>
  1893. struct partial_unwrap_check_htrans2_redirect {};
  1894. template<typename T1>
  1895. struct partial_unwrap_check_htrans2_redirect<T1, false> { typedef partial_unwrap_check_htrans2_default<T1> result; };
  1896. template<typename T1>
  1897. struct partial_unwrap_check_htrans2_redirect<T1, true> { typedef partial_unwrap_check_htrans2_fixed<T1> result; };
  1898. template<typename T1>
  1899. struct partial_unwrap_check< Op<T1, op_htrans2> > : public partial_unwrap_check_htrans2_redirect<T1, is_Mat_fixed<T1>::value >::result
  1900. {
  1901. typedef typename T1::elem_type eT;
  1902. inline partial_unwrap_check(const Op<T1, op_htrans2>& A, const Mat<eT>& B)
  1903. : partial_unwrap_check_htrans2_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
  1904. {
  1905. }
  1906. };
  1907. template<typename eT>
  1908. struct partial_unwrap_check< Op< Mat<eT>, op_htrans2> >
  1909. {
  1910. typedef Mat<eT> stored_type;
  1911. inline
  1912. partial_unwrap_check(const Op< Mat<eT>, op_htrans2>& A, const Mat<eT>& B)
  1913. : val (A.aux)
  1914. , M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : 0 )
  1915. , M ( (&A.m == &B) ? (*M_local) : A.m )
  1916. {
  1917. arma_extra_debug_sigprint();
  1918. }
  1919. inline
  1920. ~partial_unwrap_check()
  1921. {
  1922. arma_extra_debug_sigprint();
  1923. if(M_local) { delete M_local; }
  1924. }
  1925. arma_inline eT get_val() const { return val; }
  1926. static const bool do_trans = true;
  1927. static const bool do_times = true;
  1928. // the order below is important
  1929. const eT val;
  1930. const Mat<eT>* M_local;
  1931. const Mat<eT>& M;
  1932. };
  1933. template<typename eT>
  1934. struct partial_unwrap_check< Op< Row<eT>, op_htrans2> >
  1935. {
  1936. typedef Row<eT> stored_type;
  1937. inline
  1938. partial_unwrap_check(const Op< Row<eT>, op_htrans2>& A, const Mat<eT>& B)
  1939. : val (A.aux)
  1940. , M_local ( (&A.m == &B) ? new Row<eT>(A.m) : 0 )
  1941. , M ( (&A.m == &B) ? (*M_local) : A.m )
  1942. {
  1943. arma_extra_debug_sigprint();
  1944. }
  1945. inline
  1946. ~partial_unwrap_check()
  1947. {
  1948. arma_extra_debug_sigprint();
  1949. if(M_local) { delete M_local; }
  1950. }
  1951. arma_inline eT get_val() const { return val; }
  1952. static const bool do_trans = true;
  1953. static const bool do_times = true;
  1954. // the order below is important
  1955. const eT val;
  1956. const Row<eT>* M_local;
  1957. const Row<eT>& M;
  1958. };
  1959. template<typename eT>
  1960. struct partial_unwrap_check< Op< Col<eT>, op_htrans2> >
  1961. {
  1962. typedef Col<eT> stored_type;
  1963. inline
  1964. partial_unwrap_check(const Op< Col<eT>, op_htrans2>& A, const Mat<eT>& B)
  1965. : val (A.aux)
  1966. , M_local ( (&A.m == &B) ? new Col<eT>(A.m) : 0 )
  1967. , M ( (&A.m == &B) ? (*M_local) : A.m )
  1968. {
  1969. arma_extra_debug_sigprint();
  1970. }
  1971. inline
  1972. ~partial_unwrap_check()
  1973. {
  1974. arma_extra_debug_sigprint();
  1975. if(M_local) { delete M_local; }
  1976. }
  1977. arma_inline eT get_val() const { return val; }
  1978. static const bool do_trans = true;
  1979. static const bool do_times = true;
  1980. // the order below is important
  1981. const eT val;
  1982. const Col<eT>* M_local;
  1983. const Col<eT>& M;
  1984. };
  1985. // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class,
  1986. // NOTE: which relies on partial_unwrap_check to check for aliasing
  1987. template<typename eT>
  1988. struct partial_unwrap_check< Op< subview_col<eT>, op_htrans2> >
  1989. {
  1990. typedef Col<eT> stored_type;
  1991. inline
  1992. partial_unwrap_check(const Op< subview_col<eT>, op_htrans2>& A, const Mat<eT>& B)
  1993. : val( A.aux )
  1994. , M ( const_cast<eT*>( A.m.colptr(0) ), A.m.n_rows, (&(A.m.m) == &B), false )
  1995. {
  1996. arma_extra_debug_sigprint();
  1997. }
  1998. arma_inline eT get_val() const { return val; }
  1999. static const bool do_trans = true;
  2000. static const bool do_times = true;
  2001. const eT val;
  2002. const Col<eT> M;
  2003. };
  2004. template<typename T1>
  2005. struct partial_unwrap_check_scalar_times_default
  2006. {
  2007. typedef typename T1::elem_type eT;
  2008. typedef Mat<eT> stored_type;
  2009. inline
  2010. partial_unwrap_check_scalar_times_default(const eOp<T1, eop_scalar_times>& A, const Mat<eT>&)
  2011. : val(A.aux)
  2012. , M (A.P.Q)
  2013. {
  2014. arma_extra_debug_sigprint();
  2015. }
  2016. arma_inline eT get_val() const { return val; }
  2017. static const bool do_trans = false;
  2018. static const bool do_times = true;
  2019. const eT val;
  2020. const Mat<eT> M;
  2021. };
  2022. template<typename T1>
  2023. struct partial_unwrap_check_scalar_times_fixed
  2024. {
  2025. typedef typename T1::elem_type eT;
  2026. typedef T1 stored_type;
  2027. inline explicit
  2028. partial_unwrap_check_scalar_times_fixed(const eOp<T1, eop_scalar_times>& A, const Mat<eT>& B)
  2029. : val ( A.aux )
  2030. , M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : 0 )
  2031. , M ( (&(A.P.Q) == &B) ? (*M_local) : A.P.Q )
  2032. {
  2033. arma_extra_debug_sigprint();
  2034. }
  2035. inline
  2036. ~partial_unwrap_check_scalar_times_fixed()
  2037. {
  2038. arma_extra_debug_sigprint();
  2039. if(M_local) { delete M_local; }
  2040. }
  2041. arma_inline eT get_val() const { return val; }
  2042. static const bool do_trans = false;
  2043. static const bool do_times = true;
  2044. const eT val;
  2045. const T1* M_local;
  2046. const T1& M;
  2047. };
  2048. template<typename T1, bool condition>
  2049. struct partial_unwrap_check_scalar_times_redirect {};
  2050. template<typename T1>
  2051. struct partial_unwrap_check_scalar_times_redirect<T1, false> { typedef partial_unwrap_check_scalar_times_default<T1> result; };
  2052. template<typename T1>
  2053. struct partial_unwrap_check_scalar_times_redirect<T1, true> { typedef partial_unwrap_check_scalar_times_fixed<T1> result; };
  2054. template<typename T1>
  2055. struct partial_unwrap_check< eOp<T1, eop_scalar_times> > : public partial_unwrap_check_scalar_times_redirect<T1, is_Mat_fixed<T1>::value >::result
  2056. {
  2057. typedef typename T1::elem_type eT;
  2058. inline partial_unwrap_check(const eOp<T1, eop_scalar_times>& A, const Mat<eT>& B)
  2059. : partial_unwrap_check_scalar_times_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
  2060. {
  2061. }
  2062. };
  2063. template<typename eT>
  2064. struct partial_unwrap_check< eOp<Mat<eT>, eop_scalar_times> >
  2065. {
  2066. typedef Mat<eT> stored_type;
  2067. inline
  2068. partial_unwrap_check(const eOp<Mat<eT>,eop_scalar_times>& A, const Mat<eT>& B)
  2069. : val (A.aux)
  2070. , M_local( (&(A.P.Q) == &B) ? new Mat<eT>(A.P.Q) : 0 )
  2071. , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q )
  2072. {
  2073. arma_extra_debug_sigprint();
  2074. }
  2075. inline
  2076. ~partial_unwrap_check()
  2077. {
  2078. arma_extra_debug_sigprint();
  2079. if(M_local) { delete M_local; }
  2080. }
  2081. arma_inline eT get_val() const { return val; }
  2082. static const bool do_trans = false;
  2083. static const bool do_times = true;
  2084. const eT val;
  2085. const Mat<eT>* M_local;
  2086. const Mat<eT>& M;
  2087. };
  2088. template<typename eT>
  2089. struct partial_unwrap_check< eOp<Row<eT>, eop_scalar_times> >
  2090. {
  2091. typedef Row<eT> stored_type;
  2092. inline
  2093. partial_unwrap_check(const eOp<Row<eT>,eop_scalar_times>& A, const Mat<eT>& B)
  2094. : val(A.aux)
  2095. , M_local( (&(A.P.Q) == &B) ? new Row<eT>(A.P.Q) : 0 )
  2096. , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q )
  2097. {
  2098. arma_extra_debug_sigprint();
  2099. }
  2100. inline
  2101. ~partial_unwrap_check()
  2102. {
  2103. arma_extra_debug_sigprint();
  2104. if(M_local) { delete M_local; }
  2105. }
  2106. arma_inline eT get_val() const { return val; }
  2107. static const bool do_trans = false;
  2108. static const bool do_times = true;
  2109. const eT val;
  2110. const Row<eT>* M_local;
  2111. const Row<eT>& M;
  2112. };
  2113. template<typename eT>
  2114. struct partial_unwrap_check< eOp<Col<eT>, eop_scalar_times> >
  2115. {
  2116. typedef Col<eT> stored_type;
  2117. inline
  2118. partial_unwrap_check(const eOp<Col<eT>,eop_scalar_times>& A, const Mat<eT>& B)
  2119. : val ( A.aux )
  2120. , M_local( (&(A.P.Q) == &B) ? new Col<eT>(A.P.Q) : 0 )
  2121. , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q )
  2122. {
  2123. arma_extra_debug_sigprint();
  2124. }
  2125. inline
  2126. ~partial_unwrap_check()
  2127. {
  2128. arma_extra_debug_sigprint();
  2129. if(M_local) { delete M_local; }
  2130. }
  2131. arma_inline eT get_val() const { return val; }
  2132. static const bool do_trans = false;
  2133. static const bool do_times = true;
  2134. const eT val;
  2135. const Col<eT>* M_local;
  2136. const Col<eT>& M;
  2137. };
  2138. // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class,
  2139. // NOTE: which relies on partial_unwrap_check to check for aliasing
  2140. template<typename eT>
  2141. struct partial_unwrap_check< eOp<subview_col<eT>, eop_scalar_times> >
  2142. {
  2143. typedef Col<eT> stored_type;
  2144. inline
  2145. partial_unwrap_check(const eOp<subview_col<eT>,eop_scalar_times>& A, const Mat<eT>& B)
  2146. : val( A.aux )
  2147. , M ( const_cast<eT*>( A.P.Q.colptr(0) ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false )
  2148. {
  2149. arma_extra_debug_sigprint();
  2150. }
  2151. arma_inline eT get_val() const { return val; }
  2152. static const bool do_trans = false;
  2153. static const bool do_times = true;
  2154. const eT val;
  2155. const Col<eT> M;
  2156. };
  2157. template<typename T1>
  2158. struct partial_unwrap_check_neg_default
  2159. {
  2160. typedef typename T1::elem_type eT;
  2161. typedef Mat<eT> stored_type;
  2162. inline
  2163. partial_unwrap_check_neg_default(const eOp<T1, eop_neg>& A, const Mat<eT>&)
  2164. : M(A.P.Q)
  2165. {
  2166. arma_extra_debug_sigprint();
  2167. }
  2168. arma_inline eT get_val() const { return eT(-1); }
  2169. static const bool do_trans = false;
  2170. static const bool do_times = true;
  2171. const Mat<eT> M;
  2172. };
  2173. template<typename T1>
  2174. struct partial_unwrap_check_neg_fixed
  2175. {
  2176. typedef typename T1::elem_type eT;
  2177. typedef T1 stored_type;
  2178. inline explicit
  2179. partial_unwrap_check_neg_fixed(const eOp<T1, eop_neg>& A, const Mat<eT>& B)
  2180. : M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : 0 )
  2181. , M ( (&(A.P.Q) == &B) ? (*M_local) : A.P.Q )
  2182. {
  2183. arma_extra_debug_sigprint();
  2184. }
  2185. inline
  2186. ~partial_unwrap_check_neg_fixed()
  2187. {
  2188. arma_extra_debug_sigprint();
  2189. if(M_local) { delete M_local; }
  2190. }
  2191. arma_inline eT get_val() const { return eT(-1); }
  2192. static const bool do_trans = false;
  2193. static const bool do_times = true;
  2194. const T1* M_local;
  2195. const T1& M;
  2196. };
  2197. template<typename T1, bool condition>
  2198. struct partial_unwrap_check_neg_redirect {};
  2199. template<typename T1>
  2200. struct partial_unwrap_check_neg_redirect<T1, false> { typedef partial_unwrap_check_neg_default<T1> result; };
  2201. template<typename T1>
  2202. struct partial_unwrap_check_neg_redirect<T1, true> { typedef partial_unwrap_check_neg_fixed<T1> result; };
  2203. template<typename T1>
  2204. struct partial_unwrap_check< eOp<T1, eop_neg> > : public partial_unwrap_check_neg_redirect<T1, is_Mat_fixed<T1>::value >::result
  2205. {
  2206. typedef typename T1::elem_type eT;
  2207. inline partial_unwrap_check(const eOp<T1, eop_neg>& A, const Mat<eT>& B)
  2208. : partial_unwrap_check_neg_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
  2209. {
  2210. }
  2211. };
  2212. template<typename eT>
  2213. struct partial_unwrap_check< eOp<Mat<eT>, eop_neg> >
  2214. {
  2215. typedef Mat<eT> stored_type;
  2216. inline
  2217. partial_unwrap_check(const eOp<Mat<eT>,eop_neg>& A, const Mat<eT>& B)
  2218. : M_local( (&(A.P.Q) == &B) ? new Mat<eT>(A.P.Q) : 0 )
  2219. , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q )
  2220. {
  2221. arma_extra_debug_sigprint();
  2222. }
  2223. inline
  2224. ~partial_unwrap_check()
  2225. {
  2226. arma_extra_debug_sigprint();
  2227. if(M_local) { delete M_local; }
  2228. }
  2229. arma_inline eT get_val() const { return eT(-1); }
  2230. static const bool do_trans = false;
  2231. static const bool do_times = true;
  2232. const Mat<eT>* M_local;
  2233. const Mat<eT>& M;
  2234. };
  2235. template<typename eT>
  2236. struct partial_unwrap_check< eOp<Row<eT>, eop_neg> >
  2237. {
  2238. typedef Row<eT> stored_type;
  2239. inline
  2240. partial_unwrap_check(const eOp<Row<eT>,eop_neg>& A, const Mat<eT>& B)
  2241. : M_local( (&(A.P.Q) == &B) ? new Row<eT>(A.P.Q) : 0 )
  2242. , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q )
  2243. {
  2244. arma_extra_debug_sigprint();
  2245. }
  2246. inline
  2247. ~partial_unwrap_check()
  2248. {
  2249. arma_extra_debug_sigprint();
  2250. if(M_local) { delete M_local; }
  2251. }
  2252. arma_inline eT get_val() const { return eT(-1); }
  2253. static const bool do_trans = false;
  2254. static const bool do_times = true;
  2255. const Row<eT>* M_local;
  2256. const Row<eT>& M;
  2257. };
  2258. template<typename eT>
  2259. struct partial_unwrap_check< eOp<Col<eT>, eop_neg> >
  2260. {
  2261. typedef Col<eT> stored_type;
  2262. inline
  2263. partial_unwrap_check(const eOp<Col<eT>,eop_neg>& A, const Mat<eT>& B)
  2264. : M_local( (&(A.P.Q) == &B) ? new Col<eT>(A.P.Q) : 0 )
  2265. , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q )
  2266. {
  2267. arma_extra_debug_sigprint();
  2268. }
  2269. inline
  2270. ~partial_unwrap_check()
  2271. {
  2272. arma_extra_debug_sigprint();
  2273. if(M_local) { delete M_local; }
  2274. }
  2275. arma_inline eT get_val() const { return eT(-1); }
  2276. static const bool do_trans = false;
  2277. static const bool do_times = true;
  2278. const Col<eT>* M_local;
  2279. const Col<eT>& M;
  2280. };
  2281. // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class,
  2282. // NOTE: which relies on partial_unwrap_check to check for aliasing
  2283. template<typename eT>
  2284. struct partial_unwrap_check< eOp<subview_col<eT>, eop_neg> >
  2285. {
  2286. typedef Col<eT> stored_type;
  2287. inline
  2288. partial_unwrap_check(const eOp<subview_col<eT>,eop_neg>& A, const Mat<eT>& B)
  2289. : M ( const_cast<eT*>( A.P.Q.colptr(0) ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false )
  2290. {
  2291. arma_extra_debug_sigprint();
  2292. }
  2293. arma_inline eT get_val() const { return eT(-1); }
  2294. static const bool do_trans = false;
  2295. static const bool do_times = true;
  2296. const Col<eT> M;
  2297. };
  2298. //! @}