aboutsummaryrefslogtreecommitdiff
path: root/cpp/nissy.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cpp/nissy.cpp216
1 files changed, 216 insertions, 0 deletions
diff --git a/cpp/nissy.cpp b/cpp/nissy.cpp
new file mode 100644
index 0000000..7987f6c
--- /dev/null
+++ b/cpp/nissy.cpp
@@ -0,0 +1,216 @@
1/*
2C++20 interface for nissy.
3
4TODO: add more documentation (here and in README.md)
5*/
6
7#include "./nissy.h"
8
9extern "C" {
10 long long nissy_compose(const char *, const char *, char *);
11 long long nissy_inverse(const char *, char *);
12 long long nissy_applymoves(const char *, const char *, char *);
13 long long nissy_applytrans(const char *, const char *, char *);
14 long long nissy_convert(const char *, const char *, const char *,
15 unsigned, char *);
16 long long nissy_getcube(long long, long long, long long, long long,
17 const char *, char *);
18 long long nissy_solverinfo(const char *, char *);
19 long long nissy_gendata(const char *, unsigned long long, char *);
20 long long nissy_checkdata(unsigned long long, const char *);
21 long long nissy_solve(const char *, const char *, unsigned, unsigned,
22 unsigned, unsigned, int, int, unsigned long long, const char *,
23 unsigned, char *, long long *);
24 long long nissy_countmoves(const char *);
25 long long nissy_setlogger(void (*)(const char *));
26}
27
28namespace nissy {
29 namespace utils {
30 void fixstr(std::string& str)
31 {
32 size_t n = str.find('\0');
33 str.resize(n);
34 }
35
36 std::variant<cube_t, error_t>
37 cube_or_error(const char *r, long long e)
38 {
39 if (e < 0)
40 return error_t{e};
41 return cube_t{r};
42 }
43
44 std::variant<std::string, error_t>
45 string_or_error(const char *cstr, long long e)
46 {
47 if (e < 0)
48 return error_t{e};
49
50 std::string str{cstr};
51 fixstr(str);
52 return str;
53 }
54
55 std::function<void(const char *)>
56 char_str_fn(std::function<void(std::string&)> f)
57 {
58 return [&](const char *cc){
59 std::string str{cc};
60 f(str);
61 };
62 }
63 }
64
65 std::variant<cube_t, error_t>
66 compose(const cube_t& cube, const cube_t& permutation)
67 {
68 char result[size::B32];
69
70 auto error = nissy_compose(cube.value.c_str(),
71 permutation.value.c_str(), result);
72
73 return utils::cube_or_error(result, error);
74 }
75
76 std::variant<cube_t, error_t>
77 inverse(const cube_t& cube)
78 {
79 char result[size::B32];
80
81 auto error = nissy_inverse(cube.value.c_str(), result);
82
83 return utils::cube_or_error(result, error);
84 }
85
86 std::variant<cube_t, error_t>
87 applymoves(const cube_t& cube, const moves_t& moves)
88 {
89 char result[size::B32];
90
91 auto error = nissy_applymoves(cube.value.c_str(),
92 moves.value.c_str(), result);
93
94 return utils::cube_or_error(result, error);
95 }
96
97 std::variant<cube_t, error_t>
98 applytrans(const cube_t& cube, const trans_t& trans)
99 {
100 char result[size::B32];
101
102 auto error = nissy_applytrans(cube.value.c_str(),
103 trans.value.c_str(), result);
104
105 return utils::cube_or_error(result, error);
106 }
107
108 std::variant<std::string, error_t>
109 convert(const cube_format_t& format_in,
110 const cube_format_t& format_out, const std::string& cube_string)
111 {
112 char result[size::CUBE_MAX];
113
114 auto error = nissy_convert(format_in.value.c_str(),
115 format_out.value.c_str(), cube_string.c_str(),
116 size::CUBE_MAX, result);
117
118 return utils::string_or_error(result, error);
119 }
120
121 std::variant<cube_t, error_t>
122 getcube(long long ep, long long eo, long long cp, long long co,
123 const std::string& options)
124 {
125 char result[size::B32];
126
127 auto error = nissy_getcube(ep, eo, cp, co, options.c_str(),
128 result);
129
130 return utils::cube_or_error(result, error);
131 }
132
133 std::variant<std::pair<size_t, std::string>, error_t>
134 solverinfo(const solver_t& solver)
135 {
136 char dataid[size::DATAID];
137
138 auto error = nissy_solverinfo(solver.value.c_str(), dataid);
139 if (error < 0)
140 return error_t{error};
141
142 return std::pair{error, dataid};
143 }
144
145 std::variant<solver_data_t, error_t>
146 gendata(const solver_t& solver)
147 {
148 char dataid[size::DATAID];
149
150 auto error = nissy_solverinfo(solver.value.c_str(), dataid);
151 if (error < 0)
152 return error_t{error};
153
154 size_t sz = error;
155 std::vector<std::byte> buffer(sz);
156 error = nissy_gendata(solver.value.c_str(), sz,
157 reinterpret_cast<char *>(buffer.data()));
158 if (error < 0)
159 return error_t{error};
160
161 return solver_data_t{buffer};
162 }
163
164 std::optional<error_t>
165 checkdata(const solver_data_t& data)
166 {
167 auto error = nissy_checkdata(data.value.size(),
168 reinterpret_cast<const char *>(data.value.data()));
169
170 if (error < 0)
171 return error_t{error};
172 return std::nullopt;
173 }
174
175 std::variant<solve_result_t, error_t>
176 solve(const cube_t& cube, const solver_t& solver,
177 nissflag_t niss, unsigned minmoves, unsigned maxmoves,
178 unsigned maxsolutions, int optimal, int threads,
179 const solver_data_t& data)
180 {
181 const size_t len = 3 * (maxmoves+1) * maxsolutions;
182 char csols[len];
183 long long cstats[size::SOLVE_STATS];
184
185 auto error = nissy_solve(cube.value.c_str(),
186 solver.value.c_str(), niss.value, minmoves, maxmoves,
187 maxsolutions, optimal, threads, data.value.size(),
188 reinterpret_cast<const char *>(data.value.data()),
189 len, csols, cstats);
190
191 if (error < 0)
192 return error_t{error};
193
194 std::vector<std::string> sols;
195 std::string_view strsols(csols);
196 for (auto r : strsols | std::views::split('\n'))
197 sols.push_back(std::string{r.begin(), r.end()});
198
199 return solve_result_t{sols, std::to_array(cstats)};
200 }
201
202 std::variant<unsigned, error_t>
203 countmoves(const moves_t& moves)
204 {
205 auto error = nissy_countmoves(moves.value.c_str());
206 if (error < 0)
207 return error_t{error};
208 return (unsigned)error;
209 }
210
211 void setlogger(std::function<void(std::string&)> log)
212 {
213 nissy_setlogger(
214 utils::char_str_fn(log).target<void(const char *)>());
215 }
216}

Generated with cgit - Back to sebastiano.tronto.net