Cleanup
This commit is contained in:
4
Makefile
4
Makefile
@@ -2,8 +2,8 @@ SRCDIR := .
|
|||||||
CC := $(CROSS)gcc
|
CC := $(CROSS)gcc
|
||||||
CFLAGS := -fPIC -O3
|
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 := -std=c++14 -Wall $(F_LTO)
|
CXXFLAGS_EXTRA := -std=c++14 -Wall $(F_LTO) -fstrict-flex-arrays=3
|
||||||
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
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
cl /nologo /O2 /W4 /wd4244 /c /D_CRT_SECURE_NO_DEPRECATE /I "C:\Program Files\luarocks\include" /EHs /I kiwi luakiwi\luakiwi.cpp
|
cl /nologo /O2 /W4 /wd4200 /c /D_CRT_SECURE_NO_DEPRECATE /I "C:\Program Files\luarocks\include" /EHs /I kiwi luakiwi\luakiwi.cpp
|
||||||
link /DLL /out:ckiwi.dll /def:luakiwi.def /LIBPATH:"C:\Program Files\luarocks\lib" luakiwi.obj lua54.lib
|
link /DLL /out:ckiwi.dll /def:luakiwi.def /LIBPATH:"C:\Program Files\luarocks\lib" luakiwi.obj lua54.lib
|
||||||
|
|||||||
@@ -4,21 +4,24 @@
|
|||||||
#include <kiwi/kiwi.h>
|
#include <kiwi/kiwi.h>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#include "luacompat.h"
|
#include "luacompat.h"
|
||||||
|
|
||||||
#define ARR_COUNT(x) ((int)(sizeof(x) / sizeof((x)[0])))
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && !defined(LKIWI_NO_BUILTIN)
|
#if defined(__GNUC__) && !defined(LKIWI_NO_BUILTIN)
|
||||||
#define l_likely(x) (__builtin_expect(((x) != 0), 1))
|
#define lk_likely(x) (__builtin_expect(((x) != 0), 1))
|
||||||
#define l_unlikely(x) (__builtin_expect(((x) != 0), 0))
|
#define lk_unlikely(x) (__builtin_expect(((x) != 0), 0))
|
||||||
#else
|
#else
|
||||||
#define l_likely(x) (x)
|
#define lk_likely(x) (x)
|
||||||
#define l_unlikely(x) (x)
|
#define lk_unlikely(x) (x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using namespace kiwi;
|
||||||
|
|
||||||
// Lua 5.1 compatibility for missing lua_arith.
|
// Lua 5.1 compatibility for missing lua_arith.
|
||||||
static void compat_arith_unm(lua_State* L) {
|
inline void compat_arith_unm(lua_State* L) {
|
||||||
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
|
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
|
||||||
lua_Number n = lua_tonumber(L, -1);
|
lua_Number n = lua_tonumber(L, -1);
|
||||||
if (n != 0 || lua_isnumber(L, -1)) {
|
if (n != 0 || lua_isnumber(L, -1)) {
|
||||||
@@ -35,14 +38,13 @@ static void compat_arith_unm(lua_State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This version supports placeholders.
|
// This version supports placeholders.
|
||||||
static void setfuncs(lua_State* L, const luaL_Reg* l, int nup) {
|
inline void setfuncs(lua_State* L, const luaL_Reg* l, int nup) {
|
||||||
luaL_checkstack(L, nup, "too many upvalues");
|
luaL_checkstack(L, nup, "too many upvalues");
|
||||||
for (; l->name != NULL; l++) { /* fill the table with given functions */
|
for (; l->name != NULL; l++) { /* fill the table with given functions */
|
||||||
if (l->func == NULL) /* place holder? */
|
if (l->func == NULL) /* place holder? */
|
||||||
lua_pushboolean(L, 0);
|
lua_pushboolean(L, 0);
|
||||||
else {
|
else {
|
||||||
int i;
|
for (int i = 0; i < nup; i++) /* copy upvalues to the top */
|
||||||
for (i = 0; i < nup; i++) /* copy upvalues to the top */
|
|
||||||
lua_pushvalue(L, -nup);
|
lua_pushvalue(L, -nup);
|
||||||
lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
|
lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
|
||||||
}
|
}
|
||||||
@@ -51,11 +53,15 @@ static void setfuncs(lua_State* L, const luaL_Reg* l, int nup) {
|
|||||||
lua_pop(L, nup); /* remove upvalues */
|
lua_pop(L, nup); /* remove upvalues */
|
||||||
}
|
}
|
||||||
|
|
||||||
#define newlib(L, l) (lua_newtable((L)), setfuncs((L), (l), 0))
|
template<typename T, std::size_t N>
|
||||||
|
constexpr int array_count(T (&)[N]) {
|
||||||
|
return static_cast<int>(N);
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
void newlib(lua_State* L, const luaL_Reg* l) {
|
||||||
|
lua_newtable(L);
|
||||||
using namespace kiwi;
|
setfuncs(L, l, 0);
|
||||||
|
}
|
||||||
|
|
||||||
enum KiwiErrKind {
|
enum KiwiErrKind {
|
||||||
KiwiErrNone,
|
KiwiErrNone,
|
||||||
@@ -80,20 +86,32 @@ 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
|
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||||
// trailing one-element array members analogously to zero-length arrays.
|
KiwiTerm terms[];
|
||||||
// The only reason avoiding FAM here is to support older MSVC.
|
|
||||||
// Otherwise this is a non-issue.
|
static constexpr std::size_t sz(int count) {
|
||||||
|
return sizeof(KiwiExpression) + sizeof(KiwiTerm) * (count > 0 ? count : 0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
KiwiTerm terms[1];
|
KiwiTerm terms[1];
|
||||||
|
|
||||||
|
static constexpr std::size_t sz(int count) {
|
||||||
|
return sizeof(KiwiExpression) + sizeof(KiwiTerm) * (count > 1 ? count - 1 : 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
KiwiExpression() = delete;
|
||||||
|
KiwiExpression(const KiwiExpression&) = delete;
|
||||||
|
KiwiExpression& operator=(const KiwiExpression&) = delete;
|
||||||
|
~KiwiExpression() = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This structure was initially designed for LuaJIT FFI. It works OK for C++
|
// This mechanism was initially designed for LuaJIT FFI.
|
||||||
// though it certainly isn't idiomatic.
|
|
||||||
struct KiwiErr {
|
struct KiwiErr {
|
||||||
enum KiwiErrKind kind;
|
enum KiwiErrKind kind;
|
||||||
const char* message;
|
const char* message;
|
||||||
bool must_free;
|
bool must_delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KiwiSolver {
|
struct KiwiSolver {
|
||||||
@@ -101,28 +119,27 @@ struct KiwiSolver {
|
|||||||
Solver solver;
|
Solver solver;
|
||||||
};
|
};
|
||||||
|
|
||||||
const KiwiErr* new_error(const KiwiErr* base, const std::exception& ex) {
|
inline const KiwiErr* new_error(const KiwiErr* base, const std::exception& ex) {
|
||||||
if (!std::strcmp(ex.what(), base->message))
|
if (!std::strcmp(ex.what(), base->message))
|
||||||
return base;
|
return base;
|
||||||
|
|
||||||
const auto msg_n = std::strlen(ex.what()) + 1;
|
const auto msg_n = std::strlen(ex.what()) + 1;
|
||||||
|
|
||||||
auto* mem = static_cast<char*>(std::malloc(sizeof(KiwiErr) + msg_n));
|
auto* mem = static_cast<char*>(::operator new(sizeof(KiwiErr) + msg_n, std::nothrow));
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
auto* msg = mem + sizeof(KiwiErr);
|
||||||
const auto* err = new (mem) KiwiErr {base->kind, mem + sizeof(KiwiErr), true};
|
std::memcpy(msg, ex.what(), msg_n);
|
||||||
std::memcpy(const_cast<char*>(err->message), ex.what(), msg_n);
|
return new (mem) KiwiErr {base->kind, msg, true};
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const constexpr KiwiErr kKiwiErrUnhandledCxxException {
|
|
||||||
KiwiErrUnknown,
|
|
||||||
"An unhandled C++ exception occurred."};
|
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline const KiwiErr* wrap_err(F&& f) {
|
inline const KiwiErr* wrap_err(F&& f) {
|
||||||
|
static const constexpr KiwiErr kKiwiErrUnhandledCxxException {
|
||||||
|
KiwiErrUnknown,
|
||||||
|
"An unhandled C++ exception occurred."};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
f();
|
f();
|
||||||
} catch (const UnsatisfiableConstraint&) {
|
} catch (const UnsatisfiableConstraint&) {
|
||||||
@@ -198,12 +215,12 @@ inline Constraint* kiwi_constraint_retain(Constraint* c) {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void kiwi_constraint_new(
|
inline Constraint* kiwi_constraint_new(
|
||||||
const KiwiExpression* lhs,
|
const KiwiExpression* lhs,
|
||||||
const KiwiExpression* rhs,
|
const KiwiExpression* rhs,
|
||||||
RelationalOperator op,
|
RelationalOperator op,
|
||||||
double strength,
|
double strength,
|
||||||
Constraint* mem
|
void* mem
|
||||||
) {
|
) {
|
||||||
if (strength < 0.0) {
|
if (strength < 0.0) {
|
||||||
strength = kiwi::strength::required;
|
strength = kiwi::strength::required;
|
||||||
@@ -222,7 +239,7 @@ inline void kiwi_constraint_new(
|
|||||||
terms.emplace_back(*t->var, -t->coefficient);
|
terms.emplace_back(*t->var, -t->coefficient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new (mem) Constraint(
|
return new (mem) Constraint(
|
||||||
Expression(std::move(terms), (lhs ? lhs->constant : 0.0) - (rhs ? rhs->constant : 0.0)),
|
Expression(std::move(terms), (lhs ? lhs->constant : 0.0) - (rhs ? rhs->constant : 0.0)),
|
||||||
static_cast<RelationalOperator>(op),
|
static_cast<RelationalOperator>(op),
|
||||||
strength
|
strength
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
12
t.lua
12
t.lua
@@ -8,14 +8,16 @@ do
|
|||||||
local v3 = kiwi.Var("v3")
|
local v3 = kiwi.Var("v3")
|
||||||
local v4 = kiwi.Var("v4")
|
local v4 = kiwi.Var("v4")
|
||||||
local v5 = kiwi.Var("v5")
|
local v5 = kiwi.Var("v5")
|
||||||
local c = (3 * v1 + 4 * v2 + 6 * v3):eq(0)
|
local c1 = (3 * v1 + 4 * v2 + 6 * v3):eq(0)
|
||||||
|
local c2 = (6 * v4 + 4 * v5 + 2 * v1 + 1.4 * v1 / 0.3):le(1000)
|
||||||
|
|
||||||
local e = c:expression()
|
local e = c1:expression()
|
||||||
print(e)
|
local s = kiwi.Solver()
|
||||||
|
|
||||||
|
s:add_constraints({ c1, c2, c1 })
|
||||||
|
print(s:dumps())
|
||||||
end
|
end
|
||||||
|
|
||||||
collectgarbage("collect")
|
|
||||||
collectgarbage("collect")
|
|
||||||
-- c = (3 * v1 + 4 * v2 + 6 * v3):eq(0)
|
-- c = (3 * v1 + 4 * v2 + 6 * v3):eq(0)
|
||||||
|
|
||||||
-- local t = c:expression():terms()
|
-- local t = c:expression():terms()
|
||||||
|
|||||||
Reference in New Issue
Block a user