1#ifndef BOOST_QVM_MAP_VEC_MAT_HPP_INCLUDED
2#define BOOST_QVM_MAP_VEC_MAT_HPP_INCLUDED
3
4// Copyright 2008-2022 Emil Dotchevski and Reverge Studios, Inc.
5
6// Distributed under the Boost Software License, Version 1.0. (See accompanying
7// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8
9#include <boost/qvm/config.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
15namespace boost { namespace qvm {
16
17namespace
18qvm_detail
19 {
20 template <class OriginalVector>
21 class
22 col_mat_
23 {
24 col_mat_( col_mat_ const & );
25 col_mat_ & operator=( col_mat_ const & );
26 ~col_mat_();
27
28 public:
29
30 template <class T>
31 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
32 col_mat_ &
33 operator=( T const & x )
34 {
35 assign(*this,x);
36 return *this;
37 }
38
39 template <class R
40#if __cplusplus >= 201103L
41 , class = typename enable_if<is_mat<R> >::type
42#endif
43 >
44 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
45 operator R() const
46 {
47 R r;
48 assign(r,*this);
49 return r;
50 }
51 };
52
53 template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
54 struct col_mat_write_traits;
55
56 template <class OriginalVector>
57 struct
58 col_mat_write_traits<OriginalVector,true>
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_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
68 scalar_type &
69 write_element( this_matrix & 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 write_element<Row>(reinterpret_cast<OriginalVector &>(x));
75 }
76
77 static
78 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
79 scalar_type &
80 write_element_idx( int row, int col, this_matrix & x )
81 {
82 BOOST_QVM_ASSERT(col==0);
83 BOOST_QVM_ASSERT(row>=0);
84 BOOST_QVM_ASSERT(row<rows);
85 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
86 }
87 };
88
89 template <class OriginalVector>
90 struct
91 col_mat_write_traits<OriginalVector,false>
92 {
93 typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
94 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
95 static int const rows=vec_traits<OriginalVector>::dim;
96 static int const cols=1;
97
98 template <int Row,int Col>
99 static
100 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
101 void
102 write_element( this_matrix & x, scalar_type s )
103 {
104 BOOST_QVM_STATIC_ASSERT(Col==0);
105 BOOST_QVM_STATIC_ASSERT(Row>=0);
106 BOOST_QVM_STATIC_ASSERT(Row<rows);
107 vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
108 }
109
110 static
111 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
112 void
113 write_element_idx( int row, int col, this_matrix & x, scalar_type s )
114 {
115 BOOST_QVM_ASSERT(col==0);
116 BOOST_QVM_ASSERT(row>=0);
117 BOOST_QVM_ASSERT(row<rows);
118 vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
119 }
120 };
121 }
122
123template <class OriginalVector>
124struct
125mat_traits< qvm_detail::col_mat_<OriginalVector> >:
126 qvm_detail::col_mat_write_traits<OriginalVector>
127 {
128 typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
129 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
130 static int const rows=vec_traits<OriginalVector>::dim;
131 static int const cols=1;
132
133 template <int Row,int Col>
134 static
135 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
136 scalar_type
137 read_element( this_matrix const & x )
138 {
139 BOOST_QVM_STATIC_ASSERT(Col==0);
140 BOOST_QVM_STATIC_ASSERT(Row>=0);
141 BOOST_QVM_STATIC_ASSERT(Row<rows);
142 return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
143 }
144
145 static
146 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
147 scalar_type
148 read_element_idx( int row, int col, this_matrix const & x )
149 {
150 BOOST_QVM_ASSERT(col==0);
151 BOOST_QVM_ASSERT(row>=0);
152 BOOST_QVM_ASSERT(row<rows);
153 return vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x));
154 }
155 };
156
157template <class OriginalVector,int R,int C>
158struct
159deduce_mat<qvm_detail::col_mat_<OriginalVector>,R,C>
160 {
161 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
162 };
163
164template <class OriginalVector,int R,int C>
165struct
166deduce_mat2<qvm_detail::col_mat_<OriginalVector>,qvm_detail::col_mat_<OriginalVector>,R,C>
167 {
168 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
169 };
170
171template <class A>
172typename enable_if_c<
173 is_vec<A>::value,
174 qvm_detail::col_mat_<A> const &>::type
175BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
176col_mat( A const & a )
177 {
178 return reinterpret_cast<typename qvm_detail::col_mat_<A> const &>(a);
179 }
180
181template <class A>
182typename enable_if_c<
183 is_vec<A>::value,
184 qvm_detail::col_mat_<A> &>::type
185BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
186col_mat( A & a )
187 {
188 return reinterpret_cast<typename qvm_detail::col_mat_<A> &>(a);
189 }
190
191////////////////////////////////////////////////
192
193namespace
194qvm_detail
195 {
196 template <class OriginalVector>
197 class
198 row_mat_
199 {
200 row_mat_( row_mat_ const & );
201 row_mat_ & operator=( row_mat_ const & );
202 ~row_mat_();
203
204 public:
205
206 template <class T>
207 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
208 row_mat_ &
209 operator=( T const & x )
210 {
211 assign(*this,x);
212 return *this;
213 }
214
215 template <class R
216#if __cplusplus >= 201103L
217 , class = typename enable_if<is_mat<R> >::type
218#endif
219 >
220 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
221 operator R() const
222 {
223 R r;
224 assign(r,*this);
225 return r;
226 }
227 };
228
229 template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
230 struct row_mat_write_traits;
231
232 template <class OriginalVector>
233 struct
234 row_mat_write_traits<OriginalVector,true>
235 {
236 typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
237 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
238 static int const rows=1;
239 static int const cols=vec_traits<OriginalVector>::dim;
240
241 template <int Row,int Col>
242 static
243 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
244 scalar_type &
245 write_element( this_matrix & x )
246 {
247 BOOST_QVM_STATIC_ASSERT(Row==0);
248 BOOST_QVM_STATIC_ASSERT(Col>=0);
249 BOOST_QVM_STATIC_ASSERT(Col<cols);
250 return vec_traits<OriginalVector>::template write_element<Col>(reinterpret_cast<OriginalVector &>(x));
251 }
252
253 static
254 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
255 scalar_type &
256 write_element_idx( int row, int col, this_matrix & x )
257 {
258 BOOST_QVM_ASSERT(row==0);
259 BOOST_QVM_ASSERT(col>=0);
260 BOOST_QVM_ASSERT(col<cols);
261 return vec_traits<OriginalVector>::write_element_idx(col,reinterpret_cast<OriginalVector &>(x));
262 }
263 };
264
265 template <class OriginalVector>
266 struct
267 row_mat_write_traits<OriginalVector,false>
268 {
269 typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
270 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
271 static int const rows=1;
272 static int const cols=vec_traits<OriginalVector>::dim;
273
274 template <int Row,int Col>
275 static
276 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
277 void
278 write_element( this_matrix & x, scalar_type s )
279 {
280 BOOST_QVM_STATIC_ASSERT(Row==0);
281 BOOST_QVM_STATIC_ASSERT(Col>=0);
282 BOOST_QVM_STATIC_ASSERT(Col<cols);
283 vec_traits<OriginalVector>::template write_element<Col>(reinterpret_cast<OriginalVector &>(x), s);
284 }
285
286 static
287 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
288 void
289 write_element_idx( int row, int col, this_matrix & x, scalar_type s )
290 {
291 BOOST_QVM_ASSERT(row==0);
292 BOOST_QVM_ASSERT(col>=0);
293 BOOST_QVM_ASSERT(col<cols);
294 vec_traits<OriginalVector>::write_element_idx(col,reinterpret_cast<OriginalVector &>(x), s);
295 }
296 };
297 }
298
299template <class OriginalVector>
300struct
301mat_traits< qvm_detail::row_mat_<OriginalVector> >:
302 qvm_detail::row_mat_write_traits<OriginalVector>
303 {
304 typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
305 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
306 static int const rows=1;
307 static int const cols=vec_traits<OriginalVector>::dim;
308
309 template <int Row,int Col>
310 static
311 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
312 scalar_type
313 read_element( this_matrix const & x )
314 {
315 BOOST_QVM_STATIC_ASSERT(Row==0);
316 BOOST_QVM_STATIC_ASSERT(Col>=0);
317 BOOST_QVM_STATIC_ASSERT(Col<cols);
318 return vec_traits<OriginalVector>::template read_element<Col>(reinterpret_cast<OriginalVector const &>(x));
319 }
320
321 static
322 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
323 scalar_type
324 read_element_idx( int row, int col, this_matrix const & x )
325 {
326 BOOST_QVM_ASSERT(row==0);
327 BOOST_QVM_ASSERT(col>=0);
328 BOOST_QVM_ASSERT(col<cols);
329 return vec_traits<OriginalVector>::read_element_idx(col,reinterpret_cast<OriginalVector const &>(x));
330 }
331 };
332
333template <class OriginalVector,int R,int C>
334struct
335deduce_mat<qvm_detail::row_mat_<OriginalVector>,R,C>
336 {
337 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
338 };
339
340template <class OriginalVector,int R,int C>
341struct
342deduce_mat2<qvm_detail::row_mat_<OriginalVector>,qvm_detail::row_mat_<OriginalVector>,R,C>
343 {
344 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
345 };
346
347template <class A>
348typename enable_if_c<
349 is_vec<A>::value,
350 qvm_detail::row_mat_<A> const &>::type
351BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
352row_mat( A const & a )
353 {
354 return reinterpret_cast<typename qvm_detail::row_mat_<A> const &>(a);
355 }
356
357template <class A>
358typename enable_if_c<
359 is_vec<A>::value,
360 qvm_detail::row_mat_<A> &>::type
361BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
362row_mat( A & a )
363 {
364 return reinterpret_cast<typename qvm_detail::row_mat_<A> &>(a);
365 }
366
367////////////////////////////////////////////////
368
369namespace
370qvm_detail
371 {
372 template <class OriginalVector>
373 class
374 translation_mat_
375 {
376 translation_mat_( translation_mat_ const & );
377 translation_mat_ & operator=( translation_mat_ const & );
378 ~translation_mat_();
379
380 public:
381
382 template <class T>
383 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
384 translation_mat_ &
385 operator=( T const & x )
386 {
387 assign(*this,x);
388 return *this;
389 }
390
391 template <class R
392#if __cplusplus >= 201103L
393 , class = typename enable_if<is_mat<R> >::type
394#endif
395 >
396 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
397 operator R() const
398 {
399 R r;
400 assign(r,*this);
401 return r;
402 }
403 };
404
405 template <class M,int Row,int Col,bool TransCol=(Col==mat_traits<M>::cols-1)>
406 struct read_translation_matat;
407
408 template <class OriginalVector,int Row,int Col,bool TransCol>
409 struct
410 read_translation_matat<translation_mat_<OriginalVector>,Row,Col,TransCol>
411 {
412 static
413 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
414 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
415 f( translation_mat_<OriginalVector> const & )
416 {
417 return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(0);
418 }
419 };
420
421 template <class OriginalVector,int D>
422 struct
423 read_translation_matat<translation_mat_<OriginalVector>,D,D,false>
424 {
425 static
426 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
427 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
428 f( translation_mat_<OriginalVector> const & )
429 {
430 return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
431 }
432 };
433
434 template <class OriginalVector,int D>
435 struct
436 read_translation_matat<translation_mat_<OriginalVector>,D,D,true>
437 {
438 static
439 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
440 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
441 f( translation_mat_<OriginalVector> const & )
442 {
443 return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
444 }
445 };
446
447 template <class OriginalVector,int Row,int Col>
448 struct
449 read_translation_matat<translation_mat_<OriginalVector>,Row,Col,true>
450 {
451 static
452 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
453 typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
454 f( translation_mat_<OriginalVector> const & x )
455 {
456 return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
457 }
458 };
459
460 template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
461 struct translation_mat_write_traits;
462
463 template <class OriginalVector>
464 struct
465 translation_mat_write_traits<OriginalVector,true>
466 {
467 typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
468 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
469 static int const rows=vec_traits<OriginalVector>::dim+1;
470 static int const cols=vec_traits<OriginalVector>::dim+1;
471
472 template <int Row,int Col>
473 static
474 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
475 scalar_type &
476 write_element( this_matrix & x )
477 {
478 BOOST_QVM_STATIC_ASSERT(Row>=0);
479 BOOST_QVM_STATIC_ASSERT(Row<rows-1);
480 BOOST_QVM_STATIC_ASSERT(Col==cols-1 || Col==0);
481 //The following should be a static_assert, but this is a constexpr
482 //function and it gets instantiated with Row=0 and Col=0 in the
483 //mat_write_element_ref test (in a sizeof expression).
484 BOOST_QVM_ASSERT(Col==cols-1);
485 return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
486 }
487
488 static
489 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
490 scalar_type &
491 write_element_idx( int row, int col, this_matrix const & x )
492 {
493 BOOST_QVM_ASSERT(row>=0);
494 BOOST_QVM_ASSERT(row<rows-1);
495 BOOST_QVM_ASSERT(col==cols-1);
496 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
497 }
498 };
499
500 template <class OriginalVector>
501 struct
502 translation_mat_write_traits<OriginalVector,false>
503 {
504 typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
505 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
506 static int const rows=vec_traits<OriginalVector>::dim+1;
507 static int const cols=vec_traits<OriginalVector>::dim+1;
508
509 template <int Row,int Col>
510 static
511 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
512 void
513 write_element( this_matrix & x, scalar_type s )
514 {
515 BOOST_QVM_STATIC_ASSERT(Row>=0);
516 BOOST_QVM_STATIC_ASSERT(Row<rows-1);
517 BOOST_QVM_STATIC_ASSERT(Col==cols-1 || Col==0);
518 //The following should be a static_assert, but this is a constexpr
519 //function and it gets instantiated with Row=0 and Col=0 in the
520 //mat_write_element_ref test (in a sizeof expression).
521 BOOST_QVM_ASSERT(Col==cols-1);
522 vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
523 }
524
525 static
526 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
527 void
528 write_element_idx( int row, int col, this_matrix const & x, scalar_type s )
529 {
530 BOOST_QVM_ASSERT(row>=0);
531 BOOST_QVM_ASSERT(row<rows);
532 BOOST_QVM_ASSERT(col==cols-1);
533 BOOST_QVM_ASSERT(col!=row);
534 vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
535 }
536 };
537 }
538
539template <class OriginalVector>
540struct
541mat_traits< qvm_detail::translation_mat_<OriginalVector> >:
542 qvm_detail::translation_mat_write_traits<OriginalVector>
543 {
544 typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
545 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
546 static int const rows=vec_traits<OriginalVector>::dim+1;
547 static int const cols=vec_traits<OriginalVector>::dim+1;
548
549 template <int Row,int Col>
550 static
551 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
552 scalar_type
553 read_element( this_matrix const & x )
554 {
555 BOOST_QVM_STATIC_ASSERT(Row>=0);
556 BOOST_QVM_STATIC_ASSERT(Row<rows);
557 BOOST_QVM_STATIC_ASSERT(Col>=0);
558 BOOST_QVM_STATIC_ASSERT(Col<cols);
559 return qvm_detail::read_translation_matat<qvm_detail::translation_mat_<OriginalVector>,Row,Col>::f(x);
560 }
561
562 static
563 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
564 scalar_type
565 read_element_idx( int row, int col, this_matrix const & x )
566 {
567 BOOST_QVM_ASSERT(row>=0);
568 BOOST_QVM_ASSERT(row<rows);
569 BOOST_QVM_ASSERT(col>=0);
570 BOOST_QVM_ASSERT(col<cols);
571 return
572 row==col?
573 scalar_traits<scalar_type>::value(1):
574 (col==cols-1?
575 vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):
576 scalar_traits<scalar_type>::value(0));
577 }
578 };
579
580template <class OriginalVector,int R,int C>
581struct
582deduce_mat<qvm_detail::translation_mat_<OriginalVector>,R,C>
583 {
584 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
585 };
586
587template <class OriginalVector,int R,int C>
588struct
589deduce_mat2<qvm_detail::translation_mat_<OriginalVector>,qvm_detail::translation_mat_<OriginalVector>,R,C>
590 {
591 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
592 };
593
594template <class A>
595typename enable_if_c<
596 is_vec<A>::value,
597 qvm_detail::translation_mat_<A> const &>::type
598BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
599translation_mat( A const & a )
600 {
601 return reinterpret_cast<typename qvm_detail::translation_mat_<A> const &>(a);
602 }
603
604template <class A>
605typename enable_if_c<
606 is_vec<A>::value,
607 qvm_detail::translation_mat_<A> &>::type
608BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
609translation_mat( A & a )
610 {
611 return reinterpret_cast<typename qvm_detail::translation_mat_<A> &>(a);
612 }
613
614////////////////////////////////////////////////
615
616namespace
617qvm_detail
618 {
619 template <class OriginalVector>
620 class
621 diag_mat_
622 {
623 diag_mat_( diag_mat_ const & );
624 diag_mat_ & operator=( diag_mat_ const & );
625 ~diag_mat_();
626
627 public:
628
629 template <class T>
630 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
631 diag_mat_ &
632 operator=( T const & x )
633 {
634 assign(*this,x);
635 return *this;
636 }
637
638 template <class R
639#if __cplusplus >= 201103L
640 , class = typename enable_if<is_mat<R> >::type
641#endif
642 >
643 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
644 operator R() const
645 {
646 R r;
647 assign(r,*this);
648 return r;
649 }
650 };
651
652 template <class OriginalVector,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
653 struct diag_mat_write_traits;
654
655 template <class OriginalVector>
656 struct
657 diag_mat_write_traits<OriginalVector,true>
658 {
659 typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
660 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
661 static int const rows=vec_traits<OriginalVector>::dim;
662 static int const cols=vec_traits<OriginalVector>::dim;
663
664 template <int Row,int Col>
665 static
666 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
667 scalar_type &
668 write_element( this_matrix & x )
669 {
670 BOOST_QVM_STATIC_ASSERT(Row>=0);
671 BOOST_QVM_STATIC_ASSERT(Row<rows);
672 BOOST_QVM_STATIC_ASSERT(Row==Col);
673 return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
674 }
675
676 static
677 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
678 scalar_type &
679 write_element_idx( int row, int col, this_matrix & x )
680 {
681 BOOST_QVM_ASSERT(row>=0);
682 BOOST_QVM_ASSERT(row<rows);
683 BOOST_QVM_ASSERT(row==col);
684 return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
685 }
686 };
687
688 template <class OriginalVector>
689 struct
690 diag_mat_write_traits<OriginalVector,false>
691 {
692 typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
693 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
694 static int const rows=vec_traits<OriginalVector>::dim;
695 static int const cols=vec_traits<OriginalVector>::dim;
696
697 template <int Row,int Col>
698 static
699 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
700 void
701 write_element( this_matrix & x, scalar_type s )
702 {
703 BOOST_QVM_STATIC_ASSERT(Row>=0);
704 BOOST_QVM_STATIC_ASSERT(Row<rows);
705 BOOST_QVM_STATIC_ASSERT(Row==Col);
706 vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x), s);
707 }
708
709 static
710 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
711 void
712 write_element_idx( int row, int col, this_matrix & x, scalar_type s )
713 {
714 BOOST_QVM_ASSERT(row>=0);
715 BOOST_QVM_ASSERT(row<rows);
716 BOOST_QVM_ASSERT(row==col);
717 vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x), s);
718 }
719 };
720 }
721
722template <class OriginalVector>
723struct
724mat_traits< qvm_detail::diag_mat_<OriginalVector> >:
725 qvm_detail::diag_mat_write_traits<OriginalVector>
726 {
727 typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
728 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
729 static int const rows=vec_traits<OriginalVector>::dim;
730 static int const cols=vec_traits<OriginalVector>::dim;
731
732 template <int Row,int Col>
733 static
734 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
735 scalar_type
736 read_element( this_matrix const & x )
737 {
738 BOOST_QVM_STATIC_ASSERT(Row>=0);
739 BOOST_QVM_STATIC_ASSERT(Row<rows);
740 BOOST_QVM_STATIC_ASSERT(Col>=0);
741 BOOST_QVM_STATIC_ASSERT(Col<cols);
742 return Row==Col?vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
743 }
744
745 static
746 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
747 scalar_type
748 read_element_idx( int row, int col, this_matrix const & x )
749 {
750 BOOST_QVM_ASSERT(row>=0);
751 BOOST_QVM_ASSERT(row<rows);
752 BOOST_QVM_ASSERT(col>=0);
753 BOOST_QVM_ASSERT(col<cols);
754 return row==col?vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
755 }
756 };
757
758template <class OriginalVector,int R,int C>
759struct
760deduce_mat<qvm_detail::diag_mat_<OriginalVector>,R,C>
761 {
762 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
763 };
764
765template <class OriginalVector,int R,int C>
766struct
767deduce_mat2<qvm_detail::diag_mat_<OriginalVector>,qvm_detail::diag_mat_<OriginalVector>,R,C>
768 {
769 typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
770 };
771
772template <class A>
773typename enable_if_c<
774 is_vec<A>::value,
775 qvm_detail::diag_mat_<A> const &>::type
776BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
777diag_mat( A const & a )
778 {
779 return reinterpret_cast<typename qvm_detail::diag_mat_<A> const &>(a);
780 }
781
782template <class A>
783typename enable_if_c<
784 is_vec<A>::value,
785 qvm_detail::diag_mat_<A> &>::type
786BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
787diag_mat( A & a )
788 {
789 return reinterpret_cast<typename qvm_detail::diag_mat_<A> &>(a);
790 }
791
792} }
793
794#endif
795

source code of boost/libs/qvm/include/boost/qvm/map_vec_mat.hpp