Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #ifndef BOOST_QVM_MAP_VEC_MAT_HPP_INCLUDED
0002 #define BOOST_QVM_MAP_VEC_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/vec_traits.hpp>
0011 #include <boost/qvm/assert.hpp>
0012 #include <boost/qvm/enable_if.hpp>
0013 
0014 namespace boost { namespace qvm {
0015 
0016 namespace
0017 qvm_detail
0018     {
0019     template <class OriginalVector>
0020     class
0021     col_mat_
0022         {
0023         col_mat_( col_mat_ const & );
0024         col_mat_ & operator=( col_mat_ const & );
0025         ~col_mat_();
0026 
0027         public:
0028 
0029         template <class T>
0030         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0031         col_mat_ &
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 <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
0053     struct col_mat_write_traits;
0054 
0055     template <class OriginalVector>
0056     struct
0057     col_mat_write_traits<OriginalVector,true>
0058         {
0059         typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
0060         typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0061         static int const rows=vec_traits<OriginalVector>::dim;
0062         static int const cols=1;
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(Col==0);
0071             BOOST_QVM_STATIC_ASSERT(Row>=0);
0072             BOOST_QVM_STATIC_ASSERT(Row<rows);
0073             return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
0074             }
0075 
0076         static
0077         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0078         scalar_type &
0079         write_element_idx( int row, int col, this_matrix & x )
0080             {
0081             BOOST_QVM_ASSERT(col==0); (void)col;
0082             BOOST_QVM_ASSERT(row>=0);
0083             BOOST_QVM_ASSERT(row<rows);
0084             return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
0085             }
0086         };
0087 
0088     template <class OriginalVector>
0089     struct
0090     col_mat_write_traits<OriginalVector,false>
0091         {
0092         typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
0093         typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0094         static int const rows=vec_traits<OriginalVector>::dim;
0095         static int const cols=1;
0096 
0097         template <int Row,int Col>
0098         static
0099         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0100         void
0101         write_element( this_matrix & x, scalar_type s )
0102             {
0103             BOOST_QVM_STATIC_ASSERT(Col==0);
0104             BOOST_QVM_STATIC_ASSERT(Row>=0);
0105             BOOST_QVM_STATIC_ASSERT(Row<rows);
0106             vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
0107             }
0108 
0109         static
0110         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0111         void
0112         write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0113             {
0114             BOOST_QVM_ASSERT(col==0); (void)col;
0115             BOOST_QVM_ASSERT(row>=0);
0116             BOOST_QVM_ASSERT(row<rows);
0117             vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
0118             }
0119         };
0120     }
0121 
0122 template <class OriginalVector>
0123 struct
0124 mat_traits< qvm_detail::col_mat_<OriginalVector> >:
0125     qvm_detail::col_mat_write_traits<OriginalVector>
0126     {
0127     typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
0128     typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0129     static int const rows=vec_traits<OriginalVector>::dim;
0130     static int const cols=1;
0131 
0132     template <int Row,int Col>
0133     static
0134     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0135     scalar_type
0136     read_element( this_matrix const & x )
0137         {
0138         BOOST_QVM_STATIC_ASSERT(Col==0);
0139         BOOST_QVM_STATIC_ASSERT(Row>=0);
0140         BOOST_QVM_STATIC_ASSERT(Row<rows);
0141         return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
0142         }
0143 
0144     static
0145     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0146     scalar_type
0147     read_element_idx( int row, int col, this_matrix const & x )
0148         {
0149         BOOST_QVM_ASSERT(col==0); (void)col;
0150         BOOST_QVM_ASSERT(row>=0);
0151         BOOST_QVM_ASSERT(row<rows);
0152         return vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x));
0153         }
0154     };
0155 
0156 template <class OriginalVector,int R,int C>
0157 struct
0158 deduce_mat<qvm_detail::col_mat_<OriginalVector>,R,C>
0159     {
0160     typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0161     };
0162 
0163 template <class OriginalVector,int R,int C>
0164 struct
0165 deduce_mat2<qvm_detail::col_mat_<OriginalVector>,qvm_detail::col_mat_<OriginalVector>,R,C>
0166     {
0167     typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0168     };
0169 
0170 template <class A>
0171 typename enable_if_c<
0172     is_vec<A>::value,
0173     qvm_detail::col_mat_<A> const &>::type
0174 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0175 col_mat( A const & a )
0176     {
0177     return reinterpret_cast<typename qvm_detail::col_mat_<A> const &>(a);
0178     }
0179 
0180 template <class A>
0181 typename enable_if_c<
0182     is_vec<A>::value,
0183     qvm_detail::col_mat_<A> &>::type
0184 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0185 col_mat( A & a )
0186     {
0187     return reinterpret_cast<typename qvm_detail::col_mat_<A> &>(a);
0188     }
0189 
0190 ////////////////////////////////////////////////
0191 
0192 namespace
0193 qvm_detail
0194     {
0195     template <class OriginalVector>
0196     class
0197     row_mat_
0198         {
0199         row_mat_( row_mat_ const & );
0200         row_mat_ & operator=( row_mat_ const & );
0201         ~row_mat_();
0202 
0203         public:
0204 
0205         template <class T>
0206         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0207         row_mat_ &
0208         operator=( T const & x )
0209             {
0210             assign(*this,x);
0211             return *this;
0212             }
0213 
0214         template <class R
0215 #if __cplusplus >= 201103L
0216             , class = typename enable_if<is_mat<R> >::type
0217 #endif
0218         >
0219         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0220         operator R() const
0221             {
0222             R r;
0223             assign(r,*this);
0224             return r;
0225             }
0226         };
0227 
0228     template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
0229     struct row_mat_write_traits;
0230 
0231     template <class OriginalVector>
0232     struct
0233     row_mat_write_traits<OriginalVector,true>
0234         {
0235         typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
0236         typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0237         static int const rows=1;
0238         static int const cols=vec_traits<OriginalVector>::dim;
0239 
0240         template <int Row,int Col>
0241         static
0242         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0243         scalar_type &
0244         write_element( this_matrix & x )
0245             {
0246             BOOST_QVM_STATIC_ASSERT(Row==0);
0247             BOOST_QVM_STATIC_ASSERT(Col>=0);
0248             BOOST_QVM_STATIC_ASSERT(Col<cols);
0249             return vec_traits<OriginalVector>::template write_element<Col>(reinterpret_cast<OriginalVector &>(x));
0250             }
0251 
0252         static
0253         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0254         scalar_type &
0255         write_element_idx( int row, int col, this_matrix & x )
0256             {
0257             BOOST_QVM_ASSERT(row==0); (void)row;
0258             BOOST_QVM_ASSERT(col>=0);
0259             BOOST_QVM_ASSERT(col<cols);
0260             return vec_traits<OriginalVector>::write_element_idx(col,reinterpret_cast<OriginalVector &>(x));
0261             }
0262         };
0263 
0264     template <class OriginalVector>
0265     struct
0266     row_mat_write_traits<OriginalVector,false>
0267         {
0268         typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
0269         typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0270         static int const rows=1;
0271         static int const cols=vec_traits<OriginalVector>::dim;
0272 
0273         template <int Row,int Col>
0274         static
0275         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0276         void
0277         write_element( this_matrix & x, scalar_type s )
0278             {
0279             BOOST_QVM_STATIC_ASSERT(Row==0);
0280             BOOST_QVM_STATIC_ASSERT(Col>=0);
0281             BOOST_QVM_STATIC_ASSERT(Col<cols);
0282             vec_traits<OriginalVector>::template write_element<Col>(reinterpret_cast<OriginalVector &>(x), s);
0283             }
0284 
0285         static
0286         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0287         void
0288         write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0289             {
0290             BOOST_QVM_ASSERT(row==0); (void)row;
0291             BOOST_QVM_ASSERT(col>=0);
0292             BOOST_QVM_ASSERT(col<cols);
0293             vec_traits<OriginalVector>::write_element_idx(col,reinterpret_cast<OriginalVector &>(x), s);
0294             }
0295         };
0296     }
0297 
0298 template <class OriginalVector>
0299 struct
0300 mat_traits< qvm_detail::row_mat_<OriginalVector> >:
0301     qvm_detail::row_mat_write_traits<OriginalVector>
0302     {
0303     typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
0304     typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0305     static int const rows=1;
0306     static int const cols=vec_traits<OriginalVector>::dim;
0307 
0308     template <int Row,int Col>
0309     static
0310     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0311     scalar_type
0312     read_element( this_matrix const & x )
0313         {
0314         BOOST_QVM_STATIC_ASSERT(Row==0);
0315         BOOST_QVM_STATIC_ASSERT(Col>=0);
0316         BOOST_QVM_STATIC_ASSERT(Col<cols);
0317         return vec_traits<OriginalVector>::template read_element<Col>(reinterpret_cast<OriginalVector const &>(x));
0318         }
0319 
0320     static
0321     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0322     scalar_type
0323     read_element_idx( int row, int col, this_matrix const & x )
0324         {
0325         BOOST_QVM_ASSERT(row==0); (void)row;
0326         BOOST_QVM_ASSERT(col>=0);
0327         BOOST_QVM_ASSERT(col<cols);
0328         return vec_traits<OriginalVector>::read_element_idx(col,reinterpret_cast<OriginalVector const &>(x));
0329         }
0330     };
0331 
0332 template <class OriginalVector,int R,int C>
0333 struct
0334 deduce_mat<qvm_detail::row_mat_<OriginalVector>,R,C>
0335     {
0336     typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0337     };
0338 
0339 template <class OriginalVector,int R,int C>
0340 struct
0341 deduce_mat2<qvm_detail::row_mat_<OriginalVector>,qvm_detail::row_mat_<OriginalVector>,R,C>
0342     {
0343     typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0344     };
0345 
0346 template <class A>
0347 typename enable_if_c<
0348     is_vec<A>::value,
0349     qvm_detail::row_mat_<A> const &>::type
0350 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0351 row_mat( A const & a )
0352     {
0353     return reinterpret_cast<typename qvm_detail::row_mat_<A> const &>(a);
0354     }
0355 
0356 template <class A>
0357 typename enable_if_c<
0358     is_vec<A>::value,
0359     qvm_detail::row_mat_<A> &>::type
0360 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0361 row_mat( A & a )
0362     {
0363     return reinterpret_cast<typename qvm_detail::row_mat_<A> &>(a);
0364     }
0365 
0366 ////////////////////////////////////////////////
0367 
0368 namespace
0369 qvm_detail
0370     {
0371     template <class OriginalVector>
0372     class
0373     translation_mat_
0374         {
0375         translation_mat_( translation_mat_ const & );
0376         translation_mat_ & operator=( translation_mat_ const & );
0377         ~translation_mat_();
0378 
0379         public:
0380 
0381         template <class T>
0382         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0383         translation_mat_ &
0384         operator=( T const & x )
0385             {
0386             assign(*this,x);
0387             return *this;
0388             }
0389 
0390         template <class R
0391 #if __cplusplus >= 201103L
0392             , class = typename enable_if<is_mat<R> >::type
0393 #endif
0394         >
0395         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0396         operator R() const
0397             {
0398             R r;
0399             assign(r,*this);
0400             return r;
0401             }
0402         };
0403 
0404     template <class M,int Row,int Col,bool TransCol=(Col==mat_traits<M>::cols-1)>
0405     struct read_translation_matat;
0406 
0407     template <class OriginalVector,int Row,int Col,bool TransCol>
0408     struct
0409     read_translation_matat<translation_mat_<OriginalVector>,Row,Col,TransCol>
0410         {
0411         static
0412         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0413         typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
0414         f( translation_mat_<OriginalVector> const & )
0415             {
0416             return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(0);
0417             }
0418         };
0419 
0420     template <class OriginalVector,int D>
0421     struct
0422     read_translation_matat<translation_mat_<OriginalVector>,D,D,false>
0423         {
0424         static
0425         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0426         typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
0427         f( translation_mat_<OriginalVector> const & )
0428             {
0429             return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
0430             }
0431         };
0432 
0433     template <class OriginalVector,int D>
0434     struct
0435     read_translation_matat<translation_mat_<OriginalVector>,D,D,true>
0436         {
0437         static
0438         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0439         typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
0440         f( translation_mat_<OriginalVector> const & )
0441             {
0442             return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
0443             }
0444         };
0445 
0446     template <class OriginalVector,int Row,int Col>
0447     struct
0448     read_translation_matat<translation_mat_<OriginalVector>,Row,Col,true>
0449         {
0450         static
0451         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0452         typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
0453         f( translation_mat_<OriginalVector> const & x )
0454             {
0455             return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
0456             }
0457         };
0458 
0459     template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
0460     struct translation_mat_write_traits;
0461 
0462     template <class OriginalVector>
0463     struct
0464     translation_mat_write_traits<OriginalVector,true>
0465         {
0466         typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
0467         typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0468         static int const rows=vec_traits<OriginalVector>::dim+1;
0469         static int const cols=vec_traits<OriginalVector>::dim+1;
0470 
0471         template <int Row,int Col>
0472         static
0473         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0474         scalar_type &
0475         write_element( this_matrix & x )
0476             {
0477             BOOST_QVM_STATIC_ASSERT(Row>=0);
0478             BOOST_QVM_STATIC_ASSERT(Row<rows-1);
0479             BOOST_QVM_STATIC_ASSERT(Col==cols-1 || Col==0);
0480             //The following should be a static_assert, but this is a constexpr
0481             //function and it gets instantiated with Row=0 and Col=0 in the
0482             //mat_write_element_ref test (in a sizeof expression).
0483             BOOST_QVM_ASSERT(Col==cols-1);
0484             return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
0485             }
0486 
0487         static
0488         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0489         scalar_type &
0490         write_element_idx( int row, int col, this_matrix const & x )
0491             {
0492             BOOST_QVM_ASSERT(row>=0);
0493             BOOST_QVM_ASSERT(row<rows-1);
0494             BOOST_QVM_ASSERT(col==cols-1); (void)col;
0495             return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
0496             }
0497         };
0498 
0499     template <class OriginalVector>
0500     struct
0501     translation_mat_write_traits<OriginalVector,false>
0502         {
0503         typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
0504         typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0505         static int const rows=vec_traits<OriginalVector>::dim+1;
0506         static int const cols=vec_traits<OriginalVector>::dim+1;
0507 
0508         template <int Row,int Col>
0509         static
0510         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0511         void
0512         write_element( this_matrix & x, scalar_type s )
0513             {
0514             BOOST_QVM_STATIC_ASSERT(Row>=0);
0515             BOOST_QVM_STATIC_ASSERT(Row<rows-1);
0516             BOOST_QVM_STATIC_ASSERT(Col==cols-1 || Col==0);
0517             //The following should be a static_assert, but this is a constexpr
0518             //function and it gets instantiated with Row=0 and Col=0 in the
0519             //mat_write_element_ref test (in a sizeof expression).
0520             BOOST_QVM_ASSERT(Col==cols-1);
0521             vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
0522             }
0523 
0524         static
0525         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0526         void
0527         write_element_idx( int row, int col, this_matrix const & x, scalar_type s )
0528             {
0529             BOOST_QVM_ASSERT(row>=0);
0530             BOOST_QVM_ASSERT(row<rows);
0531             BOOST_QVM_ASSERT(col==cols-1); (void)col;
0532             BOOST_QVM_ASSERT(col!=row);
0533             vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
0534             }
0535         };
0536     }
0537 
0538 template <class OriginalVector>
0539 struct
0540 mat_traits< qvm_detail::translation_mat_<OriginalVector> >:
0541     qvm_detail::translation_mat_write_traits<OriginalVector>
0542     {
0543     typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
0544     typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0545     static int const rows=vec_traits<OriginalVector>::dim+1;
0546     static int const cols=vec_traits<OriginalVector>::dim+1;
0547 
0548     template <int Row,int Col>
0549     static
0550     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0551     scalar_type
0552     read_element( this_matrix const & x )
0553         {
0554         BOOST_QVM_STATIC_ASSERT(Row>=0);
0555         BOOST_QVM_STATIC_ASSERT(Row<rows);
0556         BOOST_QVM_STATIC_ASSERT(Col>=0);
0557         BOOST_QVM_STATIC_ASSERT(Col<cols);
0558         return qvm_detail::read_translation_matat<qvm_detail::translation_mat_<OriginalVector>,Row,Col>::f(x);
0559         }
0560 
0561     static
0562     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0563     scalar_type
0564     read_element_idx( int row, int col, this_matrix const & x )
0565         {
0566         BOOST_QVM_ASSERT(row>=0);
0567         BOOST_QVM_ASSERT(row<rows);
0568         BOOST_QVM_ASSERT(col>=0);
0569         BOOST_QVM_ASSERT(col<cols);
0570         return
0571             row==col?
0572                 scalar_traits<scalar_type>::value(1):
0573                 (col==cols-1?
0574                     vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):
0575                     scalar_traits<scalar_type>::value(0));
0576         }
0577     };
0578 
0579 template <class OriginalVector,int R,int C>
0580 struct
0581 deduce_mat<qvm_detail::translation_mat_<OriginalVector>,R,C>
0582     {
0583     typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0584     };
0585 
0586 template <class OriginalVector,int R,int C>
0587 struct
0588 deduce_mat2<qvm_detail::translation_mat_<OriginalVector>,qvm_detail::translation_mat_<OriginalVector>,R,C>
0589     {
0590     typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0591     };
0592 
0593 template <class A>
0594 typename enable_if_c<
0595     is_vec<A>::value,
0596     qvm_detail::translation_mat_<A> const &>::type
0597 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0598 translation_mat( A const & a )
0599     {
0600     return reinterpret_cast<typename qvm_detail::translation_mat_<A> const &>(a);
0601     }
0602 
0603 template <class A>
0604 typename enable_if_c<
0605     is_vec<A>::value,
0606     qvm_detail::translation_mat_<A> &>::type
0607 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0608 translation_mat( A & a )
0609     {
0610     return reinterpret_cast<typename qvm_detail::translation_mat_<A> &>(a);
0611     }
0612 
0613 ////////////////////////////////////////////////
0614 
0615 namespace
0616 qvm_detail
0617     {
0618     template <class OriginalVector>
0619     class
0620     diag_mat_
0621         {
0622         diag_mat_( diag_mat_ const & );
0623         diag_mat_ & operator=( diag_mat_ const & );
0624         ~diag_mat_();
0625 
0626         public:
0627 
0628         template <class T>
0629         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0630         diag_mat_ &
0631         operator=( T const & x )
0632             {
0633             assign(*this,x);
0634             return *this;
0635             }
0636 
0637         template <class R
0638 #if __cplusplus >= 201103L
0639             , class = typename enable_if<is_mat<R> >::type
0640 #endif
0641         >
0642         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0643         operator R() const
0644             {
0645             R r;
0646             assign(r,*this);
0647             return r;
0648             }
0649         };
0650 
0651     template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
0652     struct diag_mat_write_traits;
0653 
0654     template <class OriginalVector>
0655     struct
0656     diag_mat_write_traits<OriginalVector,true>
0657         {
0658         typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
0659         typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0660         static int const rows=vec_traits<OriginalVector>::dim;
0661         static int const cols=vec_traits<OriginalVector>::dim;
0662 
0663         template <int Row,int Col>
0664         static
0665         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0666         scalar_type &
0667         write_element( this_matrix & x )
0668             {
0669             BOOST_QVM_STATIC_ASSERT(Row>=0);
0670             BOOST_QVM_STATIC_ASSERT(Row<rows);
0671             BOOST_QVM_STATIC_ASSERT(Row==Col);
0672             return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
0673             }
0674 
0675         static
0676         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0677         scalar_type &
0678         write_element_idx( int row, int col, this_matrix & x )
0679             {
0680             BOOST_QVM_ASSERT(row>=0);
0681             BOOST_QVM_ASSERT(row<rows);
0682             BOOST_QVM_ASSERT(row==col); (void)col;
0683             return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
0684             }
0685         };
0686 
0687     template <class OriginalVector>
0688     struct
0689     diag_mat_write_traits<OriginalVector,false>
0690         {
0691         typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
0692         typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0693         static int const rows=vec_traits<OriginalVector>::dim;
0694         static int const cols=vec_traits<OriginalVector>::dim;
0695 
0696         template <int Row,int Col>
0697         static
0698         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0699         void
0700         write_element( this_matrix & x, scalar_type s )
0701             {
0702             BOOST_QVM_STATIC_ASSERT(Row>=0);
0703             BOOST_QVM_STATIC_ASSERT(Row<rows);
0704             BOOST_QVM_STATIC_ASSERT(Row==Col);
0705             vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
0706             }
0707 
0708         static
0709         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0710         void
0711         write_element_idx( int row, int col, this_matrix & x, scalar_type s )
0712             {
0713             BOOST_QVM_ASSERT(row>=0);
0714             BOOST_QVM_ASSERT(row<rows);
0715             BOOST_QVM_ASSERT(row==col); (void)col;
0716             vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
0717             }
0718         };
0719     }
0720 
0721 template <class OriginalVector>
0722 struct
0723 mat_traits< qvm_detail::diag_mat_<OriginalVector> >:
0724     qvm_detail::diag_mat_write_traits<OriginalVector>
0725     {
0726     typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
0727     typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0728     static int const rows=vec_traits<OriginalVector>::dim;
0729     static int const cols=vec_traits<OriginalVector>::dim;
0730 
0731     template <int Row,int Col>
0732     static
0733     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0734     scalar_type
0735     read_element( this_matrix const & x )
0736         {
0737         BOOST_QVM_STATIC_ASSERT(Row>=0);
0738         BOOST_QVM_STATIC_ASSERT(Row<rows);
0739         BOOST_QVM_STATIC_ASSERT(Col>=0);
0740         BOOST_QVM_STATIC_ASSERT(Col<cols);
0741         return Row==Col?vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
0742         }
0743 
0744     static
0745     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0746     scalar_type
0747     read_element_idx( int row, int col, this_matrix const & x )
0748         {
0749         BOOST_QVM_ASSERT(row>=0);
0750         BOOST_QVM_ASSERT(row<rows);
0751         BOOST_QVM_ASSERT(col>=0);
0752         BOOST_QVM_ASSERT(col<cols);
0753         return row==col?vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
0754         }
0755     };
0756 
0757 template <class OriginalVector,int R,int C>
0758 struct
0759 deduce_mat<qvm_detail::diag_mat_<OriginalVector>,R,C>
0760     {
0761     typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0762     };
0763 
0764 template <class OriginalVector,int R,int C>
0765 struct
0766 deduce_mat2<qvm_detail::diag_mat_<OriginalVector>,qvm_detail::diag_mat_<OriginalVector>,R,C>
0767     {
0768     typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
0769     };
0770 
0771 template <class A>
0772 typename enable_if_c<
0773     is_vec<A>::value,
0774     qvm_detail::diag_mat_<A> const &>::type
0775 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0776 diag_mat( A const & a )
0777     {
0778     return reinterpret_cast<typename qvm_detail::diag_mat_<A> const &>(a);
0779     }
0780 
0781 template <class A>
0782 typename enable_if_c<
0783     is_vec<A>::value,
0784     qvm_detail::diag_mat_<A> &>::type
0785 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0786 diag_mat( A & a )
0787     {
0788     return reinterpret_cast<typename qvm_detail::diag_mat_<A> &>(a);
0789     }
0790 
0791 } }
0792 
0793 #endif