1 // SPDX-License-Identifier: Apache-2.0 2 // 3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) 4 // Copyright 2008-2016 National ICT Australia (NICTA) 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // ------------------------------------------------------------------------ 17 18 19 //! \addtogroup unwrap 20 //! @{ 21 22 23 // TODO: document the conditions and restrictions for the use of each unwrap variant: 24 // TODO: unwrap, unwrap_check, quasi_unwrap, partial_unwrap, partial_unwrap_check 25 26 27 template<typename T1> 28 struct unwrap_default 29 { 30 typedef typename T1::elem_type eT; 31 typedef Mat<eT> stored_type; 32 33 inline unwrap_defaultunwrap_default34 unwrap_default(const T1& A) 35 : M(A) 36 { 37 arma_extra_debug_sigprint(); 38 } 39 40 const Mat<eT> M; 41 }; 42 43 44 45 template<typename T1> 46 struct unwrap_fixed 47 { 48 typedef T1 stored_type; 49 50 inline explicit unwrap_fixedunwrap_fixed51 unwrap_fixed(const T1& A) 52 : M(A) 53 { 54 arma_extra_debug_sigprint(); 55 } 56 57 const T1& M; 58 }; 59 60 61 62 template<typename T1, bool condition> 63 struct unwrap_redirect {}; 64 65 template<typename T1> 66 struct unwrap_redirect<T1, false> { typedef unwrap_default<T1> result; }; 67 68 template<typename T1> 69 struct unwrap_redirect<T1, true> { typedef unwrap_fixed<T1> result; }; 70 71 72 template<typename T1> 73 struct unwrap : public unwrap_redirect<T1, is_Mat_fixed<T1>::value>::result 74 { 75 inline unwrapunwrap76 unwrap(const T1& A) 77 : unwrap_redirect<T1, is_Mat_fixed<T1>::value>::result(A) 78 { 79 } 80 }; 81 82 83 84 template<typename eT> 85 struct unwrap< Mat<eT> > 86 { 87 typedef Mat<eT> stored_type; 88 89 inline unwrapunwrap90 unwrap(const Mat<eT>& A) 91 : M(A) 92 { 93 arma_extra_debug_sigprint(); 94 } 95 96 const Mat<eT>& M; 97 }; 98 99 100 101 template<typename eT> 102 struct unwrap< Row<eT> > 103 { 104 typedef Row<eT> stored_type; 105 106 inline unwrapunwrap107 unwrap(const Row<eT>& A) 108 : M(A) 109 { 110 arma_extra_debug_sigprint(); 111 } 112 113 const Row<eT>& M; 114 }; 115 116 117 118 template<typename eT> 119 struct unwrap< Col<eT> > 120 { 121 typedef Col<eT> stored_type; 122 123 inline unwrapunwrap124 unwrap(const Col<eT>& A) 125 : M(A) 126 { 127 arma_extra_debug_sigprint(); 128 } 129 130 const Col<eT>& M; 131 }; 132 133 134 135 template<typename eT> 136 struct unwrap< subview_col<eT> > 137 { 138 typedef Col<eT> stored_type; 139 140 inline unwrapunwrap141 unwrap(const subview_col<eT>& A) 142 : M(A.colmem, A.n_rows) 143 { 144 arma_extra_debug_sigprint(); 145 } 146 147 const Col<eT> M; 148 }; 149 150 151 152 template<typename eT> 153 struct unwrap< subview_cols<eT> > 154 { 155 typedef Mat<eT> stored_type; 156 157 inline unwrapunwrap158 unwrap(const subview_cols<eT>& A) 159 : M(A.colptr(0), A.n_rows, A.n_cols) 160 { 161 arma_extra_debug_sigprint(); 162 } 163 164 const Mat<eT> M; 165 }; 166 167 168 169 template<typename out_eT, typename T1, typename T2, typename glue_type> 170 struct unwrap< mtGlue<out_eT, T1, T2, glue_type> > 171 { 172 typedef Mat<out_eT> stored_type; 173 174 inline unwrapunwrap175 unwrap(const mtGlue<out_eT, T1, T2, glue_type>& A) 176 : M(A) 177 { 178 arma_extra_debug_sigprint(); 179 } 180 181 const Mat<out_eT> M; 182 }; 183 184 185 186 template<typename out_eT, typename T1, typename op_type> 187 struct unwrap< mtOp<out_eT, T1, op_type> > 188 { 189 typedef Mat<out_eT> stored_type; 190 191 inline unwrapunwrap192 unwrap(const mtOp<out_eT, T1, op_type>& A) 193 : M(A) 194 { 195 arma_extra_debug_sigprint(); 196 } 197 198 const Mat<out_eT> M; 199 }; 200 201 202 203 // 204 // 205 // 206 207 208 209 template<typename T1> 210 struct quasi_unwrap_default 211 { 212 typedef typename T1::elem_type eT; 213 214 inline quasi_unwrap_defaultquasi_unwrap_default215 quasi_unwrap_default(const T1& A) 216 : M(A) 217 { 218 arma_extra_debug_sigprint(); 219 } 220 221 // NOTE: DO NOT DIRECTLY CHECK FOR ALIASING BY TAKING THE ADDRESS OF THE "M" OBJECT IN ANY quasi_unwrap CLASS !!! 222 Mat<eT> M; 223 224 static constexpr bool is_const = false; 225 static constexpr bool has_subview = false; 226 static constexpr bool has_orig_mem = false; 227 228 template<typename eT2> is_aliasquasi_unwrap_default229 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 230 }; 231 232 233 234 template<typename T1> 235 struct quasi_unwrap_fixed 236 { 237 typedef typename T1::elem_type eT; 238 239 inline explicit quasi_unwrap_fixedquasi_unwrap_fixed240 quasi_unwrap_fixed(const T1& A) 241 : M(A) 242 { 243 arma_extra_debug_sigprint(); 244 } 245 246 const T1& M; 247 248 static constexpr bool is_const = true; 249 static constexpr bool has_subview = false; 250 static constexpr bool has_orig_mem = true; 251 252 template<typename eT2> is_aliasquasi_unwrap_fixed253 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); } 254 }; 255 256 257 258 template<typename T1, bool condition> 259 struct quasi_unwrap_redirect {}; 260 261 template<typename T1> 262 struct quasi_unwrap_redirect<T1, false> { typedef quasi_unwrap_default<T1> result; }; 263 264 template<typename T1> 265 struct quasi_unwrap_redirect<T1, true> { typedef quasi_unwrap_fixed<T1> result; }; 266 267 268 template<typename T1> 269 struct quasi_unwrap : public quasi_unwrap_redirect<T1, is_Mat_fixed<T1>::value>::result 270 { 271 typedef typename quasi_unwrap_redirect<T1, is_Mat_fixed<T1>::value>::result quasi_unwrap_extra; 272 273 inline quasi_unwrapquasi_unwrap274 quasi_unwrap(const T1& A) 275 : quasi_unwrap_extra(A) 276 { 277 } 278 279 static constexpr bool is_const = quasi_unwrap_extra::is_const; 280 static constexpr bool has_subview = quasi_unwrap_extra::has_subview; 281 static constexpr bool has_orig_mem = quasi_unwrap_extra::has_orig_mem; 282 283 using quasi_unwrap_extra::M; 284 using quasi_unwrap_extra::is_alias; 285 }; 286 287 288 289 template<typename eT> 290 struct quasi_unwrap< Mat<eT> > 291 { 292 inline quasi_unwrapquasi_unwrap293 quasi_unwrap(const Mat<eT>& A) 294 : M(A) 295 { 296 arma_extra_debug_sigprint(); 297 } 298 299 const Mat<eT>& M; 300 301 static constexpr bool is_const = true; 302 static constexpr bool has_subview = false; 303 static constexpr bool has_orig_mem = true; 304 305 template<typename eT2> is_aliasquasi_unwrap306 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); } 307 }; 308 309 310 311 template<typename eT> 312 struct quasi_unwrap< Row<eT> > 313 { 314 315 inline quasi_unwrapquasi_unwrap316 quasi_unwrap(const Row<eT>& A) 317 : M(A) 318 { 319 arma_extra_debug_sigprint(); 320 } 321 322 const Row<eT>& M; 323 324 static constexpr bool is_const = true; 325 static constexpr bool has_subview = false; 326 static constexpr bool has_orig_mem = true; 327 328 template<typename eT2> is_aliasquasi_unwrap329 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); } 330 }; 331 332 333 334 template<typename eT> 335 struct quasi_unwrap< Col<eT> > 336 { 337 inline quasi_unwrapquasi_unwrap338 quasi_unwrap(const Col<eT>& A) 339 : M(A) 340 { 341 arma_extra_debug_sigprint(); 342 } 343 344 const Col<eT>& M; 345 346 static constexpr bool is_const = true; 347 static constexpr bool has_subview = false; 348 static constexpr bool has_orig_mem = true; 349 350 template<typename eT2> is_aliasquasi_unwrap351 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); } 352 }; 353 354 355 356 template<typename eT> 357 struct quasi_unwrap< subview<eT> > 358 { 359 inline quasi_unwrapquasi_unwrap360 quasi_unwrap(const subview<eT>& A) 361 : sv( A ) 362 , M ( A, ((A.aux_row1 == 0) && (A.n_rows == A.m.n_rows)) ) // reuse memory if the subview is a contiguous chunk 363 { 364 arma_extra_debug_sigprint(); 365 } 366 367 const subview<eT>& sv; 368 const Mat<eT> M; 369 370 static constexpr bool is_const = true; 371 static constexpr bool has_subview = true; 372 static constexpr 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 373 374 template<typename eT2> is_aliasquasi_unwrap375 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 ); } 376 }; 377 378 379 380 template<typename eT> 381 struct quasi_unwrap< subview_row<eT> > 382 { 383 inline quasi_unwrapquasi_unwrap384 quasi_unwrap(const subview_row<eT>& A) 385 : M(A) 386 { 387 arma_extra_debug_sigprint(); 388 } 389 390 Row<eT> M; 391 392 static constexpr bool is_const = false; 393 static constexpr bool has_subview = false; 394 static constexpr bool has_orig_mem = false; 395 396 template<typename eT2> is_aliasquasi_unwrap397 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 398 }; 399 400 401 402 template<typename eT> 403 struct quasi_unwrap< subview_col<eT> > 404 { 405 inline quasi_unwrapquasi_unwrap406 quasi_unwrap(const subview_col<eT>& A) 407 : orig( A.m ) 408 , M ( const_cast<eT*>( A.colmem ), A.n_rows, false, false ) 409 { 410 arma_extra_debug_sigprint(); 411 } 412 413 const Mat<eT>& orig; 414 const Col<eT> M; 415 416 static constexpr bool is_const = true; 417 static constexpr bool has_subview = true; 418 static constexpr bool has_orig_mem = true; 419 420 template<typename eT2> is_aliasquasi_unwrap421 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); } 422 }; 423 424 425 426 template<typename eT> 427 struct quasi_unwrap< subview_cols<eT> > 428 { 429 inline quasi_unwrapquasi_unwrap430 quasi_unwrap(const subview_cols<eT>& A) 431 : orig( A.m ) 432 , M ( const_cast<eT*>( A.colptr(0) ), A.n_rows, A.n_cols, false, false ) 433 { 434 arma_extra_debug_sigprint(); 435 } 436 437 const Mat<eT>& orig; 438 const Mat<eT> M; 439 440 static constexpr bool is_const = true; 441 static constexpr bool has_subview = true; 442 static constexpr bool has_orig_mem = true; 443 444 template<typename eT2> is_aliasquasi_unwrap445 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); } 446 }; 447 448 449 450 template<typename out_eT, typename T1, typename T2, typename glue_type> 451 struct quasi_unwrap< mtGlue<out_eT, T1, T2, glue_type> > 452 { 453 inline quasi_unwrapquasi_unwrap454 quasi_unwrap(const mtGlue<out_eT, T1, T2, glue_type>& A) 455 : M(A) 456 { 457 arma_extra_debug_sigprint(); 458 } 459 460 Mat<out_eT> M; 461 462 static constexpr bool is_const = false; 463 static constexpr bool has_subview = false; 464 static constexpr bool has_orig_mem = false; 465 466 template<typename eT2> is_aliasquasi_unwrap467 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 468 }; 469 470 471 472 template<typename out_eT, typename T1, typename op_type> 473 struct quasi_unwrap< mtOp<out_eT, T1, op_type> > 474 { 475 inline quasi_unwrapquasi_unwrap476 quasi_unwrap(const mtOp<out_eT, T1, op_type>& A) 477 : M(A) 478 { 479 arma_extra_debug_sigprint(); 480 } 481 482 Mat<out_eT> M; 483 484 static constexpr bool is_const = false; 485 static constexpr bool has_subview = false; 486 static constexpr bool has_orig_mem = false; 487 488 template<typename eT2> is_aliasquasi_unwrap489 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 490 }; 491 492 493 494 template<typename T1> 495 struct quasi_unwrap< Op<T1, op_vectorise_col> > 496 { 497 typedef typename T1::elem_type eT; 498 499 inline quasi_unwrapquasi_unwrap500 quasi_unwrap(const Op<T1, op_vectorise_col>& A) 501 : U( A.m ) 502 , M( const_cast<eT*>(U.M.memptr()), U.M.n_elem, 1, false, false ) 503 { 504 arma_extra_debug_sigprint(); 505 } 506 507 const quasi_unwrap<T1> U; 508 const Mat<eT> M; 509 510 static constexpr bool is_const = true; 511 static constexpr bool has_subview = true; 512 static constexpr bool has_orig_mem = true; 513 514 template<typename eT2> is_aliasquasi_unwrap515 arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); } 516 }; 517 518 519 520 template<typename eT> 521 struct quasi_unwrap< Op<Col<eT>, op_strans> > 522 { 523 inline quasi_unwrapquasi_unwrap524 quasi_unwrap(const Op<Col<eT>, op_strans>& A) 525 : orig(A.m) 526 , M (const_cast<eT*>(A.m.memptr()), A.m.n_elem, false, false) 527 { 528 arma_extra_debug_sigprint(); 529 } 530 531 const Col<eT>& orig; 532 const Row<eT> M; 533 534 static constexpr bool is_const = true; 535 static constexpr bool has_subview = true; 536 static constexpr bool has_orig_mem = true; 537 538 template<typename eT2> is_aliasquasi_unwrap539 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); } 540 }; 541 542 543 544 template<typename eT> 545 struct quasi_unwrap< Op<Row<eT>, op_strans> > 546 { 547 inline quasi_unwrapquasi_unwrap548 quasi_unwrap(const Op<Row<eT>, op_strans>& A) 549 : orig(A.m) 550 , M (const_cast<eT*>(A.m.memptr()), A.m.n_elem, false, false) 551 { 552 arma_extra_debug_sigprint(); 553 } 554 555 const Row<eT>& orig; 556 const Col<eT> M; 557 558 static constexpr bool is_const = true; 559 static constexpr bool has_subview = true; 560 static constexpr bool has_orig_mem = true; 561 562 template<typename eT2> is_aliasquasi_unwrap563 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); } 564 }; 565 566 567 568 template<typename eT> 569 struct quasi_unwrap< Op<subview_col<eT>, op_strans> > 570 { 571 inline quasi_unwrapquasi_unwrap572 quasi_unwrap(const Op<subview_col<eT>, op_strans>& A) 573 : orig( A.m.m ) 574 , M ( const_cast<eT*>( A.m.colmem ), A.m.n_rows, false, false ) 575 { 576 arma_extra_debug_sigprint(); 577 } 578 579 const Mat<eT>& orig; 580 const Row<eT> M; 581 582 static constexpr bool is_const = true; 583 static constexpr bool has_subview = true; 584 static constexpr bool has_orig_mem = true; 585 586 template<typename eT2> is_aliasquasi_unwrap587 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); } 588 }; 589 590 591 592 template<typename T1> 593 struct quasi_unwrap_Col_htrans 594 { quasi_unwrap_Col_htransquasi_unwrap_Col_htrans595 inline quasi_unwrap_Col_htrans(const T1&) {} 596 }; 597 598 599 600 template<typename eT> 601 struct quasi_unwrap_Col_htrans< Op<Col<eT>, op_htrans> > 602 { 603 inline quasi_unwrap_Col_htransquasi_unwrap_Col_htrans604 quasi_unwrap_Col_htrans(const Op<Col<eT>, op_htrans>& A) 605 : orig(A.m) 606 , M (const_cast<eT*>(A.m.memptr()), A.m.n_elem, false, false) 607 { 608 arma_extra_debug_sigprint(); 609 } 610 611 const Col<eT>& orig; 612 const Row<eT> M; 613 614 static constexpr bool is_const = true; 615 static constexpr bool has_subview = true; 616 static constexpr bool has_orig_mem = true; 617 618 template<typename eT2> is_aliasquasi_unwrap_Col_htrans619 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); } 620 }; 621 622 623 624 template<typename T1, bool condition> 625 struct quasi_unwrap_Col_htrans_redirect {}; 626 627 template<typename T1> 628 struct quasi_unwrap_Col_htrans_redirect<T1, true> { typedef quasi_unwrap_default<T1> result; }; 629 630 template<typename T1> 631 struct quasi_unwrap_Col_htrans_redirect<T1, false> { typedef quasi_unwrap_Col_htrans<T1> result; }; 632 633 634 template<typename eT> 635 struct quasi_unwrap< Op<Col<eT>, op_htrans> > 636 : public quasi_unwrap_Col_htrans_redirect< Op<Col<eT>, op_htrans>, is_cx<eT>::value >::result 637 { 638 typedef typename quasi_unwrap_Col_htrans_redirect< Op<Col<eT>, op_htrans>, is_cx<eT>::value >::result quasi_unwrap_Col_htrans_extra; 639 640 inline quasi_unwrapquasi_unwrap641 quasi_unwrap(const Op<Col<eT>, op_htrans>& A) 642 : quasi_unwrap_Col_htrans_extra(A) 643 { 644 } 645 646 static constexpr bool is_const = quasi_unwrap_Col_htrans_extra::is_const; 647 static constexpr bool has_subview = quasi_unwrap_Col_htrans_extra::has_subview; 648 static constexpr bool has_orig_mem = quasi_unwrap_Col_htrans_extra::has_orig_mem; 649 650 using quasi_unwrap_Col_htrans_extra::M; 651 using quasi_unwrap_Col_htrans_extra::is_alias; 652 }; 653 654 655 656 template<typename T1> 657 struct quasi_unwrap_Row_htrans 658 { quasi_unwrap_Row_htransquasi_unwrap_Row_htrans659 inline quasi_unwrap_Row_htrans(const T1&) {} 660 }; 661 662 663 664 template<typename eT> 665 struct quasi_unwrap_Row_htrans< Op<Row<eT>, op_htrans> > 666 { 667 inline quasi_unwrap_Row_htransquasi_unwrap_Row_htrans668 quasi_unwrap_Row_htrans(const Op<Row<eT>, op_htrans>& A) 669 : orig(A.m) 670 , M (const_cast<eT*>(A.m.memptr()), A.m.n_elem, false, false) 671 { 672 arma_extra_debug_sigprint(); 673 } 674 675 const Row<eT>& orig; 676 const Col<eT> M; 677 678 static constexpr bool is_const = true; 679 static constexpr bool has_subview = true; 680 static constexpr bool has_orig_mem = true; 681 682 template<typename eT2> is_aliasquasi_unwrap_Row_htrans683 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); } 684 }; 685 686 687 688 template<typename T1, bool condition> 689 struct quasi_unwrap_Row_htrans_redirect {}; 690 691 template<typename T1> 692 struct quasi_unwrap_Row_htrans_redirect<T1, true> { typedef quasi_unwrap_default<T1> result; }; 693 694 template<typename T1> 695 struct quasi_unwrap_Row_htrans_redirect<T1, false> { typedef quasi_unwrap_Row_htrans<T1> result; }; 696 697 698 template<typename eT> 699 struct quasi_unwrap< Op<Row<eT>, op_htrans> > 700 : public quasi_unwrap_Row_htrans_redirect< Op<Row<eT>, op_htrans>, is_cx<eT>::value >::result 701 { 702 typedef typename quasi_unwrap_Row_htrans_redirect< Op<Row<eT>, op_htrans>, is_cx<eT>::value >::result quasi_unwrap_Row_htrans_extra; 703 704 inline quasi_unwrapquasi_unwrap705 quasi_unwrap(const Op<Row<eT>, op_htrans>& A) 706 : quasi_unwrap_Row_htrans_extra(A) 707 { 708 } 709 710 static constexpr bool is_const = quasi_unwrap_Row_htrans_extra::is_const; 711 static constexpr bool has_subview = quasi_unwrap_Row_htrans_extra::has_subview; 712 static constexpr bool has_orig_mem = quasi_unwrap_Row_htrans_extra::has_orig_mem; 713 714 using quasi_unwrap_Row_htrans_extra::M; 715 using quasi_unwrap_Row_htrans_extra::is_alias; 716 }; 717 718 719 720 template<typename T1> 721 struct quasi_unwrap_subview_col_htrans 722 { quasi_unwrap_subview_col_htransquasi_unwrap_subview_col_htrans723 inline quasi_unwrap_subview_col_htrans(const T1&) {} 724 }; 725 726 727 728 template<typename eT> 729 struct quasi_unwrap_subview_col_htrans< Op<subview_col<eT>, op_htrans> > 730 { 731 inline quasi_unwrap_subview_col_htransquasi_unwrap_subview_col_htrans732 quasi_unwrap_subview_col_htrans(const Op<subview_col<eT>, op_htrans>& A) 733 : orig(A.m.m) 734 , M (const_cast<eT*>(A.m.colmem), A.m.n_rows, false, false) 735 { 736 arma_extra_debug_sigprint(); 737 } 738 739 const Mat<eT>& orig; 740 const Row<eT> M; 741 742 static constexpr bool is_const = true; 743 static constexpr bool has_subview = true; 744 static constexpr bool has_orig_mem = true; 745 746 template<typename eT2> is_aliasquasi_unwrap_subview_col_htrans747 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); } 748 }; 749 750 751 752 template<typename T1, bool condition> 753 struct quasi_unwrap_subview_col_htrans_redirect {}; 754 755 template<typename T1> 756 struct quasi_unwrap_subview_col_htrans_redirect<T1, true> { typedef quasi_unwrap_default<T1> result; }; 757 758 template<typename T1> 759 struct quasi_unwrap_subview_col_htrans_redirect<T1, false> { typedef quasi_unwrap_subview_col_htrans<T1> result; }; 760 761 762 template<typename eT> 763 struct quasi_unwrap< Op<subview_col<eT>, op_htrans> > 764 : public quasi_unwrap_subview_col_htrans_redirect< Op<subview_col<eT>, op_htrans>, is_cx<eT>::value >::result 765 { 766 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; 767 768 inline quasi_unwrapquasi_unwrap769 quasi_unwrap(const Op<subview_col<eT>, op_htrans>& A) 770 : quasi_unwrap_subview_col_htrans_extra(A) 771 { 772 } 773 774 static constexpr bool is_const = quasi_unwrap_subview_col_htrans_extra::is_const; 775 static constexpr bool has_subview = quasi_unwrap_subview_col_htrans_extra::has_subview; 776 static constexpr bool has_orig_mem = quasi_unwrap_subview_col_htrans_extra::has_orig_mem; 777 778 using quasi_unwrap_subview_col_htrans_extra::M; 779 using quasi_unwrap_subview_col_htrans_extra::is_alias; 780 }; 781 782 783 784 template<typename T1> 785 struct quasi_unwrap< CubeToMatOp<T1, op_vectorise_cube_col> > 786 { 787 typedef typename T1::elem_type eT; 788 789 inline quasi_unwrapquasi_unwrap790 quasi_unwrap(const CubeToMatOp<T1, op_vectorise_cube_col>& A) 791 : U( A.m ) 792 , M( const_cast<eT*>(U.M.memptr()), U.M.n_elem, 1, false, true ) 793 { 794 arma_extra_debug_sigprint(); 795 } 796 797 const unwrap_cube<T1> U; 798 const Mat<eT> M; 799 800 static constexpr bool is_const = true; 801 static constexpr bool has_subview = true; 802 static constexpr bool has_orig_mem = true; 803 804 template<typename eT2> is_aliasquasi_unwrap805 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 806 }; 807 808 809 810 template<typename T1> 811 struct quasi_unwrap< SpToDOp<T1, op_nonzeros_spmat> > 812 { 813 typedef typename T1::elem_type eT; 814 815 inline quasi_unwrapquasi_unwrap816 quasi_unwrap(const SpToDOp<T1, op_nonzeros_spmat>& A) 817 : U( A.m ) 818 , M( const_cast<eT*>(U.M.values), U.M.n_nonzero, 1, false, true ) 819 { 820 arma_extra_debug_sigprint(); 821 } 822 823 const unwrap_spmat<T1> U; 824 const Mat<eT> M; 825 826 static constexpr bool is_const = true; 827 static constexpr bool has_subview = true; 828 static constexpr bool has_orig_mem = true; 829 830 template<typename eT2> is_aliasquasi_unwrap831 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 832 }; 833 834 835 836 // 837 // 838 // 839 840 841 842 template<typename T1> 843 struct unwrap_check_default 844 { 845 typedef typename T1::elem_type eT; 846 typedef Mat<eT> stored_type; 847 848 inline unwrap_check_defaultunwrap_check_default849 unwrap_check_default(const T1& A, const Mat<eT>&) 850 : M(A) 851 { 852 arma_extra_debug_sigprint(); 853 } 854 855 inline unwrap_check_defaultunwrap_check_default856 unwrap_check_default(const T1& A, const bool) 857 : M(A) 858 { 859 arma_extra_debug_sigprint(); 860 } 861 862 const Mat<eT> M; 863 }; 864 865 866 867 template<typename T1> 868 struct unwrap_check_fixed 869 { 870 typedef typename T1::elem_type eT; 871 typedef T1 stored_type; 872 873 inline unwrap_check_fixedunwrap_check_fixed874 unwrap_check_fixed(const T1& A, const Mat<eT>& B) 875 : M_local( (&A == &B) ? new T1(A) : nullptr ) 876 , M ( (&A == &B) ? *M_local : A ) 877 { 878 arma_extra_debug_sigprint(); 879 } 880 881 inline unwrap_check_fixedunwrap_check_fixed882 unwrap_check_fixed(const T1& A, const bool is_alias) 883 : M_local( is_alias ? new T1(A) : nullptr ) 884 , M ( is_alias ? *M_local : A ) 885 { 886 arma_extra_debug_sigprint(); 887 } 888 889 inline ~unwrap_check_fixedunwrap_check_fixed890 ~unwrap_check_fixed() 891 { 892 arma_extra_debug_sigprint(); 893 894 if(M_local) { delete M_local; } 895 } 896 897 898 // the order below is important 899 const T1* M_local; 900 const T1& M; 901 }; 902 903 904 905 template<typename T1, bool condition> 906 struct unwrap_check_redirect {}; 907 908 template<typename T1> 909 struct unwrap_check_redirect<T1, false> { typedef unwrap_check_default<T1> result; }; 910 911 template<typename T1> 912 struct unwrap_check_redirect<T1, true> { typedef unwrap_check_fixed<T1> result; }; 913 914 915 template<typename T1> 916 struct unwrap_check : public unwrap_check_redirect<T1, is_Mat_fixed<T1>::value>::result 917 { unwrap_checkunwrap_check918 inline unwrap_check(const T1& A, const Mat<typename T1::elem_type>& B) 919 : unwrap_check_redirect<T1, is_Mat_fixed<T1>::value>::result(A, B) 920 { 921 } 922 unwrap_checkunwrap_check923 inline unwrap_check(const T1& A, const bool is_alias) 924 : unwrap_check_redirect<T1, is_Mat_fixed<T1>::value>::result(A, is_alias) 925 { 926 } 927 }; 928 929 930 931 template<typename eT> 932 struct unwrap_check< Mat<eT> > 933 { 934 typedef Mat<eT> stored_type; 935 936 inline unwrap_checkunwrap_check937 unwrap_check(const Mat<eT>& A, const Mat<eT>& B) 938 : M_local( (&A == &B) ? new Mat<eT>(A) : nullptr ) 939 , M ( (&A == &B) ? (*M_local) : A ) 940 { 941 arma_extra_debug_sigprint(); 942 } 943 944 inline unwrap_checkunwrap_check945 unwrap_check(const Mat<eT>& A, const bool is_alias) 946 : M_local( is_alias ? new Mat<eT>(A) : nullptr ) 947 , M ( is_alias ? (*M_local) : A ) 948 { 949 arma_extra_debug_sigprint(); 950 } 951 952 inline ~unwrap_checkunwrap_check953 ~unwrap_check() 954 { 955 arma_extra_debug_sigprint(); 956 957 if(M_local) { delete M_local; } 958 } 959 960 961 // the order below is important 962 const Mat<eT>* M_local; 963 const Mat<eT>& M; 964 }; 965 966 967 968 template<typename eT> 969 struct unwrap_check< Row<eT> > 970 { 971 typedef Row<eT> stored_type; 972 973 inline unwrap_checkunwrap_check974 unwrap_check(const Row<eT>& A, const Mat<eT>& B) 975 : M_local( (&A == &B) ? new Row<eT>(A) : nullptr ) 976 , M ( (&A == &B) ? (*M_local) : A ) 977 { 978 arma_extra_debug_sigprint(); 979 } 980 981 inline unwrap_checkunwrap_check982 unwrap_check(const Row<eT>& A, const bool is_alias) 983 : M_local( is_alias ? new Row<eT>(A) : nullptr ) 984 , M ( is_alias ? (*M_local) : A ) 985 { 986 arma_extra_debug_sigprint(); 987 } 988 989 inline ~unwrap_checkunwrap_check990 ~unwrap_check() 991 { 992 arma_extra_debug_sigprint(); 993 994 if(M_local) { delete M_local; } 995 } 996 997 998 // the order below is important 999 const Row<eT>* M_local; 1000 const Row<eT>& M; 1001 }; 1002 1003 1004 1005 template<typename eT> 1006 struct unwrap_check< Col<eT> > 1007 { 1008 typedef Col<eT> stored_type; 1009 1010 inline unwrap_checkunwrap_check1011 unwrap_check(const Col<eT>& A, const Mat<eT>& B) 1012 : M_local( (&A == &B) ? new Col<eT>(A) : nullptr ) 1013 , M ( (&A == &B) ? (*M_local) : A ) 1014 { 1015 arma_extra_debug_sigprint(); 1016 } 1017 1018 inline unwrap_checkunwrap_check1019 unwrap_check(const Col<eT>& A, const bool is_alias) 1020 : M_local( is_alias ? new Col<eT>(A) : nullptr ) 1021 , M ( is_alias ? (*M_local) : A ) 1022 { 1023 arma_extra_debug_sigprint(); 1024 } 1025 1026 inline ~unwrap_checkunwrap_check1027 ~unwrap_check() 1028 { 1029 arma_extra_debug_sigprint(); 1030 1031 if(M_local) { delete M_local; } 1032 } 1033 1034 1035 // the order below is important 1036 const Col<eT>* M_local; 1037 const Col<eT>& M; 1038 }; 1039 1040 1041 1042 // 1043 // 1044 // 1045 1046 1047 1048 template<typename T1> 1049 struct unwrap_check_mixed 1050 { 1051 typedef typename T1::elem_type eT1; 1052 1053 template<typename eT2> 1054 inline unwrap_check_mixedunwrap_check_mixed1055 unwrap_check_mixed(const T1& A, const Mat<eT2>&) 1056 : M(A) 1057 { 1058 arma_extra_debug_sigprint(); 1059 } 1060 1061 //template<typename eT2> 1062 inline unwrap_check_mixedunwrap_check_mixed1063 unwrap_check_mixed(const T1& A, const bool) 1064 : M(A) 1065 { 1066 arma_extra_debug_sigprint(); 1067 } 1068 1069 const Mat<eT1> M; 1070 }; 1071 1072 1073 1074 template<typename eT1> 1075 struct unwrap_check_mixed< Mat<eT1> > 1076 { 1077 template<typename eT2> 1078 inline unwrap_check_mixedunwrap_check_mixed1079 unwrap_check_mixed(const Mat<eT1>& A, const Mat<eT2>& B) 1080 : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Mat<eT1>(A) : nullptr ) 1081 , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) 1082 { 1083 arma_extra_debug_sigprint(); 1084 } 1085 1086 //template<typename eT2> 1087 inline unwrap_check_mixedunwrap_check_mixed1088 unwrap_check_mixed(const Mat<eT1>& A, const bool is_alias) 1089 : M_local( is_alias ? new Mat<eT1>(A) : nullptr ) 1090 , M ( is_alias ? (*M_local) : A ) 1091 { 1092 arma_extra_debug_sigprint(); 1093 } 1094 1095 inline ~unwrap_check_mixedunwrap_check_mixed1096 ~unwrap_check_mixed() 1097 { 1098 arma_extra_debug_sigprint(); 1099 1100 if(M_local) { delete M_local; } 1101 } 1102 1103 1104 // the order below is important 1105 const Mat<eT1>* M_local; 1106 const Mat<eT1>& M; 1107 }; 1108 1109 1110 1111 template<typename eT1> 1112 struct unwrap_check_mixed< Row<eT1> > 1113 { 1114 template<typename eT2> 1115 inline unwrap_check_mixedunwrap_check_mixed1116 unwrap_check_mixed(const Row<eT1>& A, const Mat<eT2>& B) 1117 : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Row<eT1>(A) : nullptr ) 1118 , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) 1119 { 1120 arma_extra_debug_sigprint(); 1121 } 1122 1123 1124 //template<typename eT2> 1125 inline unwrap_check_mixedunwrap_check_mixed1126 unwrap_check_mixed(const Row<eT1>& A, const bool is_alias) 1127 : M_local( is_alias ? new Row<eT1>(A) : nullptr ) 1128 , M ( is_alias ? (*M_local) : A ) 1129 { 1130 arma_extra_debug_sigprint(); 1131 } 1132 1133 inline ~unwrap_check_mixedunwrap_check_mixed1134 ~unwrap_check_mixed() 1135 { 1136 arma_extra_debug_sigprint(); 1137 1138 if(M_local) { delete M_local; } 1139 } 1140 1141 1142 // the order below is important 1143 const Row<eT1>* M_local; 1144 const Row<eT1>& M; 1145 }; 1146 1147 1148 1149 template<typename eT1> 1150 struct unwrap_check_mixed< Col<eT1> > 1151 { 1152 template<typename eT2> 1153 inline unwrap_check_mixedunwrap_check_mixed1154 unwrap_check_mixed(const Col<eT1>& A, const Mat<eT2>& B) 1155 : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Col<eT1>(A) : nullptr ) 1156 , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) 1157 { 1158 arma_extra_debug_sigprint(); 1159 } 1160 1161 //template<typename eT2> 1162 inline unwrap_check_mixedunwrap_check_mixed1163 unwrap_check_mixed(const Col<eT1>& A, const bool is_alias) 1164 : M_local( is_alias ? new Col<eT1>(A) : nullptr ) 1165 , M ( is_alias ? (*M_local) : A ) 1166 { 1167 arma_extra_debug_sigprint(); 1168 } 1169 1170 inline ~unwrap_check_mixedunwrap_check_mixed1171 ~unwrap_check_mixed() 1172 { 1173 arma_extra_debug_sigprint(); 1174 1175 if(M_local) { delete M_local; } 1176 } 1177 1178 1179 // the order below is important 1180 const Col<eT1>* M_local; 1181 const Col<eT1>& M; 1182 }; 1183 1184 1185 1186 // 1187 // 1188 // 1189 1190 1191 1192 template<typename T1> 1193 struct partial_unwrap_default 1194 { 1195 typedef typename T1::elem_type eT; 1196 typedef Mat<eT> stored_type; 1197 1198 inline partial_unwrap_defaultpartial_unwrap_default1199 partial_unwrap_default(const T1& A) 1200 : M(A) 1201 { 1202 arma_extra_debug_sigprint(); 1203 } 1204 get_valpartial_unwrap_default1205 constexpr eT get_val() const { return eT(1); } 1206 1207 template<typename eT2> is_aliaspartial_unwrap_default1208 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 1209 1210 static constexpr bool do_trans = false; 1211 static constexpr bool do_times = false; 1212 1213 const Mat<eT> M; 1214 }; 1215 1216 1217 template<typename T1> 1218 struct partial_unwrap_fixed 1219 { 1220 typedef typename T1::elem_type eT; 1221 typedef T1 stored_type; 1222 1223 inline explicit partial_unwrap_fixedpartial_unwrap_fixed1224 partial_unwrap_fixed(const T1& A) 1225 : M(A) 1226 { 1227 arma_extra_debug_sigprint(); 1228 } 1229 get_valpartial_unwrap_fixed1230 constexpr eT get_val() const { return eT(1); } 1231 1232 template<typename eT2> is_aliaspartial_unwrap_fixed1233 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1234 1235 static constexpr bool do_trans = false; 1236 static constexpr bool do_times = false; 1237 1238 const T1& M; 1239 }; 1240 1241 1242 1243 template<typename T1, bool condition> 1244 struct partial_unwrap_redirect {}; 1245 1246 template<typename T1> 1247 struct partial_unwrap_redirect<T1, false> { typedef partial_unwrap_default<T1> result; }; 1248 1249 template<typename T1> 1250 struct partial_unwrap_redirect<T1, true> { typedef partial_unwrap_fixed<T1> result; }; 1251 1252 template<typename T1> 1253 struct partial_unwrap : public partial_unwrap_redirect<T1, is_Mat_fixed<T1>::value>::result 1254 { 1255 inline partial_unwrappartial_unwrap1256 partial_unwrap(const T1& A) 1257 : partial_unwrap_redirect< T1, is_Mat_fixed<T1>::value>::result(A) 1258 { 1259 } 1260 }; 1261 1262 1263 1264 template<typename eT> 1265 struct partial_unwrap< Mat<eT> > 1266 { 1267 typedef Mat<eT> stored_type; 1268 1269 inline partial_unwrappartial_unwrap1270 partial_unwrap(const Mat<eT>& A) 1271 : M(A) 1272 { 1273 arma_extra_debug_sigprint(); 1274 } 1275 get_valpartial_unwrap1276 constexpr eT get_val() const { return eT(1); } 1277 1278 template<typename eT2> is_aliaspartial_unwrap1279 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1280 1281 static constexpr bool do_trans = false; 1282 static constexpr bool do_times = false; 1283 1284 const Mat<eT>& M; 1285 }; 1286 1287 1288 1289 template<typename eT> 1290 struct partial_unwrap< Row<eT> > 1291 { 1292 typedef Row<eT> stored_type; 1293 1294 inline partial_unwrappartial_unwrap1295 partial_unwrap(const Row<eT>& A) 1296 : M(A) 1297 { 1298 arma_extra_debug_sigprint(); 1299 } 1300 get_valpartial_unwrap1301 constexpr eT get_val() const { return eT(1); } 1302 1303 template<typename eT2> is_aliaspartial_unwrap1304 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1305 1306 static constexpr bool do_trans = false; 1307 static constexpr bool do_times = false; 1308 1309 const Row<eT>& M; 1310 }; 1311 1312 1313 1314 template<typename eT> 1315 struct partial_unwrap< Col<eT> > 1316 { 1317 typedef Col<eT> stored_type; 1318 1319 inline partial_unwrappartial_unwrap1320 partial_unwrap(const Col<eT>& A) 1321 : M(A) 1322 { 1323 arma_extra_debug_sigprint(); 1324 } 1325 get_valpartial_unwrap1326 constexpr eT get_val() const { return eT(1); } 1327 1328 template<typename eT2> is_aliaspartial_unwrap1329 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1330 1331 static constexpr bool do_trans = false; 1332 static constexpr bool do_times = false; 1333 1334 const Col<eT>& M; 1335 }; 1336 1337 1338 1339 template<typename eT> 1340 struct partial_unwrap< subview<eT> > 1341 { 1342 typedef Mat<eT> stored_type; 1343 1344 inline partial_unwrappartial_unwrap1345 partial_unwrap(const subview<eT>& A) 1346 : sv( A ) 1347 , M ( A, ((A.aux_row1 == 0) && (A.n_rows == A.m.n_rows)) ) // reuse memory if the subview is a contiguous chunk 1348 { 1349 arma_extra_debug_sigprint(); 1350 } 1351 get_valpartial_unwrap1352 constexpr eT get_val() const { return eT(1); } 1353 1354 template<typename eT2> is_aliaspartial_unwrap1355 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 ); } 1356 1357 static constexpr bool do_trans = false; 1358 static constexpr bool do_times = false; 1359 1360 const subview<eT>& sv; 1361 const Mat<eT> M; 1362 }; 1363 1364 1365 1366 template<typename eT> 1367 struct partial_unwrap< subview_col<eT> > 1368 { 1369 typedef Col<eT> stored_type; 1370 1371 inline partial_unwrappartial_unwrap1372 partial_unwrap(const subview_col<eT>& A) 1373 : orig( A.m ) 1374 , M ( const_cast<eT*>( A.colmem ), A.n_rows, false, false ) 1375 { 1376 arma_extra_debug_sigprint(); 1377 } 1378 get_valpartial_unwrap1379 constexpr eT get_val() const { return eT(1); } 1380 1381 template<typename eT2> is_aliaspartial_unwrap1382 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); } 1383 1384 static constexpr bool do_trans = false; 1385 static constexpr bool do_times = false; 1386 1387 const Mat<eT>& orig; 1388 const Col<eT> M; 1389 }; 1390 1391 1392 1393 template<typename eT> 1394 struct partial_unwrap< subview_cols<eT> > 1395 { 1396 typedef Mat<eT> stored_type; 1397 1398 inline partial_unwrappartial_unwrap1399 partial_unwrap(const subview_cols<eT>& A) 1400 : orig( A.m ) 1401 , M ( const_cast<eT*>( A.colptr(0) ), A.n_rows, A.n_cols, false, false ) 1402 { 1403 arma_extra_debug_sigprint(); 1404 } 1405 get_valpartial_unwrap1406 constexpr eT get_val() const { return eT(1); } 1407 1408 template<typename eT2> is_aliaspartial_unwrap1409 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); } 1410 1411 static constexpr bool do_trans = false; 1412 static constexpr bool do_times = false; 1413 1414 const Mat<eT>& orig; 1415 const Mat<eT> M; 1416 }; 1417 1418 1419 1420 template<typename eT> 1421 struct partial_unwrap< subview_row<eT> > 1422 { 1423 typedef Row<eT> stored_type; 1424 1425 inline partial_unwrappartial_unwrap1426 partial_unwrap(const subview_row<eT>& A) 1427 : M(A) 1428 { 1429 arma_extra_debug_sigprint(); 1430 } 1431 get_valpartial_unwrap1432 constexpr eT get_val() const { return eT(1); } 1433 1434 template<typename eT2> is_aliaspartial_unwrap1435 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 1436 1437 static constexpr bool do_trans = false; 1438 static constexpr bool do_times = false; 1439 1440 const Row<eT> M; 1441 }; 1442 1443 1444 1445 template<typename T1> 1446 struct partial_unwrap_htrans_default 1447 { 1448 typedef typename T1::elem_type eT; 1449 typedef Mat<eT> stored_type; 1450 1451 inline partial_unwrap_htrans_defaultpartial_unwrap_htrans_default1452 partial_unwrap_htrans_default(const Op<T1, op_htrans>& A) 1453 : M(A.m) 1454 { 1455 arma_extra_debug_sigprint(); 1456 } 1457 get_valpartial_unwrap_htrans_default1458 constexpr eT get_val() const { return eT(1); } 1459 1460 template<typename eT2> is_aliaspartial_unwrap_htrans_default1461 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 1462 1463 static constexpr bool do_trans = true; 1464 static constexpr bool do_times = false; 1465 1466 const Mat<eT> M; 1467 }; 1468 1469 1470 template<typename T1> 1471 struct partial_unwrap_htrans_fixed 1472 { 1473 typedef typename T1::elem_type eT; 1474 typedef T1 stored_type; 1475 1476 inline explicit partial_unwrap_htrans_fixedpartial_unwrap_htrans_fixed1477 partial_unwrap_htrans_fixed(const Op<T1, op_htrans>& A) 1478 : M(A.m) 1479 { 1480 arma_extra_debug_sigprint(); 1481 } 1482 get_valpartial_unwrap_htrans_fixed1483 constexpr eT get_val() const { return eT(1); } 1484 1485 template<typename eT2> is_aliaspartial_unwrap_htrans_fixed1486 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1487 1488 static constexpr bool do_trans = true; 1489 static constexpr bool do_times = false; 1490 1491 const T1& M; 1492 }; 1493 1494 1495 1496 template<typename T1, bool condition> 1497 struct partial_unwrap_htrans_redirect {}; 1498 1499 template<typename T1> 1500 struct partial_unwrap_htrans_redirect<T1, false> { typedef partial_unwrap_htrans_default<T1> result; }; 1501 1502 template<typename T1> 1503 struct partial_unwrap_htrans_redirect<T1, true> { typedef partial_unwrap_htrans_fixed<T1> result; }; 1504 1505 template<typename T1> 1506 struct partial_unwrap< Op<T1, op_htrans> > : public partial_unwrap_htrans_redirect<T1, is_Mat_fixed<T1>::value>::result 1507 { partial_unwrappartial_unwrap1508 inline partial_unwrap(const Op<T1, op_htrans>& A) 1509 : partial_unwrap_htrans_redirect<T1, is_Mat_fixed<T1>::value>::result(A) 1510 { 1511 } 1512 }; 1513 1514 1515 1516 template<typename eT> 1517 struct partial_unwrap< Op< Mat<eT>, op_htrans> > 1518 { 1519 typedef Mat<eT> stored_type; 1520 1521 inline partial_unwrappartial_unwrap1522 partial_unwrap(const Op< Mat<eT>, op_htrans>& A) 1523 : M(A.m) 1524 { 1525 arma_extra_debug_sigprint(); 1526 } 1527 get_valpartial_unwrap1528 constexpr eT get_val() const { return eT(1); } 1529 1530 template<typename eT2> is_aliaspartial_unwrap1531 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1532 1533 static constexpr bool do_trans = true; 1534 static constexpr bool do_times = false; 1535 1536 const Mat<eT>& M; 1537 }; 1538 1539 1540 1541 template<typename eT> 1542 struct partial_unwrap< Op< Row<eT>, op_htrans> > 1543 { 1544 typedef Row<eT> stored_type; 1545 1546 inline partial_unwrappartial_unwrap1547 partial_unwrap(const Op< Row<eT>, op_htrans>& A) 1548 : M(A.m) 1549 { 1550 arma_extra_debug_sigprint(); 1551 } 1552 get_valpartial_unwrap1553 constexpr eT get_val() const { return eT(1); } 1554 1555 template<typename eT2> is_aliaspartial_unwrap1556 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1557 1558 static constexpr bool do_trans = true; 1559 static constexpr bool do_times = false; 1560 1561 const Row<eT>& M; 1562 }; 1563 1564 1565 1566 template<typename eT> 1567 struct partial_unwrap< Op< Col<eT>, op_htrans> > 1568 { 1569 typedef Col<eT> stored_type; 1570 1571 inline partial_unwrappartial_unwrap1572 partial_unwrap(const Op< Col<eT>, op_htrans>& A) 1573 : M(A.m) 1574 { 1575 arma_extra_debug_sigprint(); 1576 } 1577 get_valpartial_unwrap1578 constexpr eT get_val() const { return eT(1); } 1579 1580 template<typename eT2> is_aliaspartial_unwrap1581 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1582 1583 static constexpr bool do_trans = true; 1584 static constexpr bool do_times = false; 1585 1586 const Col<eT>& M; 1587 }; 1588 1589 1590 1591 template<typename eT> 1592 struct partial_unwrap< Op< subview<eT>, op_htrans> > 1593 { 1594 typedef Mat<eT> stored_type; 1595 1596 inline partial_unwrappartial_unwrap1597 partial_unwrap(const Op< subview<eT>, op_htrans>& A) 1598 : sv( A.m ) 1599 , M ( A.m, ((A.m.aux_row1 == 0) && (A.m.n_rows == A.m.m.n_rows)) ) // reuse memory if the subview is a contiguous chunk 1600 { 1601 arma_extra_debug_sigprint(); 1602 } 1603 get_valpartial_unwrap1604 constexpr eT get_val() const { return eT(1); } 1605 1606 template<typename eT2> is_aliaspartial_unwrap1607 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 ); } 1608 1609 static constexpr bool do_trans = true; 1610 static constexpr bool do_times = false; 1611 1612 const subview<eT>& sv; 1613 const Mat<eT> M; 1614 }; 1615 1616 1617 1618 template<typename eT> 1619 struct partial_unwrap< Op< subview_cols<eT>, op_htrans> > 1620 { 1621 typedef Mat<eT> stored_type; 1622 1623 inline partial_unwrappartial_unwrap1624 partial_unwrap(const Op< subview_cols<eT>, op_htrans>& A) 1625 : orig( A.m.m ) 1626 , M ( const_cast<eT*>( A.m.colptr(0) ), A.m.n_rows, A.m.n_cols, false, false ) 1627 { 1628 arma_extra_debug_sigprint(); 1629 } 1630 get_valpartial_unwrap1631 constexpr eT get_val() const { return eT(1); } 1632 1633 template<typename eT2> is_aliaspartial_unwrap1634 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); } 1635 1636 static constexpr bool do_trans = true; 1637 static constexpr bool do_times = false; 1638 1639 const Mat<eT>& orig; 1640 const Mat<eT> M; 1641 }; 1642 1643 1644 1645 template<typename eT> 1646 struct partial_unwrap< Op< subview_col<eT>, op_htrans> > 1647 { 1648 typedef Col<eT> stored_type; 1649 1650 inline partial_unwrappartial_unwrap1651 partial_unwrap(const Op< subview_col<eT>, op_htrans>& A) 1652 : orig( A.m.m ) 1653 , M ( const_cast<eT*>( A.m.colmem ), A.m.n_rows, false, false ) 1654 { 1655 arma_extra_debug_sigprint(); 1656 } 1657 get_valpartial_unwrap1658 constexpr eT get_val() const { return eT(1); } 1659 1660 template<typename eT2> is_aliaspartial_unwrap1661 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); } 1662 1663 static constexpr bool do_trans = true; 1664 static constexpr bool do_times = false; 1665 1666 const Mat<eT>& orig; 1667 const Col<eT> M; 1668 }; 1669 1670 1671 1672 template<typename eT> 1673 struct partial_unwrap< Op< subview_row<eT>, op_htrans> > 1674 { 1675 typedef Row<eT> stored_type; 1676 1677 inline partial_unwrappartial_unwrap1678 partial_unwrap(const Op< subview_row<eT>, op_htrans>& A) 1679 : M(A.m) 1680 { 1681 arma_extra_debug_sigprint(); 1682 } 1683 get_valpartial_unwrap1684 constexpr eT get_val() const { return eT(1); } 1685 1686 template<typename eT2> is_aliaspartial_unwrap1687 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 1688 1689 static constexpr bool do_trans = true; 1690 static constexpr bool do_times = false; 1691 1692 const Row<eT> M; 1693 }; 1694 1695 1696 1697 template<typename T1> 1698 struct partial_unwrap_htrans2_default 1699 { 1700 typedef typename T1::elem_type eT; 1701 typedef Mat<eT> stored_type; 1702 1703 inline partial_unwrap_htrans2_defaultpartial_unwrap_htrans2_default1704 partial_unwrap_htrans2_default(const Op<T1, op_htrans2>& A) 1705 : val(A.aux) 1706 , M (A.m) 1707 { 1708 arma_extra_debug_sigprint(); 1709 } 1710 get_valpartial_unwrap_htrans2_default1711 arma_inline eT get_val() const { return val; } 1712 1713 template<typename eT2> is_aliaspartial_unwrap_htrans2_default1714 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 1715 1716 static constexpr bool do_trans = true; 1717 static constexpr bool do_times = true; 1718 1719 const eT val; 1720 const Mat<eT> M; 1721 }; 1722 1723 1724 template<typename T1> 1725 struct partial_unwrap_htrans2_fixed 1726 { 1727 typedef typename T1::elem_type eT; 1728 typedef T1 stored_type; 1729 1730 inline explicit partial_unwrap_htrans2_fixedpartial_unwrap_htrans2_fixed1731 partial_unwrap_htrans2_fixed(const Op<T1, op_htrans2>& A) 1732 : val(A.aux) 1733 , M (A.m) 1734 { 1735 arma_extra_debug_sigprint(); 1736 } 1737 get_valpartial_unwrap_htrans2_fixed1738 arma_inline eT get_val() const { return val; } 1739 1740 template<typename eT2> is_aliaspartial_unwrap_htrans2_fixed1741 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1742 1743 static constexpr bool do_trans = true; 1744 static constexpr bool do_times = true; 1745 1746 const eT val; 1747 const T1& M; 1748 }; 1749 1750 1751 1752 template<typename T1, bool condition> 1753 struct partial_unwrap_htrans2_redirect {}; 1754 1755 template<typename T1> 1756 struct partial_unwrap_htrans2_redirect<T1, false> { typedef partial_unwrap_htrans2_default<T1> result; }; 1757 1758 template<typename T1> 1759 struct partial_unwrap_htrans2_redirect<T1, true> { typedef partial_unwrap_htrans2_fixed<T1> result; }; 1760 1761 template<typename T1> 1762 struct partial_unwrap< Op<T1, op_htrans2> > : public partial_unwrap_htrans2_redirect<T1, is_Mat_fixed<T1>::value>::result 1763 { partial_unwrappartial_unwrap1764 inline partial_unwrap(const Op<T1, op_htrans2>& A) 1765 : partial_unwrap_htrans2_redirect<T1, is_Mat_fixed<T1>::value>::result(A) 1766 { 1767 } 1768 }; 1769 1770 1771 1772 template<typename eT> 1773 struct partial_unwrap< Op< Mat<eT>, op_htrans2> > 1774 { 1775 typedef Mat<eT> stored_type; 1776 1777 inline partial_unwrappartial_unwrap1778 partial_unwrap(const Op< Mat<eT>, op_htrans2>& A) 1779 : val(A.aux) 1780 , M (A.m) 1781 { 1782 arma_extra_debug_sigprint(); 1783 } 1784 get_valpartial_unwrap1785 inline eT get_val() const { return val; } 1786 1787 template<typename eT2> is_aliaspartial_unwrap1788 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1789 1790 static constexpr bool do_trans = true; 1791 static constexpr bool do_times = true; 1792 1793 const eT val; 1794 const Mat<eT>& M; 1795 }; 1796 1797 1798 1799 template<typename eT> 1800 struct partial_unwrap< Op< Row<eT>, op_htrans2> > 1801 { 1802 typedef Row<eT> stored_type; 1803 1804 inline partial_unwrappartial_unwrap1805 partial_unwrap(const Op< Row<eT>, op_htrans2>& A) 1806 : val(A.aux) 1807 , M (A.m) 1808 { 1809 arma_extra_debug_sigprint(); 1810 } 1811 get_valpartial_unwrap1812 inline eT get_val() const { return val; } 1813 1814 template<typename eT2> is_aliaspartial_unwrap1815 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1816 1817 static constexpr bool do_trans = true; 1818 static constexpr bool do_times = true; 1819 1820 const eT val; 1821 const Row<eT>& M; 1822 }; 1823 1824 1825 1826 template<typename eT> 1827 struct partial_unwrap< Op< Col<eT>, op_htrans2> > 1828 { 1829 typedef Col<eT> stored_type; 1830 1831 inline partial_unwrappartial_unwrap1832 partial_unwrap(const Op< Col<eT>, op_htrans2>& A) 1833 : val(A.aux) 1834 , M (A.m) 1835 { 1836 arma_extra_debug_sigprint(); 1837 } 1838 get_valpartial_unwrap1839 inline eT get_val() const { return val; } 1840 1841 template<typename eT2> is_aliaspartial_unwrap1842 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 1843 1844 static constexpr bool do_trans = true; 1845 static constexpr bool do_times = true; 1846 1847 const eT val; 1848 const Col<eT>& M; 1849 }; 1850 1851 1852 1853 template<typename eT> 1854 struct partial_unwrap< Op< subview<eT>, op_htrans2> > 1855 { 1856 typedef Mat<eT> stored_type; 1857 1858 inline partial_unwrappartial_unwrap1859 partial_unwrap(const Op< subview<eT>, op_htrans2>& A) 1860 : sv ( A.m ) 1861 , val( A.aux ) 1862 , M ( A.m, ((A.m.aux_row1 == 0) && (A.m.n_rows == A.m.m.n_rows)) ) // reuse memory if the subview is a contiguous chunk 1863 { 1864 arma_extra_debug_sigprint(); 1865 } 1866 get_valpartial_unwrap1867 inline eT get_val() const { return val; } 1868 1869 template<typename eT2> is_aliaspartial_unwrap1870 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 ); } 1871 1872 static constexpr bool do_trans = true; 1873 static constexpr bool do_times = true; 1874 1875 const subview<eT>& sv; 1876 const eT val; 1877 const Mat<eT> M; 1878 }; 1879 1880 1881 1882 template<typename eT> 1883 struct partial_unwrap< Op< subview_cols<eT>, op_htrans2> > 1884 { 1885 typedef Mat<eT> stored_type; 1886 1887 inline partial_unwrappartial_unwrap1888 partial_unwrap(const Op< subview_cols<eT>, op_htrans2>& A) 1889 : orig( A.m.m ) 1890 , val ( A.aux ) 1891 , M ( const_cast<eT*>( A.m.colptr(0) ), A.m.n_rows, A.m.n_cols, false, false ) 1892 { 1893 arma_extra_debug_sigprint(); 1894 } 1895 get_valpartial_unwrap1896 inline eT get_val() const { return val; } 1897 1898 template<typename eT2> is_aliaspartial_unwrap1899 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&orig) == void_ptr(&X)); } 1900 1901 static constexpr bool do_trans = true; 1902 static constexpr bool do_times = true; 1903 1904 const Mat<eT>& orig; 1905 const eT val; 1906 const Mat<eT> M; 1907 }; 1908 1909 1910 1911 template<typename eT> 1912 struct partial_unwrap< Op< subview_col<eT>, op_htrans2> > 1913 { 1914 typedef Col<eT> stored_type; 1915 1916 inline partial_unwrappartial_unwrap1917 partial_unwrap(const Op< subview_col<eT>, op_htrans2>& A) 1918 : orig( A.m.m ) 1919 , val ( A.aux ) 1920 , M ( const_cast<eT*>( A.m.colmem ), A.m.n_rows, false, false ) 1921 { 1922 arma_extra_debug_sigprint(); 1923 } 1924 get_valpartial_unwrap1925 inline eT get_val() const { return val; } 1926 1927 template<typename eT2> is_aliaspartial_unwrap1928 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); } 1929 1930 static constexpr bool do_trans = true; 1931 static constexpr bool do_times = true; 1932 1933 const Mat<eT>& orig; 1934 1935 const eT val; 1936 const Col<eT> M; 1937 }; 1938 1939 1940 1941 template<typename eT> 1942 struct partial_unwrap< Op< subview_row<eT>, op_htrans2> > 1943 { 1944 typedef Row<eT> stored_type; 1945 1946 inline partial_unwrappartial_unwrap1947 partial_unwrap(const Op< subview_row<eT>, op_htrans2>& A) 1948 : val(A.aux) 1949 , M (A.m ) 1950 { 1951 arma_extra_debug_sigprint(); 1952 } 1953 get_valpartial_unwrap1954 arma_inline eT get_val() const { return val; } 1955 1956 template<typename eT2> is_aliaspartial_unwrap1957 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 1958 1959 static constexpr bool do_trans = true; 1960 static constexpr bool do_times = true; 1961 1962 const eT val; 1963 const Row<eT> M; 1964 }; 1965 1966 1967 1968 template<typename T1> 1969 struct partial_unwrap_scalar_times_default 1970 { 1971 typedef typename T1::elem_type eT; 1972 typedef Mat<eT> stored_type; 1973 1974 inline partial_unwrap_scalar_times_defaultpartial_unwrap_scalar_times_default1975 partial_unwrap_scalar_times_default(const eOp<T1, eop_scalar_times>& A) 1976 : val(A.aux) 1977 , M (A.P.Q) 1978 { 1979 arma_extra_debug_sigprint(); 1980 } 1981 get_valpartial_unwrap_scalar_times_default1982 arma_inline eT get_val() const { return val; } 1983 1984 template<typename eT2> is_aliaspartial_unwrap_scalar_times_default1985 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 1986 1987 static constexpr bool do_trans = false; 1988 static constexpr bool do_times = true; 1989 1990 const eT val; 1991 const Mat<eT> M; 1992 }; 1993 1994 1995 1996 template<typename T1> 1997 struct partial_unwrap_scalar_times_fixed 1998 { 1999 typedef typename T1::elem_type eT; 2000 typedef T1 stored_type; 2001 2002 inline explicit partial_unwrap_scalar_times_fixedpartial_unwrap_scalar_times_fixed2003 partial_unwrap_scalar_times_fixed(const eOp<T1, eop_scalar_times>& A) 2004 : val(A.aux) 2005 , M (A.P.Q) 2006 { 2007 arma_extra_debug_sigprint(); 2008 } 2009 get_valpartial_unwrap_scalar_times_fixed2010 arma_inline eT get_val() const { return val; } 2011 2012 template<typename eT2> is_aliaspartial_unwrap_scalar_times_fixed2013 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 2014 2015 static constexpr bool do_trans = false; 2016 static constexpr bool do_times = true; 2017 2018 const eT val; 2019 const T1& M; 2020 }; 2021 2022 2023 2024 template<typename T1, bool condition> 2025 struct partial_unwrap_scalar_times_redirect {}; 2026 2027 template<typename T1> 2028 struct partial_unwrap_scalar_times_redirect<T1, false> { typedef partial_unwrap_scalar_times_default<T1> result; }; 2029 2030 template<typename T1> 2031 struct partial_unwrap_scalar_times_redirect<T1, true> { typedef partial_unwrap_scalar_times_fixed<T1> result; }; 2032 2033 2034 template<typename T1> 2035 struct partial_unwrap< eOp<T1, eop_scalar_times> > : public partial_unwrap_scalar_times_redirect<T1, is_Mat_fixed<T1>::value>::result 2036 { 2037 typedef typename T1::elem_type eT; 2038 2039 inline partial_unwrappartial_unwrap2040 partial_unwrap(const eOp<T1, eop_scalar_times>& A) 2041 : partial_unwrap_scalar_times_redirect< T1, is_Mat_fixed<T1>::value>::result(A) 2042 { 2043 } 2044 }; 2045 2046 2047 2048 template<typename eT> 2049 struct partial_unwrap< eOp<Mat<eT>, eop_scalar_times> > 2050 { 2051 typedef Mat<eT> stored_type; 2052 2053 inline partial_unwrappartial_unwrap2054 partial_unwrap(const eOp<Mat<eT>,eop_scalar_times>& A) 2055 : val(A.aux) 2056 , M (A.P.Q) 2057 { 2058 arma_extra_debug_sigprint(); 2059 } 2060 get_valpartial_unwrap2061 inline eT get_val() const { return val; } 2062 2063 template<typename eT2> is_aliaspartial_unwrap2064 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 2065 2066 static constexpr bool do_trans = false; 2067 static constexpr bool do_times = true; 2068 2069 const eT val; 2070 const Mat<eT>& M; 2071 }; 2072 2073 2074 2075 template<typename eT> 2076 struct partial_unwrap< eOp<Row<eT>, eop_scalar_times> > 2077 { 2078 typedef Row<eT> stored_type; 2079 2080 inline partial_unwrappartial_unwrap2081 partial_unwrap(const eOp<Row<eT>,eop_scalar_times>& A) 2082 : val(A.aux) 2083 , M (A.P.Q) 2084 { 2085 arma_extra_debug_sigprint(); 2086 } 2087 get_valpartial_unwrap2088 inline eT get_val() const { return val; } 2089 2090 template<typename eT2> is_aliaspartial_unwrap2091 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 2092 2093 static constexpr bool do_trans = false; 2094 static constexpr bool do_times = true; 2095 2096 const eT val; 2097 const Row<eT>& M; 2098 }; 2099 2100 2101 2102 template<typename eT> 2103 struct partial_unwrap< eOp<Col<eT>, eop_scalar_times> > 2104 { 2105 typedef Col<eT> stored_type; 2106 2107 inline partial_unwrappartial_unwrap2108 partial_unwrap(const eOp<Col<eT>,eop_scalar_times>& A) 2109 : val(A.aux) 2110 , M (A.P.Q) 2111 { 2112 arma_extra_debug_sigprint(); 2113 } 2114 get_valpartial_unwrap2115 inline eT get_val() const { return val; } 2116 2117 template<typename eT2> is_aliaspartial_unwrap2118 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 2119 2120 static constexpr bool do_trans = false; 2121 static constexpr bool do_times = true; 2122 2123 const eT val; 2124 const Col<eT>& M; 2125 }; 2126 2127 2128 2129 template<typename eT> 2130 struct partial_unwrap< eOp<subview_col<eT>, eop_scalar_times> > 2131 { 2132 typedef Col<eT> stored_type; 2133 2134 inline partial_unwrappartial_unwrap2135 partial_unwrap(const eOp<subview_col<eT>,eop_scalar_times>& A) 2136 : orig( A.P.Q.m ) 2137 , val ( A.aux ) 2138 , M ( const_cast<eT*>( A.P.Q.colmem ), A.P.Q.n_rows, false, false ) 2139 { 2140 arma_extra_debug_sigprint(); 2141 } 2142 get_valpartial_unwrap2143 arma_inline eT get_val() const { return val; } 2144 2145 template<typename eT2> is_aliaspartial_unwrap2146 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); } 2147 2148 static constexpr bool do_trans = false; 2149 static constexpr bool do_times = true; 2150 2151 const Mat<eT>& orig; 2152 2153 const eT val; 2154 const Col<eT> M; 2155 }; 2156 2157 2158 2159 template<typename eT> 2160 struct partial_unwrap< eOp<subview_row<eT>, eop_scalar_times> > 2161 { 2162 typedef Row<eT> stored_type; 2163 2164 inline partial_unwrappartial_unwrap2165 partial_unwrap(const eOp<subview_row<eT>,eop_scalar_times>& A) 2166 : val(A.aux) 2167 , M (A.P.Q) 2168 { 2169 arma_extra_debug_sigprint(); 2170 } 2171 get_valpartial_unwrap2172 arma_inline eT get_val() const { return val; } 2173 2174 template<typename eT2> is_aliaspartial_unwrap2175 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 2176 2177 static constexpr bool do_trans = false; 2178 static constexpr bool do_times = true; 2179 2180 const eT val; 2181 const Row<eT> M; 2182 }; 2183 2184 2185 2186 template<typename T1> 2187 struct partial_unwrap_neg_default 2188 { 2189 typedef typename T1::elem_type eT; 2190 typedef Mat<eT> stored_type; 2191 2192 inline partial_unwrap_neg_defaultpartial_unwrap_neg_default2193 partial_unwrap_neg_default(const eOp<T1, eop_neg>& A) 2194 : M(A.P.Q) 2195 { 2196 arma_extra_debug_sigprint(); 2197 } 2198 get_valpartial_unwrap_neg_default2199 constexpr eT get_val() const { return eT(-1); } 2200 2201 template<typename eT2> is_aliaspartial_unwrap_neg_default2202 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 2203 2204 static constexpr bool do_trans = false; 2205 static constexpr bool do_times = true; 2206 2207 const Mat<eT> M; 2208 }; 2209 2210 2211 2212 template<typename T1> 2213 struct partial_unwrap_neg_fixed 2214 { 2215 typedef typename T1::elem_type eT; 2216 typedef T1 stored_type; 2217 2218 inline explicit partial_unwrap_neg_fixedpartial_unwrap_neg_fixed2219 partial_unwrap_neg_fixed(const eOp<T1, eop_neg>& A) 2220 : M(A.P.Q) 2221 { 2222 arma_extra_debug_sigprint(); 2223 } 2224 get_valpartial_unwrap_neg_fixed2225 constexpr eT get_val() const { return eT(-1); } 2226 2227 template<typename eT2> is_aliaspartial_unwrap_neg_fixed2228 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 2229 2230 static constexpr bool do_trans = false; 2231 static constexpr bool do_times = true; 2232 2233 const T1& M; 2234 }; 2235 2236 2237 2238 template<typename T1, bool condition> 2239 struct partial_unwrap_neg_redirect {}; 2240 2241 template<typename T1> 2242 struct partial_unwrap_neg_redirect<T1, false> { typedef partial_unwrap_neg_default<T1> result; }; 2243 2244 template<typename T1> 2245 struct partial_unwrap_neg_redirect<T1, true> { typedef partial_unwrap_neg_fixed<T1> result; }; 2246 2247 2248 template<typename T1> 2249 struct partial_unwrap< eOp<T1, eop_neg> > : public partial_unwrap_neg_redirect<T1, is_Mat_fixed<T1>::value>::result 2250 { 2251 typedef typename T1::elem_type eT; 2252 2253 inline partial_unwrappartial_unwrap2254 partial_unwrap(const eOp<T1, eop_neg>& A) 2255 : partial_unwrap_neg_redirect< T1, is_Mat_fixed<T1>::value>::result(A) 2256 { 2257 } 2258 }; 2259 2260 2261 2262 template<typename eT> 2263 struct partial_unwrap< eOp<Mat<eT>, eop_neg> > 2264 { 2265 typedef Mat<eT> stored_type; 2266 2267 inline partial_unwrappartial_unwrap2268 partial_unwrap(const eOp<Mat<eT>,eop_neg>& A) 2269 : M(A.P.Q) 2270 { 2271 arma_extra_debug_sigprint(); 2272 } 2273 get_valpartial_unwrap2274 constexpr eT get_val() const { return eT(-1); } 2275 2276 template<typename eT2> is_aliaspartial_unwrap2277 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 2278 2279 static constexpr bool do_trans = false; 2280 static constexpr bool do_times = true; 2281 2282 const Mat<eT>& M; 2283 }; 2284 2285 2286 2287 template<typename eT> 2288 struct partial_unwrap< eOp<Row<eT>, eop_neg> > 2289 { 2290 typedef Row<eT> stored_type; 2291 2292 inline partial_unwrappartial_unwrap2293 partial_unwrap(const eOp<Row<eT>,eop_neg>& A) 2294 : M(A.P.Q) 2295 { 2296 arma_extra_debug_sigprint(); 2297 } 2298 get_valpartial_unwrap2299 constexpr eT get_val() const { return eT(-1); } 2300 2301 template<typename eT2> is_aliaspartial_unwrap2302 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 2303 2304 static constexpr bool do_trans = false; 2305 static constexpr bool do_times = true; 2306 2307 const Row<eT>& M; 2308 }; 2309 2310 2311 2312 template<typename eT> 2313 struct partial_unwrap< eOp<Col<eT>, eop_neg> > 2314 { 2315 typedef Col<eT> stored_type; 2316 2317 inline partial_unwrappartial_unwrap2318 partial_unwrap(const eOp<Col<eT>,eop_neg>& A) 2319 : M(A.P.Q) 2320 { 2321 arma_extra_debug_sigprint(); 2322 } 2323 get_valpartial_unwrap2324 constexpr eT get_val() const { return eT(-1); } 2325 2326 template<typename eT2> is_aliaspartial_unwrap2327 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&M)); } 2328 2329 static constexpr bool do_trans = false; 2330 static constexpr bool do_times = true; 2331 2332 const Col<eT>& M; 2333 }; 2334 2335 2336 2337 template<typename eT> 2338 struct partial_unwrap< eOp<subview_col<eT>, eop_neg> > 2339 { 2340 typedef Col<eT> stored_type; 2341 2342 inline partial_unwrappartial_unwrap2343 partial_unwrap(const eOp<subview_col<eT>,eop_neg>& A) 2344 : orig( A.P.Q.m ) 2345 , M ( const_cast<eT*>( A.P.Q.colmem ), A.P.Q.n_rows, false, false ) 2346 { 2347 arma_extra_debug_sigprint(); 2348 } 2349 get_valpartial_unwrap2350 constexpr eT get_val() const { return eT(-1); } 2351 2352 template<typename eT2> is_aliaspartial_unwrap2353 arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&X) == void_ptr(&orig)); } 2354 2355 static constexpr bool do_trans = false; 2356 static constexpr bool do_times = true; 2357 2358 const Mat<eT>& orig; 2359 const Col<eT> M; 2360 }; 2361 2362 2363 2364 template<typename eT> 2365 struct partial_unwrap< eOp<subview_row<eT>, eop_neg> > 2366 { 2367 typedef Row<eT> stored_type; 2368 2369 inline partial_unwrappartial_unwrap2370 partial_unwrap(const eOp<subview_row<eT>,eop_neg>& A) 2371 : M(A.P.Q) 2372 { 2373 arma_extra_debug_sigprint(); 2374 } 2375 get_valpartial_unwrap2376 constexpr eT get_val() const { return eT(-1); } 2377 2378 template<typename eT2> is_aliaspartial_unwrap2379 constexpr bool is_alias(const Mat<eT2>&) const { return false; } 2380 2381 static constexpr bool do_trans = false; 2382 static constexpr bool do_times = true; 2383 2384 const Row<eT> M; 2385 }; 2386 2387 2388 2389 // 2390 2391 2392 2393 template<typename T1> 2394 struct partial_unwrap_check_default 2395 { 2396 typedef typename T1::elem_type eT; 2397 typedef Mat<eT> stored_type; 2398 2399 inline partial_unwrap_check_defaultpartial_unwrap_check_default2400 partial_unwrap_check_default(const T1& A, const Mat<eT>&) 2401 : M(A) 2402 { 2403 arma_extra_debug_sigprint(); 2404 } 2405 get_valpartial_unwrap_check_default2406 constexpr eT get_val() const { return eT(1); } 2407 2408 static constexpr bool do_trans = false; 2409 static constexpr bool do_times = false; 2410 2411 const Mat<eT> M; 2412 }; 2413 2414 2415 template<typename T1> 2416 struct partial_unwrap_check_fixed 2417 { 2418 typedef typename T1::elem_type eT; 2419 typedef T1 stored_type; 2420 2421 inline explicit partial_unwrap_check_fixedpartial_unwrap_check_fixed2422 partial_unwrap_check_fixed(const T1& A, const Mat<eT>& B) 2423 : M_local( (&A == &B) ? new T1(A) : nullptr ) 2424 , M ( (&A == &B) ? (*M_local) : A ) 2425 { 2426 arma_extra_debug_sigprint(); 2427 } 2428 2429 inline ~partial_unwrap_check_fixedpartial_unwrap_check_fixed2430 ~partial_unwrap_check_fixed() 2431 { 2432 arma_extra_debug_sigprint(); 2433 2434 if(M_local) { delete M_local; } 2435 } 2436 get_valpartial_unwrap_check_fixed2437 constexpr eT get_val() const { return eT(1); } 2438 2439 static constexpr bool do_trans = false; 2440 static constexpr bool do_times = false; 2441 2442 const T1* M_local; 2443 const T1& M; 2444 }; 2445 2446 2447 2448 template<typename T1, bool condition> 2449 struct partial_unwrap_check_redirect {}; 2450 2451 template<typename T1> 2452 struct partial_unwrap_check_redirect<T1, false> { typedef partial_unwrap_check_default<T1> result; }; 2453 2454 template<typename T1> 2455 struct partial_unwrap_check_redirect<T1, true> { typedef partial_unwrap_check_fixed<T1> result; }; 2456 2457 template<typename T1> 2458 struct partial_unwrap_check : public partial_unwrap_check_redirect<T1, is_Mat_fixed<T1>::value>::result 2459 { 2460 typedef typename T1::elem_type eT; 2461 partial_unwrap_checkpartial_unwrap_check2462 inline partial_unwrap_check(const T1& A, const Mat<eT>& B) 2463 : partial_unwrap_check_redirect<T1, is_Mat_fixed<T1>::value>::result(A, B) 2464 { 2465 } 2466 }; 2467 2468 2469 2470 template<typename eT> 2471 struct partial_unwrap_check< Mat<eT> > 2472 { 2473 typedef Mat<eT> stored_type; 2474 2475 inline partial_unwrap_checkpartial_unwrap_check2476 partial_unwrap_check(const Mat<eT>& A, const Mat<eT>& B) 2477 : M_local ( (&A == &B) ? new Mat<eT>(A) : nullptr ) 2478 , M ( (&A == &B) ? (*M_local) : A ) 2479 { 2480 arma_extra_debug_sigprint(); 2481 } 2482 2483 2484 inline ~partial_unwrap_checkpartial_unwrap_check2485 ~partial_unwrap_check() 2486 { 2487 arma_extra_debug_sigprint(); 2488 2489 if(M_local) { delete M_local; } 2490 } 2491 get_valpartial_unwrap_check2492 constexpr eT get_val() const { return eT(1); } 2493 2494 static constexpr bool do_trans = false; 2495 static constexpr bool do_times = false; 2496 2497 // the order below is important 2498 const Mat<eT>* M_local; 2499 const Mat<eT>& M; 2500 }; 2501 2502 2503 2504 template<typename eT> 2505 struct partial_unwrap_check< Row<eT> > 2506 { 2507 typedef Row<eT> stored_type; 2508 2509 inline partial_unwrap_checkpartial_unwrap_check2510 partial_unwrap_check(const Row<eT>& A, const Mat<eT>& B) 2511 : M_local ( (&A == &B) ? new Row<eT>(A) : nullptr ) 2512 , M ( (&A == &B) ? (*M_local) : A ) 2513 { 2514 arma_extra_debug_sigprint(); 2515 } 2516 2517 2518 inline ~partial_unwrap_checkpartial_unwrap_check2519 ~partial_unwrap_check() 2520 { 2521 arma_extra_debug_sigprint(); 2522 2523 if(M_local) { delete M_local; } 2524 } 2525 get_valpartial_unwrap_check2526 constexpr eT get_val() const { return eT(1); } 2527 2528 static constexpr bool do_trans = false; 2529 static constexpr bool do_times = false; 2530 2531 // the order below is important 2532 const Row<eT>* M_local; 2533 const Row<eT>& M; 2534 }; 2535 2536 2537 2538 template<typename eT> 2539 struct partial_unwrap_check< Col<eT> > 2540 { 2541 typedef Col<eT> stored_type; 2542 2543 inline partial_unwrap_checkpartial_unwrap_check2544 partial_unwrap_check(const Col<eT>& A, const Mat<eT>& B) 2545 : M_local ( (&A == &B) ? new Col<eT>(A) : nullptr ) 2546 , M ( (&A == &B) ? (*M_local) : A ) 2547 { 2548 arma_extra_debug_sigprint(); 2549 } 2550 2551 2552 inline ~partial_unwrap_checkpartial_unwrap_check2553 ~partial_unwrap_check() 2554 { 2555 arma_extra_debug_sigprint(); 2556 2557 if(M_local) { delete M_local; } 2558 } 2559 get_valpartial_unwrap_check2560 constexpr eT get_val() const { return eT(1); } 2561 2562 static constexpr bool do_trans = false; 2563 static constexpr bool do_times = false; 2564 2565 // the order below is important 2566 const Col<eT>* M_local; 2567 const Col<eT>& M; 2568 }; 2569 2570 2571 2572 // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class, 2573 // NOTE: which relies on partial_unwrap_check to check for aliasing 2574 template<typename eT> 2575 struct partial_unwrap_check< subview_col<eT> > 2576 { 2577 typedef Col<eT> stored_type; 2578 2579 inline partial_unwrap_checkpartial_unwrap_check2580 partial_unwrap_check(const subview_col<eT>& A, const Mat<eT>& B) 2581 : M ( const_cast<eT*>( A.colmem ), A.n_rows, (&(A.m) == &B), false ) 2582 { 2583 arma_extra_debug_sigprint(); 2584 } 2585 get_valpartial_unwrap_check2586 constexpr eT get_val() const { return eT(1); } 2587 2588 static constexpr bool do_trans = false; 2589 static constexpr bool do_times = false; 2590 2591 const Col<eT> M; 2592 }; 2593 2594 2595 2596 template<typename T1> 2597 struct partial_unwrap_check_htrans_default 2598 { 2599 typedef typename T1::elem_type eT; 2600 typedef Mat<eT> stored_type; 2601 2602 inline partial_unwrap_check_htrans_defaultpartial_unwrap_check_htrans_default2603 partial_unwrap_check_htrans_default(const Op<T1, op_htrans>& A, const Mat<eT>&) 2604 : M(A.m) 2605 { 2606 arma_extra_debug_sigprint(); 2607 } 2608 get_valpartial_unwrap_check_htrans_default2609 constexpr eT get_val() const { return eT(1); } 2610 2611 static constexpr bool do_trans = true; 2612 static constexpr bool do_times = false; 2613 2614 const Mat<eT> M; 2615 }; 2616 2617 2618 template<typename T1> 2619 struct partial_unwrap_check_htrans_fixed 2620 { 2621 typedef typename T1::elem_type eT; 2622 typedef T1 stored_type; 2623 2624 inline explicit partial_unwrap_check_htrans_fixedpartial_unwrap_check_htrans_fixed2625 partial_unwrap_check_htrans_fixed(const Op<T1, op_htrans>& A, const Mat<eT>& B) 2626 : M_local( (&(A.m) == &B) ? new T1(A.m) : nullptr ) 2627 , M ( (&(A.m) == &B) ? (*M_local) : A.m ) 2628 { 2629 arma_extra_debug_sigprint(); 2630 } 2631 2632 inline ~partial_unwrap_check_htrans_fixedpartial_unwrap_check_htrans_fixed2633 ~partial_unwrap_check_htrans_fixed() 2634 { 2635 arma_extra_debug_sigprint(); 2636 2637 if(M_local) { delete M_local; } 2638 } 2639 get_valpartial_unwrap_check_htrans_fixed2640 constexpr eT get_val() const { return eT(1); } 2641 2642 static constexpr bool do_trans = true; 2643 static constexpr bool do_times = false; 2644 2645 const T1* M_local; 2646 const T1& M; 2647 }; 2648 2649 2650 2651 template<typename T1, bool condition> 2652 struct partial_unwrap_check_htrans_redirect {}; 2653 2654 template<typename T1> 2655 struct partial_unwrap_check_htrans_redirect<T1, false> { typedef partial_unwrap_check_htrans_default<T1> result; }; 2656 2657 template<typename T1> 2658 struct partial_unwrap_check_htrans_redirect<T1, true> { typedef partial_unwrap_check_htrans_fixed<T1> result; }; 2659 2660 2661 template<typename T1> 2662 struct partial_unwrap_check< Op<T1, op_htrans> > : public partial_unwrap_check_htrans_redirect<T1, is_Mat_fixed<T1>::value>::result 2663 { 2664 typedef typename T1::elem_type eT; 2665 partial_unwrap_checkpartial_unwrap_check2666 inline partial_unwrap_check(const Op<T1, op_htrans>& A, const Mat<eT>& B) 2667 : partial_unwrap_check_htrans_redirect<T1, is_Mat_fixed<T1>::value>::result(A, B) 2668 { 2669 } 2670 }; 2671 2672 2673 2674 template<typename eT> 2675 struct partial_unwrap_check< Op< Mat<eT>, op_htrans> > 2676 { 2677 typedef Mat<eT> stored_type; 2678 2679 inline partial_unwrap_checkpartial_unwrap_check2680 partial_unwrap_check(const Op< Mat<eT>, op_htrans>& A, const Mat<eT>& B) 2681 : M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : nullptr ) 2682 , M ( (&A.m == &B) ? (*M_local) : A.m ) 2683 { 2684 arma_extra_debug_sigprint(); 2685 } 2686 2687 inline ~partial_unwrap_checkpartial_unwrap_check2688 ~partial_unwrap_check() 2689 { 2690 arma_extra_debug_sigprint(); 2691 2692 if(M_local) { delete M_local; } 2693 } 2694 get_valpartial_unwrap_check2695 constexpr eT get_val() const { return eT(1); } 2696 2697 static constexpr bool do_trans = true; 2698 static constexpr bool do_times = false; 2699 2700 // the order below is important 2701 const Mat<eT>* M_local; 2702 const Mat<eT>& M; 2703 }; 2704 2705 2706 2707 template<typename eT> 2708 struct partial_unwrap_check< Op< Row<eT>, op_htrans> > 2709 { 2710 typedef Row<eT> stored_type; 2711 2712 inline partial_unwrap_checkpartial_unwrap_check2713 partial_unwrap_check(const Op< Row<eT>, op_htrans>& A, const Mat<eT>& B) 2714 : M_local ( (&A.m == &B) ? new Row<eT>(A.m) : nullptr ) 2715 , M ( (&A.m == &B) ? (*M_local) : A.m ) 2716 { 2717 arma_extra_debug_sigprint(); 2718 } 2719 2720 inline ~partial_unwrap_checkpartial_unwrap_check2721 ~partial_unwrap_check() 2722 { 2723 arma_extra_debug_sigprint(); 2724 2725 if(M_local) { delete M_local; } 2726 } 2727 get_valpartial_unwrap_check2728 constexpr eT get_val() const { return eT(1); } 2729 2730 static constexpr bool do_trans = true; 2731 static constexpr bool do_times = false; 2732 2733 // the order below is important 2734 const Row<eT>* M_local; 2735 const Row<eT>& M; 2736 }; 2737 2738 2739 2740 template<typename eT> 2741 struct partial_unwrap_check< Op< Col<eT>, op_htrans> > 2742 { 2743 typedef Col<eT> stored_type; 2744 2745 inline partial_unwrap_checkpartial_unwrap_check2746 partial_unwrap_check(const Op< Col<eT>, op_htrans>& A, const Mat<eT>& B) 2747 : M_local ( (&A.m == &B) ? new Col<eT>(A.m) : nullptr ) 2748 , M ( (&A.m == &B) ? (*M_local) : A.m ) 2749 { 2750 arma_extra_debug_sigprint(); 2751 } 2752 2753 inline ~partial_unwrap_checkpartial_unwrap_check2754 ~partial_unwrap_check() 2755 { 2756 arma_extra_debug_sigprint(); 2757 2758 if(M_local) { delete M_local; } 2759 } 2760 get_valpartial_unwrap_check2761 constexpr eT get_val() const { return eT(1); } 2762 2763 static constexpr bool do_trans = true; 2764 static constexpr bool do_times = false; 2765 2766 // the order below is important 2767 const Col<eT>* M_local; 2768 const Col<eT>& M; 2769 }; 2770 2771 2772 2773 // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class, 2774 // NOTE: which relies on partial_unwrap_check to check for aliasing 2775 template<typename eT> 2776 struct partial_unwrap_check< Op< subview_col<eT>, op_htrans> > 2777 { 2778 typedef Col<eT> stored_type; 2779 2780 inline partial_unwrap_checkpartial_unwrap_check2781 partial_unwrap_check(const Op< subview_col<eT>, op_htrans>& A, const Mat<eT>& B) 2782 : M ( const_cast<eT*>( A.m.colmem ), A.m.n_rows, (&(A.m.m) == &B), false ) 2783 { 2784 arma_extra_debug_sigprint(); 2785 } 2786 get_valpartial_unwrap_check2787 constexpr eT get_val() const { return eT(1); } 2788 2789 static constexpr bool do_trans = true; 2790 static constexpr bool do_times = false; 2791 2792 const Col<eT> M; 2793 }; 2794 2795 2796 2797 template<typename T1> 2798 struct partial_unwrap_check_htrans2_default 2799 { 2800 typedef typename T1::elem_type eT; 2801 typedef Mat<eT> stored_type; 2802 2803 inline partial_unwrap_check_htrans2_defaultpartial_unwrap_check_htrans2_default2804 partial_unwrap_check_htrans2_default(const Op<T1, op_htrans2>& A, const Mat<eT>&) 2805 : val(A.aux) 2806 , M (A.m) 2807 { 2808 arma_extra_debug_sigprint(); 2809 } 2810 get_valpartial_unwrap_check_htrans2_default2811 arma_inline eT get_val() const { return val; } 2812 2813 static constexpr bool do_trans = true; 2814 static constexpr bool do_times = true; 2815 2816 const eT val; 2817 const Mat<eT> M; 2818 }; 2819 2820 2821 2822 template<typename T1> 2823 struct partial_unwrap_check_htrans2_fixed 2824 { 2825 typedef typename T1::elem_type eT; 2826 typedef T1 stored_type; 2827 2828 inline explicit partial_unwrap_check_htrans2_fixedpartial_unwrap_check_htrans2_fixed2829 partial_unwrap_check_htrans2_fixed(const Op<T1, op_htrans2>& A, const Mat<eT>& B) 2830 : val (A.aux) 2831 , M_local( (&(A.m) == &B) ? new T1(A.m) : nullptr ) 2832 , M ( (&(A.m) == &B) ? (*M_local) : A.m ) 2833 { 2834 arma_extra_debug_sigprint(); 2835 } 2836 2837 inline ~partial_unwrap_check_htrans2_fixedpartial_unwrap_check_htrans2_fixed2838 ~partial_unwrap_check_htrans2_fixed() 2839 { 2840 arma_extra_debug_sigprint(); 2841 2842 if(M_local) { delete M_local; } 2843 } 2844 get_valpartial_unwrap_check_htrans2_fixed2845 arma_inline eT get_val() const { return val; } 2846 2847 static constexpr bool do_trans = true; 2848 static constexpr bool do_times = true; 2849 2850 const eT val; 2851 const T1* M_local; 2852 const T1& M; 2853 }; 2854 2855 2856 2857 template<typename T1, bool condition> 2858 struct partial_unwrap_check_htrans2_redirect {}; 2859 2860 template<typename T1> 2861 struct partial_unwrap_check_htrans2_redirect<T1, false> { typedef partial_unwrap_check_htrans2_default<T1> result; }; 2862 2863 template<typename T1> 2864 struct partial_unwrap_check_htrans2_redirect<T1, true> { typedef partial_unwrap_check_htrans2_fixed<T1> result; }; 2865 2866 2867 template<typename T1> 2868 struct partial_unwrap_check< Op<T1, op_htrans2> > : public partial_unwrap_check_htrans2_redirect<T1, is_Mat_fixed<T1>::value>::result 2869 { 2870 typedef typename T1::elem_type eT; 2871 partial_unwrap_checkpartial_unwrap_check2872 inline partial_unwrap_check(const Op<T1, op_htrans2>& A, const Mat<eT>& B) 2873 : partial_unwrap_check_htrans2_redirect<T1, is_Mat_fixed<T1>::value>::result(A, B) 2874 { 2875 } 2876 }; 2877 2878 2879 2880 template<typename eT> 2881 struct partial_unwrap_check< Op< Mat<eT>, op_htrans2> > 2882 { 2883 typedef Mat<eT> stored_type; 2884 2885 inline partial_unwrap_checkpartial_unwrap_check2886 partial_unwrap_check(const Op< Mat<eT>, op_htrans2>& A, const Mat<eT>& B) 2887 : val (A.aux) 2888 , M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : nullptr ) 2889 , M ( (&A.m == &B) ? (*M_local) : A.m ) 2890 { 2891 arma_extra_debug_sigprint(); 2892 } 2893 2894 inline ~partial_unwrap_checkpartial_unwrap_check2895 ~partial_unwrap_check() 2896 { 2897 arma_extra_debug_sigprint(); 2898 2899 if(M_local) { delete M_local; } 2900 } 2901 get_valpartial_unwrap_check2902 arma_inline eT get_val() const { return val; } 2903 2904 static constexpr bool do_trans = true; 2905 static constexpr bool do_times = true; 2906 2907 // the order below is important 2908 const eT val; 2909 const Mat<eT>* M_local; 2910 const Mat<eT>& M; 2911 }; 2912 2913 2914 2915 template<typename eT> 2916 struct partial_unwrap_check< Op< Row<eT>, op_htrans2> > 2917 { 2918 typedef Row<eT> stored_type; 2919 2920 inline partial_unwrap_checkpartial_unwrap_check2921 partial_unwrap_check(const Op< Row<eT>, op_htrans2>& A, const Mat<eT>& B) 2922 : val (A.aux) 2923 , M_local ( (&A.m == &B) ? new Row<eT>(A.m) : nullptr ) 2924 , M ( (&A.m == &B) ? (*M_local) : A.m ) 2925 { 2926 arma_extra_debug_sigprint(); 2927 } 2928 2929 inline ~partial_unwrap_checkpartial_unwrap_check2930 ~partial_unwrap_check() 2931 { 2932 arma_extra_debug_sigprint(); 2933 2934 if(M_local) { delete M_local; } 2935 } 2936 get_valpartial_unwrap_check2937 arma_inline eT get_val() const { return val; } 2938 2939 static constexpr bool do_trans = true; 2940 static constexpr bool do_times = true; 2941 2942 // the order below is important 2943 const eT val; 2944 const Row<eT>* M_local; 2945 const Row<eT>& M; 2946 }; 2947 2948 2949 2950 template<typename eT> 2951 struct partial_unwrap_check< Op< Col<eT>, op_htrans2> > 2952 { 2953 typedef Col<eT> stored_type; 2954 2955 inline partial_unwrap_checkpartial_unwrap_check2956 partial_unwrap_check(const Op< Col<eT>, op_htrans2>& A, const Mat<eT>& B) 2957 : val (A.aux) 2958 , M_local ( (&A.m == &B) ? new Col<eT>(A.m) : nullptr ) 2959 , M ( (&A.m == &B) ? (*M_local) : A.m ) 2960 { 2961 arma_extra_debug_sigprint(); 2962 } 2963 2964 inline ~partial_unwrap_checkpartial_unwrap_check2965 ~partial_unwrap_check() 2966 { 2967 arma_extra_debug_sigprint(); 2968 2969 if(M_local) { delete M_local; } 2970 } 2971 get_valpartial_unwrap_check2972 arma_inline eT get_val() const { return val; } 2973 2974 static constexpr bool do_trans = true; 2975 static constexpr bool do_times = true; 2976 2977 // the order below is important 2978 const eT val; 2979 const Col<eT>* M_local; 2980 const Col<eT>& M; 2981 }; 2982 2983 2984 2985 // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class, 2986 // NOTE: which relies on partial_unwrap_check to check for aliasing 2987 template<typename eT> 2988 struct partial_unwrap_check< Op< subview_col<eT>, op_htrans2> > 2989 { 2990 typedef Col<eT> stored_type; 2991 2992 inline partial_unwrap_checkpartial_unwrap_check2993 partial_unwrap_check(const Op< subview_col<eT>, op_htrans2>& A, const Mat<eT>& B) 2994 : val( A.aux ) 2995 , M ( const_cast<eT*>( A.m.colmem ), A.m.n_rows, (&(A.m.m) == &B), false ) 2996 { 2997 arma_extra_debug_sigprint(); 2998 } 2999 get_valpartial_unwrap_check3000 arma_inline eT get_val() const { return val; } 3001 3002 static constexpr bool do_trans = true; 3003 static constexpr bool do_times = true; 3004 3005 const eT val; 3006 const Col<eT> M; 3007 }; 3008 3009 3010 3011 template<typename T1> 3012 struct partial_unwrap_check_scalar_times_default 3013 { 3014 typedef typename T1::elem_type eT; 3015 typedef Mat<eT> stored_type; 3016 3017 inline partial_unwrap_check_scalar_times_defaultpartial_unwrap_check_scalar_times_default3018 partial_unwrap_check_scalar_times_default(const eOp<T1, eop_scalar_times>& A, const Mat<eT>&) 3019 : val(A.aux) 3020 , M (A.P.Q) 3021 { 3022 arma_extra_debug_sigprint(); 3023 } 3024 get_valpartial_unwrap_check_scalar_times_default3025 arma_inline eT get_val() const { return val; } 3026 3027 static constexpr bool do_trans = false; 3028 static constexpr bool do_times = true; 3029 3030 const eT val; 3031 const Mat<eT> M; 3032 }; 3033 3034 3035 3036 template<typename T1> 3037 struct partial_unwrap_check_scalar_times_fixed 3038 { 3039 typedef typename T1::elem_type eT; 3040 typedef T1 stored_type; 3041 3042 inline explicit partial_unwrap_check_scalar_times_fixedpartial_unwrap_check_scalar_times_fixed3043 partial_unwrap_check_scalar_times_fixed(const eOp<T1, eop_scalar_times>& A, const Mat<eT>& B) 3044 : val ( A.aux ) 3045 , M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : nullptr ) 3046 , M ( (&(A.P.Q) == &B) ? (*M_local) : A.P.Q ) 3047 { 3048 arma_extra_debug_sigprint(); 3049 } 3050 3051 inline ~partial_unwrap_check_scalar_times_fixedpartial_unwrap_check_scalar_times_fixed3052 ~partial_unwrap_check_scalar_times_fixed() 3053 { 3054 arma_extra_debug_sigprint(); 3055 3056 if(M_local) { delete M_local; } 3057 } 3058 get_valpartial_unwrap_check_scalar_times_fixed3059 arma_inline eT get_val() const { return val; } 3060 3061 static constexpr bool do_trans = false; 3062 static constexpr bool do_times = true; 3063 3064 const eT val; 3065 const T1* M_local; 3066 const T1& M; 3067 }; 3068 3069 3070 3071 template<typename T1, bool condition> 3072 struct partial_unwrap_check_scalar_times_redirect {}; 3073 3074 template<typename T1> 3075 struct partial_unwrap_check_scalar_times_redirect<T1, false> { typedef partial_unwrap_check_scalar_times_default<T1> result; }; 3076 3077 template<typename T1> 3078 struct partial_unwrap_check_scalar_times_redirect<T1, true> { typedef partial_unwrap_check_scalar_times_fixed<T1> result; }; 3079 3080 3081 template<typename T1> 3082 struct partial_unwrap_check< eOp<T1, eop_scalar_times> > : public partial_unwrap_check_scalar_times_redirect<T1, is_Mat_fixed<T1>::value>::result 3083 { 3084 typedef typename T1::elem_type eT; 3085 partial_unwrap_checkpartial_unwrap_check3086 inline partial_unwrap_check(const eOp<T1, eop_scalar_times>& A, const Mat<eT>& B) 3087 : partial_unwrap_check_scalar_times_redirect<T1, is_Mat_fixed<T1>::value>::result(A, B) 3088 { 3089 } 3090 }; 3091 3092 3093 3094 template<typename eT> 3095 struct partial_unwrap_check< eOp<Mat<eT>, eop_scalar_times> > 3096 { 3097 typedef Mat<eT> stored_type; 3098 3099 inline partial_unwrap_checkpartial_unwrap_check3100 partial_unwrap_check(const eOp<Mat<eT>,eop_scalar_times>& A, const Mat<eT>& B) 3101 : val (A.aux) 3102 , M_local( (&(A.P.Q) == &B) ? new Mat<eT>(A.P.Q) : nullptr ) 3103 , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) 3104 { 3105 arma_extra_debug_sigprint(); 3106 } 3107 3108 inline ~partial_unwrap_checkpartial_unwrap_check3109 ~partial_unwrap_check() 3110 { 3111 arma_extra_debug_sigprint(); 3112 3113 if(M_local) { delete M_local; } 3114 } 3115 get_valpartial_unwrap_check3116 arma_inline eT get_val() const { return val; } 3117 3118 static constexpr bool do_trans = false; 3119 static constexpr bool do_times = true; 3120 3121 const eT val; 3122 const Mat<eT>* M_local; 3123 const Mat<eT>& M; 3124 }; 3125 3126 3127 3128 template<typename eT> 3129 struct partial_unwrap_check< eOp<Row<eT>, eop_scalar_times> > 3130 { 3131 typedef Row<eT> stored_type; 3132 3133 inline partial_unwrap_checkpartial_unwrap_check3134 partial_unwrap_check(const eOp<Row<eT>,eop_scalar_times>& A, const Mat<eT>& B) 3135 : val(A.aux) 3136 , M_local( (&(A.P.Q) == &B) ? new Row<eT>(A.P.Q) : nullptr ) 3137 , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) 3138 { 3139 arma_extra_debug_sigprint(); 3140 } 3141 3142 inline ~partial_unwrap_checkpartial_unwrap_check3143 ~partial_unwrap_check() 3144 { 3145 arma_extra_debug_sigprint(); 3146 3147 if(M_local) { delete M_local; } 3148 } 3149 get_valpartial_unwrap_check3150 arma_inline eT get_val() const { return val; } 3151 3152 static constexpr bool do_trans = false; 3153 static constexpr bool do_times = true; 3154 3155 const eT val; 3156 const Row<eT>* M_local; 3157 const Row<eT>& M; 3158 }; 3159 3160 3161 3162 template<typename eT> 3163 struct partial_unwrap_check< eOp<Col<eT>, eop_scalar_times> > 3164 { 3165 typedef Col<eT> stored_type; 3166 3167 inline partial_unwrap_checkpartial_unwrap_check3168 partial_unwrap_check(const eOp<Col<eT>,eop_scalar_times>& A, const Mat<eT>& B) 3169 : val ( A.aux ) 3170 , M_local( (&(A.P.Q) == &B) ? new Col<eT>(A.P.Q) : nullptr ) 3171 , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) 3172 { 3173 arma_extra_debug_sigprint(); 3174 } 3175 3176 inline ~partial_unwrap_checkpartial_unwrap_check3177 ~partial_unwrap_check() 3178 { 3179 arma_extra_debug_sigprint(); 3180 3181 if(M_local) { delete M_local; } 3182 } 3183 get_valpartial_unwrap_check3184 arma_inline eT get_val() const { return val; } 3185 3186 static constexpr bool do_trans = false; 3187 static constexpr bool do_times = true; 3188 3189 const eT val; 3190 const Col<eT>* M_local; 3191 const Col<eT>& M; 3192 }; 3193 3194 3195 3196 // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class, 3197 // NOTE: which relies on partial_unwrap_check to check for aliasing 3198 template<typename eT> 3199 struct partial_unwrap_check< eOp<subview_col<eT>, eop_scalar_times> > 3200 { 3201 typedef Col<eT> stored_type; 3202 3203 inline partial_unwrap_checkpartial_unwrap_check3204 partial_unwrap_check(const eOp<subview_col<eT>,eop_scalar_times>& A, const Mat<eT>& B) 3205 : val( A.aux ) 3206 , M ( const_cast<eT*>( A.P.Q.colmem ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false ) 3207 { 3208 arma_extra_debug_sigprint(); 3209 } 3210 get_valpartial_unwrap_check3211 arma_inline eT get_val() const { return val; } 3212 3213 static constexpr bool do_trans = false; 3214 static constexpr bool do_times = true; 3215 3216 const eT val; 3217 const Col<eT> M; 3218 }; 3219 3220 3221 3222 template<typename T1> 3223 struct partial_unwrap_check_neg_default 3224 { 3225 typedef typename T1::elem_type eT; 3226 typedef Mat<eT> stored_type; 3227 3228 inline partial_unwrap_check_neg_defaultpartial_unwrap_check_neg_default3229 partial_unwrap_check_neg_default(const eOp<T1, eop_neg>& A, const Mat<eT>&) 3230 : M(A.P.Q) 3231 { 3232 arma_extra_debug_sigprint(); 3233 } 3234 get_valpartial_unwrap_check_neg_default3235 constexpr eT get_val() const { return eT(-1); } 3236 3237 static constexpr bool do_trans = false; 3238 static constexpr bool do_times = true; 3239 3240 const Mat<eT> M; 3241 }; 3242 3243 3244 3245 template<typename T1> 3246 struct partial_unwrap_check_neg_fixed 3247 { 3248 typedef typename T1::elem_type eT; 3249 typedef T1 stored_type; 3250 3251 inline explicit partial_unwrap_check_neg_fixedpartial_unwrap_check_neg_fixed3252 partial_unwrap_check_neg_fixed(const eOp<T1, eop_neg>& A, const Mat<eT>& B) 3253 : M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : nullptr ) 3254 , M ( (&(A.P.Q) == &B) ? (*M_local) : A.P.Q ) 3255 { 3256 arma_extra_debug_sigprint(); 3257 } 3258 3259 inline ~partial_unwrap_check_neg_fixedpartial_unwrap_check_neg_fixed3260 ~partial_unwrap_check_neg_fixed() 3261 { 3262 arma_extra_debug_sigprint(); 3263 3264 if(M_local) { delete M_local; } 3265 } 3266 get_valpartial_unwrap_check_neg_fixed3267 constexpr eT get_val() const { return eT(-1); } 3268 3269 static constexpr bool do_trans = false; 3270 static constexpr bool do_times = true; 3271 3272 const T1* M_local; 3273 const T1& M; 3274 }; 3275 3276 3277 3278 template<typename T1, bool condition> 3279 struct partial_unwrap_check_neg_redirect {}; 3280 3281 template<typename T1> 3282 struct partial_unwrap_check_neg_redirect<T1, false> { typedef partial_unwrap_check_neg_default<T1> result; }; 3283 3284 template<typename T1> 3285 struct partial_unwrap_check_neg_redirect<T1, true> { typedef partial_unwrap_check_neg_fixed<T1> result; }; 3286 3287 3288 template<typename T1> 3289 struct partial_unwrap_check< eOp<T1, eop_neg> > : public partial_unwrap_check_neg_redirect<T1, is_Mat_fixed<T1>::value>::result 3290 { 3291 typedef typename T1::elem_type eT; 3292 partial_unwrap_checkpartial_unwrap_check3293 inline partial_unwrap_check(const eOp<T1, eop_neg>& A, const Mat<eT>& B) 3294 : partial_unwrap_check_neg_redirect<T1, is_Mat_fixed<T1>::value>::result(A, B) 3295 { 3296 } 3297 }; 3298 3299 3300 3301 template<typename eT> 3302 struct partial_unwrap_check< eOp<Mat<eT>, eop_neg> > 3303 { 3304 typedef Mat<eT> stored_type; 3305 3306 inline partial_unwrap_checkpartial_unwrap_check3307 partial_unwrap_check(const eOp<Mat<eT>,eop_neg>& A, const Mat<eT>& B) 3308 : M_local( (&(A.P.Q) == &B) ? new Mat<eT>(A.P.Q) : nullptr ) 3309 , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) 3310 { 3311 arma_extra_debug_sigprint(); 3312 } 3313 3314 inline ~partial_unwrap_checkpartial_unwrap_check3315 ~partial_unwrap_check() 3316 { 3317 arma_extra_debug_sigprint(); 3318 3319 if(M_local) { delete M_local; } 3320 } 3321 get_valpartial_unwrap_check3322 constexpr eT get_val() const { return eT(-1); } 3323 3324 static constexpr bool do_trans = false; 3325 static constexpr bool do_times = true; 3326 3327 const Mat<eT>* M_local; 3328 const Mat<eT>& M; 3329 }; 3330 3331 3332 3333 template<typename eT> 3334 struct partial_unwrap_check< eOp<Row<eT>, eop_neg> > 3335 { 3336 typedef Row<eT> stored_type; 3337 3338 inline partial_unwrap_checkpartial_unwrap_check3339 partial_unwrap_check(const eOp<Row<eT>,eop_neg>& A, const Mat<eT>& B) 3340 : M_local( (&(A.P.Q) == &B) ? new Row<eT>(A.P.Q) : nullptr ) 3341 , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) 3342 { 3343 arma_extra_debug_sigprint(); 3344 } 3345 3346 inline ~partial_unwrap_checkpartial_unwrap_check3347 ~partial_unwrap_check() 3348 { 3349 arma_extra_debug_sigprint(); 3350 3351 if(M_local) { delete M_local; } 3352 } 3353 get_valpartial_unwrap_check3354 constexpr eT get_val() const { return eT(-1); } 3355 3356 static constexpr bool do_trans = false; 3357 static constexpr bool do_times = true; 3358 3359 const Row<eT>* M_local; 3360 const Row<eT>& M; 3361 }; 3362 3363 3364 3365 template<typename eT> 3366 struct partial_unwrap_check< eOp<Col<eT>, eop_neg> > 3367 { 3368 typedef Col<eT> stored_type; 3369 3370 inline partial_unwrap_checkpartial_unwrap_check3371 partial_unwrap_check(const eOp<Col<eT>,eop_neg>& A, const Mat<eT>& B) 3372 : M_local( (&(A.P.Q) == &B) ? new Col<eT>(A.P.Q) : nullptr ) 3373 , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) 3374 { 3375 arma_extra_debug_sigprint(); 3376 } 3377 3378 inline ~partial_unwrap_checkpartial_unwrap_check3379 ~partial_unwrap_check() 3380 { 3381 arma_extra_debug_sigprint(); 3382 3383 if(M_local) { delete M_local; } 3384 } 3385 get_valpartial_unwrap_check3386 constexpr eT get_val() const { return eT(-1); } 3387 3388 static constexpr bool do_trans = false; 3389 static constexpr bool do_times = true; 3390 3391 const Col<eT>* M_local; 3392 const Col<eT>& M; 3393 }; 3394 3395 3396 3397 // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class, 3398 // NOTE: which relies on partial_unwrap_check to check for aliasing 3399 template<typename eT> 3400 struct partial_unwrap_check< eOp<subview_col<eT>, eop_neg> > 3401 { 3402 typedef Col<eT> stored_type; 3403 3404 inline partial_unwrap_checkpartial_unwrap_check3405 partial_unwrap_check(const eOp<subview_col<eT>,eop_neg>& A, const Mat<eT>& B) 3406 : M ( const_cast<eT*>( A.P.Q.colmem ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false ) 3407 { 3408 arma_extra_debug_sigprint(); 3409 } 3410 get_valpartial_unwrap_check3411 constexpr eT get_val() const { return eT(-1); } 3412 3413 static constexpr bool do_trans = false; 3414 static constexpr bool do_times = true; 3415 3416 const Col<eT> M; 3417 }; 3418 3419 3420 3421 //! @} 3422