This commit is contained in:
2024-02-22 22:57:27 -06:00
parent a8c1a10cab
commit 00a9fda814
3 changed files with 23 additions and 27 deletions

View File

@@ -1,9 +1,9 @@
SRCDIR := . SRCDIR := .
CC := $(CROSS)gcc CC := $(CROSS)gcc
CFLAGS := -fPIC -Os CFLAGS := -fPIC -O3
CXXFLAGS := -I$(SRCDIR)/kiwi -fno-rtti CXXFLAGS := -I$(SRCDIR)/kiwi -fno-rtti
F_LTO := -flto=auto F_LTO := -flto=auto
CXXFLAGS_EXTRA := -pedantic -std=c++14 -Wall $(F_LTO) CXXFLAGS_EXTRA := -std=c++14 -Wall $(F_LTO)
CFLAGS_EXTRA := -pedantic -std=c99 -Wall $(F_LTO) CFLAGS_EXTRA := -pedantic -std=c99 -Wall $(F_LTO)
LIBFLAG := -shared LIBFLAG := -shared
LIB_EXT := so LIB_EXT := so

View File

@@ -80,6 +80,11 @@ struct KiwiExpression {
double constant; double constant;
int term_count; int term_count;
Constraint* owner; Constraint* owner;
// https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
// Although using one-element arrays this way is discouraged, GCC handles accesses to
// trailing one-element array members analogously to zero-length arrays.
// The only reason avoiding FAM here is to support older MSVC.
// Otherwise this is a non-issue.
KiwiTerm terms[1]; KiwiTerm terms[1];
}; };

View File

@@ -1308,9 +1308,8 @@ static int lkiwi_solver_dumps(lua_State* L) {
return 1; return 1;
} }
typedef const KiwiErr* (*add_remove_fn_t)(lua_State*, KiwiSolver*, void*); template<typename F>
static int lkiwi_add_remove_tab(lua_State* L, F&& fn) {
static int lkiwi_add_remove_tab(lua_State* L, add_remove_fn_t fn, void* d) {
KiwiSolver* solver = get_solver(L, 1); KiwiSolver* solver = get_solver(L, 1);
int narg = lua_gettop(L); int narg = lua_gettop(L);
@@ -1322,10 +1321,10 @@ static int lkiwi_add_remove_tab(lua_State* L, add_remove_fn_t fn, void* d) {
if (lua_geti(L, 2, i) == LUA_TNIL) { if (lua_geti(L, 2, i) == LUA_TNIL) {
break; break;
} }
const KiwiErr* err = fn(L, solver, d); const KiwiErr* err = fn(L, solver);
if (err) { if (err) {
error_new(L, err, 1, narg + 1 /* item_absi */); error_new(L, err, 1, narg + 1 /* item_absi */);
unsigned error_mask = solver->error_mask; const auto error_mask = solver->error_mask;
if (error_mask & (1 << err->kind)) { if (error_mask & (1 << err->kind)) {
lua_replace(L, 3); lua_replace(L, 3);
lua_settop(L, 3); lua_settop(L, 3);
@@ -1340,37 +1339,29 @@ static int lkiwi_add_remove_tab(lua_State* L, add_remove_fn_t fn, void* d) {
return 1; return 1;
} }
static const KiwiErr* add_constraint_fn(lua_State* L, KiwiSolver* s, void*) {
return kiwi_solver_add_constraint(s->solver, *get_constraint(L, -1));
}
static int lkiwi_solver_add_constraints(lua_State* L) { static int lkiwi_solver_add_constraints(lua_State* L) {
return lkiwi_add_remove_tab(L, add_constraint_fn, 0); return lkiwi_add_remove_tab(L, [](lua_State* L, KiwiSolver* s) {
} return kiwi_solver_add_constraint(s->solver, *get_constraint(L, -1));
});
static const KiwiErr* remove_constraint_fn(lua_State* L, KiwiSolver* s, void*) {
return kiwi_solver_remove_constraint(s->solver, *get_constraint(L, -1));
} }
static int lkiwi_solver_remove_constraints(lua_State* L) { static int lkiwi_solver_remove_constraints(lua_State* L) {
return lkiwi_add_remove_tab(L, remove_constraint_fn, 0); return lkiwi_add_remove_tab(L, [](lua_State* L, KiwiSolver* s) {
} return kiwi_solver_add_constraint(s->solver, *get_constraint(L, -1));
});
static const KiwiErr* add_edit_var_fn(lua_State* L, KiwiSolver* s, void* d) {
return kiwi_solver_add_edit_var(s->solver, *get_var(L, -1), *(double*)d);
} }
static int lkiwi_solver_add_edit_vars(lua_State* L) { static int lkiwi_solver_add_edit_vars(lua_State* L) {
double strength = luaL_checknumber(L, 3); double strength = luaL_checknumber(L, 3);
return lkiwi_add_remove_tab(L, add_edit_var_fn, &strength); return lkiwi_add_remove_tab(L, [strength](lua_State* L, KiwiSolver* s) {
} return kiwi_solver_add_edit_var(s->solver, *get_var(L, -1), strength);
});
static const KiwiErr* remove_edit_var_fn(lua_State* L, KiwiSolver* s, void*) {
return kiwi_solver_remove_edit_var(s->solver, *get_var(L, -1));
} }
static int lkiwi_solver_remove_edit_vars(lua_State* L) { static int lkiwi_solver_remove_edit_vars(lua_State* L) {
return lkiwi_add_remove_tab(L, remove_edit_var_fn, 0); return lkiwi_add_remove_tab(L, [](lua_State* L, KiwiSolver* s) {
return kiwi_solver_remove_edit_var(s->solver, *get_var(L, -1));
});
} }
static int lkiwi_solver_suggest_values(lua_State* L) { static int lkiwi_solver_suggest_values(lua_State* L) {