• 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_20D98340A3EB11DEB2180CD156D89593
7 #define BOOST_QVM_20D98340A3EB11DEB2180CD156D89593
8 
9 #include <boost/qvm/inline.hpp>
10 #include <boost/qvm/deduce_mat.hpp>
11 #include <boost/qvm/assert.hpp>
12 #include <boost/qvm/enable_if.hpp>
13 #include <boost/qvm/detail/transp_impl.hpp>
14 
15 namespace
16 boost
17     {
18     namespace
19     qvm
20         {
21         ////////////////////////////////////////////////
22 
23         namespace
24         qvm_detail
25             {
26             template <int Row,class OriginalMatrix>
27             class
28             del_row_
29                 {
30                 del_row_( del_row_ const & );
31                 del_row_ & operator=( del_row_ const & );
32                 ~del_row_();
33 
34                 public:
35 
36                 template <class T>
37                 BOOST_QVM_INLINE_TRIVIAL
38                 del_row_ &
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 <int I,class OriginalMatrix>
57         struct
58         mat_traits< qvm_detail::del_row_<I,OriginalMatrix> >
59             {
60             typedef qvm_detail::del_row_<I,OriginalMatrix> this_matrix;
61             typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
62             static int const rows=mat_traits<OriginalMatrix>::rows-1;
63             static int const cols=mat_traits<OriginalMatrix>::cols;
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(Row>=0);
72                 BOOST_QVM_STATIC_ASSERT(Row<rows);
73                 BOOST_QVM_STATIC_ASSERT(Col>=0);
74                 BOOST_QVM_STATIC_ASSERT(Col<cols);
75                 return mat_traits<OriginalMatrix>::template read_element<Row+(Row>=I),Col>(reinterpret_cast<OriginalMatrix const &>(x));
76                 }
77 
78             template <int Row,int Col>
79             static
80             BOOST_QVM_INLINE_CRITICAL
81             scalar_type &
write_elementboost::qvm::mat_traits82             write_element( this_matrix & x )
83                 {
84                 BOOST_QVM_STATIC_ASSERT(Row>=0);
85                 BOOST_QVM_STATIC_ASSERT(Row<rows);
86                 BOOST_QVM_STATIC_ASSERT(Col>=0);
87                 BOOST_QVM_STATIC_ASSERT(Col<cols);
88                 return mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col>(reinterpret_cast<OriginalMatrix &>(x));
89                 }
90 
91             static
92             BOOST_QVM_INLINE_CRITICAL
93             scalar_type
read_element_idxboost::qvm::mat_traits94             read_element_idx( int row, int col, this_matrix const & x )
95                 {
96                 BOOST_QVM_ASSERT(row>=0);
97                 BOOST_QVM_ASSERT(row<rows);
98                 BOOST_QVM_ASSERT(col>=0);
99                 BOOST_QVM_ASSERT(col<cols);
100                 return mat_traits<OriginalMatrix>::read_element_idx(row+(row>=I),col,reinterpret_cast<OriginalMatrix const &>(x));
101                 }
102 
103             static
104             BOOST_QVM_INLINE_CRITICAL
105             scalar_type &
write_element_idxboost::qvm::mat_traits106             write_element_idx( int row, int col, this_matrix & x )
107                 {
108                 BOOST_QVM_ASSERT(row>=0);
109                 BOOST_QVM_ASSERT(row<rows);
110                 BOOST_QVM_ASSERT(col>=0);
111                 BOOST_QVM_ASSERT(col<cols);
112                 return mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col,reinterpret_cast<OriginalMatrix &>(x));
113                 }
114             };
115 
116         template <int J,class OriginalMatrix,int R,int C>
117         struct
118         deduce_mat<qvm_detail::del_row_<J,OriginalMatrix>,R,C>
119             {
120             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
121             };
122 
123         template <int J,class OriginalMatrix,int R,int C>
124         struct
125         deduce_mat2<qvm_detail::del_row_<J,OriginalMatrix>,qvm_detail::del_row_<J,OriginalMatrix>,R,C>
126             {
127             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
128             };
129 
130         template <int Row,class A>
131         typename boost::enable_if_c<
132             is_mat<A>::value,
133             qvm_detail::del_row_<Row,A> const &>::type
134         BOOST_QVM_INLINE_TRIVIAL
del_row(A const & a)135         del_row( A const & a )
136             {
137             return reinterpret_cast<typename qvm_detail::del_row_<Row,A> const &>(a);
138             }
139 
140         template <int Row,class A>
141         typename boost::enable_if_c<
142             is_mat<A>::value,
143             qvm_detail::del_row_<Row,A> &>::type
144         BOOST_QVM_INLINE_TRIVIAL
del_row(A & a)145         del_row( A & a )
146             {
147             return reinterpret_cast<typename qvm_detail::del_row_<Row,A> &>(a);
148             }
149 
150         ////////////////////////////////////////////////
151 
152         namespace
153         qvm_detail
154             {
155             template <int Col,class OriginalMatrix>
156             class
157             del_col_
158                 {
159                 del_col_( del_col_ const & );
160                 del_col_ & operator=( del_col_ const & );
161                 ~del_col_();
162 
163                 public:
164 
165                 template <class T>
166                 BOOST_QVM_INLINE_TRIVIAL
167                 del_col_ &
operator =(T const & x)168                 operator=( T const & x )
169                     {
170                     assign(*this,x);
171                     return *this;
172                     }
173 
174                 template <class R>
175                 BOOST_QVM_INLINE_TRIVIAL
operator R() const176                 operator R() const
177                     {
178                     R r;
179                     assign(r,*this);
180                     return r;
181                     }
182                 };
183             }
184 
185         template <int J,class OriginalMatrix>
186         struct
187         mat_traits< qvm_detail::del_col_<J,OriginalMatrix> >
188             {
189             typedef qvm_detail::del_col_<J,OriginalMatrix> this_matrix;
190             typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
191             static int const rows=mat_traits<OriginalMatrix>::rows;
192             static int const cols=mat_traits<OriginalMatrix>::cols-1;
193 
194             template <int Row,int Col>
195             static
196             BOOST_QVM_INLINE_CRITICAL
197             scalar_type
read_elementboost::qvm::mat_traits198             read_element( this_matrix const & x )
199                 {
200                 BOOST_QVM_STATIC_ASSERT(Row>=0);
201                 BOOST_QVM_STATIC_ASSERT(Row<rows);
202                 BOOST_QVM_STATIC_ASSERT(Col>=0);
203                 BOOST_QVM_STATIC_ASSERT(Col<cols);
204                 return mat_traits<OriginalMatrix>::template read_element<Row,Col+(Col>=J)>(reinterpret_cast<OriginalMatrix const &>(x));
205                 }
206 
207             template <int Row,int Col>
208             static
209             BOOST_QVM_INLINE_CRITICAL
210             scalar_type &
write_elementboost::qvm::mat_traits211             write_element( this_matrix & x )
212                 {
213                 BOOST_QVM_STATIC_ASSERT(Row>=0);
214                 BOOST_QVM_STATIC_ASSERT(Row<rows);
215                 BOOST_QVM_STATIC_ASSERT(Col>=0);
216                 BOOST_QVM_STATIC_ASSERT(Col<cols);
217                 return mat_traits<OriginalMatrix>::template write_element<Row,Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x));
218                 }
219 
220             static
221             BOOST_QVM_INLINE_CRITICAL
222             scalar_type
read_element_idxboost::qvm::mat_traits223             read_element_idx( int row, int col, this_matrix const & x )
224                 {
225                 BOOST_QVM_ASSERT(row>=0);
226                 BOOST_QVM_ASSERT(row<rows);
227                 BOOST_QVM_ASSERT(col>=0);
228                 BOOST_QVM_ASSERT(col<cols);
229                 return mat_traits<OriginalMatrix>::read_element_idx(row,col+(col>=J),reinterpret_cast<OriginalMatrix const &>(x));
230                 }
231 
232             static
233             BOOST_QVM_INLINE_CRITICAL
234             scalar_type &
write_element_idxboost::qvm::mat_traits235             write_element_idx( int row, int col, this_matrix & x )
236                 {
237                 BOOST_QVM_ASSERT(row>=0);
238                 BOOST_QVM_ASSERT(row<rows);
239                 BOOST_QVM_ASSERT(col>=0);
240                 BOOST_QVM_ASSERT(col<cols);
241                 return mat_traits<OriginalMatrix>::write_element_idx(row,col+(col>=J),reinterpret_cast<OriginalMatrix &>(x));
242                 }
243             };
244 
245         template <int J,class OriginalMatrix,int R,int C>
246         struct
247         deduce_mat<qvm_detail::del_col_<J,OriginalMatrix>,R,C>
248             {
249             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
250             };
251 
252         template <int J,class OriginalMatrix,int R,int C>
253         struct
254         deduce_mat2<qvm_detail::del_col_<J,OriginalMatrix>,qvm_detail::del_col_<J,OriginalMatrix>,R,C>
255             {
256             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
257             };
258 
259         template <int Col,class A>
260         typename boost::enable_if_c<
261             is_mat<A>::value,
262             qvm_detail::del_col_<Col,A> const &>::type
263         BOOST_QVM_INLINE_TRIVIAL
del_col(A const & a)264         del_col( A const & a )
265             {
266             return reinterpret_cast<typename qvm_detail::del_col_<Col,A> const &>(a);
267             }
268 
269         template <int Col,class A>
270         typename boost::enable_if_c<
271             is_mat<A>::value,
272             qvm_detail::del_col_<Col,A> &>::type
273         BOOST_QVM_INLINE_TRIVIAL
del_col(A & a)274         del_col( A & a )
275             {
276             return reinterpret_cast<typename qvm_detail::del_col_<Col,A> &>(a);
277             }
278 
279         ////////////////////////////////////////////////
280 
281         namespace
282         qvm_detail
283             {
284             template <int Row,int Col,class OriginalMatrix>
285             class
286             del_row_col_
287                 {
288                 del_row_col_( del_row_col_ const & );
289                 ~del_row_col_();
290 
291                 public:
292 
293                 BOOST_QVM_INLINE_TRIVIAL
294                 del_row_col_ &
operator =(del_row_col_ const & x)295                 operator=( del_row_col_ const & x )
296                     {
297                     assign(*this,x);
298                     return *this;
299                     }
300 
301                 template <class T>
302                 BOOST_QVM_INLINE_TRIVIAL
303                 del_row_col_ &
operator =(T const & x)304                 operator=( T const & x )
305                     {
306                     assign(*this,x);
307                     return *this;
308                     }
309 
310                 template <class R>
311                 BOOST_QVM_INLINE_TRIVIAL
operator R() const312                 operator R() const
313                     {
314                     R r;
315                     assign(r,*this);
316                     return r;
317                     }
318                 };
319             }
320 
321         template <int I,int J,class OriginalMatrix>
322         struct
323         mat_traits< qvm_detail::del_row_col_<I,J,OriginalMatrix> >
324             {
325             typedef qvm_detail::del_row_col_<I,J,OriginalMatrix> this_matrix;
326             typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
327             static int const rows=mat_traits<OriginalMatrix>::rows-1;
328             static int const cols=mat_traits<OriginalMatrix>::cols-1;
329 
330             template <int Row,int Col>
331             static
332             BOOST_QVM_INLINE_CRITICAL
333             scalar_type
read_elementboost::qvm::mat_traits334             read_element( this_matrix const & x )
335                 {
336                 BOOST_QVM_STATIC_ASSERT(Row>=0);
337                 BOOST_QVM_STATIC_ASSERT(Row<rows);
338                 BOOST_QVM_STATIC_ASSERT(Col>=0);
339                 BOOST_QVM_STATIC_ASSERT(Col<cols);
340                 return mat_traits<OriginalMatrix>::template read_element<Row+(Row>=I),Col+(Col>=J)>(reinterpret_cast<OriginalMatrix const &>(x));
341                 }
342 
343             template <int Row,int Col>
344             static
345             BOOST_QVM_INLINE_CRITICAL
346             scalar_type &
write_elementboost::qvm::mat_traits347             write_element( this_matrix & x )
348                 {
349                 BOOST_QVM_STATIC_ASSERT(Row>=0);
350                 BOOST_QVM_STATIC_ASSERT(Row<rows);
351                 BOOST_QVM_STATIC_ASSERT(Col>=0);
352                 BOOST_QVM_STATIC_ASSERT(Col<cols);
353                 return mat_traits<OriginalMatrix>::template write_element<Row+(Row>=I),Col+(Col>=J)>(reinterpret_cast<OriginalMatrix &>(x));
354                 }
355 
356             static
357             BOOST_QVM_INLINE_CRITICAL
358             scalar_type
read_element_idxboost::qvm::mat_traits359             read_element_idx( int row, int col, this_matrix const & x )
360                 {
361                 BOOST_QVM_ASSERT(row>=0);
362                 BOOST_QVM_ASSERT(row<rows);
363                 BOOST_QVM_ASSERT(col>=0);
364                 BOOST_QVM_ASSERT(col<cols);
365                 return mat_traits<OriginalMatrix>::read_element_idx(row+(row>=I),col+(col>=J),reinterpret_cast<OriginalMatrix const &>(x));
366                 }
367 
368             static
369             BOOST_QVM_INLINE_CRITICAL
370             scalar_type &
write_element_idxboost::qvm::mat_traits371             write_element_idx( int row, int col, this_matrix & x )
372                 {
373                 BOOST_QVM_ASSERT(row>=0);
374                 BOOST_QVM_ASSERT(row<rows);
375                 BOOST_QVM_ASSERT(col>=0);
376                 BOOST_QVM_ASSERT(col<cols);
377                 return mat_traits<OriginalMatrix>::write_element_idx(row+(row>=I),col+(col>=J),reinterpret_cast<OriginalMatrix &>(x));
378                 }
379             };
380 
381         template <int I,int J,class OriginalMatrix,int R,int C>
382         struct
383         deduce_mat<qvm_detail::del_row_col_<I,J,OriginalMatrix>,R,C>
384             {
385             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
386             };
387 
388         template <int I,int J,class OriginalMatrix,int R,int C>
389         struct
390         deduce_mat2<qvm_detail::del_row_col_<I,J,OriginalMatrix>,qvm_detail::del_row_col_<I,J,OriginalMatrix>,R,C>
391             {
392             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
393             };
394 
395         template <int Row,int Col,class A>
396         typename boost::enable_if_c<
397             is_mat<A>::value,
398             qvm_detail::del_row_col_<Row,Col,A> const &>::type
399         BOOST_QVM_INLINE_TRIVIAL
del_row_col(A const & a)400         del_row_col( A const & a )
401             {
402             return reinterpret_cast<typename qvm_detail::del_row_col_<Row,Col,A> const &>(a);
403             }
404 
405         template <int Row,int Col,class A>
406         typename boost::enable_if_c<
407             is_mat<A>::value,
408             qvm_detail::del_row_col_<Row,Col,A> &>::type
409         BOOST_QVM_INLINE_TRIVIAL
del_row_col(A & a)410         del_row_col( A & a )
411             {
412             return reinterpret_cast<typename qvm_detail::del_row_col_<Row,Col,A> &>(a);
413             }
414 
415         ////////////////////////////////////////////////
416 
417         namespace
418         qvm_detail
419             {
420             template <int Row,class OriginalMatrix>
421             class
422             neg_row_
423                 {
424                 neg_row_( neg_row_ const & );
425                 neg_row_ & operator=( neg_row_ const & );
426                 ~neg_row_();
427 
428                 public:
429 
430                 template <class T>
431                 BOOST_QVM_INLINE_TRIVIAL
432                 neg_row_ &
operator =(T const & x)433                 operator=( T const & x )
434                     {
435                     assign(*this,x);
436                     return *this;
437                     }
438 
439                 template <class R>
440                 BOOST_QVM_INLINE_TRIVIAL
operator R() const441                 operator R() const
442                     {
443                     R r;
444                     assign(r,*this);
445                     return r;
446                     }
447                 };
448             }
449 
450         template <int I,class OriginalMatrix>
451         struct
452         mat_traits< qvm_detail::neg_row_<I,OriginalMatrix> >
453             {
454             typedef qvm_detail::neg_row_<I,OriginalMatrix> this_matrix;
455             typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
456             static int const rows=mat_traits<OriginalMatrix>::rows;
457             static int const cols=mat_traits<OriginalMatrix>::cols;
458 
459             template <int Row,int Col>
460             static
461             BOOST_QVM_INLINE_CRITICAL
462             scalar_type
read_elementboost::qvm::mat_traits463             read_element( this_matrix const & x )
464                 {
465                 BOOST_QVM_STATIC_ASSERT(Row>=0);
466                 BOOST_QVM_STATIC_ASSERT(Row<rows);
467                 BOOST_QVM_STATIC_ASSERT(Col>=0);
468                 BOOST_QVM_STATIC_ASSERT(Col<cols);
469                 return Row==I ?
470                     -mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x)) :
471                     mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x));
472                 }
473 
474             static
475             BOOST_QVM_INLINE_CRITICAL
476             scalar_type
read_element_idxboost::qvm::mat_traits477             read_element_idx( int row, int col, this_matrix const & x )
478                 {
479                 BOOST_QVM_ASSERT(row>=0);
480                 BOOST_QVM_ASSERT(row<rows);
481                 BOOST_QVM_ASSERT(col>=0);
482                 BOOST_QVM_ASSERT(col<cols);
483                 return row==I?
484                     -mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x)) :
485                     mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x));
486                 }
487             };
488 
489         template <int J,class OriginalMatrix,int R,int C>
490         struct
491         deduce_mat<qvm_detail::neg_row_<J,OriginalMatrix>,R,C>
492             {
493             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
494             };
495 
496         template <int J,class OriginalMatrix,int R,int C>
497         struct
498         deduce_mat2<qvm_detail::neg_row_<J,OriginalMatrix>,qvm_detail::neg_row_<J,OriginalMatrix>,R,C>
499             {
500             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
501             };
502 
503         template <int Row,class A>
504         typename boost::enable_if_c<
505             is_mat<A>::value,
506             qvm_detail::neg_row_<Row,A> const &>::type
507         BOOST_QVM_INLINE_TRIVIAL
neg_row(A const & a)508         neg_row( A const & a )
509             {
510             return reinterpret_cast<typename qvm_detail::neg_row_<Row,A> const &>(a);
511             }
512 
513         ////////////////////////////////////////////////
514 
515         namespace
516         qvm_detail
517             {
518             template <int Col,class OriginalMatrix>
519             class
520             neg_col_
521                 {
522                 neg_col_( neg_col_ const & );
523                 neg_col_ & operator=( neg_col_ const & );
524                 ~neg_col_();
525 
526                 public:
527 
528                 template <class T>
529                 BOOST_QVM_INLINE_TRIVIAL
530                 neg_col_ &
operator =(T const & x)531                 operator=( T const & x )
532                     {
533                     assign(*this,x);
534                     return *this;
535                     }
536 
537                 template <class R>
538                 BOOST_QVM_INLINE_TRIVIAL
operator R() const539                 operator R() const
540                     {
541                     R r;
542                     assign(r,*this);
543                     return r;
544                     }
545                 };
546             }
547 
548         template <int J,class OriginalMatrix>
549         struct
550         mat_traits< qvm_detail::neg_col_<J,OriginalMatrix> >
551             {
552             typedef qvm_detail::neg_col_<J,OriginalMatrix> this_matrix;
553             typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
554             static int const rows=mat_traits<OriginalMatrix>::rows;
555             static int const cols=mat_traits<OriginalMatrix>::cols;
556 
557             template <int Row,int Col>
558             static
559             BOOST_QVM_INLINE_CRITICAL
560             scalar_type
read_elementboost::qvm::mat_traits561             read_element( this_matrix const & x )
562                 {
563                 BOOST_QVM_STATIC_ASSERT(Row>=0);
564                 BOOST_QVM_STATIC_ASSERT(Row<rows);
565                 BOOST_QVM_STATIC_ASSERT(Col>=0);
566                 BOOST_QVM_STATIC_ASSERT(Col<cols);
567                 return Col==J?
568                     -mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x)) :
569                     mat_traits<OriginalMatrix>::template read_element<Row,Col>(reinterpret_cast<OriginalMatrix const &>(x));
570                 }
571 
572             static
573             BOOST_QVM_INLINE_CRITICAL
574             scalar_type
read_element_idxboost::qvm::mat_traits575             read_element_idx( int row, int col, this_matrix const & x )
576                 {
577                 BOOST_QVM_ASSERT(row>=0);
578                 BOOST_QVM_ASSERT(row<rows);
579                 BOOST_QVM_ASSERT(col>=0);
580                 BOOST_QVM_ASSERT(col<cols);
581                 return col==J?
582                     -mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x)) :
583                     mat_traits<OriginalMatrix>::read_element_idx(row,col,reinterpret_cast<OriginalMatrix const &>(x));
584                 }
585             };
586 
587         template <int J,class OriginalMatrix,int R,int C>
588         struct
589         deduce_mat<qvm_detail::neg_col_<J,OriginalMatrix>,R,C>
590             {
591             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
592             };
593 
594         template <int J,class OriginalMatrix,int R,int C>
595         struct
596         deduce_mat2<qvm_detail::neg_col_<J,OriginalMatrix>,qvm_detail::neg_col_<J,OriginalMatrix>,R,C>
597             {
598             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
599             };
600 
601         template <int Col,class A>
602         typename boost::enable_if_c<
603             is_mat<A>::value,
604             qvm_detail::neg_col_<Col,A> const &>::type
605         BOOST_QVM_INLINE_TRIVIAL
neg_col(A const & a)606         neg_col( A const & a )
607             {
608             return reinterpret_cast<typename qvm_detail::neg_col_<Col,A> const &>(a);
609             }
610 
611         ////////////////////////////////////////////////
612 
613         template <class A>
614         typename boost::enable_if_c<
615             is_mat<A>::value,
616             qvm_detail::transposed_<A> const &>::type
617         BOOST_QVM_INLINE_TRIVIAL
transposed(A const & a)618         transposed( A const & a )
619             {
620             return reinterpret_cast<typename qvm_detail::transposed_<A> const &>(a);
621             }
622 
623         template <class A>
624         typename boost::enable_if_c<
625             is_mat<A>::value,
626             qvm_detail::transposed_<A> &>::type
627         BOOST_QVM_INLINE_TRIVIAL
transposed(A & a)628         transposed( A & a )
629             {
630             return reinterpret_cast<typename qvm_detail::transposed_<A> &>(a);
631             }
632 
633         ////////////////////////////////////////////////
634 
635         namespace
636         qvm_detail
637             {
638             template <int Row1,int Row2,class OriginalMatrix>
639             class
640             swap_rows_
641                 {
642                 swap_rows_( swap_rows_ const & );
643                 swap_rows_ & operator=( swap_rows_ const & );
644                 ~swap_rows_();
645 
646                 public:
647 
648                 template <class T>
649                 BOOST_QVM_INLINE_TRIVIAL
650                 swap_rows_ &
operator =(T const & x)651                 operator=( T const & x )
652                     {
653                     assign(*this,x);
654                     return *this;
655                     }
656 
657                 template <class R>
658                 BOOST_QVM_INLINE_TRIVIAL
operator R() const659                 operator R() const
660                     {
661                     R r;
662                     assign(r,*this);
663                     return r;
664                     }
665                 };
666             }
667 
668         template <int R1,int R2,class OriginalMatrix>
669         struct
670         mat_traits< qvm_detail::swap_rows_<R1,R2,OriginalMatrix> >
671             {
672             typedef qvm_detail::swap_rows_<R1,R2,OriginalMatrix> this_matrix;
673             typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
674             static int const rows=mat_traits<OriginalMatrix>::rows;
675             static int const cols=mat_traits<OriginalMatrix>::cols;
676 
677             template <int Row,int Col>
678             static
679             BOOST_QVM_INLINE_CRITICAL
680             scalar_type
read_elementboost::qvm::mat_traits681             read_element( this_matrix const & x )
682                 {
683                 BOOST_QVM_STATIC_ASSERT(Row>=0);
684                 BOOST_QVM_STATIC_ASSERT(Row<rows);
685                 BOOST_QVM_STATIC_ASSERT(Col>=0);
686                 BOOST_QVM_STATIC_ASSERT(Col<cols);
687                 return mat_traits<OriginalMatrix>::template read_element<(Row==R1 && R1!=R2)*R2+(Row==R2 && R1!=R2)*R1+((Row!=R1 && Row!=R2) || R1==R2)*Row,Col>(reinterpret_cast<OriginalMatrix const &>(x));
688                 }
689 
690             template <int Row,int Col>
691             static
692             BOOST_QVM_INLINE_CRITICAL
693             scalar_type &
write_elementboost::qvm::mat_traits694             write_element( this_matrix & x )
695                 {
696                 BOOST_QVM_STATIC_ASSERT(Row>=0);
697                 BOOST_QVM_STATIC_ASSERT(Row<rows);
698                 BOOST_QVM_STATIC_ASSERT(Col>=0);
699                 BOOST_QVM_STATIC_ASSERT(Col<cols);
700                 return mat_traits<OriginalMatrix>::template write_element<(Row==R1 && R1!=R2)*R2+(Row==R2 && R1!=R2)*R1+((Row!=R1 && Row!=R2) || R1==R2)*Row,Col>(reinterpret_cast<OriginalMatrix &>(x));
701                 }
702 
703             static
704             BOOST_QVM_INLINE_CRITICAL
705             scalar_type
read_element_idxboost::qvm::mat_traits706             read_element_idx( int row, int col, this_matrix const & x )
707                 {
708                 BOOST_QVM_ASSERT(row>=0);
709                 BOOST_QVM_ASSERT(row<rows);
710                 BOOST_QVM_ASSERT(col>=0);
711                 BOOST_QVM_ASSERT(col<cols);
712                 return mat_traits<OriginalMatrix>::read_element_idx(row==R1?R2:row==R2?R1:row,col,reinterpret_cast<OriginalMatrix const &>(x));
713                 }
714 
715             static
716             BOOST_QVM_INLINE_CRITICAL
717             scalar_type &
write_element_idxboost::qvm::mat_traits718             write_element_idx( int row, int col, this_matrix & x )
719                 {
720                 BOOST_QVM_ASSERT(row>=0);
721                 BOOST_QVM_ASSERT(row<rows);
722                 BOOST_QVM_ASSERT(col>=0);
723                 BOOST_QVM_ASSERT(col<cols);
724                 return mat_traits<OriginalMatrix>::write_element_idx(row==R1?R2:row==R2?R1:row,col,reinterpret_cast<OriginalMatrix &>(x));
725                 }
726             };
727 
728         template <int R1,int R2,class OriginalMatrix,int R,int C>
729         struct
730         deduce_mat<qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,R,C>
731             {
732             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
733             };
734 
735         template <int R1,int R2,class OriginalMatrix,int R,int C>
736         struct
737         deduce_mat2<qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,qvm_detail::swap_rows_<R1,R2,OriginalMatrix>,R,C>
738             {
739             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
740             };
741 
742         template <int R1,int R2,class A>
743         typename boost::enable_if_c<
744             is_mat<A>::value,
745             qvm_detail::swap_rows_<R1,R2,A> const &>::type
746         BOOST_QVM_INLINE_TRIVIAL
swap_rows(A const & a)747         swap_rows( A const & a )
748             {
749             return reinterpret_cast<typename qvm_detail::swap_rows_<R1,R2,A> const &>(a);
750             }
751 
752         template <int R1,int R2,class A>
753         typename boost::enable_if_c<
754             is_mat<A>::value,
755             qvm_detail::swap_rows_<R1,R2,A> &>::type
756         BOOST_QVM_INLINE_TRIVIAL
swap_rows(A & a)757         swap_rows( A & a )
758             {
759             return reinterpret_cast<typename qvm_detail::swap_rows_<R1,R2,A> &>(a);
760             }
761 
762         ////////////////////////////////////////////////
763 
764         namespace
765         qvm_detail
766             {
767             template <int Row1,int Row2,class OriginalMatrix>
768             class
769             swap_cols_
770                 {
771                 swap_cols_( swap_cols_ const & );
772                 swap_cols_ & operator=( swap_cols_ const & );
773                 ~swap_cols_();
774 
775                 public:
776 
777                 template <class T>
778                 BOOST_QVM_INLINE_TRIVIAL
779                 swap_cols_ &
operator =(T const & x)780                 operator=( T const & x )
781                     {
782                     assign(*this,x);
783                     return *this;
784                     }
785 
786                 template <class R>
787                 BOOST_QVM_INLINE_TRIVIAL
operator R() const788                 operator R() const
789                     {
790                     R r;
791                     assign(r,*this);
792                     return r;
793                     }
794                 };
795             }
796 
797         template <int C1,int C2,class OriginalMatrix>
798         struct
799         mat_traits< qvm_detail::swap_cols_<C1,C2,OriginalMatrix> >
800             {
801             typedef qvm_detail::swap_cols_<C1,C2,OriginalMatrix> this_matrix;
802             typedef typename mat_traits<OriginalMatrix>::scalar_type scalar_type;
803             static int const rows=mat_traits<OriginalMatrix>::rows;
804             static int const cols=mat_traits<OriginalMatrix>::cols;
805 
806             template <int Row,int Col>
807             static
808             BOOST_QVM_INLINE_CRITICAL
809             scalar_type
read_elementboost::qvm::mat_traits810             read_element( this_matrix const & x )
811                 {
812                 BOOST_QVM_STATIC_ASSERT(Row>=0);
813                 BOOST_QVM_STATIC_ASSERT(Row<rows);
814                 BOOST_QVM_STATIC_ASSERT(Col>=0);
815                 BOOST_QVM_STATIC_ASSERT(Col<cols);
816                 return mat_traits<OriginalMatrix>::template read_element<Row,(Col==C1 && C1!=C2)*C2+(Col==C2 && C1!=C2)*C1+((Col!=C1 && Col!=C2) || C1==C2)*Col>(reinterpret_cast<OriginalMatrix const &>(x));
817                 }
818 
819             template <int Row,int Col>
820             static
821             BOOST_QVM_INLINE_CRITICAL
822             scalar_type &
write_elementboost::qvm::mat_traits823             write_element( this_matrix & x )
824                 {
825                 BOOST_QVM_STATIC_ASSERT(Row>=0);
826                 BOOST_QVM_STATIC_ASSERT(Row<rows);
827                 BOOST_QVM_STATIC_ASSERT(Col>=0);
828                 BOOST_QVM_STATIC_ASSERT(Col<cols);
829                 return mat_traits<OriginalMatrix>::template write_element<Row,(Col==C1 && C1!=C2)*C2+(Col==C2 && C1!=C2)*C1+((Col!=C1 && Col!=C2) || C1==C2)*Col>(reinterpret_cast<OriginalMatrix &>(x));
830                 }
831 
832             static
833             BOOST_QVM_INLINE_CRITICAL
834             scalar_type
read_element_idxboost::qvm::mat_traits835             read_element_idx( int row, int col, this_matrix const & x )
836                 {
837                 BOOST_QVM_ASSERT(row>=0);
838                 BOOST_QVM_ASSERT(row<rows);
839                 BOOST_QVM_ASSERT(col>=0);
840                 BOOST_QVM_ASSERT(col<cols);
841                 return mat_traits<OriginalMatrix>::read_element_idx(row,col==C1?C2:col==C2?C1:col,reinterpret_cast<OriginalMatrix const &>(x));
842                 }
843 
844             static
845             BOOST_QVM_INLINE_CRITICAL
846             scalar_type &
write_element_idxboost::qvm::mat_traits847             write_element_idx( int row, int col, this_matrix & x )
848                 {
849                 BOOST_QVM_ASSERT(row>=0);
850                 BOOST_QVM_ASSERT(row<rows);
851                 BOOST_QVM_ASSERT(col>=0);
852                 BOOST_QVM_ASSERT(col<cols);
853                 return mat_traits<OriginalMatrix>::write_element_idx(row,col==C1?C2:col==C2?C1:col,reinterpret_cast<OriginalMatrix &>(x));
854                 }
855             };
856 
857         template <int C1,int C2,class OriginalMatrix,int R,int C>
858         struct
859         deduce_mat<qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,R,C>
860             {
861             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
862             };
863 
864         template <int C1,int C2,class OriginalMatrix,int R,int C>
865         struct
866         deduce_mat2<qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,qvm_detail::swap_cols_<C1,C2,OriginalMatrix>,R,C>
867             {
868             typedef mat<typename mat_traits<OriginalMatrix>::scalar_type,R,C> type;
869             };
870 
871         template <int C1,int C2,class A>
872         typename boost::enable_if_c<
873             is_mat<A>::value,
874             qvm_detail::swap_cols_<C1,C2,A> const &>::type
875         BOOST_QVM_INLINE_TRIVIAL
swap_cols(A const & a)876         swap_cols( A const & a )
877             {
878             return reinterpret_cast<typename qvm_detail::swap_cols_<C1,C2,A> const &>(a);
879             }
880 
881         template <int C1,int C2,class A>
882         typename boost::enable_if_c<
883             is_mat<A>::value,
884             qvm_detail::swap_cols_<C1,C2,A> &>::type
885         BOOST_QVM_INLINE_TRIVIAL
swap_cols(A & a)886         swap_cols( A & a )
887             {
888             return reinterpret_cast<typename qvm_detail::swap_cols_<C1,C2,A> &>(a);
889             }
890 
891         ////////////////////////////////////////////////
892         }
893     }
894 
895 #endif
896