aboutsummaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/nissy.cpp216
-rw-r--r--cpp/nissy.h133
2 files changed, 349 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}
diff --git a/cpp/nissy.h b/cpp/nissy.h
new file mode 100644
index 0000000..e336c7a
--- /dev/null
+++ b/cpp/nissy.h
@@ -0,0 +1,133 @@
1/*
2C++20 header file for nissy.
3*/
4
5#ifndef NISSY_H
6#define NISSY_H
7
8#include <array>
9#include <functional>
10#include <optional>
11#include <ranges>
12#include <string>
13#include <string_view>
14#include <variant>
15#include <vector>
16
17namespace nissy {
18 /* Some constants for size for I/O buffers */
19 namespace size {
20 constexpr size_t B32 = 22;
21 constexpr size_t H48 = 88;
22 constexpr size_t CUBE_MAX = H48;
23 constexpr size_t TRANSFORMATION = 12;
24 constexpr size_t SOLVE_STATS = 10;
25 constexpr size_t DATAID = 255;
26 }
27
28 /* Some structs definitions for better type safety */
29 struct nissflag_t { unsigned value; };
30 struct error_t { long long value; };
31 struct cube_t { std::string value; };
32 struct moves_t { std::string value; };
33 struct trans_t { std::string value; };
34 struct cube_format_t { std::string value; };
35 struct solver_t { std::string value; };
36 struct solver_data_t { std::vector<std::byte> value; };
37 struct solve_result_t {
38 std::vector<std::string> solutions;
39 std::array<long long, size::SOLVE_STATS> stats;
40 };
41
42 /* Flags for NISS options */
43 namespace nissflag {
44 constexpr nissflag_t NORMAL{1};
45 constexpr nissflag_t INVERSE{2};
46 constexpr nissflag_t MIXED{4};
47 constexpr nissflag_t LINEAR{NORMAL.value | INVERSE.value};
48 constexpr nissflag_t ALL{LINEAR.value | MIXED.value};
49 }
50
51 /* Error codes */
52 namespace error {
53 constexpr error_t UNSOLVABLE{-1};
54 constexpr error_t INVALID_CUBE{-10};
55 constexpr error_t UNSOLVABLE_CUBE{-11};
56 constexpr error_t INVALID_MOVES{-20};
57 constexpr error_t INVALID_TRANS{-30};
58 constexpr error_t INVALID_FORMAT{-40};
59 constexpr error_t INVALID_SOLVER{-50};
60 constexpr error_t NULL_POINTER{-60};
61 constexpr error_t BUFFER_SIZE{-61};
62 constexpr error_t DATA{-70};
63 constexpr error_t OPTIONS{-80};
64 constexpr error_t UNKNOWN{-999};
65 }
66
67 /* Cube constants */
68 namespace cube {
69 const cube_t SOLVED{"ABCDEFGH=ABCDEFGHIJKL"};
70 }
71
72 std::variant<cube_t, error_t> inverse(
73 const cube_t& cube
74 );
75
76 std::variant<cube_t, error_t> applymoves(
77 const cube_t& cube,
78 const moves_t& moves
79 );
80
81 std::variant<cube_t, error_t> applytrans(
82 const cube_t& cube,
83 const trans_t& trans
84 );
85
86 std::variant<std::string, error_t> convert(
87 const cube_format_t& format_in,
88 const cube_format_t& format_out,
89 const std::string& cube_string
90 );
91
92 std::variant<cube_t, error_t> getcube(
93 long long ep,
94 long long eo,
95 long long cp,
96 long long co,
97 const std::string& options
98 );
99
100 std::variant<std::pair<size_t, std::string>, error_t> solverinfo(
101 const solver_t& solver
102 );
103
104 std::variant<solver_data_t, error_t> gendata(
105 const solver_t& solver
106 );
107
108 std::optional<error_t> checkdata(
109 const solver_data_t& data
110 );
111
112 std::variant<solve_result_t, error_t> solve(
113 const cube_t& cube,
114 const solver_t& solver,
115 nissflag_t niss,
116 unsigned minmoves,
117 unsigned maxmoves,
118 unsigned maxsolutions,
119 int optimal,
120 int threads,
121 const solver_data_t& data
122 );
123
124 std::variant<unsigned, error_t> countmoves(
125 const moves_t& moves
126 );
127
128 void setlogger(
129 std::function<void(std::string&)> log
130 );
131}
132
133#endif

Generated with cgit - Back to sebastiano.tronto.net