Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:51:04

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