mirror of
https://github.com/holub/mame
synced 2025-06-04 03:46:29 +03:00
luaengine: use initializers (nw)
This commit is contained in:
parent
4d533249fd
commit
a68d423992
2
3rdparty/sol2/docs/source/api/containers.rst
vendored
2
3rdparty/sol2/docs/source/api/containers.rst
vendored
@ -100,4 +100,4 @@ If you have a type that has ``begin`` or ``end`` member functions but don't prov
|
||||
namespace sol {
|
||||
template <>
|
||||
struct is_container<not_container> : std::false_type {};
|
||||
}
|
||||
}
|
8
3rdparty/sol2/docs/source/api/function.rst
vendored
8
3rdparty/sol2/docs/source/api/function.rst
vendored
@ -82,13 +82,17 @@ This makes it much easier to work with multiple return values. Using ``std::tie`
|
||||
|
||||
Calls the function. The second ``operator()`` lets you specify the templated return types using the ``my_func(sol::types<int, std::string>, ...)`` syntax. Function assumes there are no runtime errors, and thusly will call the ``atpanic`` function if an error does occur.
|
||||
|
||||
|
||||
.. _function-argument-handling:
|
||||
|
||||
functions and argument passing
|
||||
------------------------------
|
||||
|
||||
.. note::
|
||||
|
||||
All arguments are forwarded. Unlike :doc:`get/set/operator[] on sol::state<state>` or :doc:`sol::table<table>`, value semantics are not used here. It is forwarding reference semantics, which do not copy/move unless it is specifically done by the receiving functions / specifically done by the user.
|
||||
|
||||
|
||||
.. _function-argument-handling:
|
||||
|
||||
.. note::
|
||||
|
||||
This also means that you should pass and receive arguments in certain ways to maximize efficiency. For example, ``sol::table``, ``sol::object``, ``sol::userdata`` and friends are fairly cheap to copy, and should simply by taken as values. This includes primitive types like ``int`` and ``double``. However, C++ types -- if you do not want copies -- should be taken as ``const type&`` or ``type&``, to save on copies if it's important. Note that taking references from Lua also means you can modify the data inside of Lua directly, so be careful. Lua by default deals with things mostly by reference (save for primitive types).
|
||||
|
28
3rdparty/sol2/docs/source/api/resolve.rst
vendored
28
3rdparty/sol2/docs/source/api/resolve.rst
vendored
@ -7,9 +7,9 @@ utility to pick overloaded C++ function calls
|
||||
:caption: function: resolve C++ overload
|
||||
|
||||
template <typename... Args, typename F>
|
||||
auto resolve( F f );
|
||||
constexpr auto resolve( F f );
|
||||
|
||||
``resolve`` is a function that is meant to help users pick a single function out of a group of overloaded functions in C++. You can use it to pick overloads by specifying the signature as the first template argument. Given a collection of overloaded functions:
|
||||
``resolve`` is a function that is meant to help users pick a single function out of a group of overloaded functions in C++. It works for *both member and free functions* You can use it to pick overloads by specifying the signature as the first template argument. Given a collection of overloaded functions:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
@ -18,6 +18,12 @@ utility to pick overloaded C++ function calls
|
||||
int overloaded(int x, int y);
|
||||
int overloaded(int x, int y, int z);
|
||||
|
||||
struct thing {
|
||||
int overloaded(int x);
|
||||
int overloaded(int x, int y);
|
||||
int overloaded(int x, int y, int z);
|
||||
};
|
||||
|
||||
You can disambiguate them using ``resolve``:
|
||||
|
||||
.. code-block:: cpp
|
||||
@ -26,6 +32,7 @@ You can disambiguate them using ``resolve``:
|
||||
auto one_argument_func = resolve<int(int)>( overloaded );
|
||||
auto two_argument_func = resolve<int(int, int)>( overloaded );
|
||||
auto three_argument_func = resolve<int(int, int, int)>( overloaded );
|
||||
auto member_three_argument_func = resolve<int(int, int, int)>( &thing::overloaded );
|
||||
|
||||
This resolution becomes useful when setting functions on a :doc:`table<table>` or :doc:`state_view<state>`:
|
||||
|
||||
@ -37,3 +44,20 @@ This resolution becomes useful when setting functions on a :doc:`table<table>` o
|
||||
lua.set_function("a", resolve<int(int)>( overloaded ) );
|
||||
lua.set_function("b", resolve<int(int, int)>( overloaded ));
|
||||
lua.set_function("c", resolve<int(int, int, int)>( overloaded ));
|
||||
|
||||
|
||||
It can also be used with :doc:`sol::c_call<c_call>`:
|
||||
|
||||
.. code-block:: cpp
|
||||
:linenos:
|
||||
|
||||
sol::state lua;
|
||||
|
||||
auto f = sol::c_call<
|
||||
decltype(sol::resolve<int(int, int)>(&overloaded)),
|
||||
sol::resolve<int(int, int)>(&overloaded)
|
||||
>;
|
||||
lua.set_function("f", f);
|
||||
|
||||
lua.script("f(1, 2)");
|
||||
|
||||
|
2
3rdparty/sol2/docs/source/codecvt.rst
vendored
2
3rdparty/sol2/docs/source/codecvt.rst
vendored
@ -3,6 +3,6 @@ std::(w/u16/u32)string support
|
||||
because this is surprisingly hard using standard C++
|
||||
----------------------------------------------------
|
||||
|
||||
Individuals using Visual Studio 2015, or on Windows with the VC++ and MinGW compilers (possibly Clang++ on Windows as well) have ``<codecvt>`` headers, and thusly Sol will attempt to include it. Individuals on GC 4.9.x, Clang 3.5.x, Clang 3.6.x do not seem to have ``<codecvt>`` shipped with the standard library that comes with installation of these compilers. If you want ``std::wstring``, ``std::u16string``, ``std::u32string`` automatic handling then you need to make sure you have those headers and then define ``SOL_CODECVT_SUPPORT``.
|
||||
Individuals using Visual Studio 2015, or on Windows with the VC++ and MinGW compilers (possibly Clang++ on Windows as well) have ``<codecvt>`` headers, and thusly Sol will attempt to include it. Individuals on GC 4.9.x, Clang 3.5.x, Clang 3.6.x do not seem to have ``<codecvt>`` shipped with the standard library that comes with installation of these compilers. If you want ``std::wstring``, ``std::u16string``, ``std::u32string`` automatic handling then you need to make sure you have those headers and then define ``SOL_CODECVT_SUPPORT`` on unsupported compilers.
|
||||
|
||||
ThePhD did not want this to have to be a thing, but slow implementations and such force their hand. When GCC 7.x comes out, ThePhD will consider removing the effect of defining this macro and leaving <codecvt> support in at all times.
|
||||
|
2
3rdparty/sol2/docs/source/conf.py
vendored
2
3rdparty/sol2/docs/source/conf.py
vendored
@ -61,7 +61,7 @@ author = 'ThePhD'
|
||||
# The short X.Y version.
|
||||
version = '2.15'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '2.15.0'
|
||||
release = '2.15.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
8
3rdparty/sol2/docs/source/errors.rst
vendored
8
3rdparty/sol2/docs/source/errors.rst
vendored
@ -10,8 +10,9 @@ Catch and CRASH!
|
||||
|
||||
By default, Sol will add a ``default_at_panic`` handler. If exceptions are not turned off, this handler will throw to allow the user a chance to recover. However, in almost all cases, when Lua calls ``lua_atpanic`` and hits this function, it means that something *irreversibly wrong* occured in your code or the Lua code and the VM is in an unpredictable or dead state. Catching an error thrown from the default handler and then proceeding as if things are cleaned up or okay is NOT the best idea. Unexpected bugs in optimized and release mode builds can result, among other serious issues.
|
||||
|
||||
It is preferred if you catch an error that you log what happened, terminate the Lua VM as soon as possible, and then crash if your application cannot handle spinning up a new Lua state. Catching can be done, but you should understand the risks of what you're doing when you do it. For more information about catching exceptions, the potentials, not turning off exceptions and other tricks and caveats, read about :doc:`exceptions in Sol here<exceptions>`.
|
||||
|
||||
It is preferred if you catch an error that you log what happened, terminate the Lua VM as soon as possible, and then crash if your application cannot handle spinning up a new Lua state. Catching can be done, but you should understand the risks of what you're doing when you do it.
|
||||
Lua is a C API first and foremost: exceptions bubbling out of it is essentially last-ditch, terminal behavior that the VM does not expect. You can see an example of handling a panic on the exceptions page :ref:`here<typical-panic-function>`.
|
||||
|
||||
|
||||
Destructors and Safety
|
||||
@ -25,6 +26,11 @@ Protected Functions and Access
|
||||
|
||||
By default, :doc:`sol::function<api/function>` assumes the code ran just fine and there are no problems. :ref:`sol::state(_view)::script(_file)<state-script-function>` also assumes that code ran just fine. Use :doc:`sol::protected_function<api/protected_function>` to have function access where you can check if things worked out. Use :doc:`sol::optional<api/optional>` to get a value safely from Lua. Use :ref:`sol::state(_view)::do_string/do_file/load/load_file<state-do-code>` to safely load and get results from a script. The defaults are provided to be simple and fast with thrown exceptions to violently crash the VM in case things go wrong.
|
||||
|
||||
Protected Functions Are Not Catch All
|
||||
-------------------------------------
|
||||
|
||||
Sometimes, some scripts load poorly. Even if you protect the function call, the actual file loading or file execution will be bad, in which case :doc:`sol::protected_function<api/protected_function>` will not save you. Make sure you register your own panic handler so you can catch errors, or follow the advice of the catch + crash behavior above.
|
||||
|
||||
Raw Functions
|
||||
-------------
|
||||
|
||||
|
36
3rdparty/sol2/docs/source/exceptions.rst
vendored
36
3rdparty/sol2/docs/source/exceptions.rst
vendored
@ -11,23 +11,27 @@ To make this not be the case, you can set a panic function directly with ``lua_a
|
||||
|
||||
.. code-block:: cpp
|
||||
:caption: regular panic function
|
||||
:name: typical-panic-function
|
||||
|
||||
#include <sol.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int my_panic_function( lua_State* L ) {
|
||||
// error message is at the top of the stack
|
||||
const char* message = lua_tostring(L, -1);
|
||||
// message can be null, so don't crash
|
||||
// us with nullptr-constructed-string if it is
|
||||
std::string err = message ? message : "An unexpected error occurred and forced the lua state to call atpanic";
|
||||
// Weee
|
||||
std::cerr << err << std::endl;
|
||||
inline void my_panic(sol::optional<std::string> maybe_msg) {
|
||||
std::cerr << "Lua is in a panic state and will now abort() the application" << std::endl;
|
||||
if (maybe_msg) {
|
||||
const std::string& msg = maybe_msg.value();
|
||||
std::cerr << "\terror message: " << msg << std::endl;
|
||||
}
|
||||
// When this function exits, Lua will exhibit default behavior and abort()
|
||||
}
|
||||
|
||||
int main () {
|
||||
sol::state lua(my_panic_function);
|
||||
sol::state lua(sol::c_call<decltype(&my_panic), &my_panic>);
|
||||
// or, if you already have a lua_State* L
|
||||
// lua_atpanic( L, sol::c_call<decltype(&my_panic)>, &my_panic> );
|
||||
// or, with state/state_view:
|
||||
// sol::state_view lua(L);
|
||||
// lua.set_panic( sol::c_call<decltype(&my_panic)>, &my_panic> );
|
||||
}
|
||||
|
||||
|
||||
@ -41,11 +45,21 @@ If there is a place where a throw statement is called or a try/catch is used and
|
||||
LuaJIT and exceptions
|
||||
---------------------
|
||||
|
||||
It is important to note that a popular 5.1 distribution of Lua, LuaJIT, has some serious `caveats regarding exceptions`_. LuaJIT's exception promises are flaky at best on x64 (64-bit) platforms, and entirely terrible on non-x64 (32-bit, ARM, etc.) platorms. The trampolines we have in place for all functions bound through conventional means in Sol will catch exceptions and turn them into Lua errors so that LuaJIT remainds unperturbed, but if you link up a C function directly yourself and throw, chances are you might have screwed the pooch.
|
||||
It is important to note that a popular 5.1 distribution of Lua, LuaJIT, has some serious `caveats regarding exceptions`_. LuaJIT's exception promises are flaky at best on x64 (64-bit) platforms, and entirely terrible on non-x64 (32-bit, ARM, etc.) platforms. The trampolines we have in place for all functions bound through conventional means in Sol will catch exceptions and turn them into Lua errors so that LuaJIT remainds unperturbed, but if you link up a C function directly yourself and throw, chances are you might have screwed the pooch.
|
||||
|
||||
Testing in `this closed issue`_ that it doesn't play nice on 64-bit Linux in many cases either, especially when it hits an error internal to the interpreter (and does not go through Sol). We do have tests, however, that compile for our continuous integration check-ins that check this functionality across several compilers and platforms to keep you protected and given hard, strong guarantees for what happens if you throw in a function bound by Sol. If you stray outside the realm of Sol's protection, however... Good luck.
|
||||
|
||||
Lua and LuaJIT C++ Exception Full Interoperability
|
||||
--------------------------------------------------
|
||||
|
||||
You can ``#define SOL_EXCEPTIONS_SAFE_PROPAGATION`` before including Sol or define ``SOL_EXCEPTIONS_SAFE_PROPAGATION`` on the command line if you know your implmentation of Lua has proper unwinding semantics that can be thrown through the version of the Lua API you have built / are using.
|
||||
|
||||
This will prevent sol from catching ``(...)`` errors in platforms and compilers that have full C++ exception interoperability. This means that Lua errors can be caught with ``catch (...)`` in the C++ end of your code after it goes through Lua, and exceptions can pass through the Lua API and Stack safely.
|
||||
|
||||
Currently, the only known platform to do this is the listed "Full" `platforms for LuaJIT`_ and Lua compiled as C++. This define is not turned on automatically, even if Sol detects LuaJIT: *it is your job to define it if you know that your platform supports it*!
|
||||
|
||||
.. _issue: https://github.com/ThePhD/sol2/issues/
|
||||
.. _at_panic: http://www.Lua.org/manual/5.3/manual.html#4.6
|
||||
.. _caveats regarding exceptions: http://luajit.org/extensions.html#exceptions
|
||||
.. _this closed issue: https://github.com/ThePhD/sol2/issues/28
|
||||
.. _platforms for LuaJIT: http://luajit.org/extensions.html#exceptions
|
||||
.. _this closed issue: https://github.com/ThePhD/sol2/issues/28
|
||||
|
5
3rdparty/sol2/docs/source/mentions.rst
vendored
5
3rdparty/sol2/docs/source/mentions.rst
vendored
@ -24,7 +24,8 @@ Okay, so the features don't convince you, the documentation doesn't convince you
|
||||
| |before| | |after| |
|
||||
+----------+---------+
|
||||
|
||||
|
||||
* The `Multiple Arcade Machine Emulator (MAME)`_ project switched from using LuaBridge to sol2!
|
||||
- `The pull request`_ in which it was introduced to the master branch.
|
||||
* (CppNow) sol2 was mentioned in a comparison to other scripting languages by ChaiScript developer, Jason Turner (@lefticus), at a conference!
|
||||
- `Jason Turner's presentation`_
|
||||
* (CppCast) Showed up in CppCast with Elias Daler!
|
||||
@ -57,3 +58,5 @@ Are you using sol2 for something neat? Want it to be featured here or think it's
|
||||
.. _sol2's initial reddit release: https://www.reddit.com/r/cpp/comments/4a8gy7/sol2_lua_c_binding_framework/
|
||||
.. _Benchmarking Discussing: https://www.reddit.com/r/cpp/comments/4x82hd/plain_c_versus_lua_libraries_benchmarking_speed/
|
||||
.. _"sol2 saved my life.": https://twitter.com/EliasDaler/status/739215685264494593
|
||||
.. _Multiple Arcade Machine Emulator (MAME): http://www.mamedev.org/index.php
|
||||
.. _The pull request: https://github.com/mamedev/mame/pull/1626
|
||||
|
1
3rdparty/sol2/docs/source/performance.rst
vendored
1
3rdparty/sol2/docs/source/performance.rst
vendored
@ -9,6 +9,7 @@ As shown by the :doc:`benchmarks<benchmarks>`, Sol is very performant with its a
|
||||
* If you have a bound function call / bound member function that you are going to call in a very tight, performance-heavy loop, considering using :doc:`sol::c_call<api/c_call>`
|
||||
* Be wary of passing by value / reference, and what it means by reading :ref:`this note<function-argument-handling>`.
|
||||
* It is currently undocumented that usertypes will "inherit" member function / member variables from bound classes, mostly because the semantics are unclear and it is not the most performant (although it is flexible: you can register base classes after / whenever you want in relation to the derived class, provided that derived class has its bases listed). Specifying all member functions / member variables for the usertype constructor / ``new_usertype`` function call and not relying on base lookup will boost performance of member lookup
|
||||
* Use the :doc:`sol::stack_{}<api/stack_reference>` versions of functions in order to achieve maximum performance benefits when doing things like calling a function from Lua and knowing that certain arguments of certain Lua types will be on the stack. This can save you a very small fraction of performance to not copy to the register (but is also more dangerous and usually not terribly worth it).
|
||||
* Specifying base classes can make getting the usertype out of Sol a bit slower since we have to check and cast; if you know the exact type wherever you're retrieving it, considering not specifying the bases, retrieving the exact type from Sol, and then casting to a base type yourself
|
||||
* Member variables can sometimes cost an extra lookup to occur within the Lua system (as mentioned :doc:`bottom of the usertype page<api/usertype>`); until we find out a safe way around this, member variables will always incur that extra lookup cost
|
||||
|
||||
|
4
3rdparty/sol2/docs/source/safety.rst
vendored
4
3rdparty/sol2/docs/source/safety.rst
vendored
@ -3,7 +3,7 @@ safety
|
||||
|
||||
Sol was designed to be correct and fast, and in the pursuit of both uses the regular ``lua_to{x}`` functions of Lua rather than the checking versions (``lua_check{X}``) functions. The API defaults to paranoidly-safe alternatives if you have a ``#define SOL_CHECK_ARGUMENTS`` before you include Sol, or if you pass the ``SOL_CHECK_ARGUMENTS`` define on the build command for your build system. By default, it is off and remains off unless you define this, even in debug mode. The same goes for ``#define SOL_SAFE_USERTYPE``.
|
||||
|
||||
Note that you can obtain safety with regards to functions you bind by using the :doc:`protect<api/protect>` wrapper around function/variable bindings you set into Lua.
|
||||
Note that you can obtain safety with regards to functions you bind by using the :doc:`protect<api/protect>` wrapper around function/variable bindings you set into Lua. Additionally, you can have basic boolean checks when using the API by just converting to a :doc:`sol::optional\<T><api/optional>` when necessary for getting things out of Lua and for function arguments.
|
||||
|
||||
``SOL_SAFE_USERTYPE`` triggers the following change:
|
||||
* If the userdata to a usertype function is nil, will trigger an error instead of letting things go through and letting the system segfault.
|
||||
@ -13,7 +13,7 @@ Note that you can obtain safety with regards to functions you bind by using the
|
||||
* ``sol::stack::call`` and its variants will, if no templated boolean is specified, check all of the arguments for a function call.
|
||||
* If ``SOL_SAFE_USERTYPE`` is not defined, it gets defined to turn being on.
|
||||
|
||||
Remember that if you want these features, you must explicitly turn them on. Additionally, you can have basic boolean checks when using the API by just converting to a :doc:`sol::optional\<T><api/optional>` when necessary. Tests are compiled with this on to ensure everythign is going as expected.
|
||||
Tests are compiled with this on to ensure everything is going as expected. Remember that if you want these features, you must explicitly turn them on.
|
||||
|
||||
Finally, some warnings that may help with errors when working with Sol:
|
||||
|
||||
|
5
3rdparty/sol2/docs/source/usertypes.rst
vendored
5
3rdparty/sol2/docs/source/usertypes.rst
vendored
@ -23,4 +23,7 @@ The examples folder also has a number of really great examples for you to see. T
|
||||
* Member methods, properties, variables and functions taking ``self&`` arguments modify data directly
|
||||
- Work on a copy by taking or returning a copy by value.
|
||||
* The actual metatable associated with the usertype has a long name and is defined to be opaque by the Sol implementation.
|
||||
* Containers get pushed as special usertypes, but can be disabled if problems arising as detailed :doc:`here<api/containers>`.
|
||||
* Containers get pushed as special usertypes, but can be disabled if problems arising as detailed :doc:`here<api/containers>`.
|
||||
* You can use bitfields but it requires some finesse on your part. We have an example to help you get started `here that uses a few tricks`_.
|
||||
|
||||
.. _here that uses a few tricks: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_bitfields.cpp
|
||||
|
164
3rdparty/sol2/examples/usertype_bitfields.cpp
vendored
Normal file
164
3rdparty/sol2/examples/usertype_bitfields.cpp
vendored
Normal file
@ -0,0 +1,164 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <climits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace itsy_bitsy {
|
||||
|
||||
template <std::size_t sz, typename C = void>
|
||||
struct bit_type {
|
||||
typedef uint64_t type;
|
||||
};
|
||||
|
||||
template <std::size_t sz>
|
||||
struct bit_type<sz, std::enable_if_t<(sz <= 1)>> {
|
||||
typedef bool type;
|
||||
};
|
||||
|
||||
template <std::size_t sz>
|
||||
struct bit_type<sz, std::enable_if_t<(sz > 2 && sz <= 16)>> {
|
||||
typedef uint16_t type;
|
||||
};
|
||||
|
||||
template <std::size_t sz>
|
||||
struct bit_type<sz, std::enable_if_t<(sz > 16 && sz <= 32)>> {
|
||||
typedef uint32_t type;
|
||||
};
|
||||
|
||||
template <std::size_t sz>
|
||||
struct bit_type<sz, std::enable_if_t<(sz > 32 && sz <= 64)>> {
|
||||
typedef uint64_t type;
|
||||
};
|
||||
|
||||
template <std::size_t sz>
|
||||
using bit_type_t = typename bit_type<sz>::type;
|
||||
|
||||
template <typename T, typename V>
|
||||
bool vcxx_warning_crap(std::true_type, V val) {
|
||||
return val != 0;
|
||||
}
|
||||
|
||||
template <typename T, typename V>
|
||||
T vcxx_warning_crap(std::false_type, V val) {
|
||||
return static_cast<T>(val);
|
||||
}
|
||||
|
||||
template <typename T, typename V>
|
||||
auto vcxx_warning_crap(V val) {
|
||||
return vcxx_warning_crap<T>(std::is_same<bool, T>(), val);
|
||||
}
|
||||
|
||||
template <typename Base, std::size_t bit_target = 0x0, std::size_t size = 0x1>
|
||||
void write(Base& b, bit_type_t<size> bits) {
|
||||
typedef bit_type_t<sizeof(Base) * CHAR_BIT> aligned_type;
|
||||
static const std::size_t aligned_type_bit_size = sizeof(aligned_type) * CHAR_BIT;
|
||||
static_assert(sizeof(Base) * CHAR_BIT >= (bit_target + size), "bit offset and size are too large for the desired structure.");
|
||||
static_assert((bit_target % aligned_type_bit_size) <= ((bit_target + size) % aligned_type_bit_size), "bit offset and size cross beyond largest integral constant boundary.");
|
||||
|
||||
const std::size_t aligned_target = (bit_target + size) / aligned_type_bit_size;
|
||||
const aligned_type bits_left = static_cast<aligned_type>(bit_target - aligned_target);
|
||||
const aligned_type shifted_mask = ((static_cast<aligned_type>(1) << size) - 1) << bits_left;
|
||||
const aligned_type compl_shifted_mask = ~shifted_mask;
|
||||
// Jump by native size of a pointer to target
|
||||
// then OR the bits
|
||||
aligned_type* jumper = static_cast<aligned_type*>(static_cast<void*>(&b));
|
||||
jumper += aligned_target;
|
||||
aligned_type& aligned = *jumper;
|
||||
aligned &= compl_shifted_mask;
|
||||
aligned |= (static_cast<aligned_type>(bits) << bits_left);
|
||||
}
|
||||
|
||||
template <typename Base, std::size_t bit_target = 0x0, std::size_t size = 0x1>
|
||||
bit_type_t<size> read(Base& b) {
|
||||
typedef bit_type_t<sizeof(Base) * CHAR_BIT> aligned_type;
|
||||
typedef bit_type_t<size> field_type;
|
||||
static const std::size_t aligned_type_bit_size = sizeof(aligned_type) * CHAR_BIT;
|
||||
static_assert(sizeof(Base) * CHAR_BIT >= (bit_target + size), "bit offset and size are too large for the desired structure.");
|
||||
static_assert((bit_target % aligned_type_bit_size) <= ((bit_target + size) % aligned_type_bit_size), "bit offset and size cross beyond largest integral constant boundary.");
|
||||
|
||||
const std::size_t aligned_target = (bit_target + size) / aligned_type_bit_size;
|
||||
const aligned_type bits_left = static_cast<aligned_type>(bit_target - aligned_target);
|
||||
const aligned_type mask = (static_cast<aligned_type>(1) << size) - 1;
|
||||
// Jump by native size of a pointer to target
|
||||
// then OR the bits
|
||||
aligned_type* jumper = static_cast<aligned_type*>(static_cast<void*>(&b));
|
||||
jumper += aligned_target;
|
||||
const aligned_type& aligned = *jumper;
|
||||
aligned_type field_bits = (aligned >> bits_left) & mask;
|
||||
field_type bits = vcxx_warning_crap<field_type>(field_bits);
|
||||
return bits;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#pragma pack(1)
|
||||
struct flags_t {
|
||||
#else
|
||||
struct __attribute__((packed, aligned(1))) flags_t {
|
||||
#endif
|
||||
uint8_t C : 1;
|
||||
uint8_t N : 1;
|
||||
uint8_t PV : 1;
|
||||
uint8_t _3 : 1;
|
||||
uint8_t H : 1;
|
||||
uint8_t _5 : 1;
|
||||
uint8_t Z : 1;
|
||||
uint8_t S : 1;
|
||||
uint16_t D : 14;
|
||||
} flags{};
|
||||
|
||||
int main() {
|
||||
std::cout << "=== usertype_bitfields example ===" << std::endl;
|
||||
#ifdef __MINGW32__
|
||||
std::cout << "MinGW Detected, packing structs is broken in MinGW and this test may fail" << std::endl;
|
||||
#endif
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.new_usertype<flags_t>("flags_t",
|
||||
"C", sol::property(itsy_bitsy::read<flags_t, 0>, itsy_bitsy::write<flags_t, 0>),
|
||||
"N", sol::property(itsy_bitsy::read<flags_t, 1>, itsy_bitsy::write<flags_t, 1>),
|
||||
"D", sol::property(itsy_bitsy::read<flags_t, 8, 14>, itsy_bitsy::write<flags_t, 8, 14>)
|
||||
);
|
||||
|
||||
lua["f"] = std::ref(flags);
|
||||
|
||||
lua.script(R"(
|
||||
print(f.C)
|
||||
f.C = true;
|
||||
print(f.C)
|
||||
|
||||
print(f.N)
|
||||
f.N = true;
|
||||
print(f.N)
|
||||
|
||||
print(f.D)
|
||||
f.D = 0xDF;
|
||||
print(f.D)
|
||||
)");
|
||||
|
||||
bool C = flags.C;
|
||||
bool N = flags.N;
|
||||
uint16_t D = flags.D;
|
||||
|
||||
std::cout << std::hex;
|
||||
std::cout << "sizeof(flags): " << sizeof(flags) << std::endl;
|
||||
std::cout << "C: " << C << std::endl;
|
||||
std::cout << "N: " << N << std::endl;
|
||||
std::cout << "D: " << D << std::endl;
|
||||
|
||||
assert(C);
|
||||
assert(N);
|
||||
assert(D == 0xDF);
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -34,7 +34,7 @@ int main() {
|
||||
"norm", [](const vec& self) { double len = std::sqrt(dot(self, self)); return vec(self.x / len, self.y / len); },
|
||||
// we use `sol::resolve` because other operator+ can exist
|
||||
// in the (global) namespace
|
||||
sol::meta_function::addition, sol::resolve<const vec&, const vec&>(::operator+),
|
||||
sol::meta_function::addition, sol::resolve<vec(const vec&, const vec&)>(::operator+),
|
||||
sol::meta_function::subtraction, &vec::operator-
|
||||
);
|
||||
|
||||
|
469
3rdparty/sol2/single/sol/sol.hpp
vendored
469
3rdparty/sol2/single/sol/sol.hpp
vendored
@ -20,8 +20,8 @@
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// This file was generated with a script.
|
||||
// Generated 2016-11-07 18:50:10.518977 UTC
|
||||
// This header was generated with sol v2.15.0 (revision 29f10c4)
|
||||
// Generated 2016-11-16 03:43:41.504038 UTC
|
||||
// This header was generated with sol v2.15.1 (revision 4aec055)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||
@ -374,6 +374,9 @@ namespace sol {
|
||||
template<typename... Args>
|
||||
struct is_tuple<std::tuple<Args...>> : std::true_type { };
|
||||
|
||||
template <typename T>
|
||||
struct is_builtin_type : std::integral_constant<bool, std::is_arithmetic<T>::value || std::is_pointer<T>::value || std::is_array<T>::value> {};
|
||||
|
||||
template<typename T>
|
||||
struct unwrapped {
|
||||
typedef T type;
|
||||
@ -767,7 +770,7 @@ namespace sol {
|
||||
|
||||
#include <lua.hpp>
|
||||
|
||||
#if defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#if defined(_WIN32) || defined(_MSC_VER)
|
||||
#ifndef SOL_CODECVT_SUPPORT
|
||||
#define SOL_CODECVT_SUPPORT 1
|
||||
#endif // sol codecvt support
|
||||
@ -776,7 +779,7 @@ namespace sol {
|
||||
#ifndef SOL_CODECVT_SUPPORT
|
||||
#define SOL_CODECVT_SUPPORT 1
|
||||
#endif // codecvt support
|
||||
#endif // g++ 5.x.x
|
||||
#endif // g++ 5.x.x (MinGW too)
|
||||
#else
|
||||
#endif // Windows/VC++ vs. g++ vs Others
|
||||
|
||||
@ -2408,7 +2411,7 @@ namespace sol {
|
||||
#ifdef SOL_NO_EXCEPTIONS
|
||||
// we can abort here
|
||||
// but the others are constexpr, so we can't...
|
||||
: (std::abort(), *(T*)nullptr)
|
||||
: (std::abort(), *(T*)nullptr);
|
||||
#else
|
||||
: (throw bad_optional_access("bad optional access"), contained_val());
|
||||
#endif
|
||||
@ -2997,9 +3000,11 @@ namespace sol {
|
||||
catch (const std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
catch (...) {
|
||||
lua_pushstring(L, "caught (...) exception");
|
||||
}
|
||||
#endif
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
@ -3014,9 +3019,11 @@ namespace sol {
|
||||
catch (const std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
catch (...) {
|
||||
lua_pushstring(L, "caught (...) exception");
|
||||
}
|
||||
#endif
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
@ -4603,13 +4610,13 @@ namespace sol {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::string demangle() {
|
||||
inline const std::string& demangle() {
|
||||
static const std::string d = demangle_once<T>();
|
||||
return d;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::string short_demangle() {
|
||||
inline const std::string& short_demangle() {
|
||||
static const std::string d = short_demangle_once<T>();
|
||||
return d;
|
||||
}
|
||||
@ -4623,11 +4630,11 @@ namespace sol {
|
||||
template<typename T>
|
||||
struct usertype_traits {
|
||||
static const std::string& name() {
|
||||
static const std::string n = detail::short_demangle<T>();
|
||||
static const std::string& n = detail::short_demangle<T>();
|
||||
return n;
|
||||
}
|
||||
static const std::string& qualified_name() {
|
||||
static const std::string q_n = detail::demangle<T>();
|
||||
static const std::string& q_n = detail::demangle<T>();
|
||||
return q_n;
|
||||
}
|
||||
static const std::string& metatable() {
|
||||
@ -4643,7 +4650,7 @@ namespace sol {
|
||||
return u_g_m;
|
||||
}
|
||||
static const std::string& gc_table() {
|
||||
static const std::string g_t = std::string("sol.").append(detail::demangle<T>().append(".\xE2\x99\xBB"));
|
||||
static const std::string g_t = std::string("sol.").append(detail::demangle<T>()).append(".\xE2\x99\xBB");
|
||||
return g_t;
|
||||
}
|
||||
};
|
||||
@ -5086,13 +5093,17 @@ namespace sol {
|
||||
template<typename T, typename C>
|
||||
struct checker<optional<T>, type::poly, C> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
static bool check(lua_State* L, int index, Handler&&, record& tracking) {
|
||||
type t = type_of(L, index);
|
||||
if (t == type::none) {
|
||||
tracking.use(0);
|
||||
return true;
|
||||
}
|
||||
return t == type::nil || stack::check<T>(L, index, std::forward<Handler>(handler), tracking);
|
||||
if (t == type::nil) {
|
||||
tracking.use(1);
|
||||
return true;
|
||||
}
|
||||
return stack::check<T>(L, index, no_panic, tracking);
|
||||
}
|
||||
};
|
||||
} // stack
|
||||
@ -6975,13 +6986,16 @@ namespace sol {
|
||||
return call_into_lua(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||
}
|
||||
|
||||
inline call_syntax get_call_syntax(lua_State* L, const std::string& key, int index = -2) {
|
||||
inline call_syntax get_call_syntax(lua_State* L, const std::string& key, int index) {
|
||||
if (lua_gettop(L) == 0) {
|
||||
return call_syntax::dot;
|
||||
}
|
||||
luaL_getmetatable(L, key.c_str());
|
||||
auto pn = pop_n(L, 1);
|
||||
if (lua_compare(L, -1, index, LUA_OPEQ) == 1) {
|
||||
return call_syntax::colon;
|
||||
if (lua_compare(L, -1, index, LUA_OPEQ) != 1) {
|
||||
return call_syntax::dot;
|
||||
}
|
||||
return call_syntax::dot;
|
||||
return call_syntax::colon;
|
||||
}
|
||||
|
||||
inline void script(lua_State* L, const std::string& code) {
|
||||
@ -7871,7 +7885,7 @@ namespace sol {
|
||||
};
|
||||
|
||||
static int call(lua_State* L, F& f) {
|
||||
call_syntax syntax = stack::get_call_syntax(L, &usertype_traits<T>::user_metatable()[0]);
|
||||
call_syntax syntax = stack::get_call_syntax(L, &usertype_traits<T>::user_metatable()[0], 1);
|
||||
int syntaxval = static_cast<int>(syntax);
|
||||
int argcount = lua_gettop(L) - syntaxval;
|
||||
return construct_match<T, meta::pop_front_type_t<meta::function_args_t<Cxs>>...>(onmatch(), L, argcount, 1 + syntaxval, f);
|
||||
@ -8296,9 +8310,6 @@ namespace sol {
|
||||
template<typename Func>
|
||||
struct functor_function {
|
||||
typedef meta::unwrapped_t<meta::unqualified_t<Func>> Function;
|
||||
typedef decltype(&Function::operator()) function_type;
|
||||
typedef meta::function_return_t<function_type> return_type;
|
||||
typedef meta::function_args_t<function_type> args_lists;
|
||||
Function fx;
|
||||
|
||||
template<typename... Args>
|
||||
@ -8406,6 +8417,75 @@ namespace sol {
|
||||
// beginning of sol/resolve.hpp
|
||||
|
||||
namespace sol {
|
||||
// Clang has distinct problems with constexpr arguments,
|
||||
// so don't use the constexpr versions inside of clang.
|
||||
#ifndef __clang__
|
||||
namespace detail {
|
||||
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
||||
inline constexpr auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
||||
using Sig = R(Args...);
|
||||
typedef meta::unqualified_t<F> Fu;
|
||||
return static_cast<Sig Fu::*>(&Fu::operator());
|
||||
}
|
||||
|
||||
template<typename F, typename U = meta::unqualified_t<F>>
|
||||
inline constexpr auto resolve_f(std::true_type, F&& f)
|
||||
-> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
|
||||
return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline constexpr void resolve_f(std::false_type, F&&) {
|
||||
static_assert(meta::has_deducible_signature<F>::value,
|
||||
"Cannot use no-template-parameter call with an overloaded functor: specify the signature");
|
||||
}
|
||||
|
||||
template<typename F, typename U = meta::unqualified_t<F>>
|
||||
inline constexpr auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
|
||||
return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template<typename... Args, typename F, typename R = std::result_of_t<F&(Args...)>>
|
||||
inline constexpr auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
|
||||
return resolve_i(types<R(Args...)>(), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template<typename Sig, typename C>
|
||||
inline constexpr Sig C::* resolve_v(std::false_type, Sig C::* mem_func_ptr) {
|
||||
return mem_func_ptr;
|
||||
}
|
||||
|
||||
template<typename Sig, typename C>
|
||||
inline constexpr Sig C::* resolve_v(std::true_type, Sig C::* mem_variable_ptr) {
|
||||
return mem_variable_ptr;
|
||||
}
|
||||
} // detail
|
||||
|
||||
template<typename... Args, typename R>
|
||||
inline constexpr auto resolve(R fun_ptr(Args...))->R(*)(Args...) {
|
||||
return fun_ptr;
|
||||
}
|
||||
|
||||
template<typename Sig>
|
||||
inline constexpr Sig* resolve(Sig* fun_ptr) {
|
||||
return fun_ptr;
|
||||
}
|
||||
|
||||
template<typename... Args, typename R, typename C>
|
||||
inline constexpr auto resolve(R(C::*mem_ptr)(Args...))->R(C::*)(Args...) {
|
||||
return mem_ptr;
|
||||
}
|
||||
|
||||
template<typename Sig, typename C>
|
||||
inline constexpr Sig C::* resolve(Sig C::* mem_ptr) {
|
||||
return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
|
||||
}
|
||||
|
||||
template<typename... Sig, typename F, meta::disable<std::is_function<meta::unqualified_t<F>>> = meta::enabler>
|
||||
inline constexpr auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
||||
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||
}
|
||||
#else
|
||||
namespace detail {
|
||||
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
||||
inline auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
||||
@ -8471,6 +8551,7 @@ namespace sol {
|
||||
inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
||||
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||
}
|
||||
#endif
|
||||
} // sol
|
||||
|
||||
// end of sol/resolve.hpp
|
||||
@ -10906,7 +10987,33 @@ namespace sol {
|
||||
typedef std::array<char, 1> one;
|
||||
typedef std::array<char, 2> two;
|
||||
|
||||
template <typename C> static one test(decltype(&C::push_back));
|
||||
template <typename C> static one test(decltype(std::declval<C>().push_back(std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
|
||||
template <typename C> static two test(...);
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(test<T>(0)) == sizeof(char);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_clear {
|
||||
private:
|
||||
typedef std::array<char, 1> one;
|
||||
typedef std::array<char, 2> two;
|
||||
|
||||
template <typename C> static one test(decltype(&C::clear));
|
||||
template <typename C> static two test(...);
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(test<T>(0)) == sizeof(char);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_insert {
|
||||
private:
|
||||
typedef std::array<char, 1> one;
|
||||
typedef std::array<char, 2> two;
|
||||
|
||||
template <typename C> static one test(decltype(std::declval<C>().insert(std::declval<std::add_rvalue_reference_t<typename C::const_iterator>>(), std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
|
||||
template <typename C> static two test(...);
|
||||
|
||||
public:
|
||||
@ -10941,10 +11048,12 @@ namespace sol {
|
||||
|
||||
template <typename Raw, typename C = void>
|
||||
struct container_usertype_metatable {
|
||||
typedef meta::has_key_value_pair<meta::unqualified_t<Raw>> is_associative;
|
||||
typedef meta::unqualified_t<Raw> T;
|
||||
typedef std::size_t K;
|
||||
typedef typename T::value_type V;
|
||||
typedef typename T::iterator I;
|
||||
typedef std::conditional_t<is_associative::value, typename T::value_type, std::pair<std::size_t, typename T::value_type>> KV;
|
||||
typedef typename KV::first_type K;
|
||||
typedef typename KV::second_type V;
|
||||
typedef std::remove_reference_t<decltype(*std::declval<I&>())> IR;
|
||||
|
||||
struct iter {
|
||||
@ -10966,7 +11075,36 @@ namespace sol {
|
||||
#endif
|
||||
}
|
||||
|
||||
static int real_index_call(lua_State* L) {
|
||||
static int real_index_call_associative(std::true_type, lua_State* L) {
|
||||
auto k = stack::check_get<K>(L, 2);
|
||||
if (k) {
|
||||
auto& src = get_src(L);
|
||||
using std::end;
|
||||
auto it = detail::find(src, *k);
|
||||
if (it != end(src)) {
|
||||
auto& v = *it;
|
||||
return stack::push_reference(L, v.second);
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto maybename = stack::check_get<string_detail::string_shim>(L, 2);
|
||||
if (maybename) {
|
||||
auto& name = *maybename;
|
||||
if (name == "add") {
|
||||
return stack::push(L, &add_call);
|
||||
}
|
||||
else if (name == "insert") {
|
||||
return stack::push(L, &insert_call);
|
||||
}
|
||||
else if (name == "clear") {
|
||||
return stack::push(L, &clear_call);
|
||||
}
|
||||
}
|
||||
}
|
||||
return stack::push(L, nil);
|
||||
}
|
||||
|
||||
static int real_index_call_associative(std::false_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
auto maybek = stack::check_get<K>(L, 2);
|
||||
if (maybek) {
|
||||
@ -11002,12 +11140,36 @@ namespace sol {
|
||||
return stack::push(L, nil);
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::false_type, lua_State* L) {
|
||||
luaL_error(L, "sol: cannot write to a const value type or an immutable iterator (e.g., std::set)");
|
||||
static int real_index_call(lua_State* L) {
|
||||
return real_index_call_associative(is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::false_type, std::false_type, lua_State* L) {
|
||||
return luaL_error(L, "sol: cannot write to a const value type or an immutable iterator (e.g., std::set)");
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::false_type, std::true_type, lua_State* L) {
|
||||
return luaL_error(L, "sol: cannot write to a const value type or an immutable iterator (e.g., std::set)");
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::true_type, std::true_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
auto k = stack::check_get<K>(L, 2);
|
||||
if (k) {
|
||||
using std::end;
|
||||
auto it = detail::find(src, *k);
|
||||
if (it != end(src)) {
|
||||
auto& v = *it;
|
||||
v.second = stack::get<V>(L, 3);
|
||||
}
|
||||
else {
|
||||
src.insert(it, { std::move(*k), stack::get<V>(L, 3) });
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::true_type, lua_State* L) {
|
||||
static int real_new_index_call_const(std::true_type, std::false_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
auto maybek = stack::check_get<K>(L, 2);
|
||||
@ -11031,10 +11193,32 @@ namespace sol {
|
||||
}
|
||||
|
||||
static int real_new_index_call(lua_State* L) {
|
||||
return real_new_index_call_const(meta::neg<meta::any<std::is_const<V>, std::is_const<IR>>>(), L);
|
||||
return real_new_index_call_const(meta::neg<meta::any<std::is_const<V>, std::is_const<IR>>>(), is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_pairs_next_call(lua_State* L) {
|
||||
static int real_pairs_next_call_assoc(std::true_type, lua_State* L) {
|
||||
using std::end;
|
||||
iter& i = stack::get<user<iter>>(L, 1);
|
||||
auto& source = i.source;
|
||||
auto& it = i.it;
|
||||
if (it == end(source)) {
|
||||
return 0;
|
||||
}
|
||||
int p = stack::multi_push_reference(L, it->first, it->second);
|
||||
std::advance(it, 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
static int real_pairs_call_assoc(std::true_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
using std::begin;
|
||||
stack::push(L, pairs_next_call);
|
||||
stack::push<user<iter>>(L, src, begin(src));
|
||||
stack::push(L, 1);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int real_pairs_next_call_assoc(std::false_type, lua_State* L) {
|
||||
using std::end;
|
||||
iter& i = stack::get<user<iter>>(L, 1);
|
||||
auto& source = i.source;
|
||||
@ -11048,7 +11232,7 @@ namespace sol {
|
||||
return p;
|
||||
}
|
||||
|
||||
static int real_pairs_call(lua_State* L) {
|
||||
static int real_pairs_call_assoc(std::false_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
using std::begin;
|
||||
stack::push(L, pairs_next_call);
|
||||
@ -11057,40 +11241,100 @@ namespace sol {
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int real_pairs_next_call(lua_State* L) {
|
||||
return real_pairs_next_call_assoc(is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_pairs_call(lua_State* L) {
|
||||
return real_pairs_call_assoc(is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_length_call(lua_State*L) {
|
||||
auto& src = get_src(L);
|
||||
return stack::push(L, src.size());
|
||||
}
|
||||
|
||||
static int real_add_call_insert(std::true_type, lua_State*L, T& src, int boost = 0) {
|
||||
using std::end;
|
||||
src.insert(end(src), stack::get<V>(L, 2 + boost));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_add_call_insert(std::false_type, lua_State*L, T&, int = 0) {
|
||||
static const std::string& s = detail::demangle<T>();
|
||||
return luaL_error(L, "sol: cannot call insert on type %s", s.c_str());
|
||||
}
|
||||
|
||||
static int real_add_call_push(std::true_type, lua_State*L, T& src, int boost = 0) {
|
||||
src.push_back(stack::get<V>(L, 2 + boost));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_add_call_push(std::false_type, lua_State*L, T& src, int boost = 0) {
|
||||
using std::end;
|
||||
src.insert(end(src), stack::get<V>(L, 2 + boost));
|
||||
return 0;
|
||||
return real_add_call_insert(std::integral_constant<bool, detail::has_insert<T>::value>(), L, src, boost);
|
||||
}
|
||||
|
||||
static int real_add_call(lua_State*L) {
|
||||
static int real_add_call_associative(std::true_type, lua_State* L) {
|
||||
return real_insert_call(L);
|
||||
}
|
||||
|
||||
static int real_add_call_associative(std::false_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
return real_add_call_push(std::integral_constant<bool, detail::has_push_back<T>::value>(), L, src);
|
||||
}
|
||||
|
||||
static int real_insert_call(lua_State*L) {
|
||||
static int real_add_call_capable(std::true_type, lua_State* L) {
|
||||
return real_add_call_associative(is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_add_call_capable(std::false_type, lua_State* L) {
|
||||
static const std::string& s = detail::demangle<T>();
|
||||
return luaL_error(L, "sol: cannot call add on type %s", s.c_str());
|
||||
}
|
||||
|
||||
static int real_add_call(lua_State* L) {
|
||||
return real_add_call_capable(std::integral_constant<bool, detail::has_push_back<T>::value || detail::has_insert<T>::value>(), L);
|
||||
}
|
||||
|
||||
static int real_insert_call_capable(std::false_type, std::false_type, lua_State*L) {
|
||||
static const std::string& s = detail::demangle<T>();
|
||||
return luaL_error(L, "sol: cannot call insert on type %s", s.c_str());
|
||||
}
|
||||
|
||||
static int real_insert_call_capable(std::false_type, std::true_type, lua_State*L) {
|
||||
return real_insert_call_capable(std::false_type(), std::false_type(), L);
|
||||
}
|
||||
|
||||
static int real_insert_call_capable(std::true_type, std::false_type, lua_State* L) {
|
||||
using std::begin;
|
||||
auto& src = get_src(L);
|
||||
src.insert(std::next(begin(src), stack::get<K>(L, 2)), stack::get<V>(L, 3));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_clear_call(lua_State*L) {
|
||||
static int real_insert_call_capable(std::true_type, std::true_type, lua_State* L) {
|
||||
return real_new_index_call(L);
|
||||
}
|
||||
|
||||
static int real_insert_call(lua_State*L) {
|
||||
return real_insert_call_capable(std::integral_constant<bool, detail::has_insert<T>::value>(), is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_clear_call_capable(std::false_type, lua_State* L) {
|
||||
static const std::string& s = detail::demangle<T>();
|
||||
return luaL_error(L, "sol: cannot call clear on type %s", s.c_str());
|
||||
}
|
||||
|
||||
static int real_clear_call_capable(std::true_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
src.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_clear_call(lua_State*L) {
|
||||
return real_clear_call_capable(std::integral_constant<bool, detail::has_clear<T>::value>(), L);
|
||||
}
|
||||
|
||||
static int add_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_add_call)>(L);
|
||||
}
|
||||
@ -11124,157 +11368,6 @@ namespace sol {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Raw>
|
||||
struct container_usertype_metatable<Raw, std::enable_if_t<meta::has_key_value_pair<meta::unqualified_t<Raw>>::value>> {
|
||||
typedef meta::unqualified_t<Raw> T;
|
||||
typedef typename T::value_type KV;
|
||||
typedef typename KV::first_type K;
|
||||
typedef typename KV::second_type V;
|
||||
typedef typename T::iterator I;
|
||||
struct iter {
|
||||
T& source;
|
||||
I it;
|
||||
|
||||
iter(T& source, I it) : source(source), it(std::move(it)) {}
|
||||
};
|
||||
|
||||
static auto& get_src(lua_State* L) {
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
auto p = stack::check_get<T*>(L, 1);
|
||||
if (!p || p.value() == nullptr) {
|
||||
luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument or call on proper type)");
|
||||
}
|
||||
return *p.value();
|
||||
#else
|
||||
return stack::get<T>(L, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int real_index_call(lua_State* L) {
|
||||
auto k = stack::check_get<K>(L, 2);
|
||||
if (k) {
|
||||
auto& src = get_src(L);
|
||||
using std::end;
|
||||
auto it = detail::find(src, *k);
|
||||
if (it != end(src)) {
|
||||
auto& v = *it;
|
||||
return stack::push_reference(L, v.second);
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto maybename = stack::check_get<string_detail::string_shim>(L, 2);
|
||||
if (maybename) {
|
||||
auto& name = *maybename;
|
||||
if (name == "add") {
|
||||
return stack::push(L, &add_call);
|
||||
}
|
||||
else if (name == "insert") {
|
||||
return stack::push(L, &insert_call);
|
||||
}
|
||||
else if (name == "clear") {
|
||||
return stack::push(L, &clear_call);
|
||||
}
|
||||
}
|
||||
}
|
||||
return stack::push(L, nil);
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::false_type, lua_State* L) {
|
||||
luaL_error(L, "sol: cannot write to a const value type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::true_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
auto k = stack::check_get<K>(L, 2);
|
||||
if (k) {
|
||||
using std::end;
|
||||
auto it = detail::find(src, *k);
|
||||
if (it != end(src)) {
|
||||
auto& v = *it;
|
||||
v.second = stack::get<V>(L, 3);
|
||||
}
|
||||
else {
|
||||
src.insert(it, { std::move(*k), stack::get<V>(L, 3) });
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_new_index_call(lua_State* L) {
|
||||
return real_new_index_call_const(meta::neg<std::is_const<V>>(), L);
|
||||
}
|
||||
|
||||
static int real_pairs_next_call(lua_State* L) {
|
||||
using std::end;
|
||||
iter& i = stack::get<user<iter>>(L, 1);
|
||||
auto& source = i.source;
|
||||
auto& it = i.it;
|
||||
if (it == end(source)) {
|
||||
return 0;
|
||||
}
|
||||
int p = stack::multi_push_reference(L, it->first, it->second);
|
||||
std::advance(it, 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
static int real_pairs_call(lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
using std::begin;
|
||||
stack::push(L, pairs_next_call);
|
||||
stack::push<user<iter>>(L, src, begin(src));
|
||||
stack::push(L, 1);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int real_length_call(lua_State*L) {
|
||||
auto& src = get_src(L);
|
||||
return stack::push(L, src.size());
|
||||
}
|
||||
|
||||
static int real_insert_call(lua_State*L) {
|
||||
return real_new_index_call(L);
|
||||
}
|
||||
|
||||
static int real_clear_call(lua_State*L) {
|
||||
auto& src = get_src(L);
|
||||
src.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_insert_call)>(L);
|
||||
}
|
||||
|
||||
static int insert_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_insert_call)>(L);
|
||||
}
|
||||
|
||||
static int clear_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_clear_call)>(L);
|
||||
}
|
||||
|
||||
static int length_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_length_call)>(L);
|
||||
}
|
||||
|
||||
static int pairs_next_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_pairs_next_call)>(L);
|
||||
}
|
||||
|
||||
static int pairs_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_pairs_call)>(L);
|
||||
}
|
||||
|
||||
static int index_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_index_call)>(L);
|
||||
}
|
||||
|
||||
static int new_index_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_new_index_call)>(L);
|
||||
}
|
||||
};
|
||||
|
||||
namespace stack {
|
||||
namespace stack_detail {
|
||||
template <typename T>
|
||||
@ -11349,7 +11442,7 @@ namespace sol {
|
||||
template<typename T>
|
||||
struct pusher<T*, std::enable_if_t<meta::all<is_container<T>, meta::neg<meta::any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>>>::value>> {
|
||||
static int push(lua_State* L, T* cont) {
|
||||
stack_detail::metatable_setup<T*> fx(L);
|
||||
stack_detail::metatable_setup<meta::unqualified_t<std::remove_pointer_t<T>>*> fx(L);
|
||||
return pusher<detail::as_pointer_tag<T>>{}.push_fx(L, fx, cont);
|
||||
}
|
||||
};
|
||||
|
2
3rdparty/sol2/sol/call.hpp
vendored
2
3rdparty/sol2/sol/call.hpp
vendored
@ -443,7 +443,7 @@ namespace sol {
|
||||
};
|
||||
|
||||
static int call(lua_State* L, F& f) {
|
||||
call_syntax syntax = stack::get_call_syntax(L, &usertype_traits<T>::user_metatable()[0]);
|
||||
call_syntax syntax = stack::get_call_syntax(L, &usertype_traits<T>::user_metatable()[0], 1);
|
||||
int syntaxval = static_cast<int>(syntax);
|
||||
int argcount = lua_gettop(L) - syntaxval;
|
||||
return construct_match<T, meta::pop_front_type_t<meta::function_args_t<Cxs>>...>(onmatch(), L, argcount, 1 + syntaxval, f);
|
||||
|
4
3rdparty/sol2/sol/compatibility/version.hpp
vendored
4
3rdparty/sol2/sol/compatibility/version.hpp
vendored
@ -24,7 +24,7 @@
|
||||
|
||||
#include <lua.hpp>
|
||||
|
||||
#if defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#if defined(_WIN32) || defined(_MSC_VER)
|
||||
#ifndef SOL_CODECVT_SUPPORT
|
||||
#define SOL_CODECVT_SUPPORT 1
|
||||
#endif // sol codecvt support
|
||||
@ -33,7 +33,7 @@
|
||||
#ifndef SOL_CODECVT_SUPPORT
|
||||
#define SOL_CODECVT_SUPPORT 1
|
||||
#endif // codecvt support
|
||||
#endif // g++ 5.x.x
|
||||
#endif // g++ 5.x.x (MinGW too)
|
||||
#else
|
||||
// Clang sucks and doesn't really utilize codecvt support,
|
||||
// not without checking the library versions explicitly (and we're not gonna do that, so fuck you)
|
||||
|
348
3rdparty/sol2/sol/container_usertype_metatable.hpp
vendored
348
3rdparty/sol2/sol/container_usertype_metatable.hpp
vendored
@ -47,7 +47,33 @@ namespace sol {
|
||||
typedef std::array<char, 1> one;
|
||||
typedef std::array<char, 2> two;
|
||||
|
||||
template <typename C> static one test(decltype(&C::push_back));
|
||||
template <typename C> static one test(decltype(std::declval<C>().push_back(std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
|
||||
template <typename C> static two test(...);
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(test<T>(0)) == sizeof(char);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_clear {
|
||||
private:
|
||||
typedef std::array<char, 1> one;
|
||||
typedef std::array<char, 2> two;
|
||||
|
||||
template <typename C> static one test(decltype(&C::clear));
|
||||
template <typename C> static two test(...);
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(test<T>(0)) == sizeof(char);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_insert {
|
||||
private:
|
||||
typedef std::array<char, 1> one;
|
||||
typedef std::array<char, 2> two;
|
||||
|
||||
template <typename C> static one test(decltype(std::declval<C>().insert(std::declval<std::add_rvalue_reference_t<typename C::const_iterator>>(), std::declval<std::add_rvalue_reference_t<typename C::value_type>>()))*);
|
||||
template <typename C> static two test(...);
|
||||
|
||||
public:
|
||||
@ -82,10 +108,12 @@ namespace sol {
|
||||
|
||||
template <typename Raw, typename C = void>
|
||||
struct container_usertype_metatable {
|
||||
typedef meta::has_key_value_pair<meta::unqualified_t<Raw>> is_associative;
|
||||
typedef meta::unqualified_t<Raw> T;
|
||||
typedef std::size_t K;
|
||||
typedef typename T::value_type V;
|
||||
typedef typename T::iterator I;
|
||||
typedef std::conditional_t<is_associative::value, typename T::value_type, std::pair<std::size_t, typename T::value_type>> KV;
|
||||
typedef typename KV::first_type K;
|
||||
typedef typename KV::second_type V;
|
||||
typedef std::remove_reference_t<decltype(*std::declval<I&>())> IR;
|
||||
|
||||
struct iter {
|
||||
@ -107,7 +135,36 @@ namespace sol {
|
||||
#endif
|
||||
}
|
||||
|
||||
static int real_index_call(lua_State* L) {
|
||||
static int real_index_call_associative(std::true_type, lua_State* L) {
|
||||
auto k = stack::check_get<K>(L, 2);
|
||||
if (k) {
|
||||
auto& src = get_src(L);
|
||||
using std::end;
|
||||
auto it = detail::find(src, *k);
|
||||
if (it != end(src)) {
|
||||
auto& v = *it;
|
||||
return stack::push_reference(L, v.second);
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto maybename = stack::check_get<string_detail::string_shim>(L, 2);
|
||||
if (maybename) {
|
||||
auto& name = *maybename;
|
||||
if (name == "add") {
|
||||
return stack::push(L, &add_call);
|
||||
}
|
||||
else if (name == "insert") {
|
||||
return stack::push(L, &insert_call);
|
||||
}
|
||||
else if (name == "clear") {
|
||||
return stack::push(L, &clear_call);
|
||||
}
|
||||
}
|
||||
}
|
||||
return stack::push(L, nil);
|
||||
}
|
||||
|
||||
static int real_index_call_associative(std::false_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
auto maybek = stack::check_get<K>(L, 2);
|
||||
if (maybek) {
|
||||
@ -143,12 +200,36 @@ namespace sol {
|
||||
return stack::push(L, nil);
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::false_type, lua_State* L) {
|
||||
luaL_error(L, "sol: cannot write to a const value type or an immutable iterator (e.g., std::set)");
|
||||
static int real_index_call(lua_State* L) {
|
||||
return real_index_call_associative(is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::false_type, std::false_type, lua_State* L) {
|
||||
return luaL_error(L, "sol: cannot write to a const value type or an immutable iterator (e.g., std::set)");
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::false_type, std::true_type, lua_State* L) {
|
||||
return luaL_error(L, "sol: cannot write to a const value type or an immutable iterator (e.g., std::set)");
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::true_type, std::true_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
auto k = stack::check_get<K>(L, 2);
|
||||
if (k) {
|
||||
using std::end;
|
||||
auto it = detail::find(src, *k);
|
||||
if (it != end(src)) {
|
||||
auto& v = *it;
|
||||
v.second = stack::get<V>(L, 3);
|
||||
}
|
||||
else {
|
||||
src.insert(it, { std::move(*k), stack::get<V>(L, 3) });
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::true_type, lua_State* L) {
|
||||
static int real_new_index_call_const(std::true_type, std::false_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
auto maybek = stack::check_get<K>(L, 2);
|
||||
@ -172,10 +253,32 @@ namespace sol {
|
||||
}
|
||||
|
||||
static int real_new_index_call(lua_State* L) {
|
||||
return real_new_index_call_const(meta::neg<meta::any<std::is_const<V>, std::is_const<IR>>>(), L);
|
||||
return real_new_index_call_const(meta::neg<meta::any<std::is_const<V>, std::is_const<IR>>>(), is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_pairs_next_call(lua_State* L) {
|
||||
static int real_pairs_next_call_assoc(std::true_type, lua_State* L) {
|
||||
using std::end;
|
||||
iter& i = stack::get<user<iter>>(L, 1);
|
||||
auto& source = i.source;
|
||||
auto& it = i.it;
|
||||
if (it == end(source)) {
|
||||
return 0;
|
||||
}
|
||||
int p = stack::multi_push_reference(L, it->first, it->second);
|
||||
std::advance(it, 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
static int real_pairs_call_assoc(std::true_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
using std::begin;
|
||||
stack::push(L, pairs_next_call);
|
||||
stack::push<user<iter>>(L, src, begin(src));
|
||||
stack::push(L, 1);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int real_pairs_next_call_assoc(std::false_type, lua_State* L) {
|
||||
using std::end;
|
||||
iter& i = stack::get<user<iter>>(L, 1);
|
||||
auto& source = i.source;
|
||||
@ -189,7 +292,7 @@ namespace sol {
|
||||
return p;
|
||||
}
|
||||
|
||||
static int real_pairs_call(lua_State* L) {
|
||||
static int real_pairs_call_assoc(std::false_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
using std::begin;
|
||||
stack::push(L, pairs_next_call);
|
||||
@ -198,40 +301,100 @@ namespace sol {
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int real_pairs_next_call(lua_State* L) {
|
||||
return real_pairs_next_call_assoc(is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_pairs_call(lua_State* L) {
|
||||
return real_pairs_call_assoc(is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_length_call(lua_State*L) {
|
||||
auto& src = get_src(L);
|
||||
return stack::push(L, src.size());
|
||||
}
|
||||
|
||||
static int real_add_call_insert(std::true_type, lua_State*L, T& src, int boost = 0) {
|
||||
using std::end;
|
||||
src.insert(end(src), stack::get<V>(L, 2 + boost));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_add_call_insert(std::false_type, lua_State*L, T&, int = 0) {
|
||||
static const std::string& s = detail::demangle<T>();
|
||||
return luaL_error(L, "sol: cannot call insert on type %s", s.c_str());
|
||||
}
|
||||
|
||||
static int real_add_call_push(std::true_type, lua_State*L, T& src, int boost = 0) {
|
||||
src.push_back(stack::get<V>(L, 2 + boost));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_add_call_push(std::false_type, lua_State*L, T& src, int boost = 0) {
|
||||
using std::end;
|
||||
src.insert(end(src), stack::get<V>(L, 2 + boost));
|
||||
return 0;
|
||||
return real_add_call_insert(std::integral_constant<bool, detail::has_insert<T>::value>(), L, src, boost);
|
||||
}
|
||||
|
||||
static int real_add_call(lua_State*L) {
|
||||
static int real_add_call_associative(std::true_type, lua_State* L) {
|
||||
return real_insert_call(L);
|
||||
}
|
||||
|
||||
static int real_add_call_associative(std::false_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
return real_add_call_push(std::integral_constant<bool, detail::has_push_back<T>::value>(), L, src);
|
||||
}
|
||||
|
||||
static int real_insert_call(lua_State*L) {
|
||||
static int real_add_call_capable(std::true_type, lua_State* L) {
|
||||
return real_add_call_associative(is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_add_call_capable(std::false_type, lua_State* L) {
|
||||
static const std::string& s = detail::demangle<T>();
|
||||
return luaL_error(L, "sol: cannot call add on type %s", s.c_str());
|
||||
}
|
||||
|
||||
static int real_add_call(lua_State* L) {
|
||||
return real_add_call_capable(std::integral_constant<bool, detail::has_push_back<T>::value || detail::has_insert<T>::value>(), L);
|
||||
}
|
||||
|
||||
static int real_insert_call_capable(std::false_type, std::false_type, lua_State*L) {
|
||||
static const std::string& s = detail::demangle<T>();
|
||||
return luaL_error(L, "sol: cannot call insert on type %s", s.c_str());
|
||||
}
|
||||
|
||||
static int real_insert_call_capable(std::false_type, std::true_type, lua_State*L) {
|
||||
return real_insert_call_capable(std::false_type(), std::false_type(), L);
|
||||
}
|
||||
|
||||
static int real_insert_call_capable(std::true_type, std::false_type, lua_State* L) {
|
||||
using std::begin;
|
||||
auto& src = get_src(L);
|
||||
src.insert(std::next(begin(src), stack::get<K>(L, 2)), stack::get<V>(L, 3));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_clear_call(lua_State*L) {
|
||||
static int real_insert_call_capable(std::true_type, std::true_type, lua_State* L) {
|
||||
return real_new_index_call(L);
|
||||
}
|
||||
|
||||
static int real_insert_call(lua_State*L) {
|
||||
return real_insert_call_capable(std::integral_constant<bool, detail::has_insert<T>::value>(), is_associative(), L);
|
||||
}
|
||||
|
||||
static int real_clear_call_capable(std::false_type, lua_State* L) {
|
||||
static const std::string& s = detail::demangle<T>();
|
||||
return luaL_error(L, "sol: cannot call clear on type %s", s.c_str());
|
||||
}
|
||||
|
||||
static int real_clear_call_capable(std::true_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
src.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_clear_call(lua_State*L) {
|
||||
return real_clear_call_capable(std::integral_constant<bool, detail::has_clear<T>::value>(), L);
|
||||
}
|
||||
|
||||
static int add_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_add_call)>(L);
|
||||
}
|
||||
@ -265,157 +428,6 @@ namespace sol {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Raw>
|
||||
struct container_usertype_metatable<Raw, std::enable_if_t<meta::has_key_value_pair<meta::unqualified_t<Raw>>::value>> {
|
||||
typedef meta::unqualified_t<Raw> T;
|
||||
typedef typename T::value_type KV;
|
||||
typedef typename KV::first_type K;
|
||||
typedef typename KV::second_type V;
|
||||
typedef typename T::iterator I;
|
||||
struct iter {
|
||||
T& source;
|
||||
I it;
|
||||
|
||||
iter(T& source, I it) : source(source), it(std::move(it)) {}
|
||||
};
|
||||
|
||||
static auto& get_src(lua_State* L) {
|
||||
#ifdef SOL_SAFE_USERTYPE
|
||||
auto p = stack::check_get<T*>(L, 1);
|
||||
if (!p || p.value() == nullptr) {
|
||||
luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument or call on proper type)");
|
||||
}
|
||||
return *p.value();
|
||||
#else
|
||||
return stack::get<T>(L, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int real_index_call(lua_State* L) {
|
||||
auto k = stack::check_get<K>(L, 2);
|
||||
if (k) {
|
||||
auto& src = get_src(L);
|
||||
using std::end;
|
||||
auto it = detail::find(src, *k);
|
||||
if (it != end(src)) {
|
||||
auto& v = *it;
|
||||
return stack::push_reference(L, v.second);
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto maybename = stack::check_get<string_detail::string_shim>(L, 2);
|
||||
if (maybename) {
|
||||
auto& name = *maybename;
|
||||
if (name == "add") {
|
||||
return stack::push(L, &add_call);
|
||||
}
|
||||
else if (name == "insert") {
|
||||
return stack::push(L, &insert_call);
|
||||
}
|
||||
else if (name == "clear") {
|
||||
return stack::push(L, &clear_call);
|
||||
}
|
||||
}
|
||||
}
|
||||
return stack::push(L, nil);
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::false_type, lua_State* L) {
|
||||
luaL_error(L, "sol: cannot write to a const value type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_new_index_call_const(std::true_type, lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
auto k = stack::check_get<K>(L, 2);
|
||||
if (k) {
|
||||
using std::end;
|
||||
auto it = detail::find(src, *k);
|
||||
if (it != end(src)) {
|
||||
auto& v = *it;
|
||||
v.second = stack::get<V>(L, 3);
|
||||
}
|
||||
else {
|
||||
src.insert(it, { std::move(*k), stack::get<V>(L, 3) });
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int real_new_index_call(lua_State* L) {
|
||||
return real_new_index_call_const(meta::neg<std::is_const<V>>(), L);
|
||||
}
|
||||
|
||||
static int real_pairs_next_call(lua_State* L) {
|
||||
using std::end;
|
||||
iter& i = stack::get<user<iter>>(L, 1);
|
||||
auto& source = i.source;
|
||||
auto& it = i.it;
|
||||
if (it == end(source)) {
|
||||
return 0;
|
||||
}
|
||||
int p = stack::multi_push_reference(L, it->first, it->second);
|
||||
std::advance(it, 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
static int real_pairs_call(lua_State* L) {
|
||||
auto& src = get_src(L);
|
||||
using std::begin;
|
||||
stack::push(L, pairs_next_call);
|
||||
stack::push<user<iter>>(L, src, begin(src));
|
||||
stack::push(L, 1);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int real_length_call(lua_State*L) {
|
||||
auto& src = get_src(L);
|
||||
return stack::push(L, src.size());
|
||||
}
|
||||
|
||||
static int real_insert_call(lua_State*L) {
|
||||
return real_new_index_call(L);
|
||||
}
|
||||
|
||||
static int real_clear_call(lua_State*L) {
|
||||
auto& src = get_src(L);
|
||||
src.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_insert_call)>(L);
|
||||
}
|
||||
|
||||
static int insert_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_insert_call)>(L);
|
||||
}
|
||||
|
||||
static int clear_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_clear_call)>(L);
|
||||
}
|
||||
|
||||
static int length_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_length_call)>(L);
|
||||
}
|
||||
|
||||
static int pairs_next_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_pairs_next_call)>(L);
|
||||
}
|
||||
|
||||
static int pairs_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_pairs_call)>(L);
|
||||
}
|
||||
|
||||
static int index_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_index_call)>(L);
|
||||
}
|
||||
|
||||
static int new_index_call(lua_State*L) {
|
||||
return detail::static_trampoline<(&real_new_index_call)>(L);
|
||||
}
|
||||
};
|
||||
|
||||
namespace stack {
|
||||
namespace stack_detail {
|
||||
template <typename T>
|
||||
@ -490,7 +502,7 @@ namespace sol {
|
||||
template<typename T>
|
||||
struct pusher<T*, std::enable_if_t<meta::all<is_container<T>, meta::neg<meta::any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>>>::value>> {
|
||||
static int push(lua_State* L, T* cont) {
|
||||
stack_detail::metatable_setup<T*> fx(L);
|
||||
stack_detail::metatable_setup<meta::unqualified_t<std::remove_pointer_t<T>>*> fx(L);
|
||||
return pusher<detail::as_pointer_tag<T>>{}.push_fx(L, fx, cont);
|
||||
}
|
||||
};
|
||||
|
4
3rdparty/sol2/sol/demangle.hpp
vendored
4
3rdparty/sol2/sol/demangle.hpp
vendored
@ -142,13 +142,13 @@ namespace sol {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::string demangle() {
|
||||
inline const std::string& demangle() {
|
||||
static const std::string d = demangle_once<T>();
|
||||
return d;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::string short_demangle() {
|
||||
inline const std::string& short_demangle() {
|
||||
static const std::string d = short_demangle_once<T>();
|
||||
return d;
|
||||
}
|
||||
|
@ -29,9 +29,6 @@ namespace sol {
|
||||
template<typename Func>
|
||||
struct functor_function {
|
||||
typedef meta::unwrapped_t<meta::unqualified_t<Func>> Function;
|
||||
typedef decltype(&Function::operator()) function_type;
|
||||
typedef meta::function_return_t<function_type> return_type;
|
||||
typedef meta::function_args_t<function_type> args_lists;
|
||||
Function fx;
|
||||
|
||||
template<typename... Args>
|
||||
|
@ -636,7 +636,7 @@ namespace sol {
|
||||
#ifdef SOL_NO_EXCEPTIONS
|
||||
// we can abort here
|
||||
// but the others are constexpr, so we can't...
|
||||
: (std::abort(), *(T*)nullptr)
|
||||
: (std::abort(), *(T*)nullptr);
|
||||
#else
|
||||
: (throw bad_optional_access("bad optional access"), contained_val());
|
||||
#endif
|
||||
|
70
3rdparty/sol2/sol/resolve.hpp
vendored
70
3rdparty/sol2/sol/resolve.hpp
vendored
@ -26,6 +26,75 @@
|
||||
#include "tuple.hpp"
|
||||
|
||||
namespace sol {
|
||||
// Clang has distinct problems with constexpr arguments,
|
||||
// so don't use the constexpr versions inside of clang.
|
||||
#ifndef __clang__
|
||||
namespace detail {
|
||||
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
||||
inline constexpr auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
||||
using Sig = R(Args...);
|
||||
typedef meta::unqualified_t<F> Fu;
|
||||
return static_cast<Sig Fu::*>(&Fu::operator());
|
||||
}
|
||||
|
||||
template<typename F, typename U = meta::unqualified_t<F>>
|
||||
inline constexpr auto resolve_f(std::true_type, F&& f)
|
||||
-> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
|
||||
return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline constexpr void resolve_f(std::false_type, F&&) {
|
||||
static_assert(meta::has_deducible_signature<F>::value,
|
||||
"Cannot use no-template-parameter call with an overloaded functor: specify the signature");
|
||||
}
|
||||
|
||||
template<typename F, typename U = meta::unqualified_t<F>>
|
||||
inline constexpr auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
|
||||
return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template<typename... Args, typename F, typename R = std::result_of_t<F&(Args...)>>
|
||||
inline constexpr auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
|
||||
return resolve_i(types<R(Args...)>(), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template<typename Sig, typename C>
|
||||
inline constexpr Sig C::* resolve_v(std::false_type, Sig C::* mem_func_ptr) {
|
||||
return mem_func_ptr;
|
||||
}
|
||||
|
||||
template<typename Sig, typename C>
|
||||
inline constexpr Sig C::* resolve_v(std::true_type, Sig C::* mem_variable_ptr) {
|
||||
return mem_variable_ptr;
|
||||
}
|
||||
} // detail
|
||||
|
||||
template<typename... Args, typename R>
|
||||
inline constexpr auto resolve(R fun_ptr(Args...))->R(*)(Args...) {
|
||||
return fun_ptr;
|
||||
}
|
||||
|
||||
template<typename Sig>
|
||||
inline constexpr Sig* resolve(Sig* fun_ptr) {
|
||||
return fun_ptr;
|
||||
}
|
||||
|
||||
template<typename... Args, typename R, typename C>
|
||||
inline constexpr auto resolve(R(C::*mem_ptr)(Args...))->R(C::*)(Args...) {
|
||||
return mem_ptr;
|
||||
}
|
||||
|
||||
template<typename Sig, typename C>
|
||||
inline constexpr Sig C::* resolve(Sig C::* mem_ptr) {
|
||||
return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
|
||||
}
|
||||
|
||||
template<typename... Sig, typename F, meta::disable<std::is_function<meta::unqualified_t<F>>> = meta::enabler>
|
||||
inline constexpr auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
||||
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||
}
|
||||
#else
|
||||
namespace detail {
|
||||
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
|
||||
inline auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
|
||||
@ -91,6 +160,7 @@ namespace sol {
|
||||
inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
|
||||
return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
|
||||
}
|
||||
#endif
|
||||
} // sol
|
||||
|
||||
#endif // SOL_RESOLVE_HPP
|
||||
|
11
3rdparty/sol2/sol/stack.hpp
vendored
11
3rdparty/sol2/sol/stack.hpp
vendored
@ -181,13 +181,16 @@ namespace sol {
|
||||
return call_into_lua(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
|
||||
}
|
||||
|
||||
inline call_syntax get_call_syntax(lua_State* L, const std::string& key, int index = -2) {
|
||||
inline call_syntax get_call_syntax(lua_State* L, const std::string& key, int index) {
|
||||
if (lua_gettop(L) == 0) {
|
||||
return call_syntax::dot;
|
||||
}
|
||||
luaL_getmetatable(L, key.c_str());
|
||||
auto pn = pop_n(L, 1);
|
||||
if (lua_compare(L, -1, index, LUA_OPEQ) == 1) {
|
||||
return call_syntax::colon;
|
||||
if (lua_compare(L, -1, index, LUA_OPEQ) != 1) {
|
||||
return call_syntax::dot;
|
||||
}
|
||||
return call_syntax::dot;
|
||||
return call_syntax::colon;
|
||||
}
|
||||
|
||||
inline void script(lua_State* L, const std::string& code) {
|
||||
|
8
3rdparty/sol2/sol/stack_check.hpp
vendored
8
3rdparty/sol2/sol/stack_check.hpp
vendored
@ -366,13 +366,17 @@ namespace sol {
|
||||
template<typename T, typename C>
|
||||
struct checker<optional<T>, type::poly, C> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
static bool check(lua_State* L, int index, Handler&&, record& tracking) {
|
||||
type t = type_of(L, index);
|
||||
if (t == type::none) {
|
||||
tracking.use(0);
|
||||
return true;
|
||||
}
|
||||
return t == type::nil || stack::check<T>(L, index, std::forward<Handler>(handler), tracking);
|
||||
if (t == type::nil) {
|
||||
tracking.use(1);
|
||||
return true;
|
||||
}
|
||||
return stack::check<T>(L, index, no_panic, tracking);
|
||||
}
|
||||
};
|
||||
} // stack
|
||||
|
3
3rdparty/sol2/sol/traits.hpp
vendored
3
3rdparty/sol2/sol/traits.hpp
vendored
@ -45,6 +45,9 @@ namespace sol {
|
||||
template<typename... Args>
|
||||
struct is_tuple<std::tuple<Args...>> : std::true_type { };
|
||||
|
||||
template <typename T>
|
||||
struct is_builtin_type : std::integral_constant<bool, std::is_arithmetic<T>::value || std::is_pointer<T>::value || std::is_array<T>::value> {};
|
||||
|
||||
template<typename T>
|
||||
struct unwrapped {
|
||||
typedef T type;
|
||||
|
4
3rdparty/sol2/sol/types.hpp
vendored
4
3rdparty/sol2/sol/types.hpp
vendored
@ -57,9 +57,11 @@ namespace sol {
|
||||
catch (const std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
catch (...) {
|
||||
lua_pushstring(L, "caught (...) exception");
|
||||
}
|
||||
#endif
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
@ -74,9 +76,11 @@ namespace sol {
|
||||
catch (const std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
catch (...) {
|
||||
lua_pushstring(L, "caught (...) exception");
|
||||
}
|
||||
#endif
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
|
6
3rdparty/sol2/sol/usertype_traits.hpp
vendored
6
3rdparty/sol2/sol/usertype_traits.hpp
vendored
@ -29,11 +29,11 @@ namespace sol {
|
||||
template<typename T>
|
||||
struct usertype_traits {
|
||||
static const std::string& name() {
|
||||
static const std::string n = detail::short_demangle<T>();
|
||||
static const std::string& n = detail::short_demangle<T>();
|
||||
return n;
|
||||
}
|
||||
static const std::string& qualified_name() {
|
||||
static const std::string q_n = detail::demangle<T>();
|
||||
static const std::string& q_n = detail::demangle<T>();
|
||||
return q_n;
|
||||
}
|
||||
static const std::string& metatable() {
|
||||
@ -49,7 +49,7 @@ namespace sol {
|
||||
return u_g_m;
|
||||
}
|
||||
static const std::string& gc_table() {
|
||||
static const std::string g_t = std::string("sol.").append(detail::demangle<T>().append(".\xE2\x99\xBB"));
|
||||
static const std::string g_t = std::string("sol.").append(detail::demangle<T>()).append(".\xE2\x99\xBB");
|
||||
return g_t;
|
||||
}
|
||||
};
|
||||
|
35
3rdparty/sol2/test_containers.cpp
vendored
35
3rdparty/sol2/test_containers.cpp
vendored
@ -423,3 +423,38 @@ TEST_CASE("containers/is-container", "make sure the is_container trait behaves p
|
||||
}
|
||||
REQUIRE(options::livingcount == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("containers/readonly", "make sure readonly members are stored appropriately") {
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
struct bar {
|
||||
int x = 24;
|
||||
};
|
||||
|
||||
struct foo {
|
||||
std::list<bar> seq;
|
||||
};
|
||||
|
||||
lua.new_usertype<foo>(
|
||||
"foo",
|
||||
"seq", &foo::seq, // this one works
|
||||
"readonly_seq", sol::readonly(&foo::seq) // this one does not work
|
||||
);
|
||||
lua["value"] = std::list<bar>{ {},{},{} };
|
||||
|
||||
lua.script(R"(
|
||||
a = foo.new()
|
||||
x = a.seq
|
||||
a.seq = value
|
||||
y = a.readonly_seq
|
||||
)");
|
||||
std::list<bar>& seqrefx = lua["x"];
|
||||
std::list<bar>& seqrefy = lua["y"];
|
||||
REQUIRE(&seqrefx == &seqrefy);
|
||||
REQUIRE(seqrefx.size() == 3);
|
||||
auto result = lua.do_string(R"(
|
||||
a.readonly_seq = value;
|
||||
)");
|
||||
REQUIRE_FALSE(result.valid());
|
||||
}
|
||||
|
23
3rdparty/sol2/test_usertypes.cpp
vendored
23
3rdparty/sol2/test_usertypes.cpp
vendored
@ -1423,3 +1423,26 @@ TEST_CASE("usertype/destruction-test", "make sure usertypes are properly destruc
|
||||
lua["testCrash"]();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/call-initializers", "Ensure call constructors with initializers work well") {
|
||||
struct A {
|
||||
double f = 25.5;
|
||||
|
||||
static void init(A& x, double f) {
|
||||
x.f = f;
|
||||
}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries();
|
||||
|
||||
lua.new_usertype<A>("A",
|
||||
sol::call_constructor, sol::initializers(&A::init)
|
||||
);
|
||||
|
||||
lua.script(R"(
|
||||
a = A(24.3)
|
||||
)");
|
||||
A& a = lua["a"];
|
||||
REQUIRE(a.f == 24.3);
|
||||
}
|
||||
|
@ -769,18 +769,6 @@ void lua_engine::initialize()
|
||||
return sol::make_object(sol(), sol::nil);
|
||||
return sol::make_object(sol(), driver_list::driver(i));
|
||||
};
|
||||
// this throws an error when implemented as an initializer
|
||||
emu["item"] = [this](int index) {
|
||||
save_item *item = new save_item;
|
||||
if(!machine().save().indexed_item(index, item->base, item->size, item->count))
|
||||
{
|
||||
item->base = nullptr;
|
||||
item->size = 0;
|
||||
item->count= 0;
|
||||
}
|
||||
return item;
|
||||
};
|
||||
emu["thread"] = []() { context *ctx = new context; ctx->busy = false; ctx->yield = false; return ctx; };
|
||||
|
||||
emu.new_usertype<emu_file>("file", sol::call_constructor, sol::constructors<sol::types<const char *, uint32_t>>(),
|
||||
"read", [](emu_file &file, sol::buffer *buff) { buff->set_len(file.read(buff->get_ptr(), buff->get_len())); return buff; },
|
||||
@ -799,8 +787,10 @@ void lua_engine::initialize()
|
||||
* thread.yield - check if thread is yielded
|
||||
*/
|
||||
|
||||
sol().registry().new_usertype<context>("thread",
|
||||
sol::meta_function::garbage_collect, sol::destructor([](context *ctx) { delete ctx; }),
|
||||
emu.new_usertype<context>("thread", sol::call_constructor, sol::initializers([](context &ctx) {
|
||||
ctx.busy = false;
|
||||
ctx.yield = false;
|
||||
}),
|
||||
"start", [this](context &ctx, const char *scr) {
|
||||
std::string script(scr);
|
||||
if(ctx.busy)
|
||||
@ -854,8 +844,14 @@ void lua_engine::initialize()
|
||||
"busy", sol::readonly(&context::busy),
|
||||
"yield", sol::readonly(&context::yield));
|
||||
|
||||
sol().registry().new_usertype<save_item>("item",
|
||||
sol::meta_function::garbage_collect, sol::destructor([](save_item *item) { delete item; }),
|
||||
emu.new_usertype<save_item>("item", sol::call_constructor, sol::initializers([this](save_item &item, int index) {
|
||||
if(!machine().save().indexed_item(index, item.base, item.size, item.count))
|
||||
{
|
||||
item.base = nullptr;
|
||||
item.size = 0;
|
||||
item.count= 0;
|
||||
}
|
||||
}),
|
||||
"size", sol::readonly(&save_item::size),
|
||||
"count", sol::readonly(&save_item::count),
|
||||
"read", [this](save_item &item, int offset) -> sol::object {
|
||||
|
Loading…
Reference in New Issue
Block a user