Cleanup
This commit is contained in:
@@ -4,21 +4,24 @@
|
||||
#include <kiwi/kiwi.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <new>
|
||||
|
||||
#include "luacompat.h"
|
||||
|
||||
#define ARR_COUNT(x) ((int)(sizeof(x) / sizeof((x)[0])))
|
||||
|
||||
#if defined(__GNUC__) && !defined(LKIWI_NO_BUILTIN)
|
||||
#define l_likely(x) (__builtin_expect(((x) != 0), 1))
|
||||
#define l_unlikely(x) (__builtin_expect(((x) != 0), 0))
|
||||
#define lk_likely(x) (__builtin_expect(((x) != 0), 1))
|
||||
#define lk_unlikely(x) (__builtin_expect(((x) != 0), 0))
|
||||
#else
|
||||
#define l_likely(x) (x)
|
||||
#define l_unlikely(x) (x)
|
||||
#define lk_likely(x) (x)
|
||||
#define lk_unlikely(x) (x)
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace kiwi;
|
||||
|
||||
// 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
|
||||
lua_Number n = lua_tonumber(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.
|
||||
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");
|
||||
for (; l->name != NULL; l++) { /* fill the table with given functions */
|
||||
if (l->func == NULL) /* place holder? */
|
||||
lua_pushboolean(L, 0);
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < nup; i++) /* copy upvalues to the top */
|
||||
for (int i = 0; i < nup; i++) /* copy upvalues to the top */
|
||||
lua_pushvalue(L, -nup);
|
||||
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 */
|
||||
}
|
||||
|
||||
#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 {
|
||||
|
||||
using namespace kiwi;
|
||||
void newlib(lua_State* L, const luaL_Reg* l) {
|
||||
lua_newtable(L);
|
||||
setfuncs(L, l, 0);
|
||||
}
|
||||
|
||||
enum KiwiErrKind {
|
||||
KiwiErrNone,
|
||||
@@ -80,20 +86,32 @@ 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.
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
KiwiTerm terms[];
|
||||
|
||||
static constexpr std::size_t sz(int count) {
|
||||
return sizeof(KiwiExpression) + sizeof(KiwiTerm) * (count > 0 ? count : 0);
|
||||
}
|
||||
#else
|
||||
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++
|
||||
// though it certainly isn't idiomatic.
|
||||
// This mechanism was initially designed for LuaJIT FFI.
|
||||
struct KiwiErr {
|
||||
enum KiwiErrKind kind;
|
||||
const char* message;
|
||||
bool must_free;
|
||||
bool must_delete;
|
||||
};
|
||||
|
||||
struct KiwiSolver {
|
||||
@@ -101,28 +119,27 @@ struct KiwiSolver {
|
||||
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))
|
||||
return base;
|
||||
|
||||
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) {
|
||||
return base;
|
||||
}
|
||||
|
||||
const auto* err = new (mem) KiwiErr {base->kind, mem + sizeof(KiwiErr), true};
|
||||
std::memcpy(const_cast<char*>(err->message), ex.what(), msg_n);
|
||||
return err;
|
||||
auto* msg = mem + sizeof(KiwiErr);
|
||||
std::memcpy(msg, ex.what(), msg_n);
|
||||
return new (mem) KiwiErr {base->kind, msg, true};
|
||||
}
|
||||
|
||||
const constexpr KiwiErr kKiwiErrUnhandledCxxException {
|
||||
KiwiErrUnknown,
|
||||
"An unhandled C++ exception occurred."};
|
||||
|
||||
template<typename F>
|
||||
inline const KiwiErr* wrap_err(F&& f) {
|
||||
static const constexpr KiwiErr kKiwiErrUnhandledCxxException {
|
||||
KiwiErrUnknown,
|
||||
"An unhandled C++ exception occurred."};
|
||||
|
||||
try {
|
||||
f();
|
||||
} catch (const UnsatisfiableConstraint&) {
|
||||
@@ -198,12 +215,12 @@ inline Constraint* kiwi_constraint_retain(Constraint* c) {
|
||||
return c;
|
||||
}
|
||||
|
||||
inline void kiwi_constraint_new(
|
||||
inline Constraint* kiwi_constraint_new(
|
||||
const KiwiExpression* lhs,
|
||||
const KiwiExpression* rhs,
|
||||
RelationalOperator op,
|
||||
double strength,
|
||||
Constraint* mem
|
||||
void* mem
|
||||
) {
|
||||
if (strength < 0.0) {
|
||||
strength = kiwi::strength::required;
|
||||
@@ -222,7 +239,7 @@ inline void kiwi_constraint_new(
|
||||
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)),
|
||||
static_cast<RelationalOperator>(op),
|
||||
strength
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user