SeExpr
Vec.h
Go to the documentation of this file.
1/*
2 Copyright Disney Enterprises, Inc. All rights reserved.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License
6 and the following modification to it: Section 6 Trademarks.
7 deleted and replaced with:
8
9 6. Trademarks. This License does not grant permission to use the
10 trade names, trademarks, service marks, or product names of the
11 Licensor and its affiliates, except as required for reproducing
12 the content of the NOTICE file.
13
14 You may obtain a copy of the License at
15 http://www.apache.org/licenses/LICENSE-2.0
16*/
17#ifndef _vectest2_h_
18#define _vectest2_h_
19#include <iosfwd>
20#include <cstdlib>
21#include <cmath>
22#include <iostream>
23#include "Platform.h"
24
25// To fix differences in template TYPENAME resolution between MSVC and other compilers
26#if defined(WINDOWS)
27# define TYPENAME
28#else
29# define TYPENAME typename
30#endif
31
32//#############################################################################
33// Template Metaprogramming Helpers
34namespace SeExpr2 {
36template <bool b, class T>
39template <class T>
40struct seexpr_static_assert<true, T> {
41 typedef T TYPE;
42};
43
45template <bool c, class T = void>
47 typedef T TYPE;
48};
50template <class T>
51struct my_enable_if<false, T> {
52#if defined(WINDOWS)
53 typedef void TYPE;
54#endif
55};
56
58template <bool c, class T1, class T2>
59struct static_if {
60 typedef T1 TYPE;
61};
63template <class T1, class T2>
64struct static_if<false, T1, T2> {
65 typedef T2 TYPE;
66};
67
68//#############################################################################
69// Reduction class (helps prevent linear data dependency on reduce unroll)
70template <class T, int d>
71struct Reducer {
72 static T sum(T* data) {
73 T sum = 0;
74 for (int k = 0; k < d; k++) sum += data[k];
75 return sum;
76 }
77};
78template <class T>
79struct Reducer<T, 1> {
80 static T sum(T* data) { return data[0]; }
81};
82template <class T>
83struct Reducer<T, 2> {
84 static T sum(T* data) { return data[0] + data[1]; }
85};
86template <class T>
87struct Reducer<T, 3> {
88 static T sum(T* data) { return data[0] + data[1] + data[2]; }
89};
90template <class T>
91struct Reducer<T, 4> {
92 static T sum(T* data) { return (data[0] + data[1]) + (data[2] + data[3]); }
93};
94
97template <class T, int d, bool ref = false>
98class Vec {
99 // static error types
103
106
107 public:
110
112 template <class T2>
113 static Vec<T, d, false> copy(T2* raw,
117 for (int k = 0; k < d; k++) ret[k] = static_cast<T>(raw[k]);
118 return ret;
119 }
120
124
127
130 for (int k = 0; k < d; k++) x[k] = v0;
131 }
132
141
152
154 Vec(T v1,
155 T v2,
156 T v3,
157 T v4,
160 x[0] = v1;
161 x[1] = v2;
162 x[2] = v3;
163 x[3] = v4;
164 }
165 // Changed this to default. This is safe! for reference case it makes another reference
166 // for value it copies
168 // Vec(const Vec&)
169 //{TYPENAME static_assert<!ref,INVALID_WITH_VECTOR_REFERENCE>::TYPE();}
170
172 template <class T2, bool refother>
178
179 template <class T2, bool refother>
181 for (int k = 0; k < d; k++) x[k] = other[k];
182 return *this;
183 }
184
185 template <class Tother, bool refother>
186 bool operator==(const Vec<Tother, d, refother>& other) const {
187 for (int k = 0; k < d; k++)
188 if (x[k] != other[k]) return false;
189 return true;
190 }
191
192 template <class Tother, bool refother>
193 bool operator!=(const Vec<Tother, d, refother>& other) const {
194 return !(*this != other);
195 }
196
197 // non-const element access
198 T& operator[](const int i) { return x[i]; }
199
200 // const element access
201 const T& operator[](const int i) const { return x[i]; }
202
204 T length2() const {
205 T data[d];
206 for (int k = 0; k < d; k++) data[k] = x[k] * x[k];
207 return Reducer<T, d>::sum(data);
208 }
209
211 T length() const { return sqrt(length2()); }
212
215 T l = length2();
216 if (l) {
217 l = sqrt(l);
218 *this /= l;
219 } else {
220 *this = T_VEC_VALUE((T)0);
221 x[0] = 1;
222 }
223 return l;
224 }
225
228 Vec<T, d, false> other(*this);
229 other.normalize();
230 return other;
231 }
232
233 Vec& operator/=(const T val) {
234 T one_over_val = T(1) / val;
235 for (int k = 0; k < d; k++) x[k] *= one_over_val;
236 return *this;
237 }
238
239 Vec& operator*=(const T val) {
240 for (int k = 0; k < d; k++) x[k] *= val;
241 return *this;
242 }
243
244 template <bool refother>
246 for (int k = 0; k < d; k++) x[k] += other[k];
247 return *this;
248 }
249
250 template <bool refother>
252 for (int k = 0; k < d; k++) x[k] -= other[k];
253 return *this;
254 }
255
256 template <bool refother>
258 for (int k = 0; k < d; k++) x[k] *= other[k];
259 return *this;
260 }
261
262 template <bool refother>
264 for (int k = 0; k < d; k++) x[k] /= other[k];
265 return *this;
266 }
267
269 T_VEC_VALUE val(*this);
270 for (int k = 0; k < d; k++) val[k] = -val[k];
271 return val;
272 }
273
274 template <bool refother>
275 bool operator==(const Vec<T, d, refother>& other) const {
276 bool equal = true;
277 for (int k = 0; k < d; k++) equal &= (x[k] == other[k]);
278 return equal;
279 }
280
281 template <bool refother>
282 bool operator!=(const Vec<T, d, refother>& other) const {
283 return !(*this == other);
284 }
285
287 T_VEC_VALUE val(*this);
288 val *= s;
289 return val;
290 }
291
293 T_VEC_VALUE val(*this);
294 val /= s;
295 return val;
296 }
297
298 template <bool refother>
300 T_VEC_VALUE val(*this);
301 val += other;
302 return val;
303 }
304
305 template <bool refother>
307 T_VEC_VALUE val(*this);
308 val -= other;
309 return val;
310 }
311
312 template <bool refother>
314 T_VEC_VALUE val(*this);
315 val *= other;
316 return val;
317 }
318
319 template <bool refother>
321 T_VEC_VALUE val(*this);
322 val /= other;
323 return val;
324 }
325
326 friend T_VEC_VALUE operator*(T s, const Vec& v) { return v * s; }
327
329 template <bool refother>
330 T dot(const Vec<T, d, refother>& o) const {
331 T data[d];
332 for (int k = 0; k < d; k++) data[k] = x[k] * o[k];
333 return Reducer<T, d>::sum(data);
334 }
335
337 template <bool refother>
340 return T_VEC_VALUE(x[1] * o[2] - x[2] * o[1], x[2] * o[0] - x[0] * o[2], x[0] * o[1] - x[1] * o[0]);
341 }
342
346 return T_VEC_VALUE(x[1] + x[2], x[2] - x[0], -x[0] - x[1]);
347 }
348
353 template <bool refother>
354 T angle(const Vec<T, 3, refother>& o) const {
356 T l = length() * o.length();
357 if (l == 0) return 0;
358 return acos(dot(o) / l);
359 }
360
365 template <bool refother>
368 double c = cos(angle), s = sin(angle);
369 return c * (*this) + (1 - c) * dot(axis) * axis - s * cross(axis);
370 }
371};
372
374template <class T, int d, bool r>
375std::ostream& operator<<(std::ostream& out, const Vec<T, d, r>& val) {
376 if (d > 0) out << "(" << val[0];
377 for (int k = 1; k < d; k++) out << "," << val[k];
378 out << ")";
379 return out;
380}
381
406}
407#endif
Platform-specific classes, functions, and includes.
#define TYPENAME
Definition Vec.h:29
bool operator==(const Vec< Tother, d, refother > &other) const
Definition Vec.h:186
T length() const
Euclidean (2) norm.
Definition Vec.h:211
Vec & operator/=(const T val)
Definition Vec.h:233
Vec< T, d, false > T_VEC_VALUE
Definition Vec.h:108
T dot(const Vec< T, d, refother > &o) const
Definition Vec.h:330
T_VEC_VALUE operator-() const
Definition Vec.h:268
Vec< T, d, false > normalized() const
Return a copy of the vector that is normalized.
Definition Vec.h:227
Vec(INVALID_WITH_VECTOR_REFERENCE u=(TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Empty constructor (this is invalid for a reference type)
Definition Vec.h:126
const T & operator[](const int i) const
Definition Vec.h:201
friend T_VEC_VALUE operator*(T s, const Vec &v)
Definition Vec.h:326
T_VEC_VALUE operator*(const Vec< T, d, refother > &other) const
Definition Vec.h:313
Vec & operator=(const Vec< T2, d, refother > &other)
Definition Vec.h:180
T & operator[](const int i)
Definition Vec.h:198
T_VEC_VALUE operator-(const Vec< T, d, refother > &other) const
Definition Vec.h:306
Vec & operator-=(const Vec< T, d, refother > &other)
Definition Vec.h:251
T_VEC_VALUE orthogonal() const
Definition Vec.h:344
T angle(const Vec< T, 3, refother > &o) const
Definition Vec.h:354
Vec & operator*=(const T val)
Definition Vec.h:239
Vec & operator/=(const Vec< T, d, refother > &other)
Definition Vec.h:263
Vec(T v1, T v2, INVALID_WITH_VECTOR_REFERENCE u=(TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Convenience 2 vector initialization (only for d==2)
Definition Vec.h:134
T normalize()
Normalize in place and return the 2-norm before normalization.
Definition Vec.h:214
static Vec< T, d, false > copy(T2 *raw, INVALID_WITH_VECTOR_REFERENCE u=(TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Initialize vector value using raw memory.
Definition Vec.h:113
T_VEC_VALUE cross(const Vec< T, 3, refother > &o) const
Definition Vec.h:338
T length2() const
Square of euclidean (2) norm.
Definition Vec.h:204
Vec(T v0, INVALID_WITH_VECTOR_REFERENCE u=(TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Convenience constant vector initialization (valid for any d)
Definition Vec.h:129
Vec & operator+=(const Vec< T, d, refother > &other)
Definition Vec.h:245
bool operator!=(const Vec< Tother, d, refother > &other) const
Definition Vec.h:193
Vec(T v1, T v2, T v3, INVALID_WITH_VECTOR_REFERENCE u=(TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Convenience 3 vector initialization (only for d==3)
Definition Vec.h:143
Vec< T, d, true > T_VEC_REF
Definition Vec.h:109
Vec & operator*=(const Vec< T, d, refother > &other)
Definition Vec.h:257
bool operator==(const Vec< T, d, refother > &other) const
Definition Vec.h:275
Vec(T v1, T v2, T v3, T v4, INVALID_WITH_VECTOR_REFERENCE u=(TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Convenience 4 vector initialization (only for d==4)
Definition Vec.h:154
T_VEC_VALUE operator/(const Vec< T, d, refother > &other) const
Definition Vec.h:320
T_VEC_VALUE operator/(T s) const
Definition Vec.h:292
bool operator!=(const Vec< T, d, refother > &other) const
Definition Vec.h:282
static_if< ref, T *, T[d]>::TYPE x
internal data (either an explicit arary or a pointer to raw data)
Definition Vec.h:105
T_VEC_VALUE rotateBy(const Vec< T, 3, refother > &axis, T angle) const
Definition Vec.h:366
T_VEC_VALUE operator+(const Vec< T, d, refother > &other) const
Definition Vec.h:299
Vec(T *raw, INVALID_WITH_VECTOR_VALUE u=(TYPENAME my_enable_if< ref, INVALID_WITH_VECTOR_VALUE >::TYPE()))
Initialize vector to be reference to plain raw data.
Definition Vec.h:122
T_VEC_VALUE operator*(T s) const
Definition Vec.h:286
Vec(const Vec< T2, d, refother > &other, INVALID_WITH_VECTOR_REFERENCE u=(TYPENAME my_enable_if<!ref &&refother !=ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Copy construct. Only valid if we are not going to be a reference data!
Definition Vec.h:173
std::ostream & operator<<(std::ostream &out, const Vec< T, d, r > &val)
Output stream.
Definition Vec.h:375
static T sum(T *data)
Definition Vec.h:80
static T sum(T *data)
Definition Vec.h:84
static T sum(T *data)
Definition Vec.h:88
static T sum(T *data)
Definition Vec.h:92
static T sum(T *data)
Definition Vec.h:72
Enable_if success case (can find the type TYPE)
Definition Vec.h:46
Static assert error case (false)
Definition Vec.h:37
Static conditional type true case.
Definition Vec.h:59
* sin(val)/val" </pre> we would get <pre> | | | | | </pre> or if we did <pre> ./asciiGraph "x-3" </pre> we'd get <pre> | | ------------------------------|----------------- | | | | | </pre> <h2>Implement the subclass</h2> First we subclass Expression and give it a const ructor