• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
2 
3 //Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef BOOST_QVM_3EDF999CA1C011DEBA5C8DA956D89593
7 #define BOOST_QVM_3EDF999CA1C011DEBA5C8DA956D89593
8 
9 #include <boost/qvm/inline.hpp>
10 #include <boost/qvm/deduce_mat.hpp>
11 #include <boost/qvm/vec_traits.hpp>
12 #include <boost/qvm/assert.hpp>
13 #include <boost/qvm/enable_if.hpp>
14 
15 namespace
16 boost
17     {
18     namespace
19     qvm
20         {
21         ////////////////////////////////////////////////
22 
23         namespace
24         qvm_detail
25             {
26             template <class OriginalVector>
27             class
28             col_mat_
29                 {
30                 col_mat_( col_mat_ const & );
31                 col_mat_ & operator=( col_mat_ const & );
32                 ~col_mat_();
33 
34                 public:
35 
36                 template <class T>
37                 BOOST_QVM_INLINE_TRIVIAL
38                 col_mat_ &
operator =(T const & x)39                 operator=( T const & x )
40                     {
41                     assign(*this,x);
42                     return *this;
43                     }
44 
45                 template <class R>
46                 BOOST_QVM_INLINE_TRIVIAL
operator R() const47                 operator R() const
48                     {
49                     R r;
50                     assign(r,*this);
51                     return r;
52                     }
53                 };
54             }
55 
56         template <class OriginalVector>
57         struct
58         mat_traits< qvm_detail::col_mat_<OriginalVector> >
59             {
60             typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
61             typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
62             static int const rows=vec_traits<OriginalVector>::dim;
63             static int const cols=1;
64 
65             template <int Row,int Col>
66             static
67             BOOST_QVM_INLINE_CRITICAL
68             scalar_type
read_elementboost::qvm::mat_traits69             read_element( this_matrix const & x )
70                 {
71                 BOOST_QVM_STATIC_ASSERT(Col==0);
72                 BOOST_QVM_STATIC_ASSERT(Row>=0);
73                 BOOST_QVM_STATIC_ASSERT(Row<rows);
74                 return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
75                 }
76 
77             template <int Row,int Col>
78             static
79             BOOST_QVM_INLINE_CRITICAL
80             scalar_type &
write_elementboost::qvm::mat_traits81             write_element( this_matrix & x )
82                 {
83                 BOOST_QVM_STATIC_ASSERT(Col==0);
84                 BOOST_QVM_STATIC_ASSERT(Row>=0);
85                 BOOST_QVM_STATIC_ASSERT(Row<rows);
86                 return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
87                 }
88 
89             static
90             BOOST_QVM_INLINE_CRITICAL
91             scalar_type
read_element_idxboost::qvm::mat_traits92             read_element_idx( int row, int col, this_matrix const & x )
93                 {
94                 BOOST_QVM_ASSERT(col==0);
95                 BOOST_QVM_ASSERT(row>=0);
96                 BOOST_QVM_ASSERT(row<rows);
97                 return vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x));
98                 }
99 
100             static
101             BOOST_QVM_INLINE_CRITICAL
102             scalar_type &
write_element_idxboost::qvm::mat_traits103             write_element_idx( int row, int col, this_matrix & x )
104                 {
105                 BOOST_QVM_ASSERT(col==0);
106                 BOOST_QVM_ASSERT(row>=0);
107                 BOOST_QVM_ASSERT(row<rows);
108                 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
109                 }
110             };
111 
112         template <class OriginalVector,int R,int C>
113         struct
114         deduce_mat<qvm_detail::col_mat_<OriginalVector>,R,C>
115             {
116             typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
117             };
118 
119         template <class OriginalVector,int R,int C>
120         struct
121         deduce_mat2<qvm_detail::col_mat_<OriginalVector>,qvm_detail::col_mat_<OriginalVector>,R,C>
122             {
123             typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
124             };
125 
126         template <class A>
127         typename boost::enable_if_c<
128             is_vec<A>::value,
129             qvm_detail::col_mat_<A> const &>::type
130         BOOST_QVM_INLINE_TRIVIAL
col_mat(A const & a)131         col_mat( A const & a )
132             {
133             return reinterpret_cast<typename qvm_detail::col_mat_<A> const &>(a);
134             }
135 
136         template <class A>
137         typename boost::enable_if_c<
138             is_vec<A>::value,
139             qvm_detail::col_mat_<A> &>::type
140         BOOST_QVM_INLINE_TRIVIAL
col_mat(A & a)141         col_mat( A & a )
142             {
143             return reinterpret_cast<typename qvm_detail::col_mat_<A> &>(a);
144             }
145 
146         ////////////////////////////////////////////////
147 
148         namespace
149         qvm_detail
150             {
151             template <class OriginalVector>
152             class
153             row_mat_
154                 {
155                 row_mat_( row_mat_ const & );
156                 row_mat_ & operator=( row_mat_ const & );
157                 ~row_mat_();
158 
159                 public:
160 
161                 template <class T>
162                 BOOST_QVM_INLINE_TRIVIAL
163                 row_mat_ &
operator =(T const & x)164                 operator=( T const & x )
165                     {
166                     assign(*this,x);
167                     return *this;
168                     }
169 
170                 template <class R>
171                 BOOST_QVM_INLINE_TRIVIAL
operator R() const172                 operator R() const
173                     {
174                     R r;
175                     assign(r,*this);
176                     return r;
177                     }
178                 };
179             }
180 
181         template <class OriginalVector>
182         struct
183         mat_traits< qvm_detail::row_mat_<OriginalVector> >
184             {
185             typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
186             typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
187             static int const rows=1;
188             static int const cols=vec_traits<OriginalVector>::dim;
189 
190             template <int Row,int Col>
191             static
192             BOOST_QVM_INLINE_CRITICAL
193             scalar_type
read_elementboost::qvm::mat_traits194             read_element( this_matrix const & x )
195                 {
196                 BOOST_QVM_STATIC_ASSERT(Row==0);
197                 BOOST_QVM_STATIC_ASSERT(Col>=0);
198                 BOOST_QVM_STATIC_ASSERT(Col<cols);
199                 return vec_traits<OriginalVector>::template read_element<Col>(reinterpret_cast<OriginalVector const &>(x));
200                 }
201 
202             template <int Row,int Col>
203             static
204             BOOST_QVM_INLINE_CRITICAL
205             scalar_type &
write_elementboost::qvm::mat_traits206             write_element( this_matrix & x )
207                 {
208                 BOOST_QVM_STATIC_ASSERT(Row==0);
209                 BOOST_QVM_STATIC_ASSERT(Col>=0);
210                 BOOST_QVM_STATIC_ASSERT(Col<cols);
211                 return vec_traits<OriginalVector>::template write_element<Col>(reinterpret_cast<OriginalVector &>(x));
212                 }
213 
214             static
215             BOOST_QVM_INLINE_CRITICAL
216             scalar_type
read_element_idxboost::qvm::mat_traits217             read_element_idx( int row, int col, this_matrix const & x )
218                 {
219                 BOOST_QVM_ASSERT(row==0);
220                 BOOST_QVM_ASSERT(col>=0);
221                 BOOST_QVM_ASSERT(col<cols);
222                 return vec_traits<OriginalVector>::read_element_idx(col,reinterpret_cast<OriginalVector const &>(x));
223                 }
224 
225             static
226             BOOST_QVM_INLINE_CRITICAL
227             scalar_type &
write_element_idxboost::qvm::mat_traits228             write_element_idx( int row, int col, this_matrix & x )
229                 {
230                 BOOST_QVM_ASSERT(row==0);
231                 BOOST_QVM_ASSERT(col>=0);
232                 BOOST_QVM_ASSERT(col<cols);
233                 return vec_traits<OriginalVector>::write_element_idx(col,reinterpret_cast<OriginalVector &>(x));
234                 }
235             };
236 
237         template <class OriginalVector,int R,int C>
238         struct
239         deduce_mat<qvm_detail::row_mat_<OriginalVector>,R,C>
240             {
241             typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
242             };
243 
244         template <class OriginalVector,int R,int C>
245         struct
246         deduce_mat2<qvm_detail::row_mat_<OriginalVector>,qvm_detail::row_mat_<OriginalVector>,R,C>
247             {
248             typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
249             };
250 
251         template <class A>
252         typename boost::enable_if_c<
253             is_vec<A>::value,
254             qvm_detail::row_mat_<A> const &>::type
255         BOOST_QVM_INLINE_TRIVIAL
row_mat(A const & a)256         row_mat( A const & a )
257             {
258             return reinterpret_cast<typename qvm_detail::row_mat_<A> const &>(a);
259             }
260 
261         template <class A>
262         typename boost::enable_if_c<
263             is_vec<A>::value,
264             qvm_detail::row_mat_<A> &>::type
265         BOOST_QVM_INLINE_TRIVIAL
row_mat(A & a)266         row_mat( A & a )
267             {
268             return reinterpret_cast<typename qvm_detail::row_mat_<A> &>(a);
269             }
270 
271         ////////////////////////////////////////////////
272 
273         namespace
274         qvm_detail
275             {
276             template <class OriginalVector>
277             class
278             translation_mat_
279                 {
280                 translation_mat_( translation_mat_ const & );
281                 translation_mat_ & operator=( translation_mat_ const & );
282                 ~translation_mat_();
283 
284                 public:
285 
286                 template <class T>
287                 BOOST_QVM_INLINE_TRIVIAL
288                 translation_mat_ &
operator =(T const & x)289                 operator=( T const & x )
290                     {
291                     assign(*this,x);
292                     return *this;
293                     }
294 
295                 template <class R>
296                 BOOST_QVM_INLINE_TRIVIAL
operator R() const297                 operator R() const
298                     {
299                     R r;
300                     assign(r,*this);
301                     return r;
302                     }
303                 };
304 
305             template <class M,int Row,int Col,bool TransCol=(Col==mat_traits<M>::cols-1)>
306             struct read_translation_matat;
307 
308             template <class OriginalVector,int Row,int Col,bool TransCol>
309             struct
310             read_translation_matat<translation_mat_<OriginalVector>,Row,Col,TransCol>
311                 {
312                 static
313                 BOOST_QVM_INLINE_CRITICAL
314                 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
fboost::qvm::qvm_detail::read_translation_matat315                 f( translation_mat_<OriginalVector> const & )
316                     {
317                     return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(0);
318                     }
319                 };
320 
321             template <class OriginalVector,int D>
322             struct
323             read_translation_matat<translation_mat_<OriginalVector>,D,D,false>
324                 {
325                 static
326                 BOOST_QVM_INLINE_CRITICAL
327                 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
fboost::qvm::qvm_detail::read_translation_matat328                 f( translation_mat_<OriginalVector> const & )
329                     {
330                     return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
331                     }
332                 };
333 
334             template <class OriginalVector,int D>
335             struct
336             read_translation_matat<translation_mat_<OriginalVector>,D,D,true>
337                 {
338                 static
339                 BOOST_QVM_INLINE_CRITICAL
340                 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
fboost::qvm::qvm_detail::read_translation_matat341                 f( translation_mat_<OriginalVector> const & )
342                     {
343                     return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
344                     }
345                 };
346 
347             template <class OriginalVector,int Row,int Col>
348             struct
349             read_translation_matat<translation_mat_<OriginalVector>,Row,Col,true>
350                 {
351                 static
352                 BOOST_QVM_INLINE_CRITICAL
353                 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
fboost::qvm::qvm_detail::read_translation_matat354                 f( translation_mat_<OriginalVector> const & x )
355                     {
356                     return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
357                     }
358                 };
359             }
360 
361         template <class OriginalVector>
362         struct
363         mat_traits< qvm_detail::translation_mat_<OriginalVector> >
364             {
365             typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
366             typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
367             static int const rows=vec_traits<OriginalVector>::dim+1;
368             static int const cols=vec_traits<OriginalVector>::dim+1;
369 
370             template <int Row,int Col>
371             static
372             BOOST_QVM_INLINE_CRITICAL
373             scalar_type
read_elementboost::qvm::mat_traits374             read_element( this_matrix const & x )
375                 {
376                 BOOST_QVM_STATIC_ASSERT(Row>=0);
377                 BOOST_QVM_STATIC_ASSERT(Row<rows);
378                 BOOST_QVM_STATIC_ASSERT(Col>=0);
379                 BOOST_QVM_STATIC_ASSERT(Col<cols);
380                 return qvm_detail::read_translation_matat<qvm_detail::translation_mat_<OriginalVector>,Row,Col>::f(x);
381                 }
382 
383             template <int Row,int Col>
384             static
385             BOOST_QVM_INLINE_CRITICAL
386             scalar_type &
write_elementboost::qvm::mat_traits387             write_element( this_matrix & x )
388                 {
389                 BOOST_QVM_STATIC_ASSERT(Row>=0);
390                 BOOST_QVM_STATIC_ASSERT(Row<rows);
391                 BOOST_QVM_STATIC_ASSERT(Col==cols-1);
392                 BOOST_QVM_STATIC_ASSERT(Col!=Row);
393                 return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
394                 }
395 
396             static
397             BOOST_QVM_INLINE_CRITICAL
398             scalar_type
read_element_idxboost::qvm::mat_traits399             read_element_idx( int row, int col, this_matrix const & x )
400                 {
401                 BOOST_QVM_ASSERT(row>=0);
402                 BOOST_QVM_ASSERT(row<rows);
403                 BOOST_QVM_ASSERT(col>=0);
404                 BOOST_QVM_ASSERT(col<cols);
405                 return
406                     row==col?
407                         scalar_traits<scalar_type>::value(1):
408                         (col==cols-1?
409                             vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):
410                             scalar_traits<scalar_type>::value(0));
411                 }
412 
413             static
414             BOOST_QVM_INLINE_CRITICAL
415             scalar_type &
write_element_idxboost::qvm::mat_traits416             write_element_idx( int row, int col, this_matrix const & x )
417                 {
418                 BOOST_QVM_ASSERT(row>=0);
419                 BOOST_QVM_ASSERT(row<rows);
420                 BOOST_QVM_ASSERT(col==cols-1);
421                 BOOST_QVM_ASSERT(col!=row);
422                 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
423                 }
424             };
425 
426         template <class OriginalVector,int R,int C>
427         struct
428         deduce_mat<qvm_detail::translation_mat_<OriginalVector>,R,C>
429             {
430             typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
431             };
432 
433         template <class OriginalVector,int R,int C>
434         struct
435         deduce_mat2<qvm_detail::translation_mat_<OriginalVector>,qvm_detail::translation_mat_<OriginalVector>,R,C>
436             {
437             typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
438             };
439 
440         template <class A>
441         typename boost::enable_if_c<
442             is_vec<A>::value,
443             qvm_detail::translation_mat_<A> const &>::type
444         BOOST_QVM_INLINE_TRIVIAL
translation_mat(A const & a)445         translation_mat( A const & a )
446             {
447             return reinterpret_cast<typename qvm_detail::translation_mat_<A> const &>(a);
448             }
449 
450         template <class A>
451         typename boost::enable_if_c<
452             is_vec<A>::value,
453             qvm_detail::translation_mat_<A> &>::type
454         BOOST_QVM_INLINE_TRIVIAL
translation_mat(A & a)455         translation_mat( A & a )
456             {
457             return reinterpret_cast<typename qvm_detail::translation_mat_<A> &>(a);
458             }
459 
460         ////////////////////////////////////////////////
461 
462         namespace
463         qvm_detail
464             {
465             template <class OriginalVector>
466             class
467             diag_mat_
468                 {
469                 diag_mat_( diag_mat_ const & );
470                 diag_mat_ & operator=( diag_mat_ const & );
471                 ~diag_mat_();
472 
473                 public:
474 
475                 template <class T>
476                 BOOST_QVM_INLINE_TRIVIAL
477                 diag_mat_ &
operator =(T const & x)478                 operator=( T const & x )
479                     {
480                     assign(*this,x);
481                     return *this;
482                     }
483 
484                 template <class R>
485                 BOOST_QVM_INLINE_TRIVIAL
operator R() const486                 operator R() const
487                     {
488                     R r;
489                     assign(r,*this);
490                     return r;
491                     }
492                 };
493             }
494 
495         template <class OriginalVector>
496         struct
497         mat_traits< qvm_detail::diag_mat_<OriginalVector> >
498             {
499             typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
500             typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
501             static int const rows=vec_traits<OriginalVector>::dim;
502             static int const cols=vec_traits<OriginalVector>::dim;
503 
504             template <int Row,int Col>
505             static
506             BOOST_QVM_INLINE_CRITICAL
507             scalar_type
read_elementboost::qvm::mat_traits508             read_element( this_matrix const & x )
509                 {
510                 BOOST_QVM_STATIC_ASSERT(Row>=0);
511                 BOOST_QVM_STATIC_ASSERT(Row<rows);
512                 BOOST_QVM_STATIC_ASSERT(Col>=0);
513                 BOOST_QVM_STATIC_ASSERT(Col<cols);
514                 return Row==Col?vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
515                 }
516 
517             template <int Row,int Col>
518             static
519             BOOST_QVM_INLINE_CRITICAL
520             scalar_type &
write_elementboost::qvm::mat_traits521             write_element( this_matrix & x )
522                 {
523                 BOOST_QVM_STATIC_ASSERT(Row>=0);
524                 BOOST_QVM_STATIC_ASSERT(Row<rows);
525                 BOOST_QVM_STATIC_ASSERT(Row==Col);
526                 return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
527                 }
528 
529             static
530             BOOST_QVM_INLINE_CRITICAL
531             scalar_type
read_element_idxboost::qvm::mat_traits532             read_element_idx( int row, int col, this_matrix const & x )
533                 {
534                 BOOST_QVM_ASSERT(row>=0);
535                 BOOST_QVM_ASSERT(row<rows);
536                 BOOST_QVM_ASSERT(col>=0);
537                 BOOST_QVM_ASSERT(col<cols);
538                 return row==col?vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
539                 }
540 
541             static
542             BOOST_QVM_INLINE_CRITICAL
543             scalar_type &
write_element_idxboost::qvm::mat_traits544             write_element_idx( int row, int col, this_matrix & x )
545                 {
546                 BOOST_QVM_ASSERT(row>=0);
547                 BOOST_QVM_ASSERT(row<rows);
548                 BOOST_QVM_ASSERT(row==col);
549                 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
550                 }
551             };
552 
553         template <class OriginalVector,int R,int C>
554         struct
555         deduce_mat<qvm_detail::diag_mat_<OriginalVector>,R,C>
556             {
557             typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
558             };
559 
560         template <class OriginalVector,int R,int C>
561         struct
562         deduce_mat2<qvm_detail::diag_mat_<OriginalVector>,qvm_detail::diag_mat_<OriginalVector>,R,C>
563             {
564             typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
565             };
566 
567         template <class A>
568         typename boost::enable_if_c<
569             is_vec<A>::value,
570             qvm_detail::diag_mat_<A> const &>::type
571         BOOST_QVM_INLINE_TRIVIAL
diag_mat(A const & a)572         diag_mat( A const & a )
573             {
574             return reinterpret_cast<typename qvm_detail::diag_mat_<A> const &>(a);
575             }
576 
577         template <class A>
578         typename boost::enable_if_c<
579             is_vec<A>::value,
580             qvm_detail::diag_mat_<A> &>::type
581         BOOST_QVM_INLINE_TRIVIAL
diag_mat(A & a)582         diag_mat( A & a )
583             {
584             return reinterpret_cast<typename qvm_detail::diag_mat_<A> &>(a);
585             }
586 
587         ////////////////////////////////////////////////
588         }
589     }
590 
591 #endif
592