Chris@49: // Copyright (C) 2008-2013 NICTA (www.nicta.com.au) Chris@49: // Copyright (C) 2008-2013 Conrad Sanderson Chris@49: // Chris@49: // This Source Code Form is subject to the terms of the Mozilla Public Chris@49: // License, v. 2.0. If a copy of the MPL was not distributed with this Chris@49: // file, You can obtain one at http://mozilla.org/MPL/2.0/. Chris@49: Chris@49: Chris@49: //! \addtogroup unwrap Chris@49: //! @{ Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: unwrap_default(const T1& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_fixed Chris@49: { Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline explicit Chris@49: unwrap_fixed(const T1& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_redirect {}; Chris@49: Chris@49: template Chris@49: struct unwrap_redirect { typedef unwrap_default result; }; Chris@49: Chris@49: template Chris@49: struct unwrap_redirect { typedef unwrap_fixed result; }; Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap : public unwrap_redirect::value >::result Chris@49: { Chris@49: inline Chris@49: unwrap(const T1& A) Chris@49: : unwrap_redirect< T1, is_Mat_fixed::value >::result(A) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap< Mat > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: unwrap(const Mat& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap< Row > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: inline Chris@49: unwrap(const Row& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap< Col > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: inline Chris@49: unwrap(const Col& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap< mtGlue > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: unwrap(const mtGlue& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap< mtOp > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: unwrap(const mtOp& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // Chris@49: // Chris@49: // Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct quasi_unwrap_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: static const bool has_subview = false; Chris@49: Chris@49: inline Chris@49: quasi_unwrap_default(const T1& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: // NOTE: DO NOT DIRECTLY CHECK FOR ALIASING BY TAKING THE ADDRESS OF THE "M" OBJECT IN ANY quasi_unwrap CLASS !!! Chris@49: const Mat M; Chris@49: Chris@49: template Chris@49: arma_inline bool is_alias(const Mat&) const { return false; } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct quasi_unwrap_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: static const bool has_subview = false; Chris@49: Chris@49: inline explicit Chris@49: quasi_unwrap_fixed(const T1& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Mat& M; Chris@49: Chris@49: template Chris@49: arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&M) == void_ptr(&X)); } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct quasi_unwrap_redirect {}; Chris@49: Chris@49: template Chris@49: struct quasi_unwrap_redirect { typedef quasi_unwrap_default result; }; Chris@49: Chris@49: template Chris@49: struct quasi_unwrap_redirect { typedef quasi_unwrap_fixed result; }; Chris@49: Chris@49: Chris@49: template Chris@49: struct quasi_unwrap : public quasi_unwrap_redirect::value >::result Chris@49: { Chris@49: typedef typename quasi_unwrap_redirect::value >::result quasi_unwrap_extra; Chris@49: Chris@49: static const bool has_subview = quasi_unwrap_extra::has_subview; Chris@49: Chris@49: inline Chris@49: quasi_unwrap(const T1& A) Chris@49: : quasi_unwrap_extra(A) Chris@49: { Chris@49: } Chris@49: Chris@49: using quasi_unwrap_extra::M; Chris@49: using quasi_unwrap_extra::is_alias; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct quasi_unwrap< Mat > Chris@49: { Chris@49: static const bool has_subview = false; Chris@49: Chris@49: inline Chris@49: quasi_unwrap(const Mat& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Mat& M; Chris@49: Chris@49: template Chris@49: arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&M) == void_ptr(&X)); } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct quasi_unwrap< Row > Chris@49: { Chris@49: static const bool has_subview = false; Chris@49: Chris@49: inline Chris@49: quasi_unwrap(const Row& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Row& M; Chris@49: Chris@49: template Chris@49: arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&M) == void_ptr(&X)); } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct quasi_unwrap< Col > Chris@49: { Chris@49: static const bool has_subview = false; Chris@49: Chris@49: inline Chris@49: quasi_unwrap(const Col& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Col& M; Chris@49: Chris@49: template Chris@49: arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&M) == void_ptr(&X)); } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct quasi_unwrap< subview_col > Chris@49: { Chris@49: static const bool has_subview = true; Chris@49: Chris@49: inline Chris@49: quasi_unwrap(const subview_col& A) Chris@49: : M ( const_cast( A.colptr(0) ), A.n_rows, 1, false, false ) Chris@49: , src( A.m ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Mat M; Chris@49: const Mat& src; Chris@49: Chris@49: template Chris@49: arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&src) == void_ptr(&X)); } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct quasi_unwrap< mtGlue > Chris@49: { Chris@49: static const bool has_subview = false; Chris@49: Chris@49: inline Chris@49: quasi_unwrap(const mtGlue& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Mat M; Chris@49: Chris@49: template Chris@49: arma_inline bool is_alias(const Mat&) const { return false; } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct quasi_unwrap< mtOp > Chris@49: { Chris@49: static const bool has_subview = false; Chris@49: Chris@49: inline Chris@49: quasi_unwrap(const mtOp& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Mat M; Chris@49: Chris@49: template Chris@49: arma_inline bool is_alias(const Mat&) const { return false; } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // Chris@49: // Chris@49: // Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_check_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: unwrap_check_default(const T1& A, const Mat&) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: unwrap_check_default(const T1& A, const bool) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_check_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline Chris@49: unwrap_check_fixed(const T1& A, const Mat& B) Chris@49: : M_local( (&A == &B) ? new T1(A) : 0 ) Chris@49: , M ( (&A == &B) ? *M_local : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: unwrap_check_fixed(const T1& A, const bool is_alias) Chris@49: : M_local( is_alias ? new T1(A) : 0 ) Chris@49: , M ( is_alias ? *M_local : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~unwrap_check_fixed() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: Chris@49: // the order below is important Chris@49: const T1* M_local; Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_check_redirect {}; Chris@49: Chris@49: template Chris@49: struct unwrap_check_redirect { typedef unwrap_check_default result; }; Chris@49: Chris@49: template Chris@49: struct unwrap_check_redirect { typedef unwrap_check_fixed result; }; Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_check : public unwrap_check_redirect::value >::result Chris@49: { Chris@49: inline unwrap_check(const T1& A, const Mat& B) Chris@49: : unwrap_check_redirect< T1, is_Mat_fixed::value >::result(A, B) Chris@49: { Chris@49: } Chris@49: Chris@49: inline unwrap_check(const T1& A, const bool is_alias) Chris@49: : unwrap_check_redirect< T1, is_Mat_fixed::value >::result(A, is_alias) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_check< Mat > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: unwrap_check(const Mat& A, const Mat& B) Chris@49: : M_local( (&A == &B) ? new Mat(A) : 0 ) Chris@49: , M ( (&A == &B) ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: unwrap_check(const Mat& A, const bool is_alias) Chris@49: : M_local( is_alias ? new Mat(A) : 0 ) Chris@49: , M ( is_alias ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: Chris@49: // the order below is important Chris@49: const Mat* M_local; Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_check< Row > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: inline Chris@49: unwrap_check(const Row& A, const Mat& B) Chris@49: : M_local( (&A == &B) ? new Row(A) : 0 ) Chris@49: , M ( (&A == &B) ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: unwrap_check(const Row& A, const bool is_alias) Chris@49: : M_local( is_alias ? new Row(A) : 0 ) Chris@49: , M ( is_alias ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: Chris@49: // the order below is important Chris@49: const Row* M_local; Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_check< Col > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: inline Chris@49: unwrap_check(const Col& A, const Mat& B) Chris@49: : M_local( (&A == &B) ? new Col(A) : 0 ) Chris@49: , M ( (&A == &B) ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: unwrap_check(const Col& A, const bool is_alias) Chris@49: : M_local( is_alias ? new Col(A) : 0 ) Chris@49: , M ( is_alias ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: Chris@49: // the order below is important Chris@49: const Col* M_local; Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // Chris@49: // Chris@49: // Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_check_mixed Chris@49: { Chris@49: typedef typename T1::elem_type eT1; Chris@49: Chris@49: template Chris@49: inline Chris@49: unwrap_check_mixed(const T1& A, const Mat&) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: template Chris@49: inline Chris@49: unwrap_check_mixed(const T1& A, const bool) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_check_mixed< Mat > Chris@49: { Chris@49: template Chris@49: inline Chris@49: unwrap_check_mixed(const Mat& A, const Mat& B) Chris@49: : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Mat(A) : 0 ) Chris@49: , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: template Chris@49: inline Chris@49: unwrap_check_mixed(const Mat& A, const bool is_alias) Chris@49: : M_local( is_alias ? new Mat(A) : 0 ) Chris@49: , M ( is_alias ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~unwrap_check_mixed() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: Chris@49: // the order below is important Chris@49: const Mat* M_local; Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_check_mixed< Row > Chris@49: { Chris@49: template Chris@49: inline Chris@49: unwrap_check_mixed(const Row& A, const Mat& B) Chris@49: : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Row(A) : 0 ) Chris@49: , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: unwrap_check_mixed(const Row& A, const bool is_alias) Chris@49: : M_local( is_alias ? new Row(A) : 0 ) Chris@49: , M ( is_alias ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~unwrap_check_mixed() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: Chris@49: // the order below is important Chris@49: const Row* M_local; Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct unwrap_check_mixed< Col > Chris@49: { Chris@49: template Chris@49: inline Chris@49: unwrap_check_mixed(const Col& A, const Mat& B) Chris@49: : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Col(A) : 0 ) Chris@49: , M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: template Chris@49: inline Chris@49: unwrap_check_mixed(const Col& A, const bool is_alias) Chris@49: : M_local( is_alias ? new Col(A) : 0 ) Chris@49: , M ( is_alias ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~unwrap_check_mixed() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: Chris@49: // the order below is important Chris@49: const Col* M_local; Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // Chris@49: // Chris@49: // Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap_default(const T1& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline explicit Chris@49: partial_unwrap_fixed(const T1& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_redirect {}; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_redirect { typedef partial_unwrap_default result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_redirect { typedef partial_unwrap_fixed result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap : public partial_unwrap_redirect::value >::result Chris@49: { Chris@49: inline Chris@49: partial_unwrap(const T1& A) Chris@49: : partial_unwrap_redirect< T1, is_Mat_fixed::value >::result(A) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< Mat > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const Mat& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< Row > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const Row& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< Col > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const Col& A) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // NOTE: we can get away with this shortcut as the partial_unwrap class is only used by as_scalar(), Chris@49: // NOTE: which doesn't need to check for aliasing (ie. it doesn't need to compare the address of M with another matrix) Chris@49: template Chris@49: struct partial_unwrap< subview_col > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const subview_col& A) Chris@49: : M ( const_cast( A.colptr(0) ), A.n_rows, false, false ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Col M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_htrans_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap_htrans_default(const Op& A) Chris@49: : M(A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_htrans_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline explicit Chris@49: partial_unwrap_htrans_fixed(const Op& A) Chris@49: : M(A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_htrans_redirect {}; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_htrans_redirect { typedef partial_unwrap_htrans_default result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_htrans_redirect { typedef partial_unwrap_htrans_fixed result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap< Op > : public partial_unwrap_htrans_redirect::value >::result Chris@49: { Chris@49: inline partial_unwrap(const Op& A) Chris@49: : partial_unwrap_htrans_redirect< T1, is_Mat_fixed::value >::result(A) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< Op< Mat, op_htrans> > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const Op< Mat, op_htrans>& A) Chris@49: : M(A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< Op< Row, op_htrans> > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const Op< Row, op_htrans>& A) Chris@49: : M(A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< Op< Col, op_htrans> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const Op< Col, op_htrans>& A) Chris@49: : M(A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // NOTE: we can get away with this shortcut as the partial_unwrap class is only used by as_scalar(), Chris@49: // NOTE: which doesn't need to check for aliasing (ie. it doesn't need to compare the address of M with another matrix) Chris@49: template Chris@49: struct partial_unwrap< Op< subview_col, op_htrans> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const Op< subview_col, op_htrans>& A) Chris@49: : M ( const_cast( A.m.colptr(0) ), A.m.n_rows, false, false ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Col M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_htrans2_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap_htrans2_default(const Op& A) Chris@49: : val(A.aux) Chris@49: , M (A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_htrans2_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline explicit Chris@49: partial_unwrap_htrans2_fixed(const Op& A) Chris@49: : val(A.aux) Chris@49: , M (A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_htrans2_redirect {}; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_htrans2_redirect { typedef partial_unwrap_htrans2_default result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_htrans2_redirect { typedef partial_unwrap_htrans2_fixed result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap< Op > : public partial_unwrap_htrans2_redirect::value >::result Chris@49: { Chris@49: inline partial_unwrap(const Op& A) Chris@49: : partial_unwrap_htrans2_redirect< T1, is_Mat_fixed::value >::result(A) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< Op< Mat, op_htrans2> > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const Op< Mat, op_htrans2>& A) Chris@49: : val(A.aux) Chris@49: , M (A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< Op< Row, op_htrans2> > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const Op< Row, op_htrans2>& A) Chris@49: : val(A.aux) Chris@49: , M (A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< Op< Col, op_htrans2> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const Op< Col, op_htrans2>& A) Chris@49: : val(A.aux) Chris@49: , M (A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // NOTE: we can get away with this shortcut as the partial_unwrap class is only used by as_scalar(), Chris@49: // NOTE: which doesn't need to check for aliasing (ie. it doesn't need to compare the address of M with another matrix) Chris@49: template Chris@49: struct partial_unwrap< Op< subview_col, op_htrans2> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const Op< subview_col, op_htrans2>& A) Chris@49: : val( A.aux ) Chris@49: , M ( const_cast( A.m.colptr(0) ), A.m.n_rows, false, false ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Col M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_scalar_times_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap_scalar_times_default(const eOp& A) Chris@49: : val(A.aux) Chris@49: , M (A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_scalar_times_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline explicit Chris@49: partial_unwrap_scalar_times_fixed(const eOp& A) Chris@49: : val(A.aux) Chris@49: , M (A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_scalar_times_redirect {}; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_scalar_times_redirect { typedef partial_unwrap_scalar_times_default result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_scalar_times_redirect { typedef partial_unwrap_scalar_times_fixed result; }; Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< eOp > : public partial_unwrap_scalar_times_redirect::value >::result Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const eOp& A) Chris@49: : partial_unwrap_scalar_times_redirect< T1, is_Mat_fixed::value >::result(A) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< eOp, eop_scalar_times> > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const eOp,eop_scalar_times>& A) Chris@49: : val(A.aux) Chris@49: , M (A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< eOp, eop_scalar_times> > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const eOp,eop_scalar_times>& A) Chris@49: : val(A.aux) Chris@49: , M (A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< eOp, eop_scalar_times> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const eOp,eop_scalar_times>& A) Chris@49: : val(A.aux) Chris@49: , M (A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // TODO: struct partial_unwrap< eOp, eop_scalar_times> > Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_neg_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap_neg_default(const eOp& A) Chris@49: : M(A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(-1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_neg_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline explicit Chris@49: partial_unwrap_neg_fixed(const eOp& A) Chris@49: : M(A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(-1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_neg_redirect {}; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_neg_redirect { typedef partial_unwrap_neg_default result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_neg_redirect { typedef partial_unwrap_neg_fixed result; }; Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< eOp > : public partial_unwrap_neg_redirect::value >::result Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const eOp& A) Chris@49: : partial_unwrap_neg_redirect< T1, is_Mat_fixed::value >::result(A) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< eOp, eop_neg> > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const eOp,eop_neg>& A) Chris@49: : M(A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return eT(-1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< eOp, eop_neg> > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const eOp,eop_neg>& A) Chris@49: : M(A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return eT(-1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap< eOp, eop_neg> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap(const eOp,eop_neg>& A) Chris@49: : M(A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline eT get_val() const { return eT(-1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // TODO: struct partial_unwrap< eOp, eop_neg> > Chris@49: Chris@49: Chris@49: Chris@49: // Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap_check_default(const T1& A, const Mat&) Chris@49: : M(A) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline explicit Chris@49: partial_unwrap_check_fixed(const T1& A, const Mat& B) Chris@49: : M_local( (&A == &B) ? new T1(A) : 0 ) Chris@49: , M ( (&A == &B) ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check_fixed() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const T1* M_local; Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_redirect {}; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_redirect { typedef partial_unwrap_check_default result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_redirect { typedef partial_unwrap_check_fixed result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check : public partial_unwrap_check_redirect::value >::result Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: inline partial_unwrap_check(const T1& A, const Mat& B) Chris@49: : partial_unwrap_check_redirect< T1, is_Mat_fixed::value >::result(A, B) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< Mat > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const Mat& A, const Mat& B) Chris@49: : M_local ( (&A == &B) ? new Mat(A) : 0 ) Chris@49: , M ( (&A == &B) ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: // the order below is important Chris@49: const Mat* M_local; Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< Row > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const Row& A, const Mat& B) Chris@49: : M_local ( (&A == &B) ? new Row(A) : 0 ) Chris@49: , M ( (&A == &B) ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: // the order below is important Chris@49: const Row* M_local; Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< Col > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const Col& A, const Mat& B) Chris@49: : M_local ( (&A == &B) ? new Col(A) : 0 ) Chris@49: , M ( (&A == &B) ? (*M_local) : A ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: // the order below is important Chris@49: const Col* M_local; Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class, Chris@49: // NOTE: which relies on partial_unwrap_check to check for aliasing Chris@49: template Chris@49: struct partial_unwrap_check< subview_col > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const subview_col& A, const Mat& B) Chris@49: : M ( const_cast( A.colptr(0) ), A.n_rows, (&(A.m) == &B), false ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Col M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_htrans_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap_check_htrans_default(const Op& A, const Mat&) Chris@49: : M(A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_htrans_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline explicit Chris@49: partial_unwrap_check_htrans_fixed(const Op& A, const Mat& B) Chris@49: : M_local( (&(A.m) == &B) ? new T1(A.m) : 0 ) Chris@49: , M ( (&(A.m) == &B) ? (*M_local) : A.m ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check_htrans_fixed() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const T1* M_local; Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_htrans_redirect {}; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_htrans_redirect { typedef partial_unwrap_check_htrans_default result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_htrans_redirect { typedef partial_unwrap_check_htrans_fixed result; }; Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< Op > : public partial_unwrap_check_htrans_redirect::value >::result Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: inline partial_unwrap_check(const Op& A, const Mat& B) Chris@49: : partial_unwrap_check_htrans_redirect< T1, is_Mat_fixed::value >::result(A, B) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< Op< Mat, op_htrans> > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const Op< Mat, op_htrans>& A, const Mat& B) Chris@49: : M_local ( (&A.m == &B) ? new Mat(A.m) : 0 ) Chris@49: , M ( (&A.m == &B) ? (*M_local) : A.m ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: // the order below is important Chris@49: const Mat* M_local; Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< Op< Row, op_htrans> > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const Op< Row, op_htrans>& A, const Mat& B) Chris@49: : M_local ( (&A.m == &B) ? new Row(A.m) : 0 ) Chris@49: , M ( (&A.m == &B) ? (*M_local) : A.m ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: // the order below is important Chris@49: const Row* M_local; Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< Op< Col, op_htrans> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const Op< Col, op_htrans>& A, const Mat& B) Chris@49: : M_local ( (&A.m == &B) ? new Col(A.m) : 0 ) Chris@49: , M ( (&A.m == &B) ? (*M_local) : A.m ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: // the order below is important Chris@49: const Col* M_local; Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class, Chris@49: // NOTE: which relies on partial_unwrap_check to check for aliasing Chris@49: template Chris@49: struct partial_unwrap_check< Op< subview_col, op_htrans> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const Op< subview_col, op_htrans>& A, const Mat& B) Chris@49: : M ( const_cast( A.m.colptr(0) ), A.m.n_rows, (&(A.m.m) == &B), false ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(1); } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = false; Chris@49: Chris@49: const Col M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_htrans2_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap_check_htrans2_default(const Op& A, const Mat&) Chris@49: : val(A.aux) Chris@49: , M (A.m) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_htrans2_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline explicit Chris@49: partial_unwrap_check_htrans2_fixed(const Op& A, const Mat& B) Chris@49: : val (A.aux) Chris@49: , M_local( (&(A.m) == &B) ? new T1(A.m) : 0 ) Chris@49: , M ( (&(A.m) == &B) ? (*M_local) : A.m ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check_htrans2_fixed() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const T1* M_local; Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_htrans2_redirect {}; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_htrans2_redirect { typedef partial_unwrap_check_htrans2_default result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_htrans2_redirect { typedef partial_unwrap_check_htrans2_fixed result; }; Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< Op > : public partial_unwrap_check_htrans2_redirect::value >::result Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: inline partial_unwrap_check(const Op& A, const Mat& B) Chris@49: : partial_unwrap_check_htrans2_redirect< T1, is_Mat_fixed::value >::result(A, B) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< Op< Mat, op_htrans2> > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const Op< Mat, op_htrans2>& A, const Mat& B) Chris@49: : val (A.aux) Chris@49: , M_local ( (&A.m == &B) ? new Mat(A.m) : 0 ) Chris@49: , M ( (&A.m == &B) ? (*M_local) : A.m ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: // the order below is important Chris@49: const eT val; Chris@49: const Mat* M_local; Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< Op< Row, op_htrans2> > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const Op< Row, op_htrans2>& A, const Mat& B) Chris@49: : val (A.aux) Chris@49: , M_local ( (&A.m == &B) ? new Row(A.m) : 0 ) Chris@49: , M ( (&A.m == &B) ? (*M_local) : A.m ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: // the order below is important Chris@49: const eT val; Chris@49: const Row* M_local; Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< Op< Col, op_htrans2> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const Op< Col, op_htrans2>& A, const Mat& B) Chris@49: : val (A.aux) Chris@49: , M_local ( (&A.m == &B) ? new Col(A.m) : 0 ) Chris@49: , M ( (&A.m == &B) ? (*M_local) : A.m ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: // the order below is important Chris@49: const eT val; Chris@49: const Col* M_local; Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class, Chris@49: // NOTE: which relies on partial_unwrap_check to check for aliasing Chris@49: template Chris@49: struct partial_unwrap_check< Op< subview_col, op_htrans2> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const Op< subview_col, op_htrans2>& A, const Mat& B) Chris@49: : val( A.aux ) Chris@49: , M ( const_cast( A.m.colptr(0) ), A.m.n_rows, (&(A.m.m) == &B), false ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = true; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Col M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_scalar_times_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap_check_scalar_times_default(const eOp& A, const Mat&) Chris@49: : val(A.aux) Chris@49: , M (A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_scalar_times_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline explicit Chris@49: partial_unwrap_check_scalar_times_fixed(const eOp& A, const Mat& B) Chris@49: : val ( A.aux ) Chris@49: , M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : 0 ) Chris@49: , M ( (&(A.P.Q) == &B) ? (*M_local) : A.P.Q ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check_scalar_times_fixed() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const T1* M_local; Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_scalar_times_redirect {}; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_scalar_times_redirect { typedef partial_unwrap_check_scalar_times_default result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_scalar_times_redirect { typedef partial_unwrap_check_scalar_times_fixed result; }; Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< eOp > : public partial_unwrap_check_scalar_times_redirect::value >::result Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: inline partial_unwrap_check(const eOp& A, const Mat& B) Chris@49: : partial_unwrap_check_scalar_times_redirect< T1, is_Mat_fixed::value >::result(A, B) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< eOp, eop_scalar_times> > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const eOp,eop_scalar_times>& A, const Mat& B) Chris@49: : val (A.aux) Chris@49: , M_local( (&(A.P.Q) == &B) ? new Mat(A.P.Q) : 0 ) Chris@49: , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Mat* M_local; Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< eOp, eop_scalar_times> > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const eOp,eop_scalar_times>& A, const Mat& B) Chris@49: : val(A.aux) Chris@49: , M_local( (&(A.P.Q) == &B) ? new Row(A.P.Q) : 0 ) Chris@49: , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Row* M_local; Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< eOp, eop_scalar_times> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const eOp,eop_scalar_times>& A, const Mat& B) Chris@49: : val ( A.aux ) Chris@49: , M_local( (&(A.P.Q) == &B) ? new Col(A.P.Q) : 0 ) Chris@49: , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Col* M_local; Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class, Chris@49: // NOTE: which relies on partial_unwrap_check to check for aliasing Chris@49: template Chris@49: struct partial_unwrap_check< eOp, eop_scalar_times> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const eOp,eop_scalar_times>& A, const Mat& B) Chris@49: : val( A.aux ) Chris@49: , M ( const_cast( A.P.Q.colptr(0) ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return val; } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const eT val; Chris@49: const Col M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_neg_default Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef Mat stored_type; Chris@49: Chris@49: inline Chris@49: partial_unwrap_check_neg_default(const eOp& A, const Mat&) Chris@49: : M(A.P.Q) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(-1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const Mat M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_neg_fixed Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: typedef T1 stored_type; Chris@49: Chris@49: inline explicit Chris@49: partial_unwrap_check_neg_fixed(const eOp& A, const Mat& B) Chris@49: : M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : 0 ) Chris@49: , M ( (&(A.P.Q) == &B) ? (*M_local) : A.P.Q ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check_neg_fixed() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(-1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const T1* M_local; Chris@49: const T1& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_neg_redirect {}; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_neg_redirect { typedef partial_unwrap_check_neg_default result; }; Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check_neg_redirect { typedef partial_unwrap_check_neg_fixed result; }; Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< eOp > : public partial_unwrap_check_neg_redirect::value >::result Chris@49: { Chris@49: typedef typename T1::elem_type eT; Chris@49: Chris@49: inline partial_unwrap_check(const eOp& A, const Mat& B) Chris@49: : partial_unwrap_check_neg_redirect< T1, is_Mat_fixed::value >::result(A, B) Chris@49: { Chris@49: } Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< eOp, eop_neg> > Chris@49: { Chris@49: typedef Mat stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const eOp,eop_neg>& A, const Mat& B) Chris@49: : M_local( (&(A.P.Q) == &B) ? new Mat(A.P.Q) : 0 ) Chris@49: , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(-1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const Mat* M_local; Chris@49: const Mat& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< eOp, eop_neg> > Chris@49: { Chris@49: typedef Row stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const eOp,eop_neg>& A, const Mat& B) Chris@49: : M_local( (&(A.P.Q) == &B) ? new Row(A.P.Q) : 0 ) Chris@49: , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(-1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const Row* M_local; Chris@49: const Row& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: struct partial_unwrap_check< eOp, eop_neg> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const eOp,eop_neg>& A, const Mat& B) Chris@49: : M_local( (&(A.P.Q) == &B) ? new Col(A.P.Q) : 0 ) Chris@49: , M ( (&(A.P.Q) == &B) ? *M_local : A.P.Q ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: inline Chris@49: ~partial_unwrap_check() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: if(M_local) { delete M_local; } Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(-1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const Col* M_local; Chris@49: const Col& M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: // NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class, Chris@49: // NOTE: which relies on partial_unwrap_check to check for aliasing Chris@49: template Chris@49: struct partial_unwrap_check< eOp, eop_neg> > Chris@49: { Chris@49: typedef Col stored_type; Chris@49: Chris@49: arma_hot inline Chris@49: partial_unwrap_check(const eOp,eop_neg>& A, const Mat& B) Chris@49: : M ( const_cast( A.P.Q.colptr(0) ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: arma_hot arma_inline eT get_val() const { return eT(-1); } Chris@49: Chris@49: static const bool do_trans = false; Chris@49: static const bool do_times = true; Chris@49: Chris@49: const Col M; Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: //! @}