Fix up the remaining sol2 issues, prepare for more sol3 stuff

This commit is contained in:
ThePhD 2018-11-10 06:41:06 -08:00
parent a7048aea45
commit 2cfbc8c0ea
No known key found for this signature in database
GPG Key ID: 1509DB1C0F702BFA
9 changed files with 122 additions and 33 deletions

View File

@ -78,6 +78,17 @@ Gets the value associated with the keys and converts it to the type ``T``.
Gets the value associated with the keys and converts it to the type ``T``. If it is not of the proper type, it will return a ``sol::nullopt`` instead.
.. code-block:: c++
:caption: function: [overloaded] optionally get or create a value
:name: regular-get-or-create
template <typename T>
decltype(auto) get_or_create();
template <typename T, typename Otherwise>
decltype(auto) get_or_create( Otherwise&& other );
Gets the value associated with the keys if it exists. If it does not, it will set it with the value and return the result.
``operator[]`` proxy-only members
---------------------------------

View File

@ -24,7 +24,14 @@ int main() {
// "bark" namespacing in Lua
// namespacing is just putting things in a table
sol::table bark = lua.create_named_table("bark");
// forces creation if it does not exist
auto bark = lua["bark"].get_or_create<sol::table>();
// equivalent-ish:
//sol::table bark = lua["bark"].force(); // forces table creation
// equivalent, and more flexible:
//sol::table bark = lua["bark"].get_or_create<sol::table>(sol::new_table());
// equivalent, but less efficient/ugly:
//sol::table bark = lua["bark"] = lua.get_or("bark", lua.create_table());
bark.new_usertype<my_class>("my_class",
"f", &my_class::f,
"g", &my_class::g); // the usual

View File

@ -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 2018-11-09 18:52:51.075276 UTC
// This header was generated with sol v2.20.4 (revision 1f90b04)
// Generated 2018-11-10 14:40:45.361811 UTC
// This header was generated with sol v2.20.5 (revision a7048ae)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP
@ -8247,12 +8247,12 @@ namespace stack {
}
#endif // Do not allow strings to be numbers
int isnum = 0;
const lua_Number v = lua_tonumberx(L, index, &isnum);
const bool success = isnum != 0
#if (defined(SOL_SAFE_NUMERICS) && SOL_SAFE_NUMERICS) && !(defined(SOL_NO_CHECK_NUMBER_PRECISION) && SOL_NO_CHECK_NUMBER_PRECISION)
&& static_cast<lua_Number>(llround(v)) == v
const lua_Number v = lua_tonumberx(L, index, &isnum);
const bool success = isnum != 0 && static_cast<lua_Number>(llround(v)) == v;
#else
const bool success = isnum != 0;
#endif // Safe numerics and number precision checking
;
if (!success) {
// expected type, actual type
#if defined(SOL_STRINGS_ARE_NUMBERS) && SOL_STRINGS_ARE_NUMBERS
@ -14542,7 +14542,7 @@ namespace sol {
template <bool is_yielding, typename Fx, typename... Args>
static void set_fx(lua_State* L, Args&&... args) {
lua_CFunction freefunc = function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>;
lua_CFunction freefunc = detail::static_trampoline<function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>>;
int upvalues = 0;
upvalues += stack::push(L, nullptr);
@ -15512,6 +15512,19 @@ namespace sol {
return static_cast<T>(std::forward<D>(otherwise));
}
template <typename T>
decltype(auto) get_or_create() {
return get_or_create<T>(new_table());
}
template <typename T, typename Otherwise>
decltype(auto) get_or_create(Otherwise&& other) {
if (!this->valid()) {
this->set(std::forward<Otherwise>(other));
}
return get<T>();
}
template <typename K>
decltype(auto) operator[](K&& k) const {
auto keys = meta::tuplefy(key, std::forward<K>(k));
@ -15562,6 +15575,13 @@ namespace sol {
lua_State* lua_state() const {
return tbl.lua_state();
}
proxy& force() {
if (this->valid()) {
this->set(new_table());
}
return *this;
}
};
template <typename Table, typename Key, typename T>
@ -18280,6 +18300,9 @@ namespace sol {
#include <bitset>
namespace sol {
struct usertype_metatable_core;
namespace usertype_detail {
const int metatable_index = 2;
const int metatable_core_index = 3;
@ -18291,7 +18314,7 @@ namespace sol {
const int newindex_function_index = 4;
typedef void (*base_walk)(lua_State*, bool&, int&, string_view&);
typedef int (*member_search)(lua_State*, void*, int);
typedef int (*member_search)(lua_State*, void*, usertype_metatable_core&, int);
struct call_information {
member_search index;
@ -18443,8 +18466,7 @@ namespace sol {
return isnum != 0 && magic == toplevel_magic;
}
inline int runtime_object_call(lua_State* L, void*, int runtimetarget) {
usertype_metatable_core& umc = stack::get<light<usertype_metatable_core>>(L, upvalue_index(metatable_core_index));
inline int runtime_object_call(lua_State* L, void*, usertype_metatable_core& umc, int runtimetarget) {
std::vector<object>& runtime = umc.runtime;
object& runtimeobj = runtime[runtimetarget];
return stack::push(L, runtimeobj);
@ -18476,7 +18498,7 @@ namespace sol {
}
}
int runtime_new_index(lua_State* L, void*, int runtimetarget);
int runtime_new_index(lua_State* L, void*, usertype_metatable_core&, int runtimetarget);
template <typename T, bool is_simple>
inline int metatable_new_index(lua_State* L) {
@ -18575,8 +18597,7 @@ namespace sol {
return indexing_fail<T, false>(L);
}
inline int runtime_new_index(lua_State* L, void*, int runtimetarget) {
usertype_metatable_core& umc = stack::get<light<usertype_metatable_core>>(L, upvalue_index(metatable_core_index));
inline int runtime_new_index(lua_State* L, void*, usertype_metatable_core& umc, int runtimetarget) {
std::vector<object>& runtime = umc.runtime;
object& runtimeobj = runtime[runtimetarget];
runtimeobj = object(L, 3);
@ -18781,7 +18802,7 @@ namespace sol {
usertype_metatable& operator=(usertype_metatable&&) = default;
template <std::size_t I0, std::size_t I1, bool is_index>
static int real_find_call(lua_State* L, void* um, int) {
static int real_find_call(lua_State* L, void* um, usertype_metatable_core&, int) {
auto& f = *static_cast<usertype_metatable*>(um);
if (is_variable_binding<decltype(std::get<I1>(f.functions))>::value) {
return real_call_with<I1, is_index, true>(L, f);
@ -18827,7 +18848,7 @@ namespace sol {
}
}
if (member != nullptr) {
return (member)(L, static_cast<void*>(&f), runtime_target);
return (member)(L, static_cast<void*>(&f), static_cast<usertype_metatable_core&>(f), runtime_target);
}
string_view accessor = stack::get<string_view>(L, keyidx);
int ret = 0;

View File

@ -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 2018-11-09 18:52:51.285820 UTC
// This header was generated with sol v2.20.4 (revision 1f90b04)
// Generated 2018-11-10 14:40:45.917037 UTC
// This header was generated with sol v2.20.5 (revision a7048ae)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP

View File

@ -220,7 +220,7 @@ namespace sol {
template <bool is_yielding, typename Fx, typename... Args>
static void set_fx(lua_State* L, Args&&... args) {
lua_CFunction freefunc = function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>;
lua_CFunction freefunc = detail::static_trampoline<function_detail::call<meta::unqualified_t<Fx>, 2, is_yielding>>;
int upvalues = 0;
upvalues += stack::push(L, nullptr);

View File

@ -118,6 +118,20 @@ namespace sol {
return static_cast<T>(std::forward<D>(otherwise));
}
template <typename T>
decltype(auto) get_or_create() {
return get_or_create<T>(new_table());
}
template <typename T, typename Otherwise>
decltype(auto) get_or_create(Otherwise&& other) {
if (!this->valid()) {
this->set(std::forward<Otherwise>(other));
}
return get<T>();
}
template <typename K>
decltype(auto) operator[](K&& k) const {
auto keys = meta::tuplefy(key, std::forward<K>(k));
@ -168,6 +182,13 @@ namespace sol {
lua_State* lua_state() const {
return tbl.lua_state();
}
proxy& force() {
if (this->valid()) {
this->set(new_table());
}
return *this;
}
};
template <typename Table, typename Key, typename T>

View File

@ -140,12 +140,12 @@ namespace stack {
}
#endif // Do not allow strings to be numbers
int isnum = 0;
const lua_Number v = lua_tonumberx(L, index, &isnum);
const bool success = isnum != 0
#if (defined(SOL_SAFE_NUMERICS) && SOL_SAFE_NUMERICS) && !(defined(SOL_NO_CHECK_NUMBER_PRECISION) && SOL_NO_CHECK_NUMBER_PRECISION)
&& static_cast<lua_Number>(llround(v)) == v
const lua_Number v = lua_tonumberx(L, index, &isnum);
const bool success = isnum != 0 && static_cast<lua_Number>(llround(v)) == v;
#else
const bool success = isnum != 0;
#endif // Safe numerics and number precision checking
;
if (!success) {
// expected type, actual type
#if defined(SOL_STRINGS_ARE_NUMBERS) && SOL_STRINGS_ARE_NUMBERS

View File

@ -43,6 +43,9 @@
#include <bitset>
namespace sol {
struct usertype_metatable_core;
namespace usertype_detail {
const int metatable_index = 2;
const int metatable_core_index = 3;
@ -54,7 +57,7 @@ namespace sol {
const int newindex_function_index = 4;
typedef void (*base_walk)(lua_State*, bool&, int&, string_view&);
typedef int (*member_search)(lua_State*, void*, int);
typedef int (*member_search)(lua_State*, void*, usertype_metatable_core&, int);
struct call_information {
member_search index;
@ -206,8 +209,7 @@ namespace sol {
return isnum != 0 && magic == toplevel_magic;
}
inline int runtime_object_call(lua_State* L, void*, int runtimetarget) {
usertype_metatable_core& umc = stack::get<light<usertype_metatable_core>>(L, upvalue_index(metatable_core_index));
inline int runtime_object_call(lua_State* L, void*, usertype_metatable_core& umc, int runtimetarget) {
std::vector<object>& runtime = umc.runtime;
object& runtimeobj = runtime[runtimetarget];
return stack::push(L, runtimeobj);
@ -239,7 +241,7 @@ namespace sol {
}
}
int runtime_new_index(lua_State* L, void*, int runtimetarget);
int runtime_new_index(lua_State* L, void*, usertype_metatable_core&, int runtimetarget);
template <typename T, bool is_simple>
inline int metatable_new_index(lua_State* L) {
@ -338,8 +340,7 @@ namespace sol {
return indexing_fail<T, false>(L);
}
inline int runtime_new_index(lua_State* L, void*, int runtimetarget) {
usertype_metatable_core& umc = stack::get<light<usertype_metatable_core>>(L, upvalue_index(metatable_core_index));
inline int runtime_new_index(lua_State* L, void*, usertype_metatable_core& umc, int runtimetarget) {
std::vector<object>& runtime = umc.runtime;
object& runtimeobj = runtime[runtimetarget];
runtimeobj = object(L, 3);
@ -544,7 +545,7 @@ namespace sol {
usertype_metatable& operator=(usertype_metatable&&) = default;
template <std::size_t I0, std::size_t I1, bool is_index>
static int real_find_call(lua_State* L, void* um, int) {
static int real_find_call(lua_State* L, void* um, usertype_metatable_core&, int) {
auto& f = *static_cast<usertype_metatable*>(um);
if (is_variable_binding<decltype(std::get<I1>(f.functions))>::value) {
return real_call_with<I1, is_index, true>(L, f);
@ -590,7 +591,7 @@ namespace sol {
}
}
if (member != nullptr) {
return (member)(L, static_cast<void*>(&f), runtime_target);
return (member)(L, static_cast<void*>(&f), static_cast<usertype_metatable_core&>(f), runtime_target);
}
string_view accessor = stack::get<string_view>(L, keyidx);
int ret = 0;

View File

@ -1627,6 +1627,16 @@ TEST_CASE("usertype/runtime-extensibility", "Check if usertypes are runtime exte
};
int val = 0;
class base_a {
public:
int x;
};
class derived_b : public base_a {
};
SECTION("just functions") {
sol::state lua;
lua.open_libraries(sol::lib::base);
@ -1722,6 +1732,24 @@ end
val = lua["val"];
REQUIRE(val == 3);
}
SECTION("with bases") {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<base_a>("A",
"x", &base_a::x //no crash without this
);
lua.new_usertype<derived_b>("B",
sol::base_classes, sol::bases<base_a>());
auto pfr0 = lua.safe_script("function A:c() print('A') return 1 end", sol::script_pass_on_error);
REQUIRE(pfr0.valid());
auto pfr1 = lua.safe_script("function B:c() print('B') return 2 end", sol::script_pass_on_error);
REQUIRE(pfr1.valid());
auto pfr2 = lua.safe_script("local obja = A.new() local objb = B.new() assert(obja:c() == 1) assert(objb:c() == 2)", sol::script_pass_on_error);
REQUIRE(pfr2.valid());
}
}
TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly replaced at runtime for non-indexed things") {