Added static_assert from Loki
[ustl.git] / umatrix.h
blob1c99c792382fe6684d7c9563e11b7ab504f28f5b
1 // This file is part of the ustl library, an STL implementation.
2 //
3 // Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
4 // This file is free software, distributed under the MIT License.
5 //
6 // umatrix.h
7 //
9 #ifndef UMATRIX_H_740EBFEF554E833645E0FD72419A8185
10 #define UMATRIX_H_740EBFEF554E833645E0FD72419A8185
12 #include "utuple.h"
14 namespace ustl {
16 /// \class matrix umatrix.h ustl.h
17 /// \ingroup Sequences
18 ///
19 /// \brief A two-dimensional array of NX*NY elements of type T.
20 ///
21 template <size_t NX, size_t NY, typename T>
22 class matrix : public tuple<NX*NY,T> {
23 public:
24 typedef tuple<NX,T> row_type;
25 typedef tuple<NY,T> column_type;
26 typedef tuple<NX*NY,T> tuple_type;
27 typedef typename tuple_type::value_type value_type;
28 typedef typename tuple_type::size_type size_type;
29 typedef typename tuple_type::pointer pointer;
30 typedef typename tuple_type::const_pointer const_pointer;
31 typedef typename tuple_type::reference reference;
32 typedef typename tuple_type::const_reference const_reference;
33 typedef typename tuple_type::iterator iterator;
34 typedef typename tuple_type::const_iterator const_iterator;
35 typedef typename tuple_type::range_t range_t;
36 typedef typename tuple_type::const_range_t const_range_t;
37 typedef typename tuple_type::reverse_iterator reverse_iterator;
38 typedef typename tuple_type::const_reverse_iterator const_reverse_iterator;
39 public:
40 inline matrix (void) { }
41 inline size_type columns (void) const { return (NX); }
42 inline size_type rows (void) const { return (NY); }
43 inline const_iterator at (size_type i) const { return (matrix::begin() + i * NX); }
44 inline iterator at (size_type i) { return (matrix::begin() + i * NX); }
45 inline const_iterator operator[] (size_type i) const { return (at (i)); }
46 inline iterator operator[] (size_type i) { return (at (i)); }
47 inline row_type row (size_type r) const { return (row_type (at (r))); }
48 inline column_type column (size_type c) const;
49 template <typename T2>
50 inline const matrix& operator= (const matrix<NX,NY,T2>& src) { tuple_type::operator= (src); return (*this); }
51 inline const matrix& operator= (const matrix<NX,NY,T>& src) { tuple_type::operator= (src); return (*this); }
52 inline const matrix& operator+= (const_reference v) { tuple_type::operator+= (v); return (*this); }
53 inline const matrix& operator-= (const_reference v) { tuple_type::operator-= (v); return (*this); }
54 inline const matrix& operator*= (const_reference v) { tuple_type::operator*= (v); return (*this); }
55 inline const matrix& operator/= (const_reference v) { tuple_type::operator/= (v); return (*this); }
56 inline const matrix operator+ (const_reference v) const
57 { matrix result (*this); result += v; return (result); }
58 inline const matrix operator- (const_reference v) const
59 { matrix result (*this); result -= v; return (result); }
60 inline const matrix operator* (const_reference v) const
61 { matrix result (*this); result *= v; return (result); }
62 inline const matrix operator/ (const_reference v) const
63 { matrix result (*this); result /= v; return (result); }
66 template <size_t NX, size_t NY, typename T>
67 inline typename matrix<NX,NY,T>::column_type matrix<NX,NY,T>::column (size_type c) const
69 column_type result;
70 const_iterator src (matrix::begin() + c);
71 iterator dest (result.begin());
72 for (uoff_t i = 0; i < NY; ++ i, ++ dest, src += NX)
73 *dest = *src;
74 return (result);
77 //----------------------------------------------------------------------
78 // Define SIMD specializations for member functions.
80 #if CPU_HAS_SSE
81 #define MATRIX_R(v) "m"(v[0]),"m"(v[4]),"m"(v[8]),"m"(v[12])
82 #define MATRIX_W(v) "=m"(v[0]),"=m"(v[4]),"=m"(v[8]),"=m"(v[12])
83 #define SSE_TUPLE_SPECS(n,type) \
84 template <> inline tuple<n,type>::tuple (void) \
85 { asm volatile ("xorps %%xmm0, %%xmm0\n\t" \
86 "movups %%xmm0, %0\n\t" \
87 "movups %%xmm0, %1\n\t" \
88 "movups %%xmm0, %2\n\t" \
89 "movups %%xmm0, %3" \
90 : MATRIX_W(m_v) ::"xmm0","memory"); \
91 } \
92 template<> inline void tuple<n,type>::swap (tuple<n,type>& v) \
93 { asm volatile ("movups %0, %%xmm0\n\t" \
94 "movups %1, %%xmm1\n\t" \
95 "movups %2, %%xmm2\n\t" \
96 "movups %3, %%xmm3\n\t" \
97 "movups %4, %%xmm4\n\t" \
98 "movups %5, %%xmm5\n\t" \
99 "movups %6, %%xmm6\n\t" \
100 "movups %7, %%xmm7" \
101 : : MATRIX_R(m_v), MATRIX_R(v.m_v) \
102 : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "memory");\
103 asm volatile ("movups %%xmm0, %0\n\t" \
104 "movups %%xmm1, %1\n\t" \
105 "movups %%xmm2, %2\n\t" \
106 "movups %%xmm3, %3\n\t" \
107 "movups %%xmm4, %4\n\t" \
108 "movups %%xmm5, %5\n\t" \
109 "movups %%xmm6, %6\n\t" \
110 "movups %%xmm7, %7" \
111 : MATRIX_W(v.m_v), MATRIX_W(m_v) \
112 : : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "memory");\
114 namespace simd { \
115 SIMD_PASSIGN_SPEC(n,type) \
116 { asm volatile ("movups %4, %%xmm0\n\t" \
117 "movups %5, %%xmm1\n\t" \
118 "movups %6, %%xmm2\n\t" \
119 "movups %7, %%xmm3\n\t" \
120 "movups %%xmm0, %0\n\t" \
121 "movups %%xmm1, %1\n\t" \
122 "movups %%xmm2, %2\n\t" \
123 "movups %%xmm3, %3" \
124 : MATRIX_W(oout) : MATRIX_R(oin) \
125 : "xmm0", "xmm1", "xmm2", "xmm3", "memory"); \
128 SSE_TUPLE_SPECS(16,float)
129 SSE_TUPLE_SPECS(16,int32_t)
130 SSE_TUPLE_SPECS(16,uint32_t)
131 #undef SSE_TUPLE_SPECS
132 #undef TOUCH_MATRIX_R
133 #undef TOUCH_MATRIX_W
134 #undef MATRIX_R
135 #undef MATRIX_W
136 #endif
138 } // namespace ustl
140 #endif