Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:49:47

0001 #ifndef BOOST_QVM_MAP_MAT_MAT_HPP_INCLUDED
0002 #define BOOST_QVM_MAP_MAT_MAT_HPP_INCLUDED
0003 
0004 // Copyright 2008-2024 Emil Dotchevski and Reverge Studios, Inc.
0005 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #include <boost/qvm/config.hpp>
0009 #include <boost/qvm/deduce_mat.hpp>
0010 #include <boost/qvm/assert.hpp>
0011 #include <boost/qvm/enable_if.hpp>
0012 #include <boost/qvm/detail/transp_impl.hpp>
0013 
0014 namespace boost { namespace qvm {
0015 
0016 namespace
0017 qvm_detail
0018     {
0019     template <int Row,class OriginalMatrix>
0020     class
0021     del_row_
0022         {
0023         del_row_( del_row_ const & );
0024         del_row_ & operator=( del_row_ const & );
0025         ~del_row_();
0026 
0027         public:
0028 
0029         template <class T>
0030         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0031         del_row_ &
0032         operator=( T const & x )
0033             {
0034             assign(*this,x);
0035             return *this;
0036             }
0037 
0038         template <class R
0039 #if __cplusplus >= 201103L
0040             , class = typename enable_if<is_mat<R> >::type
0041 #endif
0042         >
0043         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0044         operator R() const
0045             {
0046             R r;
0047             assign(r,*this);
0048             return r;
0049             }
0050         };
0051 
0052     template <int I,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
0053     struct del_row_write_traits;
0054 
0055     template <int I,class OriginalMatrix>
0056     struct
0057     del_row_write_traits<I,OriginalMatrix,true>
0058         {
0059         typedef del_row_<I,OriginalMatrix> this_matrix;
0060         typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0061         static int const rows=mat_traits<OriginalMatrix>::rows-1;
0062         static int const cols=mat_traits<OriginalMatrix>::cols;
0063 
0064         template <int Row,int Col>
0065         static
0066         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0067         scalar_type &
0068         write_element( this_matrix & x )
0069             {
0070             BOOST_QVM_STATIC_ASSERT(Row>=0);
0071             BOOST_QVM_STATIC_ASSERT(Row<rows);
0072             BOOST_QVM_STATIC_ASSERT(Col>=0);
0073             BOOST_QVM_STATIC_ASSERT(Col<cols);
0074             return mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col>(reinterpret_cast<OriginalMatrix &>(x));
0075             }
0076 
0077         static
0078         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0079         scalar_type &
0080         write_element_idx( int row, int col, this_matrix & x )
0081             {
0082             BOOST_QVM_ASSERT(row>=0);
0083             BOOST_QVM_ASSERT(row<rows);
0084             BOOST_QVM_ASSERT(col>=0);
0085             BOOST_QVM_ASSERT(col<cols);
0086             return mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col,reinterpret_cast<OriginalMatrix &>(x));
0087             }
0088         };
0089 
0090     template <int I,class OriginalMatrix>
0091     struct
0092     del_row_write_traits<I,OriginalMatrix,false>
0093         {
0094         typedef del_row_<I,OriginalMatrix> this_matrix;
0095         typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0096         static int const rows=mat_traits<OriginalMatrix>::rows-1;
0097         static int const cols=mat_traits<OriginalMatrix>::cols;
0098 
0099         template <int Row,int Col>
0100         static
0101         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0102         void
0103         write_element( this_matrix & x, scalar_type s )
0104             {
0105             BOOST_QVM_STATIC_ASSERT(Row>=0);
0106             BOOST_QVM_STATIC_ASSERT(Row<rows);
0107             BOOST_QVM_STATIC_ASSERT(Col>=0);
0108             BOOST_QVM_STATIC_ASSERT(Col<cols);
0109             mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col>(reinterpret_cast<OriginalMatrix &>(x), s);
0110             }
0111 
0112         static
0113         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0114         void
0115         write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0116             {
0117             BOOST_QVM_ASSERT(row>=0);
0118             BOOST_QVM_ASSERT(row<rows);
0119             BOOST_QVM_ASSERT(col>=0);
0120             BOOST_QVM_ASSERT(col<cols);
0121             mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col,reinterpret_cast<OriginalMatrix &>(x), s);
0122             }
0123         };
0124     }
0125 
0126 template <int I,class OriginalMatrix>
0127 struct
0128 mat_traits<qvm_detail::del_row_<I,OriginalMatrix> >:
0129     qvm_detail::del_row_write_traits<I,OriginalMatrix>
0130     {
0131     typedef qvm_detail::del_row_<I,OriginalMatrix> this_matrix;
0132     typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0133     static int const rows=mat_traits<OriginalMatrix>::rows-1;
0134     static int const cols=mat_traits<OriginalMatrix>::cols;
0135 
0136     template <int Row,int Col>
0137     static
0138     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0139     scalar_type
0140     read_element( this_matrix const & x )
0141         {
0142         BOOST_QVM_STATIC_ASSERT(Row>=0);
0143         BOOST_QVM_STATIC_ASSERT(Row<rows);
0144         BOOST_QVM_STATIC_ASSERT(Col>=0);
0145         BOOST_QVM_STATIC_ASSERT(Col<cols);
0146         return mat_traits<OriginalMatrix>::template read_element<Row+(Row>=I),Col>(reinterpret_cast<OriginalMatrix const &>(x));
0147         }
0148 
0149     static
0150     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0151     scalar_type
0152     read_element_idx( int row, int col, this_matrix const & x )
0153         {
0154         BOOST_QVM_ASSERT(row>=0);
0155         BOOST_QVM_ASSERT(row<rows);
0156         BOOST_QVM_ASSERT(col>=0);
0157         BOOST_QVM_ASSERT(col<cols);
0158         return mat_traits<OriginalMatrix>::read_element_idx(row+(row>=I),col,reinterpret_cast<OriginalMatrix const &>(x));
0159         }
0160     };
0161 
0162 template <int J,class OriginalMatrix,int R,int C>
0163 struct
0164 deduce_mat<qvm_detail::del_row_<J,OriginalMatrix>,R,C>
0165     {
0166     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0167     };
0168 
0169 template <int J,class OriginalMatrix,int R,int C>
0170 struct
0171 deduce_mat2<qvm_detail::del_row_<J,OriginalMatrix>,qvm_detail::del_row_<J,OriginalMatrix>,R,C>
0172     {
0173     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0174     };
0175 
0176 template <int Row,class A>
0177 typename enable_if_c<
0178     is_mat<A>::value,
0179     qvm_detail::del_row_<Row,A> const &>::type
0180 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0181 del_row( A const & a )
0182     {
0183     return reinterpret_cast<typename qvm_detail::del_row_<Row,A> const &>(a);
0184     }
0185 
0186 template <int Row,class A>
0187 typename enable_if_c<
0188     is_mat<A>::value,
0189     qvm_detail::del_row_<Row,A> &>::type
0190 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0191 del_row( A & a )
0192     {
0193     return reinterpret_cast<typename qvm_detail::del_row_<Row,A> &>(a);
0194     }
0195 
0196 ////////////////////////////////////////////////
0197 
0198 namespace
0199 qvm_detail
0200     {
0201     template <int Col,class OriginalMatrix>
0202     class
0203     del_col_
0204         {
0205         del_col_( del_col_ const & );
0206         del_col_ & operator=( del_col_ const & );
0207         ~del_col_();
0208 
0209         public:
0210 
0211         template <class T>
0212         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0213         del_col_ &
0214         operator=( T const & x )
0215             {
0216             assign(*this,x);
0217             return *this;
0218             }
0219 
0220         template <class R
0221 #if __cplusplus >= 201103L
0222             , class = typename enable_if<is_mat<R> >::type
0223 #endif
0224         >
0225         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0226         operator R() const
0227             {
0228             R r;
0229             assign(r,*this);
0230             return r;
0231             }
0232         };
0233 
0234     template <int J,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
0235     struct del_col_write_traits;
0236 
0237     template <int J,class OriginalMatrix>
0238     struct
0239     del_col_write_traits<J,OriginalMatrix,true>
0240         {
0241         typedef del_col_<J,OriginalMatrix> this_matrix;
0242         typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0243         static int const rows=mat_traits<OriginalMatrix>::rows;
0244         static int const cols=mat_traits<OriginalMatrix>::cols-1;
0245 
0246         template <int Row,int Col>
0247         static
0248         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0249         scalar_type &
0250         write_element( this_matrix & x )
0251             {
0252             BOOST_QVM_STATIC_ASSERT(Row>=0);
0253             BOOST_QVM_STATIC_ASSERT(Row<rows);
0254             BOOST_QVM_STATIC_ASSERT(Col>=0);
0255             BOOST_QVM_STATIC_ASSERT(Col<cols);
0256             return mat_traits<OriginalMatrix>::template write_element<Row,Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x));
0257             }
0258 
0259         static
0260         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0261         scalar_type &
0262         write_element_idx( int row, int col, this_matrix & x )
0263             {
0264             BOOST_QVM_ASSERT(row>=0);
0265             BOOST_QVM_ASSERT(row<rows);
0266             BOOST_QVM_ASSERT(col>=0);
0267             BOOST_QVM_ASSERT(col<cols);
0268             return mat_traits<OriginalMatrix>::write_element_idx(row,col+(col>=J),reinterpret_cast<OriginalMatrix &>(x));
0269             }
0270         };
0271 
0272     template <int J,class OriginalMatrix>
0273     struct
0274     del_col_write_traits<J,OriginalMatrix,false>
0275         {
0276         typedef del_col_<J,OriginalMatrix> this_matrix;
0277         typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0278         static int const rows=mat_traits<OriginalMatrix>::rows;
0279         static int const cols=mat_traits<OriginalMatrix>::cols-1;
0280 
0281         template <int Row,int Col>
0282         static
0283         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0284         void
0285         write_element( this_matrix & x, scalar_type s )
0286             {
0287             BOOST_QVM_STATIC_ASSERT(Row>=0);
0288             BOOST_QVM_STATIC_ASSERT(Row<rows);
0289             BOOST_QVM_STATIC_ASSERT(Col>=0);
0290             BOOST_QVM_STATIC_ASSERT(Col<cols);
0291             mat_traits<OriginalMatrix>::template write_element<Row,Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x), s);
0292             }
0293 
0294         static
0295         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0296         void
0297         write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0298             {
0299             BOOST_QVM_ASSERT(row>=0);
0300             BOOST_QVM_ASSERT(row<rows);
0301             BOOST_QVM_ASSERT(col>=0);
0302             BOOST_QVM_ASSERT(col<cols);
0303             mat_traits<OriginalMatrix>::write_element_idx(row,col+(col>=J),reinterpret_cast<OriginalMatrix &>(x), s);
0304             }
0305         };
0306     }
0307 
0308 template <int J,class OriginalMatrix>
0309 struct
0310 mat_traits<qvm_detail::del_col_<J,OriginalMatrix> >:
0311     qvm_detail::del_col_write_traits<J,OriginalMatrix>
0312     {
0313     typedef qvm_detail::del_col_<J,OriginalMatrix> this_matrix;
0314     typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0315     static int const rows=mat_traits<OriginalMatrix>::rows;
0316     static int const cols=mat_traits<OriginalMatrix>::cols-1;
0317 
0318     template <int Row,int Col>
0319     static
0320     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0321     scalar_type
0322     read_element( this_matrix const & x )
0323         {
0324         BOOST_QVM_STATIC_ASSERT(Row>=0);
0325         BOOST_QVM_STATIC_ASSERT(Row<rows);
0326         BOOST_QVM_STATIC_ASSERT(Col>=0);
0327         BOOST_QVM_STATIC_ASSERT(Col<cols);
0328         return mat_traits<OriginalMatrix>::template read_element<Row,Col+(Col>=J)>(reinterpret_cast<OriginalMatrix const &>(x));
0329         }
0330 
0331     static
0332     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0333     scalar_type
0334     read_element_idx( int row, int col, this_matrix const & x )
0335         {
0336         BOOST_QVM_ASSERT(row>=0);
0337         BOOST_QVM_ASSERT(row<rows);
0338         BOOST_QVM_ASSERT(col>=0);
0339         BOOST_QVM_ASSERT(col<cols);
0340         return mat_traits<OriginalMatrix>::read_element_idx(row,col+(col>=J),reinterpret_cast<OriginalMatrix const &>(x));
0341         }
0342     };
0343 
0344 template <int J,class OriginalMatrix,int R,int C>
0345 struct
0346 deduce_mat<qvm_detail::del_col_<J,OriginalMatrix>,R,C>
0347     {
0348     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0349     };
0350 
0351 template <int J,class OriginalMatrix,int R,int C>
0352 struct
0353 deduce_mat2<qvm_detail::del_col_<J,OriginalMatrix>,qvm_detail::del_col_<J,OriginalMatrix>,R,C>
0354     {
0355     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0356     };
0357 
0358 template <int Col,class A>
0359 typename enable_if_c<
0360     is_mat<A>::value,
0361     qvm_detail::del_col_<Col,A> const &>::type
0362 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0363 del_col( A const & a )
0364     {
0365     return reinterpret_cast<typename qvm_detail::del_col_<Col,A> const &>(a);
0366     }
0367 
0368 template <int Col,class A>
0369 typename enable_if_c<
0370     is_mat<A>::value,
0371     qvm_detail::del_col_<Col,A> &>::type
0372 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0373 del_col( A & a )
0374     {
0375     return reinterpret_cast<typename qvm_detail::del_col_<Col,A> &>(a);
0376     }
0377 
0378 ////////////////////////////////////////////////
0379 
0380 namespace
0381 qvm_detail
0382     {
0383     template <int Row,int Col,class OriginalMatrix>
0384     class
0385     del_row_col_
0386         {
0387         del_row_col_( del_row_col_ const & );
0388         ~del_row_col_();
0389 
0390         public:
0391 
0392         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0393         del_row_col_ &
0394         operator=( del_row_col_ const & x )
0395             {
0396             assign(*this,x);
0397             return *this;
0398             }
0399 
0400         template <class T>
0401         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0402         del_row_col_ &
0403         operator=( T const & x )
0404             {
0405             assign(*this,x);
0406             return *this;
0407             }
0408 
0409         template <class R
0410 #if __cplusplus >= 201103L
0411             , class = typename enable_if<is_mat<R> >::type
0412 #endif
0413         >
0414         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0415         operator R() const
0416             {
0417             R r;
0418             assign(r,*this);
0419             return r;
0420             }
0421         };
0422 
0423     template <int I,int J,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
0424     struct del_row_col_write_traits;
0425 
0426     template <int I,int J,class OriginalMatrix>
0427     struct
0428     del_row_col_write_traits<I,J,OriginalMatrix,true>
0429         {
0430         typedef del_row_col_<I,J,OriginalMatrix> this_matrix;
0431         typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0432         static int const rows=mat_traits<OriginalMatrix>::rows-1;
0433         static int const cols=mat_traits<OriginalMatrix>::cols-1;
0434 
0435         template <int Row,int Col>
0436         static
0437         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0438         scalar_type &
0439         write_element( this_matrix & x )
0440             {
0441             BOOST_QVM_STATIC_ASSERT(Row>=0);
0442             BOOST_QVM_STATIC_ASSERT(Row<rows);
0443             BOOST_QVM_STATIC_ASSERT(Col>=0);
0444             BOOST_QVM_STATIC_ASSERT(Col<cols);
0445             return mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x));
0446             }
0447 
0448         static
0449         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0450         scalar_type &
0451         write_element_idx( int row, int col, this_matrix & x )
0452             {
0453             BOOST_QVM_ASSERT(row>=0);
0454             BOOST_QVM_ASSERT(row<rows);
0455             BOOST_QVM_ASSERT(col>=0);
0456             BOOST_QVM_ASSERT(col<cols);
0457             return mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col+(col>=J),reinterpret_cast<OriginalMatrix &>(x));
0458             }
0459         };
0460 
0461     template <int I,int J,class OriginalMatrix>
0462     struct
0463     del_row_col_write_traits<I,J,OriginalMatrix,false>
0464         {
0465         typedef del_row_col_<I,J,OriginalMatrix> this_matrix;
0466         typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0467         static int const rows=mat_traits<OriginalMatrix>::rows-1;
0468         static int const cols=mat_traits<OriginalMatrix>::cols-1;
0469 
0470         template <int Row,int Col>
0471         static
0472         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0473         void
0474         write_element( this_matrix & x, scalar_type s )
0475             {
0476             BOOST_QVM_STATIC_ASSERT(Row>=0);
0477             BOOST_QVM_STATIC_ASSERT(Row<rows);
0478             BOOST_QVM_STATIC_ASSERT(Col>=0);
0479             BOOST_QVM_STATIC_ASSERT(Col<cols);
0480             mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x), s);
0481             }
0482 
0483         static
0484         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0485         void
0486         write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0487             {
0488             BOOST_QVM_ASSERT(row>=0);
0489             BOOST_QVM_ASSERT(row<rows);
0490             BOOST_QVM_ASSERT(col>=0);
0491             BOOST_QVM_ASSERT(col<cols);
0492             mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col+(col>=J),reinterpret_cast<OriginalMatrix &>(x), s);
0493             }
0494         };
0495     }
0496 
0497 template <int I,int J,class OriginalMatrix>
0498 struct
0499 mat_traits<qvm_detail::del_row_col_<I,J,OriginalMatrix> >:
0500     qvm_detail::del_row_col_write_traits<I,J,OriginalMatrix>
0501     {
0502     typedef qvm_detail::del_row_col_<I,J,OriginalMatrix> this_matrix;
0503     typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0504     static int const rows=mat_traits<OriginalMatrix>::rows-1;
0505     static int const cols=mat_traits<OriginalMatrix>::cols-1;
0506 
0507     template <int Row,int Col>
0508     static
0509     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0510     scalar_type
0511     read_element( this_matrix const & x )
0512         {
0513         BOOST_QVM_STATIC_ASSERT(Row>=0);
0514         BOOST_QVM_STATIC_ASSERT(Row<rows);
0515         BOOST_QVM_STATIC_ASSERT(Col>=0);
0516         BOOST_QVM_STATIC_ASSERT(Col<cols);
0517         return mat_traits<OriginalMatrix>::template read_element<Row+(Row>=I),Col+(Col>=J)>(reinterpret_cast<OriginalMatrix const &>(x));
0518         }
0519 
0520     static
0521     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0522     scalar_type
0523     read_element_idx( int row, int col, this_matrix const & x )
0524         {
0525         BOOST_QVM_ASSERT(row>=0);
0526         BOOST_QVM_ASSERT(row<rows);
0527         BOOST_QVM_ASSERT(col>=0);
0528         BOOST_QVM_ASSERT(col<cols);
0529         return mat_traits<OriginalMatrix>::read_element_idx(row+(row>=I),col+(col>=J),reinterpret_cast<OriginalMatrix const &>(x));
0530         }
0531     };
0532 
0533 template <int I,int J,class OriginalMatrix,int R,int C>
0534 struct
0535 deduce_mat<qvm_detail::del_row_col_<I,J,OriginalMatrix>,R,C>
0536     {
0537     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0538     };
0539 
0540 template <int I,int J,class OriginalMatrix,int R,int C>
0541 struct
0542 deduce_mat2<qvm_detail::del_row_col_<I,J,OriginalMatrix>,qvm_detail::del_row_col_<I,J,OriginalMatrix>,R,C>
0543     {
0544     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0545     };
0546 
0547 template <int Row,int Col,class A>
0548 typename enable_if_c<
0549     is_mat<A>::value,
0550     qvm_detail::del_row_col_<Row,Col,A> const &>::type
0551 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0552 del_row_col( A const & a )
0553     {
0554     return reinterpret_cast<typename qvm_detail::del_row_col_<Row,Col,A> const &>(a);
0555     }
0556 
0557 template <int Row,int Col,class A>
0558 typename enable_if_c<
0559     is_mat<A>::value,
0560     qvm_detail::del_row_col_<Row,Col,A> &>::type
0561 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0562 del_row_col( A & a )
0563     {
0564     return reinterpret_cast<typename qvm_detail::del_row_col_<Row,Col,A> &>(a);
0565     }
0566 
0567 ////////////////////////////////////////////////
0568 
0569 namespace
0570 qvm_detail
0571     {
0572     template <int Row,class OriginalMatrix>
0573     class
0574     neg_row_
0575         {
0576         neg_row_( neg_row_ const & );
0577         neg_row_ & operator=( neg_row_ const & );
0578         ~neg_row_();
0579 
0580         public:
0581 
0582         template <class T>
0583         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0584         neg_row_ &
0585         operator=( T const & x )
0586             {
0587             assign(*this,x);
0588             return *this;
0589             }
0590 
0591         template <class R
0592 #if __cplusplus >= 201103L
0593             , class = typename enable_if<is_mat<R> >::type
0594 #endif
0595         >
0596         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0597         operator R() const
0598             {
0599             R r;
0600             assign(r,*this);
0601             return r;
0602             }
0603         };
0604     }
0605 
0606 template <int I,class OriginalMatrix>
0607 struct
0608 mat_traits<qvm_detail::neg_row_<I,OriginalMatrix> >
0609     {
0610     typedef qvm_detail::neg_row_<I,OriginalMatrix> this_matrix;
0611     typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0612     static int const rows=mat_traits<OriginalMatrix>::rows;
0613     static int const cols=mat_traits<OriginalMatrix>::cols;
0614 
0615     template <int Row,int Col>
0616     static
0617     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0618     scalar_type
0619     read_element( this_matrix const & x )
0620         {
0621         BOOST_QVM_STATIC_ASSERT(Row>=0);
0622         BOOST_QVM_STATIC_ASSERT(Row<rows);
0623         BOOST_QVM_STATIC_ASSERT(Col>=0);
0624         BOOST_QVM_STATIC_ASSERT(Col<cols);
0625         return Row==I ?
0626             -mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x)) :
0627             mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x));
0628         }
0629 
0630     static
0631     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0632     scalar_type
0633     read_element_idx( int row, int col, this_matrix const & x )
0634         {
0635         BOOST_QVM_ASSERT(row>=0);
0636         BOOST_QVM_ASSERT(row<rows);
0637         BOOST_QVM_ASSERT(col>=0);
0638         BOOST_QVM_ASSERT(col<cols);
0639         return row==I?
0640             -mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x)) :
0641             mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x));
0642         }
0643     };
0644 
0645 template <int J,class OriginalMatrix,int R,int C>
0646 struct
0647 deduce_mat<qvm_detail::neg_row_<J,OriginalMatrix>,R,C>
0648     {
0649     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0650     };
0651 
0652 template <int J,class OriginalMatrix,int R,int C>
0653 struct
0654 deduce_mat2<qvm_detail::neg_row_<J,OriginalMatrix>,qvm_detail::neg_row_<J,OriginalMatrix>,R,C>
0655     {
0656     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0657     };
0658 
0659 template <int Row,class A>
0660 typename enable_if_c<
0661     is_mat<A>::value,
0662     qvm_detail::neg_row_<Row,A> const &>::type
0663 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0664 neg_row( A const & a )
0665     {
0666     return reinterpret_cast<typename qvm_detail::neg_row_<Row,A> const &>(a);
0667     }
0668 
0669 ////////////////////////////////////////////////
0670 
0671 namespace
0672 qvm_detail
0673     {
0674     template <int Col,class OriginalMatrix>
0675     class
0676     neg_col_
0677         {
0678         neg_col_( neg_col_ const & );
0679         neg_col_ & operator=( neg_col_ const & );
0680         ~neg_col_();
0681 
0682         public:
0683 
0684         template <class T>
0685         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0686         neg_col_ &
0687         operator=( T const & x )
0688             {
0689             assign(*this,x);
0690             return *this;
0691             }
0692 
0693         template <class R
0694 #if __cplusplus >= 201103L
0695             , class = typename enable_if<is_mat<R> >::type
0696 #endif
0697         >
0698         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0699         operator R() const
0700             {
0701             R r;
0702             assign(r,*this);
0703             return r;
0704             }
0705         };
0706     }
0707 
0708 template <int J,class OriginalMatrix>
0709 struct
0710 mat_traits<qvm_detail::neg_col_<J,OriginalMatrix> >
0711     {
0712     typedef qvm_detail::neg_col_<J,OriginalMatrix> this_matrix;
0713     typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0714     static int const rows=mat_traits<OriginalMatrix>::rows;
0715     static int const cols=mat_traits<OriginalMatrix>::cols;
0716 
0717     template <int Row,int Col>
0718     static
0719     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0720     scalar_type
0721     read_element( this_matrix const & x )
0722         {
0723         BOOST_QVM_STATIC_ASSERT(Row>=0);
0724         BOOST_QVM_STATIC_ASSERT(Row<rows);
0725         BOOST_QVM_STATIC_ASSERT(Col>=0);
0726         BOOST_QVM_STATIC_ASSERT(Col<cols);
0727         return Col==J?
0728             -mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x)) :
0729             mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x));
0730         }
0731 
0732     static
0733     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0734     scalar_type
0735     read_element_idx( int row, int col, this_matrix const & x )
0736         {
0737         BOOST_QVM_ASSERT(row>=0);
0738         BOOST_QVM_ASSERT(row<rows);
0739         BOOST_QVM_ASSERT(col>=0);
0740         BOOST_QVM_ASSERT(col<cols);
0741         return col==J?
0742             -mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x)) :
0743             mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x));
0744         }
0745     };
0746 
0747 template <int J,class OriginalMatrix,int R,int C>
0748 struct
0749 deduce_mat<qvm_detail::neg_col_<J,OriginalMatrix>,R,C>
0750     {
0751     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0752     };
0753 
0754 template <int J,class OriginalMatrix,int R,int C>
0755 struct
0756 deduce_mat2<qvm_detail::neg_col_<J,OriginalMatrix>,qvm_detail::neg_col_<J,OriginalMatrix>,R,C>
0757     {
0758     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0759     };
0760 
0761 template <int Col,class A>
0762 typename enable_if_c<
0763     is_mat<A>::value,
0764     qvm_detail::neg_col_<Col,A> const &>::type
0765 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0766 neg_col( A const & a )
0767     {
0768     return reinterpret_cast<typename qvm_detail::neg_col_<Col,A> const &>(a);
0769     }
0770 
0771 ////////////////////////////////////////////////
0772 
0773 template <class A>
0774 typename enable_if_c<
0775     is_mat<A>::value,
0776     qvm_detail::transposed_<A> const &>::type
0777 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0778 transposed( A const & a )
0779     {
0780     return reinterpret_cast<typename qvm_detail::transposed_<A> const &>(a);
0781     }
0782 
0783 template <class A>
0784 typename enable_if_c<
0785     is_mat<A>::value,
0786     qvm_detail::transposed_<A> &>::type
0787 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0788 transposed( A & a )
0789     {
0790     return reinterpret_cast<typename qvm_detail::transposed_<A> &>(a);
0791     }
0792 
0793 ////////////////////////////////////////////////
0794 
0795 namespace
0796 qvm_detail
0797     {
0798     template <int Row1,int Row2,class OriginalMatrix>
0799     class
0800     swap_rows_
0801         {
0802         swap_rows_( swap_rows_ const & );
0803         swap_rows_ & operator=( swap_rows_ const & );
0804         ~swap_rows_();
0805 
0806         public:
0807 
0808         template <class T>
0809         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0810         swap_rows_ &
0811         operator=( T const & x )
0812             {
0813             assign(*this,x);
0814             return *this;
0815             }
0816 
0817         template <class R
0818 #if __cplusplus >= 201103L
0819             , class = typename enable_if<is_mat<R> >::type
0820 #endif
0821         >
0822         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0823         operator R() const
0824             {
0825             R r;
0826             assign(r,*this);
0827             return r;
0828             }
0829         };
0830 
0831     template <int R1,int R2,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
0832     struct swap_rows_write_traits;
0833 
0834     template <int R1,int R2,class OriginalMatrix>
0835     struct
0836     swap_rows_write_traits<R1,R2,OriginalMatrix,true>
0837         {
0838         typedef swap_rows_<R1,R2,OriginalMatrix> this_matrix;
0839         typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0840         static int const rows=mat_traits<OriginalMatrix>::rows;
0841         static int const cols=mat_traits<OriginalMatrix>::cols;
0842 
0843         template <int Row,int Col>
0844         static
0845         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0846         scalar_type &
0847         write_element( this_matrix & x )
0848             {
0849             BOOST_QVM_STATIC_ASSERT(Row>=0);
0850             BOOST_QVM_STATIC_ASSERT(Row<rows);
0851             BOOST_QVM_STATIC_ASSERT(Col>=0);
0852             BOOST_QVM_STATIC_ASSERT(Col<cols);
0853             return mat_traits<OriginalMatrix>::template write_element<(Row==R1 && R1!=R2)*R2+(Row==R2 && R1!=R2)*R1+((Row!=R1 && Row!=R2) || R1==R2)*Row,Col>(reinterpret_cast<OriginalMatrix &>(x));
0854             }
0855 
0856         static
0857         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0858         scalar_type &
0859         write_element_idx( int row, int col, this_matrix & x )
0860             {
0861             BOOST_QVM_ASSERT(row>=0);
0862             BOOST_QVM_ASSERT(row<rows);
0863             BOOST_QVM_ASSERT(col>=0);
0864             BOOST_QVM_ASSERT(col<cols);
0865             return mat_traits<OriginalMatrix>::write_element_idx(row==R1?R2:row==R2?R1:row,col,reinterpret_cast<OriginalMatrix &>(x));
0866             }
0867         };
0868 
0869     template <int R1,int R2,class OriginalMatrix>
0870     struct
0871         swap_rows_write_traits<R1,R2,OriginalMatrix,false>
0872         {
0873         typedef swap_rows_<R1,R2,OriginalMatrix> this_matrix;
0874         typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0875         static int const rows=mat_traits<OriginalMatrix>::rows;
0876         static int const cols=mat_traits<OriginalMatrix>::cols;
0877 
0878         template <int Row,int Col>
0879         static
0880         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0881         void
0882         write_element( this_matrix & x, scalar_type s )
0883             {
0884             BOOST_QVM_STATIC_ASSERT(Row>=0);
0885             BOOST_QVM_STATIC_ASSERT(Row<rows);
0886             BOOST_QVM_STATIC_ASSERT(Col>=0);
0887             BOOST_QVM_STATIC_ASSERT(Col<cols);
0888             mat_traits<OriginalMatrix>::template write_element<(Row==R1 && R1!=R2)*R2+(Row==R2 && R1!=R2)*R1+((Row!=R1 && Row!=R2) || R1==R2)*Row,Col>(reinterpret_cast<OriginalMatrix &>(x), s);
0889             }
0890 
0891         static
0892         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0893         void
0894         write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0895             {
0896             BOOST_QVM_ASSERT(row>=0);
0897             BOOST_QVM_ASSERT(row<rows);
0898             BOOST_QVM_ASSERT(col>=0);
0899             BOOST_QVM_ASSERT(col<cols);
0900             mat_traits<OriginalMatrix>::write_element_idx(row==R1?R2:row==R2?R1:row,col,reinterpret_cast<OriginalMatrix &>(x), s);
0901             }
0902         };
0903     }
0904 
0905 template <int R1,int R2,class OriginalMatrix>
0906 struct
0907 mat_traits<qvm_detail::swap_rows_<R1,R2,OriginalMatrix> >:
0908     qvm_detail::swap_rows_write_traits<R1,R2,OriginalMatrix>
0909     {
0910     typedef qvm_detail::swap_rows_<R1,R2,OriginalMatrix> this_matrix;
0911     typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
0912     static int const rows=mat_traits<OriginalMatrix>::rows;
0913     static int const cols=mat_traits<OriginalMatrix>::cols;
0914 
0915     template <int Row,int Col>
0916     static
0917     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0918     scalar_type
0919     read_element( this_matrix const & x )
0920         {
0921         BOOST_QVM_STATIC_ASSERT(Row>=0);
0922         BOOST_QVM_STATIC_ASSERT(Row<rows);
0923         BOOST_QVM_STATIC_ASSERT(Col>=0);
0924         BOOST_QVM_STATIC_ASSERT(Col<cols);
0925         return mat_traits<OriginalMatrix>::template read_element<(Row==R1 && R1!=R2)*R2+(Row==R2 && R1!=R2)*R1+((Row!=R1 && Row!=R2) || R1==R2)*Row,Col>(reinterpret_cast<OriginalMatrix const &>(x));
0926         }
0927 
0928     static
0929     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0930     scalar_type
0931     read_element_idx( int row, int col, this_matrix const & x )
0932         {
0933         BOOST_QVM_ASSERT(row>=0);
0934         BOOST_QVM_ASSERT(row<rows);
0935         BOOST_QVM_ASSERT(col>=0);
0936         BOOST_QVM_ASSERT(col<cols);
0937         return mat_traits<OriginalMatrix>::read_element_idx(row==R1?R2:row==R2?R1:row,col,reinterpret_cast<OriginalMatrix const &>(x));
0938         }
0939     };
0940 
0941 template <int R1,int R2,class OriginalMatrix,int R,int C>
0942 struct
0943 deduce_mat<qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,R,C>
0944     {
0945     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0946     };
0947 
0948 template <int R1,int R2,class OriginalMatrix,int R,int C>
0949 struct
0950 deduce_mat2<qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,R,C>
0951     {
0952     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
0953     };
0954 
0955 template <int R1,int R2,class A>
0956 typename enable_if_c<
0957     is_mat<A>::value,
0958     qvm_detail::swap_rows_<R1,R2,A> const &>::type
0959 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0960 swap_rows( A const & a )
0961     {
0962     return reinterpret_cast<typename qvm_detail::swap_rows_<R1,R2,A> const &>(a);
0963     }
0964 
0965 template <int R1,int R2,class A>
0966 typename enable_if_c<
0967     is_mat<A>::value,
0968     qvm_detail::swap_rows_<R1,R2,A> &>::type
0969 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0970 swap_rows( A & a )
0971     {
0972     return reinterpret_cast<typename qvm_detail::swap_rows_<R1,R2,A> &>(a);
0973     }
0974 
0975 ////////////////////////////////////////////////
0976 
0977 namespace
0978 qvm_detail
0979     {
0980     template <int Row1,int Row2,class OriginalMatrix>
0981     class
0982     swap_cols_
0983         {
0984         swap_cols_( swap_cols_ const & );
0985         swap_cols_ & operator=( swap_cols_ const & );
0986         ~swap_cols_();
0987 
0988         public:
0989 
0990         template <class T>
0991         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0992         swap_cols_ &
0993         operator=( T const & x )
0994             {
0995             assign(*this,x);
0996             return *this;
0997             }
0998 
0999         template <class R
1000 #if __cplusplus >= 201103L
1001             , class = typename enable_if<is_mat<R> >::type
1002 #endif
1003         >
1004         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1005         operator R() const
1006             {
1007             R r;
1008             assign(r,*this);
1009             return r;
1010             }
1011         };
1012 
1013     template <int C1,int C2,class OriginalMatrix,bool WriteElementRef=mat_write_element_ref<OriginalMatrix>::value>
1014     struct swap_cols_write_traits;
1015 
1016     template <int C1,int C2,class OriginalMatrix>
1017     struct
1018     swap_cols_write_traits<C1,C2,OriginalMatrix,true>
1019         {
1020         typedef swap_cols_<C1,C2,OriginalMatrix> this_matrix;
1021         typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
1022         static int const rows=mat_traits<OriginalMatrix>::rows;
1023         static int const cols=mat_traits<OriginalMatrix>::cols;
1024 
1025         template <int Row,int Col>
1026         static
1027         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1028         scalar_type &
1029         write_element( this_matrix & x )
1030             {
1031             BOOST_QVM_STATIC_ASSERT(Row>=0);
1032             BOOST_QVM_STATIC_ASSERT(Row<rows);
1033             BOOST_QVM_STATIC_ASSERT(Col>=0);
1034             BOOST_QVM_STATIC_ASSERT(Col<cols);
1035             return mat_traits<OriginalMatrix>::template write_element<Row,(Col==C1 && C1!=C2)*C2+(Col==C2 && C1!=C2)*C1+((Col!=C1 && Col!=C2) || C1==C2)*Col>(reinterpret_cast<OriginalMatrix &>(x));
1036             }
1037 
1038         static
1039         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1040         scalar_type &
1041         write_element_idx( int row, int col, this_matrix & x )
1042             {
1043             BOOST_QVM_ASSERT(row>=0);
1044             BOOST_QVM_ASSERT(row<rows);
1045             BOOST_QVM_ASSERT(col>=0);
1046             BOOST_QVM_ASSERT(col<cols);
1047             return mat_traits<OriginalMatrix>::write_element_idx(row,col==C1?C2:col==C2?C1:col,reinterpret_cast<OriginalMatrix &>(x));
1048             }
1049         };
1050 
1051     template <int C1,int C2,class OriginalMatrix>
1052     struct
1053     swap_cols_write_traits<C1,C2,OriginalMatrix,false>
1054         {
1055         typedef swap_cols_<C1,C2,OriginalMatrix> this_matrix;
1056         typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
1057         static int const rows=mat_traits<OriginalMatrix>::rows;
1058         static int const cols=mat_traits<OriginalMatrix>::cols;
1059 
1060         template <int Row,int Col>
1061         static
1062         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1063         void
1064         write_element( this_matrix & x, scalar_type s )
1065             {
1066             BOOST_QVM_STATIC_ASSERT(Row>=0);
1067             BOOST_QVM_STATIC_ASSERT(Row<rows);
1068             BOOST_QVM_STATIC_ASSERT(Col>=0);
1069             BOOST_QVM_STATIC_ASSERT(Col<cols);
1070             mat_traits<OriginalMatrix>::template write_element<Row,(Col==C1 && C1!=C2)*C2+(Col==C2 && C1!=C2)*C1+((Col!=C1 && Col!=C2) || C1==C2)*Col>(reinterpret_cast<OriginalMatrix &>(x), s);
1071             }
1072 
1073         static
1074         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1075         void
1076         write_element_idx( int row, int col, this_matrix & x, scalar_type s )
1077             {
1078             BOOST_QVM_ASSERT(row>=0);
1079             BOOST_QVM_ASSERT(row<rows);
1080             BOOST_QVM_ASSERT(col>=0);
1081             BOOST_QVM_ASSERT(col<cols);
1082             mat_traits<OriginalMatrix>::write_element_idx(row,col==C1?C2:col==C2?C1:col,reinterpret_cast<OriginalMatrix &>(x), s);
1083             }
1084         };
1085     }
1086 
1087 template <int C1,int C2,class OriginalMatrix>
1088 struct
1089 mat_traits<qvm_detail::swap_cols_<C1,C2,OriginalMatrix> >:
1090     qvm_detail::swap_cols_write_traits<C1,C2,OriginalMatrix>
1091     {
1092     typedef qvm_detail::swap_cols_<C1,C2,OriginalMatrix> this_matrix;
1093     typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
1094     static int const rows=mat_traits<OriginalMatrix>::rows;
1095     static int const cols=mat_traits<OriginalMatrix>::cols;
1096 
1097     template <int Row,int Col>
1098     static
1099     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1100     scalar_type
1101     read_element( this_matrix const & x )
1102         {
1103         BOOST_QVM_STATIC_ASSERT(Row>=0);
1104         BOOST_QVM_STATIC_ASSERT(Row<rows);
1105         BOOST_QVM_STATIC_ASSERT(Col>=0);
1106         BOOST_QVM_STATIC_ASSERT(Col<cols);
1107         return mat_traits<OriginalMatrix>::template read_element<Row,(Col==C1 && C1!=C2)*C2+(Col==C2 && C1!=C2)*C1+((Col!=C1 && Col!=C2) || C1==C2)*Col>(reinterpret_cast<OriginalMatrix const &>(x));
1108         }
1109 
1110     static
1111     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1112     scalar_type
1113     read_element_idx( int row, int col, this_matrix const & x )
1114         {
1115         BOOST_QVM_ASSERT(row>=0);
1116         BOOST_QVM_ASSERT(row<rows);
1117         BOOST_QVM_ASSERT(col>=0);
1118         BOOST_QVM_ASSERT(col<cols);
1119         return mat_traits<OriginalMatrix>::read_element_idx(row,col==C1?C2:col==C2?C1:col,reinterpret_cast<OriginalMatrix const &>(x));
1120         }
1121     };
1122 
1123 template <int C1,int C2,class OriginalMatrix,int R,int C>
1124 struct
1125 deduce_mat<qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,R,C>
1126     {
1127     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
1128     };
1129 
1130 template <int C1,int C2,class OriginalMatrix,int R,int C>
1131 struct
1132 deduce_mat2<qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,R,C>
1133     {
1134     typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
1135     };
1136 
1137 template <int C1,int C2,class A>
1138 typename enable_if_c<
1139     is_mat<A>::value,
1140     qvm_detail::swap_cols_<C1,C2,A> const &>::type
1141 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1142 swap_cols( A const & a )
1143     {
1144     return reinterpret_cast<typename qvm_detail::swap_cols_<C1,C2,A> const &>(a);
1145     }
1146 
1147 template <int C1,int C2,class A>
1148 typename enable_if_c<
1149     is_mat<A>::value,
1150     qvm_detail::swap_cols_<C1,C2,A> &>::type
1151 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1152 swap_cols( A & a )
1153     {
1154     return reinterpret_cast<typename qvm_detail::swap_cols_<C1,C2,A> &>(a);
1155     }
1156 
1157 } }
1158 
1159 #endif