-
Notifications
You must be signed in to change notification settings - Fork 0
/
algebra.h
76 lines (65 loc) · 1.4 KB
/
algebra.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/* Written by Todd Doucet. */
#pragma once
#include <iostream>
#include <tuple>
template<class T>
struct algebra : public T
{
using T::T;
template<typename Lambda>
static void memberwise(Lambda lambda)
{
std::apply(lambda, T::members);
}
void clear()
{
memberwise
(
[&](auto ...args) { ( (this->*args).clear(), ... ); }
);
}
algebra<T>& operator+=(T const& rhs)
{
memberwise
(
[&](auto ...args) { ( (this->*args += rhs.*args), ... ); }
);
return *this;
}
algebra<T>& operator*=(float scale)
{
memberwise
(
[&](auto ...args) { ( (this->*args *= scale), ... ); }
);
return *this;
}
algebra<T> operator*(float scale)
{
return algebra<T>(*this) *= scale;
}
};
template<class T>
algebra<T> operator+(algebra<T> const& lhs,
algebra<T> const& rhs)
{
return algebra<T>{lhs} += rhs;
}
template<class T>
std::ostream& operator<<(std::ostream& os, algebra<T> const& val)
{
algebra<T>::memberwise
(
[&os, &val](auto ...args) { ( (os << val.*args << "\n"), ... ); }
);
return os;
}
template<class T>
std::istream& operator>>(std::istream& s, algebra<T> & val)
{
algebra<T>::memberwise
(
[&s, &val](auto ...args) { ( (s >> val.*args), ... ); }
);
return s;
}