-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtransform.ixx
123 lines (108 loc) · 4.35 KB
/
transform.ixx
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
module;
#include <array>
export module cube.transform;
import cube.type;
import cube.bf;
import array_tools;
namespace cube {
template <int N> constexpr [[nodiscard]]
CubeI<N> apply(const CubeI<N>& c, const CubeI<N>& ci) {
if constexpr (N == 1) {
return CubeI<N>{ c[ci[0]], c[ci[1]] };
}
else if constexpr (N == 2) {
return CubeI<N>{ c[ci[0]], c[ci[1]], c[ci[2]], c[ci[3]] };
}
else if constexpr (N == 3) {
return CubeI<N>{ c[ci[0]], c[ci[1]], c[ci[2]], c[ci[3]], c[ci[4]], c[ci[5]], c[ci[6]], c[ci[7]] };
}
else if constexpr (N == 4) {
return CubeI<N>{
c[ci[0]], c[ci[1]], c[ci[2]], c[ci[3]], c[ci[4]], c[ci[5]], c[ci[6]], c[ci[7]],
c[ci[8]], c[ci[9]], c[ci[10]], c[ci[11]], c[ci[12]], c[ci[13]], c[ci[14]], c[ci[15]]
};
}
else if constexpr (N == 5) {
return CubeI<N>{
c[ci[0]], c[ci[1]], c[ci[2]], c[ci[3]], c[ci[4]], c[ci[5]], c[ci[6]], c[ci[7]],
c[ci[8]], c[ci[9]], c[ci[10]], c[ci[11]], c[ci[12]], c[ci[13]], c[ci[14]], c[ci[15]],
c[ci[16]], c[ci[17]], c[ci[18]], c[ci[19]], c[ci[20]], c[ci[21]], c[ci[22]], c[ci[23]],
c[ci[24]], c[ci[25]], c[ci[26]], c[ci[27]], c[ci[28]], c[ci[29]], c[ci[30]], c[ci[31]]
};
}
else if constexpr (N == 6) {
return CubeI<N>{
c[ci[0]], c[ci[1]], c[ci[2]], c[ci[3]], c[ci[4]], c[ci[5]], c[ci[6]], c[ci[7]],
c[ci[8]], c[ci[9]], c[ci[10]], c[ci[11]], c[ci[12]], c[ci[13]], c[ci[14]], c[ci[15]],
c[ci[16]], c[ci[17]], c[ci[18]], c[ci[19]], c[ci[20]], c[ci[21]], c[ci[22]], c[ci[23]],
c[ci[24]], c[ci[25]], c[ci[26]], c[ci[27]], c[ci[28]], c[ci[29]], c[ci[30]], c[ci[31]],
c[ci[32]], c[ci[33]], c[ci[34]], c[ci[35]], c[ci[36]], c[ci[37]], c[ci[38]], c[ci[39]],
c[ci[40]], c[ci[41]], c[ci[42]], c[ci[43]], c[ci[44]], c[ci[45]], c[ci[46]], c[ci[47]],
c[ci[48]], c[ci[49]], c[ci[50]], c[ci[51]], c[ci[52]], c[ci[53]], c[ci[54]], c[ci[55]],
c[ci[56]], c[ci[57]], c[ci[58]], c[ci[59]], c[ci[60]], c[ci[61]], c[ci[62]], c[ci[63]]
};
}
//return CubeI<N>();
}
template <int N, int ... S> constexpr [[nodiscard]]
BF apply_private(const BF bf, const CubeI<N>& c, std::index_sequence<S...>) noexcept {
return (... | (((bf >> c[S]) & 1) << S));
}
template <int N> constexpr [[nodiscard]]
BF apply(const BF bf, const CubeI<N>& c) noexcept {
return apply_private<N>(bf, c, std::make_index_sequence<(1 << N)>());
}
#pragma region functional composition
export template <int N> constexpr [[nodiscard]]
CubeI<N> function_composition(const CubeI<N>& a) noexcept {
return a;
}
export template <int N> constexpr [[nodiscard]]
CubeI<N> function_composition(const CubeI<N>& a0, const CubeI<N>& a1) noexcept {
return apply<N>(a0, a1);
}
export template <int N> constexpr [[nodiscard]]
CubeI<N> function_composition(const CubeI<N>& a0, const CubeI<N>& a1, const CubeI<N>& a2) noexcept {
return apply<N>(a0, apply<N>(a1, a2));
}
export template <int N> constexpr [[nodiscard]]
CubeI<N> function_composition(const CubeI<N>& a0, const CubeI<N>& a1, const CubeI<N>& a2, const CubeI<N>& a3) noexcept {
return apply<N>(apply<N>(a0, a1), apply<N>(a2, a3));
}
export template <int N, int M> constexpr [[nodiscard]]
CubeI<N> function_composition(const std::array<CubeI<N>, M>& a) noexcept {
if constexpr (M == 1) {
return function_composition(a[0]);
}
else if constexpr (M == 2) {
return function_composition(a[0], a[1]);
}
else if constexpr (M == 3) {
return function_composition(a[0], a[1], a[2]);
}
else if constexpr (M == 4) {
return function_composition(a[0], a[1], a[2], a[3]);
}
static_assert(false);
}
consteval void test_function_composition() {
constexpr int N = 2;
constexpr auto id = init_cubeI<(N)>();
static_assert(array_tools::equal(function_composition<N>(id, id), id), "");
//static_assert(array_tools::equal(function_composition<N>(value(1), value(1)), id), "");
//static_assert(array_tools::equal(function_composition<N>(value(2), value(2)), id), "");
}
#pragma endregion
// Transform (shuffle) cube c according to the change as provided by cube ci
export template <int N> constexpr [[nodiscard]]
CubeI<N> transform(const CubeI<N>& c, const CubeI<N>& ci)
{
return apply<N>(c, ci);
}
// Transform (shuffle) Boolean function bf according to the change as provided by cube
export template <int N> constexpr [[nodiscard]]
BF transform(const BF bf, const CubeI<N>& cube) noexcept
{
return apply<N>(bf, cube);
}
}