diff --git a/Makefile b/Makefile index ba5446d..e645ed2 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ SRCDIR := . CC := $(CROSS)gcc -CFLAGS := -fPIC -Os +CFLAGS := -fPIC -O3 CXXFLAGS := -I$(SRCDIR)/kiwi -fno-rtti 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) LIBFLAG := -shared LIB_EXT := so diff --git a/luakiwi/luakiwi-int.h b/luakiwi/luakiwi-int.h index fe994ea..8ca21c4 100644 --- a/luakiwi/luakiwi-int.h +++ b/luakiwi/luakiwi-int.h @@ -80,6 +80,11 @@ struct KiwiExpression { double constant; int term_count; 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]; }; diff --git a/luakiwi/luakiwi.cpp b/luakiwi/luakiwi.cpp index 68ee655..082fece 100644 --- a/luakiwi/luakiwi.cpp +++ b/luakiwi/luakiwi.cpp @@ -1308,9 +1308,8 @@ static int lkiwi_solver_dumps(lua_State* L) { return 1; } -typedef const KiwiErr* (*add_remove_fn_t)(lua_State*, KiwiSolver*, void*); - -static int lkiwi_add_remove_tab(lua_State* L, add_remove_fn_t fn, void* d) { +template +static int lkiwi_add_remove_tab(lua_State* L, F&& fn) { KiwiSolver* solver = get_solver(L, 1); 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) { break; } - const KiwiErr* err = fn(L, solver, d); + const KiwiErr* err = fn(L, solver); if (err) { 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)) { lua_replace(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; } -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) { - return lkiwi_add_remove_tab(L, add_constraint_fn, 0); -} - -static const KiwiErr* remove_constraint_fn(lua_State* L, KiwiSolver* s, void*) { - return kiwi_solver_remove_constraint(s->solver, *get_constraint(L, -1)); + return lkiwi_add_remove_tab(L, [](lua_State* L, KiwiSolver* s) { + return kiwi_solver_add_constraint(s->solver, *get_constraint(L, -1)); + }); } static int lkiwi_solver_remove_constraints(lua_State* L) { - return lkiwi_add_remove_tab(L, remove_constraint_fn, 0); -} - -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); + return lkiwi_add_remove_tab(L, [](lua_State* L, KiwiSolver* s) { + return kiwi_solver_add_constraint(s->solver, *get_constraint(L, -1)); + }); } static int lkiwi_solver_add_edit_vars(lua_State* L) { double strength = luaL_checknumber(L, 3); - return lkiwi_add_remove_tab(L, add_edit_var_fn, &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)); + 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 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) {