diff --git a/docs/source/api/api-top.rst b/docs/source/api/api-top.rst index 3a41efb1..e04f766c 100644 --- a/docs/source/api/api-top.rst +++ b/docs/source/api/api-top.rst @@ -17,11 +17,12 @@ Browse the various function and classes :doc:`Sol<../index>` utilizes to make yo function protected_function object + reference + stack_reference + make_reference overload property proxy - reference - stack_reference resolve stack optional diff --git a/docs/source/api/make_reference.rst b/docs/source/api/make_reference.rst new file mode 100644 index 00000000..39ce6320 --- /dev/null +++ b/docs/source/api/make_reference.rst @@ -0,0 +1,26 @@ +make_object/make_reference +========================== +Create a value on the Lua stack and return it +--------------------------------------------- + +.. code-block:: cpp + :caption: function: make_reference + :name: make-reference + + template + R make_reference(lua_State* L, T&& value); + template + R make_object(lua_State* L, Args&&... args); + +Makes an ``R`` out of the value. The first overload deduces the type from the passed in argument, the second allows you to specify a template parameter and forward any relevant arguments to ``sol::stack::push``. The type figured out for ``R`` is what is referenced from the stack. This allows you to request arbitrary pop-able types from Sol and have it constructed from ``R(lua_State* L, int stack_index)``. If the template boolean ``should_pop`` is ``true``, the value that was pushed will be popped off the stack. It defaults to popping, but if it encounters a type such as :doc:`sol::stack_reference` (or any of its typically derived types in Sol), it will leave the pushed values on the stack. + +.. code-block:: cpp + :caption: function: make_object + :name: make-object + + template + object make_object(lua_State* L, T&& value); + template + object make_object(lua_State* L, Args&&... args); + +Makes an object out of the value. It pushes it onto the stack, then pops it into the returned ``sol::object``. The first overload deduces the type from the passed in argument, the second allows you to specify a template parameter and forward any relevant arguments to ``sol::stack::push``. The implementation essentially defers to :ref:`sol::make_reference` with the specified arguments, ``R == object`` and ``should_pop == true``. diff --git a/docs/source/api/object.rst b/docs/source/api/object.rst index fa2db307..0f02ebec 100644 --- a/docs/source/api/object.rst +++ b/docs/source/api/object.rst @@ -60,14 +60,3 @@ These allow a person to compare an ``sol::object`` against :ref:`nil`, whic } Use this to check objects. - -.. code-block:: cpp - :caption: function: make object - :name: make-object - - template - object make_object(lua_State* L, T&& value); - template - object make_object(lua_State* L, Args&&... args); - -Makes an object out of the value. It pushes it onto the stack, then pops it into the returned ``sol::object``. \ No newline at end of file diff --git a/docs/source/tutorial/all-the-things.rst b/docs/source/tutorial/all-the-things.rst index b7727a71..a89c475f 100644 --- a/docs/source/tutorial/all-the-things.rst +++ b/docs/source/tutorial/all-the-things.rst @@ -504,6 +504,7 @@ Some more advanced things you can do/read about: * :doc:`metatable manipulations<../api/metatable_key>` allow a user to change how indexing, function calls, and other things work on a single type. * :doc:`ownership semantics` are described for how lua deals with (raw) pointers. * :doc:`stack manipulation<../api/stack>` to safely play with the stack. You can also define customization points for ``stack::get``/``stack::check``/``stack::push`` for your type. + * :doc:`make_reference/make_object convenience function<../api/make_reference>` to get the same benefits and conveniences as the low-level stack API but put into objects you can specify. * :doc:`stack references<../api/stack_reference>` to have zero-overhead Sol abstractions while not copying to the Lua registry. * :doc:`unique usertype traits<../api/unique_usertype_traits>` allows you to specialize handle/RAII types from other frameworks, like boost, and Unreal, to work with Sol. * :doc:`variadic arguments<../api/variadic_args>` in functions with ``sol::variadic_args``. diff --git a/sol/object.hpp b/sol/object.hpp index 19279802..33aff85e 100644 --- a/sol/object.hpp +++ b/sol/object.hpp @@ -79,22 +79,34 @@ namespace sol { } }; - template - object make_object(lua_State* L, T&& value) { + template ::value, typename T> + R make_reference(lua_State* L, T&& value) { int backpedal = stack::push(L, std::forward(value)); - object r = stack::get(L, -backpedal); - lua_pop(L, backpedal); + R r = stack::get(L, -backpedal); + if (should_pop) { + lua_pop(L, backpedal); + } return r; } - template - object make_object(lua_State* L, Args&&... args) { + template ::value, typename... Args> + object make_reference(lua_State* L, Args&&... args) { int backpedal = stack::push(L, std::forward(args)...); object r = stack::get(L, -backpedal); lua_pop(L, backpedal); return r; } + template + object make_object(lua_State* L, T&& value) { + return make_reference(L, std::forward(value)); + } + + template + object make_object(lua_State* L, Args&&... args) { + return make_reference(L, std::forward(args)...); + } + inline bool operator==(const object& lhs, const nil_t&) { return !lhs.valid(); }