2 // { dg-options "-fpic" { target fpic } }
4 typedef __SIZE_TYPE__ size_t;
6 template <typename NumType>
9 absolute(NumType const& x)
11 if (x < NumType(0)) return -x;
15 class trivial_accessor
18 typedef size_t index_type;
19 struct index_value_type {};
21 trivial_accessor() : size_(0) {}
23 trivial_accessor(size_t const& n) : size_(n) {}
25 size_t size_1d() const { return size_; }
33 template <typename ElementType,
34 typename AccessorType = trivial_accessor>
38 typedef ElementType value_type;
39 typedef size_t size_type;
41 typedef AccessorType accessor_type;
42 typedef typename accessor_type::index_type index_type;
43 typedef typename accessor_type::index_value_type index_value_type;
47 const_ref(const ElementType* begin, accessor_type const& accessor)
48 : begin_(begin), accessor_(accessor)
53 const_ref(const ElementType* begin, index_value_type const& n0)
54 : begin_(begin), accessor_(n0)
59 const_ref(const ElementType* begin, index_value_type const& n0,
60 index_value_type const& n1)
61 : begin_(begin), accessor_(n0, n1)
66 const_ref(const ElementType* begin, index_value_type const& n0,
67 index_value_type const& n1,
68 index_value_type const& n2)
69 : begin_(begin), accessor_(n0, n1, n2)
74 accessor_type const& accessor() const { return accessor_; }
75 size_type size() const { return size_; }
77 const ElementType* begin() const { return begin_; }
78 const ElementType* end() const { return end_; }
81 operator[](size_type i) const { return begin_[i]; }
83 const_ref<ElementType>
86 return const_ref<ElementType>(begin_, size_);
93 size_ = accessor_.size_1d();
94 end_ = begin_ + size_;
97 const ElementType* begin_;
98 accessor_type accessor_;
100 const ElementType* end_;
104 template <typename ElementType,
105 typename AccessorType = trivial_accessor>
106 class ref : public N0::const_ref<ElementType, AccessorType>
109 typedef ElementType value_type;
110 typedef size_t size_type;
112 typedef N0::const_ref<ElementType, AccessorType> base_class;
113 typedef AccessorType accessor_type;
114 typedef typename accessor_type::index_type index_type;
119 begin() const { return const_cast<ElementType*>(this->begin_); }
122 end() const { return const_cast<ElementType*>(this->end_); }
125 operator[](size_type i) const { return begin()[i]; }
129 template <typename ElementType, size_t N>
133 typedef ElementType value_type;
134 typedef size_t size_type;
136 static const size_t fixed_size=N;
138 ElementType elems[N];
142 static size_type size() { return N; }
144 ElementType* begin() { return elems; }
145 const ElementType* begin() const { return elems; }
146 ElementType* end() { return elems+N; }
147 const ElementType* end() const { return elems+N; }
148 ElementType& operator[](size_type i) { return elems[i]; }
149 ElementType const& operator[](size_type i) const { return elems[i]; }
152 template <typename ElementType, size_t N>
153 class tiny : public tiny_plain<ElementType, N>
156 typedef ElementType value_type;
157 typedef size_t size_type;
159 typedef tiny_plain<ElementType, N> base_class;
165 template <typename NumType>
166 class mat3 : public N1::tiny_plain<NumType, 9>
169 typedef typename N1::tiny_plain<NumType, 9> base_type;
172 mat3(NumType const& e00, NumType const& e01, NumType const& e02,
173 NumType const& e10, NumType const& e11, NumType const& e12,
174 NumType const& e20, NumType const& e21, NumType const& e22)
175 : base_type(e00, e01, e02, e10, e11, e12, e20, e21, e22)
177 mat3(base_type const& a)
182 operator()(size_t r, size_t c) const
184 return this->elems[r * 3 + c];
187 operator()(size_t r, size_t c)
189 return this->elems[r * 3 + c];
195 mat3 const& m = *this;
196 return m[0] + m[4] + m[8];
202 mat3 const& m = *this;
203 return m[0] * (m[4] * m[8] - m[5] * m[7])
204 - m[1] * (m[3] * m[8] - m[5] * m[6])
205 + m[2] * (m[3] * m[7] - m[4] * m[6]);
209 template <typename NumType>
212 operator-(mat3<NumType> const& v)
214 mat3<NumType> result;
215 for(size_t i=0;i<9;i++) {
221 class mat_grid : public N1::tiny<size_t, 2>
224 typedef N1::tiny<size_t, 2> index_type;
225 typedef index_type::value_type index_value_type;
227 mat_grid() { this->elems[0]=0; this->elems[1]=0; }
229 mat_grid(index_type const& n) : index_type(n) {}
231 mat_grid(index_value_type const& n0, index_value_type const& n1)
232 { this->elems[0]=n0; this->elems[1]=n1; }
234 size_t size_1d() const { return elems[0] * elems[1]; }
237 operator()(index_value_type const& r, index_value_type const& c) const
239 return r * elems[1] + c;
243 template <typename NumType, typename AccessorType = mat_grid>
244 class mat_const_ref : public N0::const_ref<NumType, AccessorType>
247 typedef AccessorType accessor_type;
248 typedef typename N0::const_ref<NumType, AccessorType> base_type;
249 typedef typename accessor_type::index_value_type index_value_type;
253 mat_const_ref(const NumType* begin, accessor_type const& grid)
254 : base_type(begin, grid)
257 mat_const_ref(const NumType* begin, index_value_type const& n_rows,
258 index_value_type const& n_columns)
259 : base_type(begin, accessor_type(n_rows, n_columns))
263 grid() const { return this->accessor(); }
265 index_value_type const&
266 n_rows() const { return this->accessor()[0]; }
268 index_value_type const&
269 n_columns() const { return this->accessor()[1]; }
272 operator()(index_value_type const& r, index_value_type const& c) const
274 return this->begin()[this->accessor()(r, c)];
278 template <typename NumType, typename AccessorType = mat_grid>
279 class mat_ref : public mat_const_ref<NumType, AccessorType>
282 typedef AccessorType accessor_type;
283 typedef mat_const_ref<NumType, AccessorType> base_type;
284 typedef typename accessor_type::index_value_type index_value_type;
288 mat_ref(NumType* begin, accessor_type const& grid)
289 : base_type(begin, grid)
292 mat_ref(NumType* begin, index_value_type n_rows,
293 index_value_type n_columns)
294 : base_type(begin, accessor_type(n_rows, n_columns))
298 begin() const { return const_cast<NumType*>(this->begin_); }
301 end() const { return const_cast<NumType*>(this->end_); }
304 operator[](index_value_type const& i) const { return begin()[i]; }
307 operator()(index_value_type const& r, index_value_type const& c) const
309 return this->begin()[this->accessor()(r, c)];
313 template <typename AnyType>
315 swap(AnyType* a, AnyType* b, size_t n)
317 for(size_t i=0;i<n;i++) {
318 AnyType t = a[i]; a[i] = b[i]; b[i] = t;
322 template <typename IntType>
324 form_t(mat_ref<IntType>& m,
325 mat_ref<IntType> const& t)
327 typedef size_t size_t;
328 size_t mr = m.n_rows();
329 size_t mc = m.n_columns();
330 size_t tc = t.n_columns();
334 for (i = j = 0; i < mr && j < mc;) {
335 size_t k = i; while (k < mr && m(k,j) == 0) k++;
340 swap(&m(i,0), &m(k,0), mc);
341 if (tc) swap(&t(i,0), &t(k,0), tc);
343 for (k++; k < mr; k++) {
344 IntType a = absolute(m(k, j));
345 if (a != 0 && a < absolute(m(i,j))) {
346 swap(&m(i,0), &m(k,0), mc);
347 if (tc) swap(&t(i,0), &t(k,0), tc);
351 for(size_t ic=0;ic<mc;ic++) m(i,ic) *= -1;
352 if (tc) for(size_t ic=0;ic<tc;ic++) t(i,ic) *= -1;
355 for (k = i+1; k < mr; k++) {
356 IntType a = m(k,j) / m(i,j);
358 for(size_t ic=0;ic<mc;ic++) m(k,ic) -= a * m(i,ic);
359 if (tc) for(size_t ic=0;ic<tc;ic++) t(k,ic) -= a * t(i,ic);
361 if (m(k,j) != 0) cleared = false;
363 if (cleared) { i++; j++; }
366 m = mat_ref<IntType>(m.begin(), i, mc);
370 template <typename IntType>
372 form(mat_ref<IntType>& m)
374 mat_ref<IntType> t(0,0,0);
378 typedef mat3<int> sg_mat3;
384 rot_mx(sg_mat3 const& m, int denominator=1)
385 : num_(m), den_(denominator)
389 num() const { return num_; }
391 num() { return num_; }
394 operator[](size_t i) const { return num_[i]; }
396 operator[](size_t i) { return num_[i]; }
399 const& operator()(int r, int c) const { return num_(r, c); }
401 operator()(int r, int c) { return num_(r, c); }
404 den() const { return den_; }
406 den() { return den_; }
409 minus_unit_mx() const
411 rot_mx result(*this);
412 for (size_t i=0;i<9;i+=4) result[i] -= den_;
417 operator-() const { return rot_mx(-num_, den_); }
423 order(int type=0) const;
433 rot_mx_info(rot_mx const& r);
435 int type() const { return type_; }
441 int rot_mx::type() const
443 int det = num_.determinant();
444 if (det == -1 || det == 1) {
445 switch (num_.trace()) {
448 case -1: if (det == -1) return -4;
450 case 0: if (det == -1) return -3;
452 case 1: if (det == -1) return -2;
461 int rot_mx::order(int type) const
463 if (type == 0) type = rot_mx::type();
464 if (type > 0) return type;
465 if (type % 2) return -type * 2;
469 rot_mx_info::rot_mx_info(rot_mx const& r)
476 int proper_order = type_;
477 // THE PROBLEM IS AROUND HERE
478 if (proper_order < 0) {
480 proper_r = -proper_r; // THIS FAILS ...
482 if (proper_order > 1) {
483 rot_mx rmi = proper_r.minus_unit_mx(); // ... THEREFORE WRONG HERE
484 mat_ref<int> re_mx(rmi.num().begin(), 3, 3);
485 if (form(re_mx) != 2) {
494 e[0] = 1; e[1] = 0; e[2] = 0;
495 e[3] = 0; e[4] = -1; e[5] = 0;
496 e[6] = 0; e[7] = 0; e[8] = 1;