forked from goldshtn/cool-cpp-things
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathintvector.h
More file actions
91 lines (77 loc) · 2.71 KB
/
intvector.h
File metadata and controls
91 lines (77 loc) · 2.71 KB
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#ifndef COOL_THINGS_INTVECTOR_H
#define COOL_THINGS_INTVECTOR_H
template <int... Ints>
struct intvector
{
using type = intvector<Ints...>;
static constexpr int length = sizeof...(Ints);
};
// Two empty intvectors are equal
constexpr bool intvector_equal(intvector<>, intvector<>)
{
return true;
}
// Two non-empty intvectors are equal if the first ints are equal
// and the tail recursively compares as equal
template <int Int1, int... Ints1, int Int2, int... Ints2>
constexpr bool intvector_equal(intvector<Int1, Ints1...>, intvector<Int2, Ints2...>)
{
static_assert(sizeof...(Ints1) == sizeof...(Ints2), "vector lengths must be equal");
return (Int1 == Int2) && intvector_equal(intvector<Ints1...>(), intvector<Ints2...>());
}
// Prepends an int to the beginning of an intvector
template <int, typename>
struct intvector_prepend;
template <int Int, int... Ints>
struct intvector_prepend<Int, intvector<Ints...>>
{
using type = intvector<Int, Ints...>;
};
// Produces a new intvector that is the pointwise sum
// of two intvectors
template <typename...>
struct intvector_add;
template <>
struct intvector_add<intvector<>, intvector<>>
{
using type = intvector<>;
};
template <int Int1, int... Ints1, int Int2, int... Ints2>
struct intvector_add<intvector<Int1, Ints1...>, intvector<Int2, Ints2...>>
{
static_assert(sizeof...(Ints1) == sizeof...(Ints2), "vector lengths must be equal");
using type = typename intvector_prepend<
Int1 + Int2,
typename intvector_add<intvector<Ints1...>, intvector<Ints2...>>::type
>::type;
};
// Produces a new intvector that is the pointwise difference
// between two intvectors
template <typename...>
struct intvector_subtract;
template <>
struct intvector_subtract<intvector<>, intvector<>>
{
using type = intvector<>;
};
template <int Int1, int... Ints1, int Int2, int... Ints2>
struct intvector_subtract<intvector<Int1, Ints1...>, intvector<Int2, Ints2...>>
{
static_assert(sizeof...(Ints1) == sizeof...(Ints2), "vector lengths must be equal");
using type = typename intvector_prepend<
Int1 - Int2,
typename intvector_subtract<intvector<Ints1...>, intvector<Ints2...>>::type
>::type;
};
void intvector_tests()
{
static_assert(intvector_equal(intvector<>(), intvector<>()), "");
static_assert(intvector_equal(intvector<1, 2>(), intvector<1, 2>()), "");
using v = intvector<1, 2, 3>;
using u = intvector<0, -1, 2>;
using sum = typename intvector_add<u, v>::type;
using diff = typename intvector_subtract<u, v>::type;
static_assert(intvector_equal(sum(), intvector<1, 1, 5>()), "");
static_assert(intvector_equal(diff(), intvector<-1, -3, -1>()), "");
}
#endif //COOL_THINGS_INTVECTOR_H