Skip to content

Instantly share code, notes, and snippets.

@Rochet2
Last active January 13, 2018 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Rochet2/920bdd736b5fa501407597b83fb15f04 to your computer and use it in GitHub Desktop.
Save Rochet2/920bdd736b5fa501407597b83fb15f04 to your computer and use it in GitHub Desktop.
#ifndef STACK_INTERFACE_64
#define STACK_INTERFACE_64
#include "wrap64.h"
#include "sol.hpp"
namespace sol {
template <> struct lua_size<int64> : std::integral_constant<int, 1> {};
template <> struct lua_size<uint64> : std::integral_constant<int, 1> {};
template <> struct lua_type_of<int64> : std::integral_constant<sol::type, sol::type::userdata> {};
template <> struct lua_type_of<uint64> : std::integral_constant<sol::type, sol::type::userdata> {};
namespace stack {
template <> struct checker<int64> {
template <typename Handler>
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
int absolute_index = lua_absindex(L, index);
bool success = stack::check<wrap64<int64>>(L, absolute_index, handler);
tracking.use(1);
return success;
}
};
template <> struct getter<int64> {
static int64 get(lua_State* L, int index, record& tracking) {
int absolute_index = lua_absindex(L, index);
auto v = stack::check_get<wrap64<int64>>(L, absolute_index);
tracking.use(1);
if (v)
return v->raw;
return 0;
}
};
template <> struct pusher<int64> {
static int push(lua_State* L, const int64& v) {
int amount = stack::push(L, wrap64<int64>(v));
return amount;
}
};
}
namespace stack {
template <> struct checker<uint64> {
template <typename Handler>
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
int absolute_index = lua_absindex(L, index);
bool success = stack::check<wrap64<uint64>>(L, absolute_index, handler);
tracking.use(1);
return success;
}
};
template <> struct getter<uint64> {
static uint64 get(lua_State* L, int index, record& tracking) {
int absolute_index = lua_absindex(L, index);
auto v = stack::check_get<wrap64<uint64>>(L, absolute_index);
tracking.use(1);
if (v)
return v->raw;
return 0;
}
};
template <> struct pusher<uint64> {
static int push(lua_State* L, const uint64& v) {
int amount = stack::push(L, wrap64<uint64>(v));
return amount;
}
};
}
}
#endif
#include "wrap64.h"
#include "sol.hpp"
#include <limits> // std::numeric_limits
void Registerwrap64(sol::state& lua)
{
lua.new_usertype<wrap64<uint64>>("uint64",
sol::constructors<
wrap64<uint64>(),
wrap64<uint64>(uint64),
wrap64<uint64>(double),
wrap64<uint64>(uint32, uint32),
wrap64<uint64>(std::string const &)
>(),
// properties
"fitsint64", sol::property([](wrap64<uint64> const & v) { return v.raw <= static_cast<uint64>(std::numeric_limits<int64>::max()); }),
"int64", sol::property([](wrap64<uint64> const & v) { return static_cast<int64>(v.raw); }),
"fitsnumber", sol::property(&wrap64<uint64>::fitsdouble),
"number", sol::property(&wrap64<uint64>::to_double),
"string", sol::property(&wrap64<uint64>::to_string),
"hex", sol::property(&wrap64<uint64>::to_hex),
"high", sol::property(&wrap64<uint64>::high),
"low", sol::property(&wrap64<uint64>::low),
"empty", sol::property(&wrap64<uint64>::empty)
);
lua.new_usertype<wrap64<int64>>("int64",
sol::constructors<
wrap64<int64>(),
wrap64<int64>(int64),
wrap64<int64>(double),
wrap64<int64>(uint32, uint32),
wrap64<int64>(std::string const &)
>(),
// properties
"fitsuint64", sol::property([](wrap64<int64> const & v) { return v.raw >= 0; }),
"uint64", sol::property([](wrap64<int64> const & v) { return static_cast<uint64>(v.raw); }),
"fitsnumber", sol::property(&wrap64<int64>::fitsdouble),
"number", sol::property(&wrap64<int64>::to_double),
"string", sol::property(&wrap64<int64>::to_string),
"hex", sol::property(&wrap64<int64>::to_hex),
"high", sol::property(&wrap64<int64>::high),
"low", sol::property(&wrap64<int64>::low),
"empty", sol::property(&wrap64<int64>::empty)
);
}
#ifndef WRAP_64
#define WRAP_64
#include "Define.h" // (u)int64, UI64LIT, SI64LIT
#include <functional> // std::hash
#include <iomanip> // std::hex
#include <sstream> // std::stringstream
#include <string> // std::stoull, std::sto(u)ll
#include <type_traits> // std::enable_if, std::is_signed
static bool FitsDouble(uint64 raw) { return raw <= UI64LIT(0x20000000000000); }
static bool FitsDouble(int64 raw) { return raw <= SI64LIT(0x20000000000000) && raw >= SI64LIT(-0x20000000000000); }
static std::string ToHex(uint64 raw) {
std::ostringstream oss;
oss << std::hex << "0x" << raw;
return oss.str();
}
static std::string ToHex(int64 raw) {
std::ostringstream oss;
oss << std::hex;
if (raw < 0)
oss << "-0x" << -raw;
else
oss << "0x" << raw;
return oss.str();
}
template<typename T>
class TC_GAME_API wrap64
{
public:
wrap64() : raw(0) { }
wrap64(T raw) : raw(raw) { }
wrap64(double raw) : raw(static_cast<T>(raw)) { }
wrap64(uint32 hi, uint32 lo) : raw((T(hi) << 32) | T(lo)) { }
template<typename R = std::string const &>
wrap64(std::enable_if_t<std::is_signed<T>::value, R> s) : raw(std::stoll(s, 0, 0)) { }
template<typename R = std::string const &>
wrap64(std::enable_if_t<std::is_unsigned<T>::value, R> s) : raw(std::stoull(s, 0, 0)) { }
operator T() const { return raw; }
uint32 high() const { return raw >> 32; }
uint32 low() const { return raw & SI64LIT(0x00000000FFFFFFFF); }
bool empty() const { return raw == 0; }
bool operator!() const { return empty(); }
bool operator==(wrap64<T> const& w64) const { return raw == w64.raw; }
bool operator!=(wrap64<T> const& w64) const { return raw != raw; }
bool operator<(wrap64<T> const& w64) const { return raw < w64.raw; }
bool fitsdouble() const { return FitsDouble(raw); }
double to_double() const { return static_cast<double>(raw); }
std::string to_string() const { return std::to_string(raw); };
std::string to_hex() const {
return ToHex(raw);
};
T raw;
};
namespace std
{
template<>
struct hash<wrap64<uint64>>
{
public:
size_t operator()(wrap64<uint64> const& key) const
{
return std::hash<uint64>()(key.raw);
}
};
template<>
struct hash<wrap64<int64>>
{
public:
size_t operator()(wrap64<int64> const& key) const
{
return std::hash<int64>()(key.raw);
}
};
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment