29# define TYPENAME typename
36template <
bool b,
class T>
45template <
bool c,
class T =
void>
58template <
bool c,
class T1,
class T2>
63template <
class T1,
class T2>
70template <
class T,
int d>
72 static T
sum(T* data) {
74 for (
int k = 0;
k < d;
k++)
sum += data[
k];
80 static T
sum(T* data) {
return data[0]; }
84 static T
sum(T* data) {
return data[0] + data[1]; }
88 static T
sum(T* data) {
return data[0] + data[1] + data[2]; }
92 static T
sum(T* data) {
return (data[0] + data[1]) + (data[2] + data[3]); }
97template <
class T,
int d,
bool ref = false>
130 for (
int k = 0;
k < d;
k++)
x[
k] =
v0;
172 template <
class T2,
bool refother>
179 template <
class T2,
bool refother>
185 template <
class Tother,
bool refother>
187 for (
int k = 0;
k < d;
k++)
192 template <
class Tother,
bool refother>
194 return !(*
this !=
other);
206 for (
int k = 0;
k < d;
k++) data[
k] =
x[
k] *
x[
k];
240 for (
int k = 0;
k < d;
k++)
x[
k] *= val;
244 template <
bool refother>
250 template <
bool refother>
256 template <
bool refother>
262 template <
bool refother>
270 for (
int k = 0;
k < d;
k++) val[
k] = -val[
k];
274 template <
bool refother>
281 template <
bool refother>
283 return !(*
this ==
other);
298 template <
bool refother>
305 template <
bool refother>
312 template <
bool refother>
319 template <
bool refother>
329 template <
bool refother>
332 for (
int k = 0;
k < d;
k++) data[
k] =
x[
k] *
o[
k];
337 template <
bool refother>
353 template <
bool refother>
357 if (
l == 0)
return 0;
365 template <
bool refother>
374template <
class T,
int d,
bool r>
376 if (d > 0)
out <<
"(" << val[0];
377 for (
int k = 1;
k < d;
k++)
out <<
"," << val[
k];
bool operator==(const Vec< Tother, d, refother > &other) const
T length() const
Euclidean (2) norm.
Vec< T, d, true > T_VEC_REF
Vec & operator/=(const T val)
T dot(const Vec< T, d, refother > &o) const
T_VEC_VALUE operator-() const
Vec< T, d, false > normalized() const
Return a copy of the vector that is normalized.
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)
const T & operator[](const int i) const
friend T_VEC_VALUE operator*(T s, const Vec &v)
T_VEC_VALUE operator*(const Vec< T, d, refother > &other) const
Vec & operator=(const Vec< T2, d, refother > &other)
T & operator[](const int i)
T_VEC_VALUE operator-(const Vec< T, d, refother > &other) const
Vec & operator-=(const Vec< T, d, refother > &other)
T_VEC_VALUE orthogonal() const
T angle(const Vec< T, 3, refother > &o) const
Vec< T, d, false > T_VEC_VALUE
Vec & operator*=(const T val)
Vec & operator/=(const Vec< T, d, refother > &other)
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 normalize()
Normalize in place and return the 2-norm before normalization.
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 cross(const Vec< T, 3, refother > &o) const
T length2() const
Square of euclidean (2) norm.
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)
Vec & operator+=(const Vec< T, d, refother > &other)
bool operator!=(const Vec< Tother, d, refother > &other) 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)
Vec & operator*=(const Vec< T, d, refother > &other)
bool operator==(const Vec< T, d, refother > &other) const
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)
T_VEC_VALUE operator/(const Vec< T, d, refother > &other) const
T_VEC_VALUE operator/(T s) const
bool operator!=(const Vec< T, d, refother > &other) const
static_if< ref, T *, T[d]>::TYPE x
internal data (either an explicit arary or a pointer to raw data)
T_VEC_VALUE rotateBy(const Vec< T, 3, refother > &axis, T angle) const
T_VEC_VALUE operator+(const Vec< T, d, refother > &other) const
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.
T_VEC_VALUE operator*(T s) const
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!
std::ostream & operator<<(std::ostream &out, const Vec< T, d, r > &val)
Output stream.
Enable_if success case (can find the type TYPE)
Static assert error case (false)
Static conditional type true case.
* 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