diff --git a/docs/source/api/object.rst b/docs/source/api/object.rst index 9c8f6cf5..fa2db307 100644 --- a/docs/source/api/object.rst +++ b/docs/source/api/object.rst @@ -15,11 +15,13 @@ members ------- .. code-block:: cpp - :caption: constructor: coroutine + :caption: overloaded constructor: object - coroutine(lua_State* L, int index = -1); + template + object(T&&); + object(lua_State* L, int index = -1); -Create an object which references the specific element at the given index in the specified ``lua_State*``. +There are 2 kinds of constructors here. One allows construction of a object from other reference types such as :doc:`table` and :doc:`stack_reference`. The other creates an object which references the specific element at the given index in the specified ``lua_State*``. .. code-block:: cpp :caption: function: type conversion diff --git a/docs/source/features.rst b/docs/source/features.rst index 21f8d841..d4f31e7f 100644 --- a/docs/source/features.rst +++ b/docs/source/features.rst @@ -150,7 +150,7 @@ kaguya - * Inspired coroutine support for Sol * Library author (satoren) is a nice guy! * C++11/14, or boostified (which makes it C++03 compatible) -* Clas registration is a bit verbose, but not as offensive as OOLua or lua-intf or others +* Class registration is a bit verbose, but not as offensive as OOLua or lua-intf or others * Deserves lots of love! Sol - @@ -185,6 +185,7 @@ luawrapper - * C++11 * No macros! * The interface can be clunky (no table-like data structures: most things go though ``readVariable`` / ``writeVariable``) +* Internal Compiler errors in Visual Studio 2015 - submitted a PR to fix it, hopefully it'll get picked up SWIG (3.0) - @@ -195,11 +196,11 @@ SWIG (3.0) - luacppinterface - -* It seems like a decent library, until you try to get a function put into Lua using CreateFunction, and then getting it out again -- it fails miserably +* The branch that fixes VC++ warnings * No member variable support * Actually has tables (but no operator[]) * Does not support arbitrary keys -* Really has potential, but falls down on its face... +* Pretty decent luabind - @@ -207,6 +208,7 @@ luabind - * Strange in-lua keywords and parsing to allow for classes to be written in lua - not sure if good feature; vendor lock-in to that library to depend on this specific class syntax? * Comprehensive lua bindings (can even bind "properties") +* There's some code that produces an ICE in Visual C++: I submitted a fix to the library in the hopes that it'll get accepted * Wonky table support: no basic conversion functions on ``luabind::object``; have to push object then use lua API to get what you want lua-api-pp - @@ -238,7 +240,7 @@ luwra - * Mentioned here because... well, it's a thing * Lightweight (read: feature-starved) wrapper library -* Can push/pop to the global namespace, but doing anymore more detailed is... harder +* Can push/pop to the global namespace, but doing anymthing more detailed is... harder * Might as well go with luawrapper if you're going to bother diff --git a/sol/function.hpp b/sol/function.hpp index edf9a6d3..14cc5a33 100644 --- a/sol/function.hpp +++ b/sol/function.hpp @@ -68,8 +68,10 @@ public: basic_function() = default; basic_function(const basic_function&) = default; basic_function& operator=(const basic_function&) = default; - basic_function(basic_function&& ) = default; - basic_function& operator=(basic_function&& ) = default; + basic_function(basic_function&&) = default; + basic_function& operator=(basic_function&&) = default; + basic_function(const stack_reference& r) : basic_function(r.lua_state(), r.stack_index()) {} + basic_function(stack_reference&& r) : basic_function(r.lua_state(), r.stack_index()) {} basic_function(lua_State* L, int index = -1): base_t(L, index) { #ifdef SOL_CHECK_ARGUMENTS stack::check(L, index, type_panic); diff --git a/sol/load_result.hpp b/sol/load_result.hpp index ea495694..2164b6be 100644 --- a/sol/load_result.hpp +++ b/sol/load_result.hpp @@ -80,7 +80,7 @@ namespace sol { load_result(load_result&& o) : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) { // Must be manual, otherwise destructor will screw us // return count being 0 is enough to keep things clean - // but will be thorough + // but we will be thorough o.L = nullptr; o.index = 0; o.returncount = 0; @@ -95,7 +95,7 @@ namespace sol { err = o.err; // Must be manual, otherwise destructor will screw us // return count being 0 is enough to keep things clean - // but will be thorough + // but we will be thorough o.L = nullptr; o.index = 0; o.returncount = 0; diff --git a/sol/object.hpp b/sol/object.hpp index 471f4c53..d6d4b206 100644 --- a/sol/object.hpp +++ b/sol/object.hpp @@ -54,8 +54,17 @@ private: } public: - using base_t::base_t; - using base_t::lua_state; + basic_object() noexcept = default; + template , basic_object>>, std::is_base_of>> = 0> + basic_object(T&& r) : base_t(std::forward(r)) {} + basic_object(nil_t r) : base_t(r) {} + basic_object(const basic_object&) = default; + basic_object(basic_object&&) = default; + basic_object& operator=(const basic_object&) = default; + basic_object& operator=(basic_object&&) = default; + basic_object(const stack_reference& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {} + basic_object(stack_reference&& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {} + basic_object(lua_State* L, int index = -1) noexcept : base_t(L, index) {} template decltype(auto) as() const { diff --git a/sol/protected_function.hpp b/sol/protected_function.hpp index b214e1c7..b9e02307 100644 --- a/sol/protected_function.hpp +++ b/sol/protected_function.hpp @@ -133,10 +133,12 @@ public: basic_protected_function() = default; basic_protected_function(const basic_protected_function&) = default; basic_protected_function& operator=(const basic_protected_function&) = default; - basic_protected_function(basic_protected_function&& ) = default; + basic_protected_function(basic_protected_function&&) = default; basic_protected_function& operator=(basic_protected_function&& ) = default; basic_protected_function(const basic_function& b) : base_t(b) {} basic_protected_function(basic_function&& b) : base_t(std::move(b)) {} + basic_protected_function(const stack_reference& r) : basic_protected_function(r.lua_state(), r.stack_index()) {} + basic_protected_function(stack_reference&& r) : basic_protected_function(r.lua_state(), r.stack_index()) {} basic_protected_function(lua_State* L, int index = -1) : base_t(L, index), error_handler(get_default_handler()) { #ifdef SOL_CHECK_ARGUMENTS stack::check(L, index, type_panic); diff --git a/sol/protected_function_result.hpp b/sol/protected_function_result.hpp index 8971ebda..d7fce6ff 100644 --- a/sol/protected_function_result.hpp +++ b/sol/protected_function_result.hpp @@ -81,7 +81,7 @@ public: protected_function_result(protected_function_result&& o) : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) { // Must be manual, otherwise destructor will screw us // return count being 0 is enough to keep things clean - // but will be thorough + // but we will be thorough o.L = nullptr; o.index = 0; o.returncount = 0; @@ -96,7 +96,7 @@ public: err = o.err; // Must be manual, otherwise destructor will screw us // return count being 0 is enough to keep things clean - // but will be thorough + // but we will be thorough o.L = nullptr; o.index = 0; o.returncount = 0; diff --git a/sol/reference.hpp b/sol/reference.hpp index 6a9607c1..ac1a9572 100644 --- a/sol/reference.hpp +++ b/sol/reference.hpp @@ -72,6 +72,7 @@ protected: public: reference() noexcept = default; + reference(nil_t) noexcept : reference() {} reference(const stack_reference& r) noexcept : reference(r.lua_state(), r.stack_index()) {} reference(stack_reference&& r) noexcept : reference(r.lua_state(), r.stack_index()) {} reference(lua_State* L, int index = -1) noexcept : L(L) { diff --git a/sol/stack_check.hpp b/sol/stack_check.hpp index b17f5434..dc209b71 100644 --- a/sol/stack_check.hpp +++ b/sol/stack_check.hpp @@ -257,7 +257,7 @@ struct checker { handler(L, index, type::userdata, indextype); return false; } - if (meta::Or, std::is_same>::value) + if (meta::Or, std::is_same, std::is_same, std::is_same>::value) return true; if (lua_getmetatable(L, index) == 0) { return true; diff --git a/sol/stack_reference.hpp b/sol/stack_reference.hpp index 60704e44..37b8f501 100644 --- a/sol/stack_reference.hpp +++ b/sol/stack_reference.hpp @@ -35,6 +35,7 @@ protected: public: stack_reference() noexcept = default; + stack_reference(nil_t) noexcept : stack_reference() {}; stack_reference(lua_State* L, int i) noexcept : L(L), index(lua_absindex(L, i)) {} stack_reference(stack_reference&& o) noexcept = default; stack_reference& operator=(stack_reference&&) noexcept = default; diff --git a/sol/table_core.hpp b/sol/table_core.hpp index 800dada2..7ec120ca 100644 --- a/sol/table_core.hpp +++ b/sol/table_core.hpp @@ -156,7 +156,12 @@ public: typedef iterator const_iterator; basic_table_core( ) noexcept : base_t( ) { } - basic_table_core( const table_core& global ) noexcept : base_t( global ) { } + template , meta::Not, basic_table_core>>, std::is_same, global_table>> = 0> + basic_table_core( T&& r ) noexcept : base_t( std::forward(r) ) { } + basic_table_core(const basic_table_core&) = default; + basic_table_core(basic_table_core&&) = default; + basic_table_core& operator=(const basic_table_core&) = default; + basic_table_core& operator=(basic_table_core&&) = default; basic_table_core(const stack_reference& r) : basic_table_core(r.lua_state(), r.stack_index()) {} basic_table_core(stack_reference&& r) : basic_table_core(r.lua_state(), r.stack_index()) {} basic_table_core( lua_State* L, int index = -1 ) : base_t( L, index ) { diff --git a/sol/thread.hpp b/sol/thread.hpp index 1e482fd9..3f2e2d3e 100644 --- a/sol/thread.hpp +++ b/sol/thread.hpp @@ -31,6 +31,8 @@ public: thread () noexcept = default; thread(const thread&) = default; thread(thread&&) = default; + thread(const stack_reference& r) : thread(r.lua_state(), r.stack_index()) {}; + thread(stack_reference&& r) : thread(r.lua_state(), r.stack_index()) {}; thread& operator=(const thread&) = default; thread& operator=(thread&&) = default; thread(lua_State* L, int index = -1) : reference(L, index) { diff --git a/tests.cpp b/tests.cpp index d7dab814..588ceec2 100644 --- a/tests.cpp +++ b/tests.cpp @@ -1138,3 +1138,51 @@ TEST_CASE("usertype/no_constructor", "make sure lua types cannot be constructed REQUIRE_THROWS(lua.script("t = thing.new()")); } + +TEST_CASE("object/conversions", "make sure all basic reference types can be made into objects") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + struct d {}; + + lua.script("function f () print('bark') end"); + lua["d"] = d{}; + lua["l"] = static_cast(nullptr); + + sol::table t = lua.create_table(); + sol::thread th = sol::thread::create(lua); + sol::function f = lua["f"]; + sol::protected_function pf = lua["f"]; + sol::userdata ud = lua["d"]; + sol::lightuserdata lud = lua["l"]; + + sol::object ot(t); + sol::object ot2 = ot; + sol::object oth(th); + sol::object of(f); + sol::object opf(pf); + sol::object od(ud); + sol::object ol(lud); + + auto oni = sol::make_object(lua, 50); + auto ond = sol::make_object(lua, 50.0); + + std::string somestring = "look at this text isn't it nice"; + auto osl = sol::make_object(lua, "Bark bark bark"); + auto os = sol::make_object(lua, somestring); + + auto omn = sol::make_object(lua, sol::nil); + + REQUIRE(ot.get_type() == sol::type::table); + REQUIRE(ot2.get_type() == sol::type::table); + REQUIRE(oth.get_type() == sol::type::thread); + REQUIRE(of.get_type() == sol::type::function); + REQUIRE(opf.get_type() == sol::type::function); + REQUIRE(od.get_type() == sol::type::userdata); + REQUIRE(ol.get_type() == sol::type::lightuserdata); + REQUIRE(oni.get_type() == sol::type::number); + REQUIRE(ond.get_type() == sol::type::number); + REQUIRE(osl.get_type() == sol::type::string); + REQUIRE(os.get_type() == sol::type::string); + REQUIRE(omn.get_type() == sol::type::nil); +}