Back to home page

EIC code displayed by LXR

 
 

    


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

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