mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Overhaul examples
Overhaul docs for examples Overhaul function_result and protected_function_result proxies
This commit is contained in:
parent
90bbeadd8c
commit
2203c1f64f
23
bootstrap.py
23
bootstrap.py
@ -158,13 +158,24 @@ for f in glob.glob('tests/test*.cpp'):
|
||||
|
||||
examples = []
|
||||
examples_input = []
|
||||
|
||||
def add_example (f):
|
||||
if 'win32' in sys.platform:
|
||||
example = os.path.join(builddir, replace_extension(f, '.exe'))
|
||||
example = example.replace('/', '\\');
|
||||
else:
|
||||
example = os.path.join(builddir, replace_extension(f, ''))
|
||||
example = example.replace('\\', '/');
|
||||
#if ' ' in example:
|
||||
# example = '"' + example + '"'
|
||||
examples_input.append(f)
|
||||
examples.append(example)
|
||||
|
||||
for f in glob.glob('examples/*.cpp'):
|
||||
if 'win32' in sys.platform:
|
||||
example = os.path.join(builddir, replace_extension(f, '.exe'))
|
||||
else:
|
||||
example = os.path.join(builddir, replace_extension(f, ''))
|
||||
examples_input.append(f)
|
||||
examples.append(example)
|
||||
add_example(f)
|
||||
|
||||
for f in glob.glob('examples/tutorials/quick_n_dirty/**.cpp'):
|
||||
add_example(f)
|
||||
|
||||
|
||||
# ninja file
|
||||
|
Binary file not shown.
@ -29,4 +29,4 @@ This marker does NOT apply to :doc:`usertypes<usertype>`.
|
||||
|
||||
You can also use this to nest types and retrieve tables within tables as shown by `this example`_.
|
||||
|
||||
.. _this example: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_simple.cpp
|
||||
.. _this example: https://github.com/ThePhD/sol2/blob/develop/examples/containers_as_table.cpp
|
||||
|
@ -66,7 +66,7 @@ After loading that file in or putting it in a string and reading the string dire
|
||||
int changed_value = z; // now it's 20!
|
||||
|
||||
|
||||
We don't recommend the above to be used across classes or between function: it's more of something you can do to save a reference to a value you like, call a script or run a lua function, and then get it afterwards. You can also set functions (and function objects :ref:`*<note 1>`) this way, and retrieve them as well.
|
||||
We don't recommend the above to be used across classes or between function: it's more of something you can do to save a reference to a value you like, call a script or run a lua function, and then get it afterwards. You can also set functions (and function objects) this way, and retrieve them as well.
|
||||
|
||||
.. code-block:: c++
|
||||
:linenos:
|
||||
@ -133,7 +133,7 @@ Returns whether this proxy actually refers to a valid object. It uses :ref:`sol:
|
||||
template <typename Fx>
|
||||
proxy& operator=( Fx&& function );
|
||||
|
||||
Sets the value associated with the keys the proxy was generated with to ``value``. If this is a function, calls ``set_function``. If it is not, just calls ``set``. Does not exist on :ref:`unsage_function_result<unsafe-function-result>` or :ref:`protected_function_result<protected-function-result>`. See :ref:`note<note 1>` for caveats.
|
||||
Sets the value associated with the keys the proxy was generated with to ``value``. If this is a function, calls ``set_function``. If it is not, just calls ``set``. Does not exist on :ref:`unsage_function_result<unsafe-function-result>` or :ref:`protected_function_result<protected-function-result>`.
|
||||
|
||||
.. code-block:: c++
|
||||
:caption: function: set a callable
|
||||
@ -154,6 +154,8 @@ Sets the value associated with the keys the proxy was generated with to a functi
|
||||
|
||||
Sets the value associated with the keys the proxy was generated with to ``value``. Does not exist on :ref:`unsafe_function_result<unsafe-function-result>` or :ref:`protected_function_result<protected-function-result>`.
|
||||
|
||||
.. _stack-proxy:
|
||||
|
||||
stack_proxy
|
||||
-----------
|
||||
|
||||
@ -169,6 +171,8 @@ unsafe_function_result
|
||||
|
||||
This type does, however, allow access to multiple underlying values. Use ``result.get<Type>(index_offset)`` to retrieve an object of ``Type`` at an offset of ``index_offset`` in the results. Offset is 0 based. Not specifying an argument defaults the value to 0.
|
||||
|
||||
``unsafe_function_result`` also has ``begin()`` and ``end()`` functions that return (almost) "random-acess" iterators. These return a proxy type that can be implicitly converted to :ref:`stack_proxy<stack-proxy>`.
|
||||
|
||||
.. _protected-function-result:
|
||||
|
||||
protected_function_result
|
||||
@ -179,11 +183,23 @@ protected_function_result
|
||||
|
||||
This type does, however, allow access to multiple underlying values. Use ``result.get<Type>(index_offset)`` to retrieve an object of ``Type`` at an offset of ``index_offset`` in the results. Offset is 0 based. Not specifying an argument defaults the value to 0.
|
||||
|
||||
``unsafe_function_result`` also has ``begin()`` and ``end()`` functions that return (almost) "random-acess" iterators. These return a proxy type that can be implicitly converted to :ref:`stack_proxy<stack-proxy>`.
|
||||
|
||||
.. _note 1:
|
||||
|
||||
on function objects and proxies
|
||||
-------------------------------
|
||||
|
||||
.. note::
|
||||
|
||||
As of recent versions of sol2 (2.18.2 and above), this is no longer an issue, as even bound classes will have any detectable function call operator automatically bound to the object, to allow this to work without having to use ``.set`` or ``.set_function``. The note here is kept for posterity and information for older versions.
|
||||
|
||||
|
||||
.. warning::
|
||||
|
||||
*The below information is outdated.*
|
||||
|
||||
|
||||
Consider the following:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
@ -23,6 +23,16 @@ A myriad of compiler errors can occur when something goes wrong. Here is some ba
|
||||
* Sometimes, using ``__stdcall`` in a 32-bit (x86) environment on VC++ can cause problems binding functions because of a compiler bug. We have a prelimanry fix in, but if it doesn't work and there are still problems: put the function in a ``std::function`` to make the compiler errors and other problems go away. Also see `this __stdcall issue report`_ for more details.
|
||||
|
||||
|
||||
Mac OSX Crashes
|
||||
---------------
|
||||
|
||||
On LuaJIT, your code may crash at seemingly random points when using Mac OSX. Make sure that your build has these flags, as advised by the LuaJIT website::
|
||||
|
||||
-pagezero_size 10000 -image_base 100000000
|
||||
|
||||
These will allow your code to run properly, without crashing arbitrarily. Please read the LuaJIT documentation on compiling and running with LuaJIT for more information.
|
||||
|
||||
|
||||
"compiler out of heap space"
|
||||
----------------------------
|
||||
|
||||
@ -41,7 +51,7 @@ Linker Errors
|
||||
|
||||
There are lots of reasons for compiler linker errors. A common one is not knowing that you've compiled the Lua library as C++: when building with C++, it is important to note that every typical (static or dynamic) library expects the C calling convention to be used and that Sol includes the code using ``extern 'C'`` where applicable.
|
||||
|
||||
However, when the target Lua library is compiled with C++, one must change the calling convention and name mangling scheme by getting rid of the ``extern 'C'`` block. This can be achieved by adding ``#define SOL_USING_CXX_LUA`` before including sol2, or by adding it to your compilation's command line. If you build LuaJIT in C++ mode (how you would even, is beyond me), then you need to ``#define SOL_USING_CXX_LUAJIT`` as well.
|
||||
However, when the target Lua library is compiled with C++, one must change the calling convention and name mangling scheme by getting rid of the ``extern 'C'`` block. This can be achieved by adding ``#define SOL_USING_CXX_LUA`` before including sol2, or by adding it to your compilation's command line. If you build LuaJIT in C++ mode (how you would even, is beyond me), then you need to ``#define SOL_USING_CXX_LUAJIT`` as well. Typically, there is never a need to use this last one.
|
||||
|
||||
Note that you should not be defining these with standard builds of either Lua or LuaJIT. See the :ref:`config page<config-linker>` for more details.
|
||||
|
||||
|
@ -10,29 +10,63 @@ You'll need to ``#include <sol.hpp>``/``#include "sol.hpp"`` somewhere in your c
|
||||
After you learn the basics of sol, it is usually advised that if you think something can work, you should TRY IT. It will probably work!
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
All of the code below is available at the `sol2 tutorial examples`_.
|
||||
|
||||
opening a state
|
||||
---------------
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
int main (int argc, char* argv[]) {
|
||||
sol::state lua;
|
||||
// open some common libraries
|
||||
lua.open_libraries(sol::lib::base, sol::lib::package);
|
||||
// go!
|
||||
lua.script( "print('bark bark bark!')" );
|
||||
}
|
||||
|
||||
|
||||
sol::state on lua_State*
|
||||
------------------------
|
||||
.. _sol-state-on-lua-state:
|
||||
|
||||
For your system/game that already has lua, but you'd like something nice:
|
||||
using sol2 on a lua_State*
|
||||
--------------------------
|
||||
|
||||
For your system/game that already has Lua or uses an in-house or pre-rolled Lua system (LuaBridge, kaguya, Luwra, etc.), but you'd still like sol2 and nice things:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int pre_existing_system( lua_State* L ) {
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int use_sol2(lua_State* L) {
|
||||
sol::state_view lua(L);
|
||||
lua.script( "print('bark bark bark!')" );
|
||||
lua.script("print('bark bark bark!')");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int, char*[]) {
|
||||
std::cout << "=== opening sol::state_view on raw Lua example ===" << std::endl;
|
||||
|
||||
lua_State* L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
|
||||
lua_pushcclosure(L, &use_sol2, 0);
|
||||
lua_setglobal(L, "use_sol2");
|
||||
|
||||
if (luaL_dostring(L, "use_sol2()")) {
|
||||
lua_error(L);
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -42,74 +76,53 @@ running lua code
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
sol::state lua;
|
||||
// load and execute from string
|
||||
lua.script("a = 'test'");
|
||||
// load and execute from file
|
||||
lua.script_file("path/to/luascript.lua");
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
// run a script, get the result
|
||||
int value = lua.script("return 54");
|
||||
// value == 54
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char*[]) {
|
||||
std::cout << "=== running lua code (low level) example ===" << std::endl;
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
sol::state lua;
|
||||
// load and execute from string
|
||||
lua.script("a = 'test'");
|
||||
// load and execute from file
|
||||
lua.script_file("a_lua_script.lua");
|
||||
|
||||
// run a script, get the result
|
||||
int value = lua.script("return 54");
|
||||
assert(value == 54);
|
||||
|
||||
/* ... continued in next block */
|
||||
|
||||
To run Lua code but have an error handler in case things go wrong:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
sol::state lua;
|
||||
|
||||
// the default handler panics or throws, depending on your settings
|
||||
auto result1 = lua.script("bad.code", &sol::default_on_error);
|
||||
/* ... from previous block */
|
||||
auto bad_code_result = lua.script("123 herp.derp", [](lua_State* L, sol::protected_function_result pfr) {
|
||||
// pfr will contain things that went wrong, for either loading or executing the script
|
||||
// Can throw your own custom error
|
||||
// You can also just return it, and let the call-site handle the error if necessary.
|
||||
return pfr;
|
||||
});
|
||||
// it did not work
|
||||
assert(!bad_code_result.valid());
|
||||
|
||||
// the default handler panics or throws, depending on your settings
|
||||
// uncomment for explosions:
|
||||
//auto bad_code_result_2 = lua.script("bad.code", &sol::script_default_on_error);
|
||||
|
||||
auto result2 = lua.script("123 herp.derp", [](lua_State* L, sol::protected_function_result pfr) {
|
||||
// pfr will contain things that went wrong, for either loading or executing the script
|
||||
// Can throw your own custom error
|
||||
// You can also just return it, and let the call-site handle the error if necessary.
|
||||
return pfr;
|
||||
});
|
||||
std::cout << std::endl;
|
||||
|
||||
|
||||
To check the success of a loading operation:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// load file without execute
|
||||
sol::load_result script1 = lua.load_file("path/to/luascript.lua");
|
||||
script1(); //execute
|
||||
|
||||
// load string without execute
|
||||
sol::load_result script2 = lua.load("a = 'test'");
|
||||
sol::protected_function_result script2result = script2(); //execute
|
||||
// optionally, check if it worked
|
||||
if (script2result.valid()) {
|
||||
// yay!
|
||||
}
|
||||
else {
|
||||
// aww
|
||||
return 0;
|
||||
}
|
||||
|
||||
sol::load_result script3 = lua.load("return 24");
|
||||
int value2 = script3(); // execute, get return value
|
||||
// value2 == 24
|
||||
|
||||
|
||||
To check whether a script was successfully run or not (if the actual loading is successful):
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// execute and return result
|
||||
sol::protected_function_result result1 = lua.do_string("return 24");
|
||||
if (result1.valid()) {
|
||||
int value = result1;
|
||||
// value == 24
|
||||
// yay!
|
||||
}
|
||||
else {
|
||||
// ahhh :c
|
||||
}
|
||||
|
||||
|
||||
There is also ``lua.do_file("path/to/luascript.lua");``.
|
||||
|
||||
set and get variables
|
||||
---------------------
|
||||
@ -168,10 +181,12 @@ Retrieve these variables using this syntax:
|
||||
// get a function
|
||||
sol::function a_function = lua["a_function"];
|
||||
int value_is_100 = a_function();
|
||||
|
||||
// get a std::function
|
||||
std::function<int()> a_std_function = lua["a_function"];
|
||||
// value_is_100 == 100
|
||||
|
||||
// convertible to std::function
|
||||
std::function<int()> a_std_function = a_function;
|
||||
int value_is_still_100 = a_std_function();
|
||||
// value_is_still_100 == 100
|
||||
|
||||
Retrieve Lua types using ``object`` and other ``sol::`` types.
|
||||
|
||||
@ -312,12 +327,13 @@ They're great. Use them:
|
||||
lua.script("function f (a, b, c, d) return 1 end");
|
||||
lua.script("function g (a, b) return a + b end");
|
||||
|
||||
// fixed signature std::function<...>
|
||||
std::function<int(int, double, int, std::string)> stdfx = lua["f"];
|
||||
// sol::function is often easier:
|
||||
// takes a variable number/types of arguments...
|
||||
sol::function fx = lua["f"];
|
||||
|
||||
// fixed signature std::function<...>
|
||||
// can be used to tie a sol::function down
|
||||
std::function<int(int, double, int, std::string)> stdfx = fx;
|
||||
|
||||
int is_one = stdfx(1, 34.5, 3, "bark");
|
||||
int is_also_one = fx(1, "boop", 3, "bark");
|
||||
|
||||
@ -497,7 +513,7 @@ Everything that is not a:
|
||||
* string type: ``std::string``, ``const char*``
|
||||
* function type: function pointers, ``lua_CFunction``, ``std::function``, :doc:`sol::function/sol::protected_function<../api/function>`, :doc:`sol::coroutine<../api/coroutine>`, member variable, member function
|
||||
* designated sol type: :doc:`sol::table<../api/table>`, :doc:`sol::thread<../api/thread>`, :doc:`sol::error<../api/error>`, :doc:`sol::object<../api/object>`
|
||||
* transparent argument type: :doc:`sol::variadic_arg<../api/variadic_args>`, :doc:`sol::this_state<../api/this_state>`
|
||||
* transparent argument type: :doc:`sol::variadic_arg<../api/variadic_args>`, :doc:`sol::this_state<../api/this_state>`, :doc:`sol::this_environment<../api/this_environment>`
|
||||
* usertype<T> class: :doc:`sol::usertype<../api/usertype>`
|
||||
|
||||
Is set as a :doc:`userdata + usertype<../api/usertype>`.
|
||||
@ -665,4 +681,4 @@ Some more things you can do/read about:
|
||||
.. _a basic example: https://github.com/ThePhD/sol2/blob/develop/examples/usertype.cpp
|
||||
.. _special functions: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_special_functions.cpp
|
||||
.. _initializers: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_initializers.cpp
|
||||
|
||||
.. _sol2 tutorial examples: https://github.com/ThePhD/sol2/tree/develop/examples/tutorials/quick 'n' dirty
|
||||
|
@ -10,6 +10,7 @@ int main(int, char*[]) {
|
||||
std::cout << "=== require from DLL example ===" << std::endl;
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::package);
|
||||
|
||||
lua.script_file(R"(
|
||||
mo = require("my_object")
|
||||
|
81
examples/tutorials/quick_n_dirty/functions_all.cpp
Normal file
81
examples/tutorials/quick_n_dirty/functions_all.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
void some_function() {
|
||||
std::cout << "some function!" << std::endl;
|
||||
}
|
||||
|
||||
void some_other_function() {
|
||||
std::cout << "some other function!" << std::endl;
|
||||
}
|
||||
|
||||
struct some_class {
|
||||
int variable = 30;
|
||||
|
||||
double member_function() {
|
||||
return 24.5;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int, char*[]) {
|
||||
std::cout << "=== functions (all) example ===" << std::endl;
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
// put an instance of "some_class" into lua
|
||||
// (we'll go into more detail about this later
|
||||
// just know here that it works and is
|
||||
// put into lua as a userdata
|
||||
lua.set("sc", some_class());
|
||||
|
||||
// binds a plain function
|
||||
lua["f1"] = some_function;
|
||||
lua.set_function("f2", &some_other_function);
|
||||
|
||||
// binds just the member function
|
||||
lua["m1"] = &some_class::member_function;
|
||||
|
||||
// binds the class to the type
|
||||
lua.set_function("m2", &some_class::member_function, some_class{});
|
||||
|
||||
// binds just the member variable as a function
|
||||
lua["v1"] = &some_class::variable;
|
||||
|
||||
// binds class with member variable as function
|
||||
lua.set_function("v2", &some_class::variable, some_class{});
|
||||
|
||||
lua.script(R"(
|
||||
f1() -- some function!
|
||||
f2() -- some other function!
|
||||
|
||||
-- need class instance if you don't bind it with the function
|
||||
print(m1(sc)) -- 24.5
|
||||
-- does not need class instance: was bound to lua with one
|
||||
print(m2()) -- 24.5
|
||||
|
||||
-- need class instance if you
|
||||
-- don't bind it with the function
|
||||
print(v1(sc)) -- 30
|
||||
-- does not need class instance:
|
||||
-- it was bound with one
|
||||
print(v2()) -- 30
|
||||
|
||||
-- can set, still
|
||||
-- requires instance
|
||||
v1(sc, 212)
|
||||
-- can set, does not need
|
||||
-- class instance: was bound with one
|
||||
v2(254)
|
||||
|
||||
print(v1(sc)) -- 212
|
||||
print(v2()) -- 254
|
||||
)");
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
32
examples/tutorials/quick_n_dirty/functions_easy.cpp
Normal file
32
examples/tutorials/quick_n_dirty/functions_easy.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char*[]) {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.script("function f (a, b, c, d) return 1 end");
|
||||
lua.script("function g (a, b) return a + b end");
|
||||
|
||||
// sol::function is often easier:
|
||||
// takes a variable number/types of arguments...
|
||||
sol::function fx = lua["f"];
|
||||
// fixed signature std::function<...>
|
||||
// can be used to tie a sol::function down
|
||||
std::function<int(int, double, int, std::string)> stdfx = fx;
|
||||
|
||||
int is_one = stdfx(1, 34.5, 3, "bark");
|
||||
assert(is_one == 1);
|
||||
int is_also_one = fx(1, "boop", 3, "bark");
|
||||
assert(is_also_one == 1);
|
||||
|
||||
// call through operator[]
|
||||
int is_three = lua["g"](1, 2);
|
||||
assert(is_three == 3);
|
||||
double is_4_8 = lua["g"](2.4, 2.4);
|
||||
assert(is_4_8 == 4.8);
|
||||
|
||||
return 0;
|
||||
}
|
35
examples/tutorials/quick_n_dirty/make_tables.cpp
Normal file
35
examples/tutorials/quick_n_dirty/make_tables.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char* []) {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua["abc_sol2"] = lua.create_table_with(
|
||||
0, 24);
|
||||
|
||||
lua.create_named_table("def_sol2",
|
||||
"ghi", lua.create_table_with("bark", 50,
|
||||
// can reference other existing stuff too
|
||||
"woof", lua["abc"]));
|
||||
|
||||
std::string code = R"(
|
||||
abc = { [0] = 24 }
|
||||
def = {
|
||||
ghi = {
|
||||
bark = 50,
|
||||
woof = abc
|
||||
}
|
||||
}
|
||||
)";
|
||||
|
||||
lua.script(code);
|
||||
lua.script(R"(
|
||||
assert(abc_sol2[0] == abc[0])
|
||||
assert(def_sol2.ghi.bark == def.ghi.bark)
|
||||
)");
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char* []) {
|
||||
sol::state lua;
|
||||
|
||||
lua.script("function f (a, b, c) return a, b, c end");
|
||||
|
||||
std::tuple<int, int, int> result;
|
||||
result = lua["f"](100, 200, 300);
|
||||
// result == { 100, 200, 300 }
|
||||
int a;
|
||||
int b;
|
||||
std::string c;
|
||||
sol::tie(a, b, c) = lua["f"](100, 200, "bark");
|
||||
assert(a == 100);
|
||||
assert(b == 200);
|
||||
assert(c == "bark");
|
||||
|
||||
return 0;
|
||||
}
|
39
examples/tutorials/quick_n_dirty/multiple_returns_to_lua.cpp
Normal file
39
examples/tutorials/quick_n_dirty/multiple_returns_to_lua.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char* []) {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua["f"] = [](int a, int b, sol::object c) {
|
||||
// sol::object can be anything here: just pass it through
|
||||
return std::make_tuple(a, b, c);
|
||||
};
|
||||
|
||||
std::tuple<int, int, int> result = lua["f"](100, 200, 300);
|
||||
const std::tuple<int, int, int> expected(100, 200, 300);
|
||||
assert(result == expected);
|
||||
|
||||
std::tuple<int, int, std::string> result2;
|
||||
result2 = lua["f"](100, 200, "BARK BARK BARK!");
|
||||
const std::tuple<int, int, std::string> expected2(100, 200, "BARK BARK BARK!");
|
||||
assert(result2 == expected2);
|
||||
|
||||
int a, b;
|
||||
std::string c;
|
||||
sol::tie(a, b, c) = lua["f"](100, 200, "bark");
|
||||
assert(a == 100);
|
||||
assert(b == 200);
|
||||
assert(c == "bark");
|
||||
|
||||
lua.script(R"(
|
||||
a, b, c = f(150, 250, "woofbark")
|
||||
assert(a == 150)
|
||||
assert(b == 250)
|
||||
assert(c == "woofbark")
|
||||
)");
|
||||
|
||||
return 0;
|
||||
}
|
18
examples/tutorials/quick_n_dirty/opening_a_state.cpp
Normal file
18
examples/tutorials/quick_n_dirty/opening_a_state.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char*[]) {
|
||||
std::cout << "=== opening a state example ===" << std::endl;
|
||||
|
||||
sol::state lua;
|
||||
// open some common libraries
|
||||
lua.open_libraries(sol::lib::base, sol::lib::package);
|
||||
lua.script("print('bark bark bark!')");
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int use_sol2(lua_State* L) {
|
||||
sol::state_view lua(L);
|
||||
lua.script("print('bark bark bark!')");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int, char*[]) {
|
||||
std::cout << "=== opening sol::state_view on raw Lua example ===" << std::endl;
|
||||
|
||||
lua_State* L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
|
||||
lua_pushcclosure(L, &use_sol2, 0);
|
||||
lua_setglobal(L, "use_sol2");
|
||||
|
||||
if (luaL_dostring(L, "use_sol2()")) {
|
||||
lua_error(L);
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
44
examples/tutorials/quick_n_dirty/running_lua_code.cpp
Normal file
44
examples/tutorials/quick_n_dirty/running_lua_code.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char*[]) {
|
||||
std::cout << "=== running lua code example ===" << std::endl;
|
||||
|
||||
{
|
||||
std::ofstream out("a_lua_script.lua");
|
||||
out << "print('hi from a lua script file')";
|
||||
}
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
// load and execute from string
|
||||
lua.script("a = 'test'");
|
||||
// load and execute from file
|
||||
lua.script_file("a_lua_script.lua");
|
||||
|
||||
// run a script, get the result
|
||||
int value = lua.script("return 54");
|
||||
assert(value == 54);
|
||||
|
||||
auto bad_code_result = lua.script("123 herp.derp", [](lua_State*, sol::protected_function_result pfr) {
|
||||
// pfr will contain things that went wrong, for either loading or executing the script
|
||||
// Can throw your own custom error
|
||||
// You can also just return it, and let the call-site handle the error if necessary.
|
||||
return pfr;
|
||||
});
|
||||
// it did not work
|
||||
assert(!bad_code_result.valid());
|
||||
|
||||
// the default handler panics or throws, depending on your settings
|
||||
// uncomment for explosions:
|
||||
//auto bad_code_result_2 = lua.script("bad.code", &sol::script_default_on_error);
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char*[]) {
|
||||
std::cout << "=== running lua code (low level) example ===" << std::endl;
|
||||
|
||||
{
|
||||
std::ofstream out("a_lua_script.lua");
|
||||
out << "print('hi from a lua script file')";
|
||||
}
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
// load file without execute
|
||||
sol::load_result script1 = lua.load_file("a_lua_script.lua");
|
||||
//execute
|
||||
script1();
|
||||
|
||||
// load string without execute
|
||||
sol::load_result script2 = lua.load("a = 'test'");
|
||||
//execute
|
||||
sol::protected_function_result script2result = script2();
|
||||
// optionally, check if it worked
|
||||
if (script2result.valid()) {
|
||||
// yay!
|
||||
}
|
||||
else {
|
||||
// aww
|
||||
}
|
||||
|
||||
sol::load_result script3 = lua.load("return 24");
|
||||
// execute, get return value
|
||||
int value2 = script3();
|
||||
assert(value2 == 24);
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,14 +1,12 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
std::cout << "=== self_call example ===" << std::endl;
|
||||
|
||||
sol::state lua;
|
||||
|
||||
lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::table);
|
||||
|
||||
// a small script using 'self' syntax
|
||||
@ -33,4 +31,6 @@ int main() {
|
||||
lua["print_some_val"]();
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
83
examples/tutorials/quick_n_dirty/set_and_get_variables.cpp
Normal file
83
examples/tutorials/quick_n_dirty/set_and_get_variables.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char*[]) {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
// integer types
|
||||
lua.set("number", 24);
|
||||
// floating point numbers
|
||||
lua["number2"] = 24.5;
|
||||
// string types
|
||||
lua["important_string"] = "woof woof";
|
||||
// is callable, therefore gets stored as a function that can be called
|
||||
lua["a_function"] = []() { return 100; };
|
||||
// make a table
|
||||
lua["some_table"] = lua.create_table_with("value", 24);
|
||||
|
||||
|
||||
// equivalent to this code
|
||||
std::string equivalent_code = R"(
|
||||
t = {
|
||||
number = 24,
|
||||
number2 = 24.5,
|
||||
important_string = "woof woof",
|
||||
a_function = function () return 100 end,
|
||||
some_table = { value = 24 }
|
||||
}
|
||||
)";
|
||||
|
||||
// check in Lua
|
||||
lua.script(equivalent_code);
|
||||
|
||||
lua.script(R"(
|
||||
assert(t.number == number)
|
||||
assert(t.number2 == number2)
|
||||
assert(t.important_string == important_string)
|
||||
assert(t.a_function() == a_function())
|
||||
assert(t.some_table.value == some_table.value)
|
||||
)");
|
||||
|
||||
|
||||
// implicit conversion
|
||||
int number = lua["number"];
|
||||
assert(number == 24);
|
||||
// explicit get
|
||||
auto number2 = lua.get<double>("number2");
|
||||
assert(number2 == 24.5);
|
||||
// strings too
|
||||
std::string important_string = lua["important_string"];
|
||||
assert(important_string == "woof woof");
|
||||
// dig into a table
|
||||
int value = lua["some_table"]["value"];
|
||||
assert(value == 24);
|
||||
// get a function
|
||||
sol::function a_function = lua["a_function"];
|
||||
int value_is_100 = a_function();
|
||||
// convertible to std::function
|
||||
std::function<int()> a_std_function = a_function;
|
||||
int value_is_still_100 = a_std_function();
|
||||
assert(value_is_100 == 100);
|
||||
assert(value_is_still_100 == 100);
|
||||
|
||||
sol::object number_obj = lua.get<sol::object>("number");
|
||||
// sol::type::number
|
||||
sol::type t1 = number_obj.get_type();
|
||||
assert(t1 == sol::type::number);
|
||||
|
||||
sol::object function_obj = lua["a_function"];
|
||||
// sol::type::function
|
||||
sol::type t2 = function_obj.get_type();
|
||||
assert(t2 == sol::type::function);
|
||||
bool is_it_really = function_obj.is<std::function<int()>>();
|
||||
assert(is_it_really);
|
||||
|
||||
// will not contain data
|
||||
sol::optional<int> check_for_me = lua["a_function"];
|
||||
assert(check_for_me == sol::nullopt);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char*[]) {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.script("exists = 250");
|
||||
|
||||
int first_try = lua.get_or("exists", 322);
|
||||
assert(first_try == 250);
|
||||
|
||||
lua.set("exists", sol::lua_nil);
|
||||
int second_try = lua.get_or("exists", 322);
|
||||
assert(second_try == 322);
|
||||
|
||||
return 0;
|
||||
}
|
46
examples/tutorials/quick_n_dirty/tables_and_nesting.cpp
Normal file
46
examples/tutorials/quick_n_dirty/tables_and_nesting.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
int main(int, char*[]) {
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
lua.script(R"(
|
||||
abc = { [0] = 24 }
|
||||
def = {
|
||||
ghi = {
|
||||
bark = 50,
|
||||
woof = abc
|
||||
}
|
||||
}
|
||||
)");
|
||||
|
||||
sol::table abc = lua["abc"];
|
||||
sol::table def = lua["def"];
|
||||
sol::table ghi = lua["def"]["ghi"];
|
||||
|
||||
int bark1 = def["ghi"]["bark"];
|
||||
int bark2 = lua["def"]["ghi"]["bark"];
|
||||
assert(bark1 == 50);
|
||||
assert(bark2 == 50);
|
||||
|
||||
int abcval1 = abc[0];
|
||||
int abcval2 = ghi["woof"][0];
|
||||
assert(abcval1 == 24);
|
||||
assert(abcval2 == 24);
|
||||
|
||||
sol::optional<int> will_not_error = lua["abc"]["DOESNOTEXIST"]["ghi"];
|
||||
assert(will_not_error == sol::nullopt);
|
||||
|
||||
int also_will_not_error = lua["abc"]["def"]["ghi"]["jklm"].get_or(25);
|
||||
assert(also_will_not_error == 25);
|
||||
|
||||
// if you don't go safe,
|
||||
// will throw (or do at_panic if no exceptions)
|
||||
//int aaaahhh = lua["boom"]["the_dynamite"];
|
||||
|
||||
return 0;
|
||||
}
|
99
examples/tutorials/quick_n_dirty/userdata.cpp
Normal file
99
examples/tutorials/quick_n_dirty/userdata.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
struct Doge {
|
||||
int tailwag = 50;
|
||||
|
||||
Doge() {
|
||||
}
|
||||
|
||||
Doge(int wags)
|
||||
: tailwag(wags) {
|
||||
}
|
||||
|
||||
~Doge() {
|
||||
std::cout << "Dog at " << this << " is being destroyed..." << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int, char* []) {
|
||||
std::cout << "=== userdata example ===" << std::endl;
|
||||
|
||||
sol::state lua;
|
||||
|
||||
Doge dog{ 30 };
|
||||
|
||||
// fresh one put into Lua
|
||||
lua["dog"] = Doge{};
|
||||
// Copy into lua: destroyed by Lua VM during garbage collection
|
||||
lua["dog_copy"] = dog;
|
||||
// OR: move semantics - will call move constructor if present instead
|
||||
// Again, owned by Lua
|
||||
lua["dog_move"] = std::move(dog);
|
||||
lua["dog_unique_ptr"] = std::make_unique<Doge>(25);
|
||||
lua["dog_shared_ptr"] = std::make_shared<Doge>(31);
|
||||
|
||||
// Identical to above
|
||||
Doge dog2{ 30 };
|
||||
lua.set("dog2", Doge{});
|
||||
lua.set("dog2_copy", dog2);
|
||||
lua.set("dog2_move", std::move(dog2));
|
||||
lua.set("dog2_unique_ptr", std::unique_ptr<Doge>(new Doge(25)));
|
||||
lua.set("dog2_shared_ptr", std::shared_ptr<Doge>(new Doge(31)));
|
||||
|
||||
// Note all of them can be retrieved the same way:
|
||||
Doge& lua_dog = lua["dog"];
|
||||
Doge& lua_dog_copy = lua["dog_copy"];
|
||||
Doge& lua_dog_move = lua["dog_move"];
|
||||
Doge& lua_dog_unique_ptr = lua["dog_unique_ptr"];
|
||||
Doge& lua_dog_shared_ptr = lua["dog_shared_ptr"];
|
||||
assert(lua_dog.tailwag == 50);
|
||||
assert(lua_dog_copy.tailwag == 30);
|
||||
assert(lua_dog_move.tailwag == 30);
|
||||
assert(lua_dog_unique_ptr.tailwag == 25);
|
||||
assert(lua_dog_shared_ptr.tailwag == 31);
|
||||
|
||||
// lua will treat these types as opaque, and you will be able to pass them around
|
||||
// to C++ functions and Lua functions alike
|
||||
|
||||
// Use a C++ reference to handle memory directly
|
||||
// otherwise take by value, without '&'
|
||||
lua["f"] = [](Doge& dog) {
|
||||
std::cout << "dog wags its tail " << dog.tailwag << " times!" << std::endl;
|
||||
};
|
||||
|
||||
// if you bind a function using a pointer,
|
||||
// you can handle when `nil` is passed
|
||||
lua["handling_f"] = [](Doge* dog) {
|
||||
if (dog == nullptr) {
|
||||
std::cout << "dog was nil!" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "dog wags its tail " << dog->tailwag << " times!" << std::endl;
|
||||
};
|
||||
|
||||
lua.script(R"(
|
||||
f(dog)
|
||||
f(dog_copy)
|
||||
f(dog_move)
|
||||
f(dog_unique_ptr)
|
||||
f(dog_shared_ptr)
|
||||
|
||||
-- C++ arguments that are pointers can handle nil
|
||||
handling_f(dog)
|
||||
handling_f(dog_copy)
|
||||
handling_f(dog_move)
|
||||
handling_f(dog_unique_ptr)
|
||||
handling_f(dog_shared_ptr)
|
||||
handling_f(nil)
|
||||
|
||||
-- never do this
|
||||
-- f(nil)
|
||||
)");
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
66
examples/tutorials/quick_n_dirty/usertypes.cpp
Normal file
66
examples/tutorials/quick_n_dirty/usertypes.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
struct Doge {
|
||||
int tailwag = 50;
|
||||
|
||||
Doge() {
|
||||
}
|
||||
|
||||
Doge(int wags)
|
||||
: tailwag(wags) {
|
||||
}
|
||||
|
||||
~Doge() {
|
||||
std::cout << "Dog at " << this << " is being destroyed..." << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int, char* []) {
|
||||
std::cout << "=== usertypes example ===" << std::endl;
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
Doge dog{ 30 };
|
||||
|
||||
lua["dog"] = Doge{};
|
||||
lua["dog_copy"] = dog;
|
||||
lua["dog_move"] = std::move(dog);
|
||||
lua["dog_unique_ptr"] = std::make_unique<Doge>(21);
|
||||
lua["dog_shared_ptr"] = std::make_shared<Doge>(51);
|
||||
|
||||
// now we can access these types in Lua
|
||||
lua.new_usertype<Doge>( "Doge",
|
||||
sol::constructors<Doge(), Doge(int)>(),
|
||||
"tailwag", &Doge::tailwag
|
||||
);
|
||||
lua.script(R"(
|
||||
function f (dog)
|
||||
if dog == nil then
|
||||
print('dog was nil!')
|
||||
return
|
||||
end
|
||||
print('dog wags its tail ' .. dog.tailwag .. ' times!')
|
||||
end
|
||||
)");
|
||||
|
||||
lua.script(R"(
|
||||
dog_lua = Doge.new()
|
||||
|
||||
f(dog_lua)
|
||||
f(dog)
|
||||
f(dog_copy)
|
||||
f(dog_move)
|
||||
f(dog)
|
||||
f(dog_unique_ptr)
|
||||
f(dog_shared_ptr)
|
||||
f(nil)
|
||||
)");
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -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 2017-11-08 01:20:39.160314 UTC
|
||||
// This header was generated with sol v2.18.6 (revision 10b1bb0)
|
||||
// Generated 2017-11-09 22:36:14.826447 UTC
|
||||
// This header was generated with sol v2.18.6 (revision 90bbead)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||
@ -253,6 +253,8 @@ namespace sol {
|
||||
using stack_thread = basic_thread<stack_reference>;
|
||||
using stack_coroutine = basic_coroutine<stack_reference>;
|
||||
|
||||
struct stack_proxy_base;
|
||||
struct stack_proxy;
|
||||
struct variadic_args;
|
||||
struct variadic_results;
|
||||
struct stack_count;
|
||||
@ -4399,11 +4401,12 @@ namespace sol {
|
||||
#else
|
||||
template <lua_CFunction f>
|
||||
int static_trampoline(lua_State* L) {
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
#if defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && !defined(SOL_LUAJIT)
|
||||
return f(L);
|
||||
|
||||
#else
|
||||
try {
|
||||
#endif
|
||||
return f(L);
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
}
|
||||
catch (const char* s) {
|
||||
lua_pushstring(L, s);
|
||||
@ -4411,10 +4414,14 @@ namespace sol {
|
||||
catch (const std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
#if defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && defined(SOL_LUAJIT)
|
||||
// LuaJIT cannot have the catchall when the safe propagation is on
|
||||
// but LuaJIT will swallow all C++ errors
|
||||
// if we don't at least catch std::exception ones
|
||||
catch (...) {
|
||||
lua_pushstring(L, "caught (...) exception");
|
||||
}
|
||||
|
||||
#endif // LuaJIT cannot have the catchall, but we must catch std::exceps for it
|
||||
return lua_error(L);
|
||||
#endif
|
||||
}
|
||||
@ -4446,11 +4453,11 @@ namespace sol {
|
||||
if (meta::bind_traits<meta::unqualified_t<Fx>>::is_noexcept) {
|
||||
return f(L, std::forward<Args>(args)...);
|
||||
}
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
#if defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && !defined(SOL_LUAJIT)
|
||||
return f(L, std::forward<Args>(args)...);
|
||||
#else
|
||||
try {
|
||||
#endif
|
||||
return f(L, std::forward<Args>(args)...);
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
}
|
||||
catch (const char* s) {
|
||||
lua_pushstring(L, s);
|
||||
@ -4458,10 +4465,14 @@ namespace sol {
|
||||
catch (const std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
#if defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && !defined(SOL_LUAJIT)
|
||||
// LuaJIT cannot have the catchall when the safe propagation is on
|
||||
// but LuaJIT will swallow all C++ errors
|
||||
// if we don't at least catch std::exception ones
|
||||
catch (...) {
|
||||
lua_pushstring(L, "caught (...) exception");
|
||||
}
|
||||
|
||||
#endif
|
||||
return lua_error(L);
|
||||
#endif
|
||||
}
|
||||
@ -5410,6 +5421,16 @@ namespace sol {
|
||||
|
||||
template <typename T>
|
||||
struct is_stack_based : std::is_base_of<stack_reference, T> {};
|
||||
template <>
|
||||
struct is_stack_based<variadic_args> : std::true_type {};
|
||||
template <>
|
||||
struct is_stack_based<unsafe_function_result> : std::true_type {};
|
||||
template <>
|
||||
struct is_stack_based<protected_function_result> : std::true_type {};
|
||||
template <>
|
||||
struct is_stack_based<stack_proxy> : std::true_type {};
|
||||
template <>
|
||||
struct is_stack_based<stack_proxy_base> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_lua_primitive<T*> : std::true_type {};
|
||||
@ -10497,6 +10518,251 @@ namespace sol {
|
||||
|
||||
// end of sol/proxy_base.hpp
|
||||
|
||||
// beginning of sol/stack_iterator.hpp
|
||||
|
||||
namespace sol {
|
||||
template <typename proxy_t, bool is_const>
|
||||
struct stack_iterator : std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const proxy_t, proxy_t>, std::ptrdiff_t, std::conditional_t<is_const, const proxy_t*, proxy_t*>, std::conditional_t<is_const, const proxy_t, proxy_t>> {
|
||||
typedef std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const proxy_t, proxy_t>, std::ptrdiff_t, std::conditional_t<is_const, const proxy_t*, proxy_t*>, std::conditional_t<is_const, const proxy_t, proxy_t>> base_t;
|
||||
typedef typename base_t::reference reference;
|
||||
typedef typename base_t::pointer pointer;
|
||||
typedef typename base_t::value_type value_type;
|
||||
typedef typename base_t::difference_type difference_type;
|
||||
typedef typename base_t::iterator_category iterator_category;
|
||||
lua_State* L;
|
||||
int index;
|
||||
int stacktop;
|
||||
proxy_t sp;
|
||||
|
||||
stack_iterator()
|
||||
: L(nullptr), index((std::numeric_limits<int>::max)()), stacktop((std::numeric_limits<int>::max)()), sp() {
|
||||
}
|
||||
stack_iterator(const stack_iterator<proxy_t, true>& r)
|
||||
: L(r.L), index(r.index), stacktop(r.stacktop), sp(r.sp) {
|
||||
}
|
||||
stack_iterator(lua_State* luastate, int idx, int topidx)
|
||||
: L(luastate), index(idx), stacktop(topidx), sp(luastate, idx) {
|
||||
}
|
||||
|
||||
reference operator*() {
|
||||
return proxy_t(L, index);
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
return proxy_t(L, index);
|
||||
}
|
||||
|
||||
pointer operator->() {
|
||||
sp = proxy_t(L, index);
|
||||
return &sp;
|
||||
}
|
||||
|
||||
pointer operator->() const {
|
||||
const_cast<proxy_t&>(sp) = proxy_t(L, index);
|
||||
return &sp;
|
||||
}
|
||||
|
||||
stack_iterator& operator++() {
|
||||
++index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
stack_iterator operator++(int) {
|
||||
auto r = *this;
|
||||
this->operator++();
|
||||
return r;
|
||||
}
|
||||
|
||||
stack_iterator& operator--() {
|
||||
--index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
stack_iterator operator--(int) {
|
||||
auto r = *this;
|
||||
this->operator--();
|
||||
return r;
|
||||
}
|
||||
|
||||
stack_iterator& operator+=(difference_type idx) {
|
||||
index += static_cast<int>(idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
stack_iterator& operator-=(difference_type idx) {
|
||||
index -= static_cast<int>(idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
difference_type operator-(const stack_iterator& r) const {
|
||||
return index - r.index;
|
||||
}
|
||||
|
||||
stack_iterator operator+(difference_type idx) const {
|
||||
stack_iterator r = *this;
|
||||
r += idx;
|
||||
return r;
|
||||
}
|
||||
|
||||
reference operator[](difference_type idx) const {
|
||||
return proxy_t(L, index + static_cast<int>(idx));
|
||||
}
|
||||
|
||||
bool operator==(const stack_iterator& r) const {
|
||||
if (stacktop == (std::numeric_limits<int>::max)()) {
|
||||
return r.index == r.stacktop;
|
||||
}
|
||||
else if (r.stacktop == (std::numeric_limits<int>::max)()) {
|
||||
return index == stacktop;
|
||||
}
|
||||
return index == r.index;
|
||||
}
|
||||
|
||||
bool operator!=(const stack_iterator& r) const {
|
||||
return !(this->operator==(r));
|
||||
}
|
||||
|
||||
bool operator<(const stack_iterator& r) const {
|
||||
return index < r.index;
|
||||
}
|
||||
|
||||
bool operator>(const stack_iterator& r) const {
|
||||
return index > r.index;
|
||||
}
|
||||
|
||||
bool operator<=(const stack_iterator& r) const {
|
||||
return index <= r.index;
|
||||
}
|
||||
|
||||
bool operator>=(const stack_iterator& r) const {
|
||||
return index >= r.index;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename proxy_t, bool is_const>
|
||||
inline stack_iterator<proxy_t, is_const> operator+(typename stack_iterator<proxy_t, is_const>::difference_type n, const stack_iterator<proxy_t, is_const>& r) {
|
||||
return r + n;
|
||||
}
|
||||
} // namespace sol
|
||||
|
||||
// end of sol/stack_iterator.hpp
|
||||
|
||||
// beginning of sol/stack_proxy.hpp
|
||||
|
||||
// beginning of sol/stack_proxy_base.hpp
|
||||
|
||||
namespace sol {
|
||||
struct stack_proxy_base : public proxy_base<stack_proxy_base> {
|
||||
private:
|
||||
lua_State* L;
|
||||
int index;
|
||||
|
||||
public:
|
||||
stack_proxy_base()
|
||||
: L(nullptr), index(0) {
|
||||
}
|
||||
stack_proxy_base(lua_State* L, int index)
|
||||
: L(L), index(index) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) get() const {
|
||||
return stack::get<T>(L, stack_index());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
return stack::check<T>(L, stack_index());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) as() const {
|
||||
return get<T>();
|
||||
}
|
||||
|
||||
type get_type() const noexcept {
|
||||
return type_of(lua_state(), stack_index());
|
||||
}
|
||||
|
||||
int push() const {
|
||||
return push(L);
|
||||
}
|
||||
|
||||
int push(lua_State* Ls) const {
|
||||
lua_pushvalue(Ls, index);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_State* lua_state() const {
|
||||
return L;
|
||||
}
|
||||
int stack_index() const {
|
||||
return index;
|
||||
}
|
||||
};
|
||||
|
||||
namespace stack {
|
||||
template <>
|
||||
struct getter<stack_proxy_base> {
|
||||
static stack_proxy_base get(lua_State* L, int index = -1) {
|
||||
return stack_proxy_base(L, index);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pusher<stack_proxy_base> {
|
||||
static int push(lua_State*, const stack_proxy_base& ref) {
|
||||
return ref.push();
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
|
||||
} // namespace sol
|
||||
|
||||
// end of sol/stack_proxy_base.hpp
|
||||
|
||||
namespace sol {
|
||||
struct stack_proxy : public stack_proxy_base {
|
||||
private:
|
||||
lua_State* L;
|
||||
int index;
|
||||
|
||||
public:
|
||||
stack_proxy()
|
||||
: stack_proxy_base() {
|
||||
}
|
||||
stack_proxy(lua_State* L, int index)
|
||||
: stack_proxy_base(L, index) {
|
||||
}
|
||||
|
||||
template <typename... Ret, typename... Args>
|
||||
decltype(auto) call(Args&&... args);
|
||||
|
||||
template <typename... Args>
|
||||
decltype(auto) operator()(Args&&... args) {
|
||||
return call<>(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
namespace stack {
|
||||
template <>
|
||||
struct getter<stack_proxy> {
|
||||
static stack_proxy get(lua_State* L, int index = -1) {
|
||||
return stack_proxy(L, index);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pusher<stack_proxy> {
|
||||
static int push(lua_State*, const stack_proxy& ref) {
|
||||
return ref.push();
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
} // namespace sol
|
||||
|
||||
// end of sol/stack_proxy.hpp
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace sol {
|
||||
@ -10549,6 +10815,16 @@ namespace sol {
|
||||
}
|
||||
|
||||
public:
|
||||
typedef stack_proxy reference_type;
|
||||
typedef stack_proxy value_type;
|
||||
typedef stack_proxy* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef stack_iterator<stack_proxy, false> iterator;
|
||||
typedef stack_iterator<stack_proxy, true> const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
protected_function_result() = default;
|
||||
protected_function_result(lua_State* Ls, int idx = -1, int retnum = 0, int popped = 0, call_status pferr = call_status::ok) noexcept
|
||||
: L(Ls), index(idx), returncount(retnum), popcount(popped), err(pferr) {
|
||||
@ -10593,6 +10869,52 @@ namespace sol {
|
||||
return tagged_get(types<meta::unqualified_t<T>>(), index_offset);
|
||||
}
|
||||
|
||||
type get_type(difference_type index_offset = 0) const noexcept {
|
||||
return type_of(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
stack_proxy operator[](difference_type index_offset) const {
|
||||
return stack_proxy(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
return iterator(L, index, stack_index() + return_count());
|
||||
}
|
||||
iterator end() {
|
||||
return iterator(L, stack_index() + return_count(), stack_index() + return_count());
|
||||
}
|
||||
const_iterator begin() const {
|
||||
return const_iterator(L, index, stack_index() + return_count());
|
||||
}
|
||||
const_iterator end() const {
|
||||
return const_iterator(L, stack_index() + return_count(), stack_index() + return_count());
|
||||
}
|
||||
const_iterator cbegin() const {
|
||||
return begin();
|
||||
}
|
||||
const_iterator cend() const {
|
||||
return end();
|
||||
}
|
||||
|
||||
reverse_iterator rbegin() {
|
||||
return std::reverse_iterator<iterator>(begin());
|
||||
}
|
||||
reverse_iterator rend() {
|
||||
return std::reverse_iterator<iterator>(end());
|
||||
}
|
||||
const_reverse_iterator rbegin() const {
|
||||
return std::reverse_iterator<const_iterator>(begin());
|
||||
}
|
||||
const_reverse_iterator rend() const {
|
||||
return std::reverse_iterator<const_iterator>(end());
|
||||
}
|
||||
const_reverse_iterator crbegin() const {
|
||||
return std::reverse_iterator<const_iterator>(cbegin());
|
||||
}
|
||||
const_reverse_iterator crend() const {
|
||||
return std::reverse_iterator<const_iterator>(cend());
|
||||
}
|
||||
|
||||
lua_State* lua_state() const noexcept {
|
||||
return L;
|
||||
};
|
||||
@ -10644,6 +10966,16 @@ namespace sol {
|
||||
int returncount;
|
||||
|
||||
public:
|
||||
typedef stack_proxy reference_type;
|
||||
typedef stack_proxy value_type;
|
||||
typedef stack_proxy* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef stack_iterator<stack_proxy, false> iterator;
|
||||
typedef stack_iterator<stack_proxy, true> const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
unsafe_function_result() = default;
|
||||
unsafe_function_result(lua_State* Ls, int idx = -1, int retnum = 0)
|
||||
: L(Ls), index(idx), returncount(retnum) {
|
||||
@ -10674,8 +11006,54 @@ namespace sol {
|
||||
unsafe_function_result& operator=(protected_function_result&& o) noexcept;
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) get(int index_offset = 0) const {
|
||||
return stack::get<T>(L, index + index_offset);
|
||||
decltype(auto) get(difference_type index_offset = 0) const {
|
||||
return stack::get<T>(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
type get_type(difference_type index_offset = 0) const noexcept {
|
||||
return type_of(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
stack_proxy operator[](difference_type index_offset) const {
|
||||
return stack_proxy(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
return iterator(L, index, stack_index() + return_count());
|
||||
}
|
||||
iterator end() {
|
||||
return iterator(L, stack_index() + return_count(), stack_index() + return_count());
|
||||
}
|
||||
const_iterator begin() const {
|
||||
return const_iterator(L, index, stack_index() + return_count());
|
||||
}
|
||||
const_iterator end() const {
|
||||
return const_iterator(L, stack_index() + return_count(), stack_index() + return_count());
|
||||
}
|
||||
const_iterator cbegin() const {
|
||||
return begin();
|
||||
}
|
||||
const_iterator cend() const {
|
||||
return end();
|
||||
}
|
||||
|
||||
reverse_iterator rbegin() {
|
||||
return std::reverse_iterator<iterator>(begin());
|
||||
}
|
||||
reverse_iterator rend() {
|
||||
return std::reverse_iterator<iterator>(end());
|
||||
}
|
||||
const_reverse_iterator rbegin() const {
|
||||
return std::reverse_iterator<const_iterator>(begin());
|
||||
}
|
||||
const_reverse_iterator rend() const {
|
||||
return std::reverse_iterator<const_iterator>(end());
|
||||
}
|
||||
const_reverse_iterator crbegin() const {
|
||||
return std::reverse_iterator<const_iterator>(cbegin());
|
||||
}
|
||||
const_reverse_iterator crend() const {
|
||||
return std::reverse_iterator<const_iterator>(cend());
|
||||
}
|
||||
|
||||
call_status status() const noexcept {
|
||||
@ -10722,6 +11100,52 @@ namespace sol {
|
||||
|
||||
// end of sol/unsafe_function_result.hpp
|
||||
|
||||
namespace sol {
|
||||
|
||||
namespace detail {
|
||||
template <>
|
||||
struct is_speshul<unsafe_function_result> : std::true_type {};
|
||||
template <>
|
||||
struct is_speshul<protected_function_result> : std::true_type {};
|
||||
|
||||
template <std::size_t I, typename... Args, typename T>
|
||||
stack_proxy get(types<Args...>, index_value<0>, index_value<I>, const T& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, std::size_t N, typename Arg, typename... Args, typename T, meta::enable<meta::boolean<(N > 0)>> = meta::enabler>
|
||||
stack_proxy get(types<Arg, Args...>, index_value<N>, index_value<I>, const T& fr) {
|
||||
return get(types<Args...>(), index_value<N - 1>(), index_value<I + lua_size<Arg>::value>(), fr);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <>
|
||||
struct tie_size<unsafe_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||
|
||||
template <>
|
||||
struct tie_size<protected_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||
|
||||
template <std::size_t I>
|
||||
stack_proxy get(const unsafe_function_result& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args>
|
||||
stack_proxy get(types<Args...> t, const unsafe_function_result& fr) {
|
||||
return detail::get(t, index_value<I>(), index_value<0>(), fr);
|
||||
}
|
||||
|
||||
template <std::size_t I>
|
||||
stack_proxy get(const protected_function_result& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args>
|
||||
stack_proxy get(types<Args...> t, const protected_function_result& fr) {
|
||||
return detail::get(t, index_value<I>(), index_value<0>(), fr);
|
||||
}
|
||||
} // namespace sol
|
||||
|
||||
// end of sol/function_result.hpp
|
||||
|
||||
// beginning of sol/function_types.hpp
|
||||
@ -13119,7 +13543,7 @@ namespace sol {
|
||||
stack::push(lua_state(), error);
|
||||
}
|
||||
};
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || defined(SOL_LUAJIT)
|
||||
try {
|
||||
#endif
|
||||
#endif // No Exceptions
|
||||
@ -13128,7 +13552,7 @@ namespace sol {
|
||||
poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid());
|
||||
returncount = poststacksize - (firstreturn - 1);
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || defined(SOL_LUAJIT)
|
||||
}
|
||||
// Handle C++ errors thrown from C++ functions bound inside of lua
|
||||
catch (const char* error) {
|
||||
@ -13141,11 +13565,16 @@ namespace sol {
|
||||
firstreturn = lua_gettop(lua_state());
|
||||
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
|
||||
}
|
||||
#if !defined(SOL_LUAJIT)
|
||||
// LuaJIT cannot have the catchall when the safe propagation is on
|
||||
// but LuaJIT will swallow all C++ errors
|
||||
// if we don't at least catch std::exception ones
|
||||
catch (...) {
|
||||
onexcept("caught (...) unknown error during protected_function call");
|
||||
firstreturn = lua_gettop(lua_state());
|
||||
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
|
||||
}
|
||||
#endif // LuaJIT
|
||||
#else
|
||||
// do not handle exceptions: they can be propogated into C++ and keep all type information / rich information
|
||||
#endif // about as safe as possible
|
||||
@ -13326,6 +13755,11 @@ namespace sol {
|
||||
// end of sol/protected_function.hpp
|
||||
|
||||
namespace sol {
|
||||
template <typename... Ret, typename... Args>
|
||||
inline decltype(auto) stack_proxy::call(Args&&... args) {
|
||||
stack_function sf(this->lua_state(), this->stack_index());
|
||||
return sf.template call<Ret...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline protected_function_result::protected_function_result(unsafe_function_result&& o) noexcept
|
||||
: L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()), popcount(o.return_count()), err(o.status()) {
|
||||
@ -13845,254 +14279,7 @@ namespace sol {
|
||||
|
||||
// beginning of sol/variadic_args.hpp
|
||||
|
||||
// beginning of sol/stack_proxy.hpp
|
||||
|
||||
namespace sol {
|
||||
struct stack_proxy : public proxy_base<stack_proxy> {
|
||||
private:
|
||||
lua_State* L;
|
||||
int index;
|
||||
|
||||
public:
|
||||
stack_proxy()
|
||||
: L(nullptr), index(0) {
|
||||
}
|
||||
stack_proxy(lua_State* L, int index)
|
||||
: L(L), index(index) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) get() const {
|
||||
return stack::get<T>(L, stack_index());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
return stack::check<T>(L, stack_index());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) as() const {
|
||||
return get<T>();
|
||||
}
|
||||
|
||||
type get_type() const noexcept {
|
||||
return type_of(lua_state(), stack_index());
|
||||
}
|
||||
|
||||
int push() const {
|
||||
return push(L);
|
||||
}
|
||||
|
||||
int push(lua_State* Ls) const {
|
||||
lua_pushvalue(Ls, index);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_State* lua_state() const {
|
||||
return L;
|
||||
}
|
||||
int stack_index() const {
|
||||
return index;
|
||||
}
|
||||
|
||||
template <typename... Ret, typename... Args>
|
||||
decltype(auto) call(Args&&... args) {
|
||||
return get<function>().template call<Ret...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
decltype(auto) operator()(Args&&... args) {
|
||||
return call<>(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
namespace stack {
|
||||
template <>
|
||||
struct getter<stack_proxy> {
|
||||
static stack_proxy get(lua_State* L, int index = -1) {
|
||||
return stack_proxy(L, index);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pusher<stack_proxy> {
|
||||
static int push(lua_State*, const stack_proxy& ref) {
|
||||
return ref.push();
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
|
||||
namespace detail {
|
||||
template <>
|
||||
struct is_speshul<unsafe_function_result> : std::true_type {};
|
||||
template <>
|
||||
struct is_speshul<protected_function_result> : std::true_type {};
|
||||
|
||||
template <std::size_t I, typename... Args, typename T>
|
||||
stack_proxy get(types<Args...>, index_value<0>, index_value<I>, const T& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, std::size_t N, typename Arg, typename... Args, typename T, meta::enable<meta::boolean<(N > 0)>> = meta::enabler>
|
||||
stack_proxy get(types<Arg, Args...>, index_value<N>, index_value<I>, const T& fr) {
|
||||
return get(types<Args...>(), index_value<N - 1>(), index_value<I + lua_size<Arg>::value>(), fr);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <>
|
||||
struct tie_size<unsafe_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||
|
||||
template <std::size_t I>
|
||||
stack_proxy get(const unsafe_function_result& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args>
|
||||
stack_proxy get(types<Args...> t, const unsafe_function_result& fr) {
|
||||
return detail::get(t, index_value<I>(), index_value<0>(), fr);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct tie_size<protected_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||
|
||||
template <std::size_t I>
|
||||
stack_proxy get(const protected_function_result& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args>
|
||||
stack_proxy get(types<Args...> t, const protected_function_result& fr) {
|
||||
return detail::get(t, index_value<I>(), index_value<0>(), fr);
|
||||
}
|
||||
} // namespace sol
|
||||
|
||||
// end of sol/stack_proxy.hpp
|
||||
|
||||
namespace sol {
|
||||
template <bool is_const>
|
||||
struct va_iterator : std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const stack_proxy, stack_proxy>, std::ptrdiff_t, std::conditional_t<is_const, const stack_proxy*, stack_proxy*>, std::conditional_t<is_const, const stack_proxy, stack_proxy>> {
|
||||
typedef std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const stack_proxy, stack_proxy>, std::ptrdiff_t, std::conditional_t<is_const, const stack_proxy*, stack_proxy*>, std::conditional_t<is_const, const stack_proxy, stack_proxy>> base_t;
|
||||
typedef typename base_t::reference reference;
|
||||
typedef typename base_t::pointer pointer;
|
||||
typedef typename base_t::value_type value_type;
|
||||
typedef typename base_t::difference_type difference_type;
|
||||
typedef typename base_t::iterator_category iterator_category;
|
||||
lua_State* L;
|
||||
int index;
|
||||
int stacktop;
|
||||
stack_proxy sp;
|
||||
|
||||
va_iterator()
|
||||
: L(nullptr), index((std::numeric_limits<int>::max)()), stacktop((std::numeric_limits<int>::max)()) {
|
||||
}
|
||||
va_iterator(const va_iterator<true>& r)
|
||||
: L(r.L), index(r.index), stacktop(r.stacktop) {
|
||||
}
|
||||
va_iterator(lua_State* luastate, int idx, int topidx)
|
||||
: L(luastate), index(idx), stacktop(topidx), sp(luastate, idx) {
|
||||
}
|
||||
|
||||
reference operator*() {
|
||||
return stack_proxy(L, index);
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
return stack_proxy(L, index);
|
||||
}
|
||||
|
||||
pointer operator->() {
|
||||
sp = stack_proxy(L, index);
|
||||
return &sp;
|
||||
}
|
||||
|
||||
pointer operator->() const {
|
||||
const_cast<stack_proxy&>(sp) = stack_proxy(L, index);
|
||||
return &sp;
|
||||
}
|
||||
|
||||
va_iterator& operator++() {
|
||||
++index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
va_iterator operator++(int) {
|
||||
auto r = *this;
|
||||
this->operator++();
|
||||
return r;
|
||||
}
|
||||
|
||||
va_iterator& operator--() {
|
||||
--index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
va_iterator operator--(int) {
|
||||
auto r = *this;
|
||||
this->operator--();
|
||||
return r;
|
||||
}
|
||||
|
||||
va_iterator& operator+=(difference_type idx) {
|
||||
index += static_cast<int>(idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
va_iterator& operator-=(difference_type idx) {
|
||||
index -= static_cast<int>(idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
difference_type operator-(const va_iterator& r) const {
|
||||
return index - r.index;
|
||||
}
|
||||
|
||||
va_iterator operator+(difference_type idx) const {
|
||||
va_iterator r = *this;
|
||||
r += idx;
|
||||
return r;
|
||||
}
|
||||
|
||||
reference operator[](difference_type idx) const {
|
||||
return stack_proxy(L, index + static_cast<int>(idx));
|
||||
}
|
||||
|
||||
bool operator==(const va_iterator& r) const {
|
||||
if (stacktop == (std::numeric_limits<int>::max)()) {
|
||||
return r.index == r.stacktop;
|
||||
}
|
||||
else if (r.stacktop == (std::numeric_limits<int>::max)()) {
|
||||
return index == stacktop;
|
||||
}
|
||||
return index == r.index;
|
||||
}
|
||||
|
||||
bool operator!=(const va_iterator& r) const {
|
||||
return !(this->operator==(r));
|
||||
}
|
||||
|
||||
bool operator<(const va_iterator& r) const {
|
||||
return index < r.index;
|
||||
}
|
||||
|
||||
bool operator>(const va_iterator& r) const {
|
||||
return index > r.index;
|
||||
}
|
||||
|
||||
bool operator<=(const va_iterator& r) const {
|
||||
return index <= r.index;
|
||||
}
|
||||
|
||||
bool operator>=(const va_iterator& r) const {
|
||||
return index >= r.index;
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_const>
|
||||
inline va_iterator<is_const> operator+(typename va_iterator<is_const>::difference_type n, const va_iterator<is_const>& r) {
|
||||
return r + n;
|
||||
}
|
||||
|
||||
struct variadic_args {
|
||||
private:
|
||||
lua_State* L;
|
||||
@ -14105,22 +14292,22 @@ namespace sol {
|
||||
typedef stack_proxy* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef va_iterator<false> iterator;
|
||||
typedef va_iterator<true> const_iterator;
|
||||
typedef stack_iterator<stack_proxy, false> iterator;
|
||||
typedef stack_iterator<stack_proxy, true> const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
variadic_args() = default;
|
||||
variadic_args(lua_State* luastate, int stackindex = -1)
|
||||
: L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lua_gettop(luastate)) {
|
||||
: L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lua_gettop(luastate)) {
|
||||
}
|
||||
variadic_args(lua_State* luastate, int stackindex, int lastindex)
|
||||
: L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lastindex) {
|
||||
: L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lastindex) {
|
||||
}
|
||||
variadic_args(const variadic_args&) = default;
|
||||
variadic_args& operator=(const variadic_args&) = default;
|
||||
variadic_args(variadic_args&& o)
|
||||
: L(o.L), index(o.index), stacktop(o.stacktop) {
|
||||
: L(o.L), index(o.index), stacktop(o.stacktop) {
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but will be thorough
|
||||
@ -14196,16 +14383,16 @@ namespace sol {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) get(difference_type start = 0) const {
|
||||
return stack::get<T>(L, index + static_cast<int>(start));
|
||||
decltype(auto) get(difference_type index_offset = 0) const {
|
||||
return stack::get<T>(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
type get_type(difference_type start = 0) const noexcept {
|
||||
return type_of(L, index + static_cast<int>(start));
|
||||
type get_type(difference_type index_offset = 0) const noexcept {
|
||||
return type_of(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
stack_proxy operator[](difference_type start) const {
|
||||
return stack_proxy(L, index + static_cast<int>(start));
|
||||
stack_proxy operator[](difference_type index_offset) const {
|
||||
return stack_proxy(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
lua_State* lua_state() const {
|
||||
|
@ -126,6 +126,8 @@ namespace sol {
|
||||
using stack_thread = basic_thread<stack_reference>;
|
||||
using stack_coroutine = basic_coroutine<stack_reference>;
|
||||
|
||||
struct stack_proxy_base;
|
||||
struct stack_proxy;
|
||||
struct variadic_args;
|
||||
struct variadic_results;
|
||||
struct stack_count;
|
||||
|
@ -28,6 +28,11 @@
|
||||
#include <functional>
|
||||
|
||||
namespace sol {
|
||||
template <typename... Ret, typename... Args>
|
||||
inline decltype(auto) stack_proxy::call(Args&&... args) {
|
||||
stack_function sf(this->lua_state(), this->stack_index());
|
||||
return sf.template call<Ret...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline protected_function_result::protected_function_result(unsafe_function_result&& o) noexcept
|
||||
: L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()), popcount(o.return_count()), err(o.status()) {
|
||||
|
@ -25,4 +25,50 @@
|
||||
#include "protected_function_result.hpp"
|
||||
#include "unsafe_function_result.hpp"
|
||||
|
||||
namespace sol {
|
||||
|
||||
namespace detail {
|
||||
template <>
|
||||
struct is_speshul<unsafe_function_result> : std::true_type {};
|
||||
template <>
|
||||
struct is_speshul<protected_function_result> : std::true_type {};
|
||||
|
||||
template <std::size_t I, typename... Args, typename T>
|
||||
stack_proxy get(types<Args...>, index_value<0>, index_value<I>, const T& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, std::size_t N, typename Arg, typename... Args, typename T, meta::enable<meta::boolean<(N > 0)>> = meta::enabler>
|
||||
stack_proxy get(types<Arg, Args...>, index_value<N>, index_value<I>, const T& fr) {
|
||||
return get(types<Args...>(), index_value<N - 1>(), index_value<I + lua_size<Arg>::value>(), fr);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <>
|
||||
struct tie_size<unsafe_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||
|
||||
template <>
|
||||
struct tie_size<protected_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||
|
||||
template <std::size_t I>
|
||||
stack_proxy get(const unsafe_function_result& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args>
|
||||
stack_proxy get(types<Args...> t, const unsafe_function_result& fr) {
|
||||
return detail::get(t, index_value<I>(), index_value<0>(), fr);
|
||||
}
|
||||
|
||||
template <std::size_t I>
|
||||
stack_proxy get(const protected_function_result& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args>
|
||||
stack_proxy get(types<Args...> t, const protected_function_result& fr) {
|
||||
return detail::get(t, index_value<I>(), index_value<0>(), fr);
|
||||
}
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_FUNCTION_RESULT_HPP
|
||||
|
@ -150,7 +150,7 @@ namespace sol {
|
||||
stack::push(lua_state(), error);
|
||||
}
|
||||
};
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || defined(SOL_LUAJIT)
|
||||
try {
|
||||
#endif
|
||||
#endif // No Exceptions
|
||||
@ -159,7 +159,7 @@ namespace sol {
|
||||
poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid());
|
||||
returncount = poststacksize - (firstreturn - 1);
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || defined(SOL_LUAJIT)
|
||||
}
|
||||
// Handle C++ errors thrown from C++ functions bound inside of lua
|
||||
catch (const char* error) {
|
||||
@ -172,11 +172,16 @@ namespace sol {
|
||||
firstreturn = lua_gettop(lua_state());
|
||||
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
|
||||
}
|
||||
#if !defined(SOL_LUAJIT)
|
||||
// LuaJIT cannot have the catchall when the safe propagation is on
|
||||
// but LuaJIT will swallow all C++ errors
|
||||
// if we don't at least catch std::exception ones
|
||||
catch (...) {
|
||||
onexcept("caught (...) unknown error during protected_function call");
|
||||
firstreturn = lua_gettop(lua_state());
|
||||
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
|
||||
}
|
||||
#endif // LuaJIT
|
||||
#else
|
||||
// do not handle exceptions: they can be propogated into C++ and keep all type information / rich information
|
||||
#endif // about as safe as possible
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "tuple.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "proxy_base.hpp"
|
||||
#include "stack_iterator.hpp"
|
||||
#include "stack_proxy.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace sol {
|
||||
@ -78,6 +80,16 @@ namespace sol {
|
||||
}
|
||||
|
||||
public:
|
||||
typedef stack_proxy reference_type;
|
||||
typedef stack_proxy value_type;
|
||||
typedef stack_proxy* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef stack_iterator<stack_proxy, false> iterator;
|
||||
typedef stack_iterator<stack_proxy, true> const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
protected_function_result() = default;
|
||||
protected_function_result(lua_State* Ls, int idx = -1, int retnum = 0, int popped = 0, call_status pferr = call_status::ok) noexcept
|
||||
: L(Ls), index(idx), returncount(retnum), popcount(popped), err(pferr) {
|
||||
@ -122,6 +134,52 @@ namespace sol {
|
||||
return tagged_get(types<meta::unqualified_t<T>>(), index_offset);
|
||||
}
|
||||
|
||||
type get_type(difference_type index_offset = 0) const noexcept {
|
||||
return type_of(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
stack_proxy operator[](difference_type index_offset) const {
|
||||
return stack_proxy(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
return iterator(L, index, stack_index() + return_count());
|
||||
}
|
||||
iterator end() {
|
||||
return iterator(L, stack_index() + return_count(), stack_index() + return_count());
|
||||
}
|
||||
const_iterator begin() const {
|
||||
return const_iterator(L, index, stack_index() + return_count());
|
||||
}
|
||||
const_iterator end() const {
|
||||
return const_iterator(L, stack_index() + return_count(), stack_index() + return_count());
|
||||
}
|
||||
const_iterator cbegin() const {
|
||||
return begin();
|
||||
}
|
||||
const_iterator cend() const {
|
||||
return end();
|
||||
}
|
||||
|
||||
reverse_iterator rbegin() {
|
||||
return std::reverse_iterator<iterator>(begin());
|
||||
}
|
||||
reverse_iterator rend() {
|
||||
return std::reverse_iterator<iterator>(end());
|
||||
}
|
||||
const_reverse_iterator rbegin() const {
|
||||
return std::reverse_iterator<const_iterator>(begin());
|
||||
}
|
||||
const_reverse_iterator rend() const {
|
||||
return std::reverse_iterator<const_iterator>(end());
|
||||
}
|
||||
const_reverse_iterator crbegin() const {
|
||||
return std::reverse_iterator<const_iterator>(cbegin());
|
||||
}
|
||||
const_reverse_iterator crend() const {
|
||||
return std::reverse_iterator<const_iterator>(cend());
|
||||
}
|
||||
|
||||
lua_State* lua_state() const noexcept {
|
||||
return L;
|
||||
};
|
||||
|
154
sol/stack_iterator.hpp
Normal file
154
sol/stack_iterator.hpp
Normal file
@ -0,0 +1,154 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2017 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_STACK_ITERATOR_HPP
|
||||
#define SOL_STACK_ITERATOR_HPP
|
||||
|
||||
#include "stack.hpp"
|
||||
#include <limits>
|
||||
#include <iterator>
|
||||
|
||||
namespace sol {
|
||||
template <typename proxy_t, bool is_const>
|
||||
struct stack_iterator : std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const proxy_t, proxy_t>, std::ptrdiff_t, std::conditional_t<is_const, const proxy_t*, proxy_t*>, std::conditional_t<is_const, const proxy_t, proxy_t>> {
|
||||
typedef std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const proxy_t, proxy_t>, std::ptrdiff_t, std::conditional_t<is_const, const proxy_t*, proxy_t*>, std::conditional_t<is_const, const proxy_t, proxy_t>> base_t;
|
||||
typedef typename base_t::reference reference;
|
||||
typedef typename base_t::pointer pointer;
|
||||
typedef typename base_t::value_type value_type;
|
||||
typedef typename base_t::difference_type difference_type;
|
||||
typedef typename base_t::iterator_category iterator_category;
|
||||
lua_State* L;
|
||||
int index;
|
||||
int stacktop;
|
||||
proxy_t sp;
|
||||
|
||||
stack_iterator()
|
||||
: L(nullptr), index((std::numeric_limits<int>::max)()), stacktop((std::numeric_limits<int>::max)()), sp() {
|
||||
}
|
||||
stack_iterator(const stack_iterator<proxy_t, true>& r)
|
||||
: L(r.L), index(r.index), stacktop(r.stacktop), sp(r.sp) {
|
||||
}
|
||||
stack_iterator(lua_State* luastate, int idx, int topidx)
|
||||
: L(luastate), index(idx), stacktop(topidx), sp(luastate, idx) {
|
||||
}
|
||||
|
||||
reference operator*() {
|
||||
return proxy_t(L, index);
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
return proxy_t(L, index);
|
||||
}
|
||||
|
||||
pointer operator->() {
|
||||
sp = proxy_t(L, index);
|
||||
return &sp;
|
||||
}
|
||||
|
||||
pointer operator->() const {
|
||||
const_cast<proxy_t&>(sp) = proxy_t(L, index);
|
||||
return &sp;
|
||||
}
|
||||
|
||||
stack_iterator& operator++() {
|
||||
++index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
stack_iterator operator++(int) {
|
||||
auto r = *this;
|
||||
this->operator++();
|
||||
return r;
|
||||
}
|
||||
|
||||
stack_iterator& operator--() {
|
||||
--index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
stack_iterator operator--(int) {
|
||||
auto r = *this;
|
||||
this->operator--();
|
||||
return r;
|
||||
}
|
||||
|
||||
stack_iterator& operator+=(difference_type idx) {
|
||||
index += static_cast<int>(idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
stack_iterator& operator-=(difference_type idx) {
|
||||
index -= static_cast<int>(idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
difference_type operator-(const stack_iterator& r) const {
|
||||
return index - r.index;
|
||||
}
|
||||
|
||||
stack_iterator operator+(difference_type idx) const {
|
||||
stack_iterator r = *this;
|
||||
r += idx;
|
||||
return r;
|
||||
}
|
||||
|
||||
reference operator[](difference_type idx) const {
|
||||
return proxy_t(L, index + static_cast<int>(idx));
|
||||
}
|
||||
|
||||
bool operator==(const stack_iterator& r) const {
|
||||
if (stacktop == (std::numeric_limits<int>::max)()) {
|
||||
return r.index == r.stacktop;
|
||||
}
|
||||
else if (r.stacktop == (std::numeric_limits<int>::max)()) {
|
||||
return index == stacktop;
|
||||
}
|
||||
return index == r.index;
|
||||
}
|
||||
|
||||
bool operator!=(const stack_iterator& r) const {
|
||||
return !(this->operator==(r));
|
||||
}
|
||||
|
||||
bool operator<(const stack_iterator& r) const {
|
||||
return index < r.index;
|
||||
}
|
||||
|
||||
bool operator>(const stack_iterator& r) const {
|
||||
return index > r.index;
|
||||
}
|
||||
|
||||
bool operator<=(const stack_iterator& r) const {
|
||||
return index <= r.index;
|
||||
}
|
||||
|
||||
bool operator>=(const stack_iterator& r) const {
|
||||
return index >= r.index;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename proxy_t, bool is_const>
|
||||
inline stack_iterator<proxy_t, is_const> operator+(typename stack_iterator<proxy_t, is_const>::difference_type n, const stack_iterator<proxy_t, is_const>& r) {
|
||||
return r + n;
|
||||
}
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_STACK_ITERATOR_HPP
|
@ -22,64 +22,24 @@
|
||||
#ifndef SOL_STACK_PROXY_HPP
|
||||
#define SOL_STACK_PROXY_HPP
|
||||
|
||||
#include "stack.hpp"
|
||||
#include "function.hpp"
|
||||
#include "protected_function.hpp"
|
||||
#include "proxy_base.hpp"
|
||||
#include "stack_proxy_base.hpp"
|
||||
|
||||
namespace sol {
|
||||
struct stack_proxy : public proxy_base<stack_proxy> {
|
||||
struct stack_proxy : public stack_proxy_base {
|
||||
private:
|
||||
lua_State* L;
|
||||
int index;
|
||||
|
||||
public:
|
||||
stack_proxy()
|
||||
: L(nullptr), index(0) {
|
||||
: stack_proxy_base() {
|
||||
}
|
||||
stack_proxy(lua_State* L, int index)
|
||||
: L(L), index(index) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) get() const {
|
||||
return stack::get<T>(L, stack_index());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
return stack::check<T>(L, stack_index());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) as() const {
|
||||
return get<T>();
|
||||
}
|
||||
|
||||
type get_type() const noexcept {
|
||||
return type_of(lua_state(), stack_index());
|
||||
}
|
||||
|
||||
int push() const {
|
||||
return push(L);
|
||||
}
|
||||
|
||||
int push(lua_State* Ls) const {
|
||||
lua_pushvalue(Ls, index);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_State* lua_state() const {
|
||||
return L;
|
||||
}
|
||||
int stack_index() const {
|
||||
return index;
|
||||
: stack_proxy_base(L, index) {
|
||||
}
|
||||
|
||||
template <typename... Ret, typename... Args>
|
||||
decltype(auto) call(Args&&... args) {
|
||||
return get<function>().template call<Ret...>(std::forward<Args>(args)...);
|
||||
}
|
||||
decltype(auto) call(Args&&... args);
|
||||
|
||||
template <typename... Args>
|
||||
decltype(auto) operator()(Args&&... args) {
|
||||
@ -102,49 +62,6 @@ namespace sol {
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
|
||||
namespace detail {
|
||||
template <>
|
||||
struct is_speshul<unsafe_function_result> : std::true_type {};
|
||||
template <>
|
||||
struct is_speshul<protected_function_result> : std::true_type {};
|
||||
|
||||
template <std::size_t I, typename... Args, typename T>
|
||||
stack_proxy get(types<Args...>, index_value<0>, index_value<I>, const T& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, std::size_t N, typename Arg, typename... Args, typename T, meta::enable<meta::boolean<(N > 0)>> = meta::enabler>
|
||||
stack_proxy get(types<Arg, Args...>, index_value<N>, index_value<I>, const T& fr) {
|
||||
return get(types<Args...>(), index_value<N - 1>(), index_value<I + lua_size<Arg>::value>(), fr);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template <>
|
||||
struct tie_size<unsafe_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||
|
||||
template <std::size_t I>
|
||||
stack_proxy get(const unsafe_function_result& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args>
|
||||
stack_proxy get(types<Args...> t, const unsafe_function_result& fr) {
|
||||
return detail::get(t, index_value<I>(), index_value<0>(), fr);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct tie_size<protected_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
|
||||
|
||||
template <std::size_t I>
|
||||
stack_proxy get(const protected_function_result& fr) {
|
||||
return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
|
||||
}
|
||||
|
||||
template <std::size_t I, typename... Args>
|
||||
stack_proxy get(types<Args...> t, const protected_function_result& fr) {
|
||||
return detail::get(t, index_value<I>(), index_value<0>(), fr);
|
||||
}
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_STACK_PROXY_HPP
|
||||
|
96
sol/stack_proxy_base.hpp
Normal file
96
sol/stack_proxy_base.hpp
Normal file
@ -0,0 +1,96 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2017 Rapptz, ThePhD and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_STACK_PROXY_BASE_HPP
|
||||
#define SOL_STACK_PROXY_BASE_HPP
|
||||
|
||||
#include "stack.hpp"
|
||||
#include "proxy_base.hpp"
|
||||
|
||||
namespace sol {
|
||||
struct stack_proxy_base : public proxy_base<stack_proxy_base> {
|
||||
private:
|
||||
lua_State* L;
|
||||
int index;
|
||||
|
||||
public:
|
||||
stack_proxy_base()
|
||||
: L(nullptr), index(0) {
|
||||
}
|
||||
stack_proxy_base(lua_State* L, int index)
|
||||
: L(L), index(index) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) get() const {
|
||||
return stack::get<T>(L, stack_index());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
return stack::check<T>(L, stack_index());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) as() const {
|
||||
return get<T>();
|
||||
}
|
||||
|
||||
type get_type() const noexcept {
|
||||
return type_of(lua_state(), stack_index());
|
||||
}
|
||||
|
||||
int push() const {
|
||||
return push(L);
|
||||
}
|
||||
|
||||
int push(lua_State* Ls) const {
|
||||
lua_pushvalue(Ls, index);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_State* lua_state() const {
|
||||
return L;
|
||||
}
|
||||
int stack_index() const {
|
||||
return index;
|
||||
}
|
||||
};
|
||||
|
||||
namespace stack {
|
||||
template <>
|
||||
struct getter<stack_proxy_base> {
|
||||
static stack_proxy_base get(lua_State* L, int index = -1) {
|
||||
return stack_proxy_base(L, index);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pusher<stack_proxy_base> {
|
||||
static int push(lua_State*, const stack_proxy_base& ref) {
|
||||
return ref.push();
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
|
||||
} // namespace sol
|
||||
|
||||
#endif // SOL_STACK_PROXY_BASE_HPP
|
@ -70,11 +70,12 @@ namespace sol {
|
||||
#else
|
||||
template <lua_CFunction f>
|
||||
int static_trampoline(lua_State* L) {
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
#if defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && !defined(SOL_LUAJIT)
|
||||
return f(L);
|
||||
|
||||
#else
|
||||
try {
|
||||
#endif
|
||||
return f(L);
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
}
|
||||
catch (const char* s) {
|
||||
lua_pushstring(L, s);
|
||||
@ -82,10 +83,14 @@ namespace sol {
|
||||
catch (const std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
#if defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && defined(SOL_LUAJIT)
|
||||
// LuaJIT cannot have the catchall when the safe propagation is on
|
||||
// but LuaJIT will swallow all C++ errors
|
||||
// if we don't at least catch std::exception ones
|
||||
catch (...) {
|
||||
lua_pushstring(L, "caught (...) exception");
|
||||
}
|
||||
|
||||
#endif // LuaJIT cannot have the catchall, but we must catch std::exceps for it
|
||||
return lua_error(L);
|
||||
#endif
|
||||
}
|
||||
@ -117,11 +122,11 @@ namespace sol {
|
||||
if (meta::bind_traits<meta::unqualified_t<Fx>>::is_noexcept) {
|
||||
return f(L, std::forward<Args>(args)...);
|
||||
}
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
#if defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && !defined(SOL_LUAJIT)
|
||||
return f(L, std::forward<Args>(args)...);
|
||||
#else
|
||||
try {
|
||||
#endif
|
||||
return f(L, std::forward<Args>(args)...);
|
||||
#if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
|
||||
}
|
||||
catch (const char* s) {
|
||||
lua_pushstring(L, s);
|
||||
@ -129,10 +134,14 @@ namespace sol {
|
||||
catch (const std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
#if defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && !defined(SOL_LUAJIT)
|
||||
// LuaJIT cannot have the catchall when the safe propagation is on
|
||||
// but LuaJIT will swallow all C++ errors
|
||||
// if we don't at least catch std::exception ones
|
||||
catch (...) {
|
||||
lua_pushstring(L, "caught (...) exception");
|
||||
}
|
||||
|
||||
#endif
|
||||
return lua_error(L);
|
||||
#endif
|
||||
}
|
||||
@ -1081,6 +1090,16 @@ namespace sol {
|
||||
|
||||
template <typename T>
|
||||
struct is_stack_based : std::is_base_of<stack_reference, T> {};
|
||||
template <>
|
||||
struct is_stack_based<variadic_args> : std::true_type {};
|
||||
template <>
|
||||
struct is_stack_based<unsafe_function_result> : std::true_type {};
|
||||
template <>
|
||||
struct is_stack_based<protected_function_result> : std::true_type {};
|
||||
template <>
|
||||
struct is_stack_based<stack_proxy> : std::true_type {};
|
||||
template <>
|
||||
struct is_stack_based<stack_proxy_base> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_lua_primitive<T*> : std::true_type {};
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "tuple.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "proxy_base.hpp"
|
||||
#include "stack_iterator.hpp"
|
||||
#include "stack_proxy.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace sol {
|
||||
@ -36,6 +38,16 @@ namespace sol {
|
||||
int returncount;
|
||||
|
||||
public:
|
||||
typedef stack_proxy reference_type;
|
||||
typedef stack_proxy value_type;
|
||||
typedef stack_proxy* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef stack_iterator<stack_proxy, false> iterator;
|
||||
typedef stack_iterator<stack_proxy, true> const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
unsafe_function_result() = default;
|
||||
unsafe_function_result(lua_State* Ls, int idx = -1, int retnum = 0)
|
||||
: L(Ls), index(idx), returncount(retnum) {
|
||||
@ -66,8 +78,54 @@ namespace sol {
|
||||
unsafe_function_result& operator=(protected_function_result&& o) noexcept;
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) get(int index_offset = 0) const {
|
||||
return stack::get<T>(L, index + index_offset);
|
||||
decltype(auto) get(difference_type index_offset = 0) const {
|
||||
return stack::get<T>(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
type get_type(difference_type index_offset = 0) const noexcept {
|
||||
return type_of(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
stack_proxy operator[](difference_type index_offset) const {
|
||||
return stack_proxy(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
return iterator(L, index, stack_index() + return_count());
|
||||
}
|
||||
iterator end() {
|
||||
return iterator(L, stack_index() + return_count(), stack_index() + return_count());
|
||||
}
|
||||
const_iterator begin() const {
|
||||
return const_iterator(L, index, stack_index() + return_count());
|
||||
}
|
||||
const_iterator end() const {
|
||||
return const_iterator(L, stack_index() + return_count(), stack_index() + return_count());
|
||||
}
|
||||
const_iterator cbegin() const {
|
||||
return begin();
|
||||
}
|
||||
const_iterator cend() const {
|
||||
return end();
|
||||
}
|
||||
|
||||
reverse_iterator rbegin() {
|
||||
return std::reverse_iterator<iterator>(begin());
|
||||
}
|
||||
reverse_iterator rend() {
|
||||
return std::reverse_iterator<iterator>(end());
|
||||
}
|
||||
const_reverse_iterator rbegin() const {
|
||||
return std::reverse_iterator<const_iterator>(begin());
|
||||
}
|
||||
const_reverse_iterator rend() const {
|
||||
return std::reverse_iterator<const_iterator>(end());
|
||||
}
|
||||
const_reverse_iterator crbegin() const {
|
||||
return std::reverse_iterator<const_iterator>(cbegin());
|
||||
}
|
||||
const_reverse_iterator crend() const {
|
||||
return std::reverse_iterator<const_iterator>(cend());
|
||||
}
|
||||
|
||||
call_status status() const noexcept {
|
||||
|
@ -24,133 +24,11 @@
|
||||
|
||||
#include "stack.hpp"
|
||||
#include "stack_proxy.hpp"
|
||||
#include "stack_iterator.hpp"
|
||||
#include <limits>
|
||||
#include <iterator>
|
||||
|
||||
namespace sol {
|
||||
template <bool is_const>
|
||||
struct va_iterator : std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const stack_proxy, stack_proxy>, std::ptrdiff_t, std::conditional_t<is_const, const stack_proxy*, stack_proxy*>, std::conditional_t<is_const, const stack_proxy, stack_proxy>> {
|
||||
typedef std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const stack_proxy, stack_proxy>, std::ptrdiff_t, std::conditional_t<is_const, const stack_proxy*, stack_proxy*>, std::conditional_t<is_const, const stack_proxy, stack_proxy>> base_t;
|
||||
typedef typename base_t::reference reference;
|
||||
typedef typename base_t::pointer pointer;
|
||||
typedef typename base_t::value_type value_type;
|
||||
typedef typename base_t::difference_type difference_type;
|
||||
typedef typename base_t::iterator_category iterator_category;
|
||||
lua_State* L;
|
||||
int index;
|
||||
int stacktop;
|
||||
stack_proxy sp;
|
||||
|
||||
va_iterator()
|
||||
: L(nullptr), index((std::numeric_limits<int>::max)()), stacktop((std::numeric_limits<int>::max)()) {
|
||||
}
|
||||
va_iterator(const va_iterator<true>& r)
|
||||
: L(r.L), index(r.index), stacktop(r.stacktop) {
|
||||
}
|
||||
va_iterator(lua_State* luastate, int idx, int topidx)
|
||||
: L(luastate), index(idx), stacktop(topidx), sp(luastate, idx) {
|
||||
}
|
||||
|
||||
reference operator*() {
|
||||
return stack_proxy(L, index);
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
return stack_proxy(L, index);
|
||||
}
|
||||
|
||||
pointer operator->() {
|
||||
sp = stack_proxy(L, index);
|
||||
return &sp;
|
||||
}
|
||||
|
||||
pointer operator->() const {
|
||||
const_cast<stack_proxy&>(sp) = stack_proxy(L, index);
|
||||
return &sp;
|
||||
}
|
||||
|
||||
va_iterator& operator++() {
|
||||
++index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
va_iterator operator++(int) {
|
||||
auto r = *this;
|
||||
this->operator++();
|
||||
return r;
|
||||
}
|
||||
|
||||
va_iterator& operator--() {
|
||||
--index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
va_iterator operator--(int) {
|
||||
auto r = *this;
|
||||
this->operator--();
|
||||
return r;
|
||||
}
|
||||
|
||||
va_iterator& operator+=(difference_type idx) {
|
||||
index += static_cast<int>(idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
va_iterator& operator-=(difference_type idx) {
|
||||
index -= static_cast<int>(idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
difference_type operator-(const va_iterator& r) const {
|
||||
return index - r.index;
|
||||
}
|
||||
|
||||
va_iterator operator+(difference_type idx) const {
|
||||
va_iterator r = *this;
|
||||
r += idx;
|
||||
return r;
|
||||
}
|
||||
|
||||
reference operator[](difference_type idx) const {
|
||||
return stack_proxy(L, index + static_cast<int>(idx));
|
||||
}
|
||||
|
||||
bool operator==(const va_iterator& r) const {
|
||||
if (stacktop == (std::numeric_limits<int>::max)()) {
|
||||
return r.index == r.stacktop;
|
||||
}
|
||||
else if (r.stacktop == (std::numeric_limits<int>::max)()) {
|
||||
return index == stacktop;
|
||||
}
|
||||
return index == r.index;
|
||||
}
|
||||
|
||||
bool operator!=(const va_iterator& r) const {
|
||||
return !(this->operator==(r));
|
||||
}
|
||||
|
||||
bool operator<(const va_iterator& r) const {
|
||||
return index < r.index;
|
||||
}
|
||||
|
||||
bool operator>(const va_iterator& r) const {
|
||||
return index > r.index;
|
||||
}
|
||||
|
||||
bool operator<=(const va_iterator& r) const {
|
||||
return index <= r.index;
|
||||
}
|
||||
|
||||
bool operator>=(const va_iterator& r) const {
|
||||
return index >= r.index;
|
||||
}
|
||||
};
|
||||
|
||||
template <bool is_const>
|
||||
inline va_iterator<is_const> operator+(typename va_iterator<is_const>::difference_type n, const va_iterator<is_const>& r) {
|
||||
return r + n;
|
||||
}
|
||||
|
||||
struct variadic_args {
|
||||
private:
|
||||
lua_State* L;
|
||||
@ -163,22 +41,22 @@ namespace sol {
|
||||
typedef stack_proxy* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef va_iterator<false> iterator;
|
||||
typedef va_iterator<true> const_iterator;
|
||||
typedef stack_iterator<stack_proxy, false> iterator;
|
||||
typedef stack_iterator<stack_proxy, true> const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
variadic_args() = default;
|
||||
variadic_args(lua_State* luastate, int stackindex = -1)
|
||||
: L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lua_gettop(luastate)) {
|
||||
: L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lua_gettop(luastate)) {
|
||||
}
|
||||
variadic_args(lua_State* luastate, int stackindex, int lastindex)
|
||||
: L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lastindex) {
|
||||
: L(luastate), index(lua_absindex(luastate, stackindex)), stacktop(lastindex) {
|
||||
}
|
||||
variadic_args(const variadic_args&) = default;
|
||||
variadic_args& operator=(const variadic_args&) = default;
|
||||
variadic_args(variadic_args&& o)
|
||||
: L(o.L), index(o.index), stacktop(o.stacktop) {
|
||||
: L(o.L), index(o.index), stacktop(o.stacktop) {
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but will be thorough
|
||||
@ -254,16 +132,16 @@ namespace sol {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) get(difference_type start = 0) const {
|
||||
return stack::get<T>(L, index + static_cast<int>(start));
|
||||
decltype(auto) get(difference_type index_offset = 0) const {
|
||||
return stack::get<T>(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
type get_type(difference_type start = 0) const noexcept {
|
||||
return type_of(L, index + static_cast<int>(start));
|
||||
type get_type(difference_type index_offset = 0) const noexcept {
|
||||
return type_of(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
stack_proxy operator[](difference_type start) const {
|
||||
return stack_proxy(L, index + static_cast<int>(start));
|
||||
stack_proxy operator[](difference_type index_offset) const {
|
||||
return stack_proxy(L, index + static_cast<int>(index_offset));
|
||||
}
|
||||
|
||||
lua_State* lua_state() const {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
#include <catch.hpp>
|
||||
|
@ -1,4 +1,5 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
|
@ -1,4 +1,5 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
|
@ -1,4 +1,5 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
#include <catch.hpp>
|
||||
|
@ -1,7 +1,10 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
|
||||
TEST_CASE("issues/stack overflow", "make sure various operations repeated don't trigger stack overflow") {
|
||||
sol::state lua;
|
||||
|
31
tests/test_proxies.cpp
Normal file
31
tests/test_proxies.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include "test_stack_guard.hpp"
|
||||
|
||||
TEST_CASE("proxy/function results", "make sure that function results return proper proxies and can be indexed nicely") {
|
||||
sol::state lua;
|
||||
SECTION("unsafe_function_result") {
|
||||
auto ufr = lua.script("return 1, 2, 3, 4");
|
||||
int accum = 0;
|
||||
for (const auto& r : ufr) {
|
||||
int v = r;
|
||||
accum += v;
|
||||
}
|
||||
REQUIRE(accum == 10);
|
||||
}
|
||||
SECTION("protected_function_result") {
|
||||
auto pfr = lua.safe_script("return 1, 2, 3, 4");
|
||||
int accum = 0;
|
||||
for (const auto& r : pfr) {
|
||||
int v = r;
|
||||
accum += v;
|
||||
}
|
||||
REQUIRE(accum == 10);
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -1,7 +1,10 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <chrono>
|
||||
|
@ -1,7 +1,9 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
|
||||
TEST_CASE("storage/registry construction", "ensure entries from the registry can be retrieved") {
|
||||
const auto& code = R"(
|
||||
|
@ -1,7 +1,9 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
@ -1,6 +1,8 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -1,7 +1,9 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
@ -1,7 +1,9 @@
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <deque>
|
||||
#include <set>
|
||||
|
@ -1,8 +1,10 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#define SOL_CHECK_ARGUMENTS
|
||||
#define SOL_CHECK_ARGUMENTS 1
|
||||
#define SOL_ENABLE_INTEROP 1
|
||||
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sol.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
Loading…
x
Reference in New Issue
Block a user