28 template <
bool b,
class T>
37 template <
bool c,
class T =
void>
46 template <
bool c,
class T1,
class T2>
51 template <
class T1,
class T2>
58 template <
class T,
int d>
60 static T
sum(T* data) {
62 for (
int k = 0; k < d; k++) sum += data[k];
68 static T
sum(T* data) {
return data[0]; }
72 static T
sum(T* data) {
return data[0] + data[1]; }
76 static T
sum(T* data) {
return data[0] + data[1] + data[2]; }
80 static T
sum(T* data) {
return (data[0] + data[1]) + (data[2] + data[3]); }
85 template <
class T,
int d,
bool ref = false>
103 for(
int k=0;k<d;k++) ret[k]=static_cast<T>(raw[k]);
116 for (
int k = 0; k < d; k++)
x[k] = v0;
158 template <
class T2,
bool refother>
160 INVALID_WITH_VECTOR_REFERENCE u =
165 template <
class T2,
bool refother>
167 for (
int k = 0; k < d; k++)
x[k] = other[k];
171 template<
class Tother,
bool refother>
173 for(
int k=0;k<d;k++)
if(
x[k] != other[k])
return false;
177 template<
class Tother,
bool refother>
189 for (
int k = 0; k < d; k++) data[k] =
x[k] *
x[k];
217 T one_over_val = T(1) / val;
218 for (
int k = 0; k < d; k++)
x[k] *= one_over_val;
223 for (
int k = 0; k < d; k++)
x[k] *= val;
227 template <
bool refother>
229 for (
int k = 0; k < d; k++)
x[k] += other[k];
233 template <
bool refother>
235 for (
int k = 0; k < d; k++)
x[k] -= other[k];
239 template <
bool refother>
241 for (
int k = 0; k < d; k++)
x[k] *= other[k];
245 template <
bool refother>
247 for (
int k = 0; k < d; k++)
x[k] /= other[k];
253 for (
int k = 0; k < d; k++) val[k] = -val[k];
257 template <
bool refother>
260 for (
int k = 0; k < d; k++) equal &= (
x[k] == other[k]);
264 template <
bool refother>
266 return !(*
this == other);
281 template <
bool refother>
288 template <
bool refother>
295 template <
bool refother>
302 template <
bool refother>
312 template <
bool refother>
315 for (
int k = 0; k < d; k++) data[k] =
x[k] * o[k];
320 template <
bool refother>
323 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]);
336 template <
bool refother>
340 if (l == 0)
return 0;
341 return acos(
dot(o) / l);
348 template <
bool refother>
351 double c = cos(angle), s =
sin(angle);
352 return c * (*this) + (1 - c) *
dot(axis) * axis - s *
cross(axis);
358 template <
class T,
int d,
bool r>
359 std::ostream& operator<<(std::ostream& out, const Vec<T, d, r>& val) {
360 if (d > 0) out <<
"(" << val[0];
361 for (
int k = 1; k < d; k++) out <<
"," << val[k];
Vec< T, d, true > T_VEC_REF
Vec & operator+=(const Vec< T, d, refother > &other)
T_VEC_VALUE rotateBy(const Vec< T, 3, refother > &axis, T angle) const
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.
T_VEC_VALUE operator+(const Vec< T, d, refother > &other) const
bool operator==(const Vec< Tother, d, refother > &other) const
friend T_VEC_VALUE operator*(T s, const Vec &v)
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.
bool operator!=(const Vec< Tother, d, refother > &other) const
Vec & operator*=(const Vec< T, d, refother > &other)
T_VEC_VALUE operator*(const Vec< T, d, refother > &other) const
Vec & operator-=(const Vec< T, d, refother > &other)
Vec< T, d, false > T_VEC_VALUE
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!
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)
const T & operator[](const int i) const
Vec & operator/=(const Vec< T, d, refother > &other)
T angle(const Vec< T, 3, refother > &o) const
T_VEC_VALUE operator-() const
Vec & operator=(const Vec< T2, d, refother > &other)
T_VEC_VALUE cross(const Vec< T, 3, refother > &o) const
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)
T length() const
Euclidean (2) norm.
T_VEC_VALUE operator/(T s) const
T length2() const
Square of euclidean (2) norm.
T_VEC_VALUE orthogonal() const
T & operator[](const int i)
bool operator==(const Vec< T, d, refother > &other) const
T_VEC_VALUE operator-(const Vec< T, d, refother > &other) const
T_VEC_VALUE operator/(const Vec< T, d, refother > &other) const
T normalize()
Normalize in place and return the 2-norm before normalization.
Vec & operator*=(const T val)
static_if< ref, T *, T[d]>::TYPE x
internal data (either an explicit arary or a pointer to raw data)
bool operator!=(const Vec< T, d, refother > &other) const
Static conditional type true case.
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)
Static assert error case (false)
Vec & operator/=(const T val)
T dot(const Vec< T, d, refother > &o) const
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)
* 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
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)
Vec< T, d, false > normalized() const
Return a copy of the vector that is normalized.
Enable_if success case (can find the type TYPE)
T_VEC_VALUE operator*(T s) const