diff --git a/docs/source/api/api-top.rst b/docs/source/api/api-top.rst
index d2951ea0..9443ef85 100644
--- a/docs/source/api/api-top.rst
+++ b/docs/source/api/api-top.rst
@@ -26,6 +26,7 @@ Browse the various function and classes :doc:`Sol<../index>` utilizes to make yo
optional
state
table
+ metatable_key
this_state
thread
tie
diff --git a/docs/source/api/metatable_key.rst b/docs/source/api/metatable_key.rst
new file mode 100644
index 00000000..901e66cc
--- /dev/null
+++ b/docs/source/api/metatable_key.rst
@@ -0,0 +1,45 @@
+metatable_key
+=============
+A key for setting and getting an object's metatable
+---------------------------------------------------
+
+.. code-block:: cpp
+
+ struct metatable_key_t {};
+ const metatable_key_t metatable_key;
+
+You can use this in conjunction with :doc:`sol::table
` to set/get a metatable. Lua metatables are powerful ways to override default behavior of objects for various kinds of operators, among other things. Here is an entirely complete example, showing getting and working with a :doc:`usertype`'s metatable defined by Sol:
+
+.. code-block:: cpp
+ :caption: messing with metatables
+ :linenos:
+
+ #include
+
+ int main () {
+
+ struct bark {
+ int operator()(int x) {
+ return x;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_usertype("bark",
+ sol::meta_function::call_function, &bark::operator()
+ );
+
+ bark b;
+ lua.set("b", &b);
+
+ sol::table b_as_table = lua["b"];
+ sol::table b_metatable = b_as_table[sol::metatable_key];
+ sol::function b_call = b_metatable["__call"];
+ sol::function b_as_function = lua["b"];
+
+ int result1 = b_as_function(1);
+ int result2 = b_call(b, 1);
+ // result1 == result2 == 1
+ }
\ No newline at end of file
diff --git a/docs/source/api/object.rst b/docs/source/api/object.rst
index bdcc829e..9c8f6cf5 100644
--- a/docs/source/api/object.rst
+++ b/docs/source/api/object.rst
@@ -49,4 +49,23 @@ non-members
bool operator!=(const object& lhs, const nil_t&);
bool operator!=(const nil_t&, const object& rhs);
-These allow a person to compare an ``sol::object`` against :ref:`nil`, which essentially checks if an object references a non-nil value, like so:
\ No newline at end of file
+These allow a person to compare an ``sol::object`` against :ref:`nil`, which essentially checks if an object references a non-nil value, like so:
+
+.. code-block:: cpp
+
+ if (myobj == sol::nil) {
+ // doesn't have anything...
+ }
+
+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/api/reference.rst b/docs/source/api/reference.rst
index f79d529e..3bd31386 100644
--- a/docs/source/api/reference.rst
+++ b/docs/source/api/reference.rst
@@ -43,7 +43,7 @@ The value of the reference in the registry.
bool valid () const noexcept;
explicit operator bool () const noexcept;
-These functions check if the reference at ``T`` is valid: that is, if it is not :doc:`nil` and if it is not non-existing (doesn't refer to anything, including nil) reference. The explicit operator bool allows you to use it in the context of an ``if ( my_obj )`` context.
+These functions check if the reference at ``T`` is valid: that is, if it is not :ref:`nil` and if it is not non-existing (doesn't refer to anything, including nil) reference. The explicit operator bool allows you to use it in the context of an ``if ( my_obj )`` context.
.. code-block:: cpp
:caption: function: retrieves the type
@@ -57,4 +57,19 @@ Gets the :doc:`sol::type` of the reference; that is, the Lua reference.
lua_State* lua_state() const noexcept;
-Gets the ``lua_State*`` this reference exists in.
\ No newline at end of file
+Gets the ``lua_State*`` this reference exists in.
+
+
+non-members
+-----------
+
+.. code-block:: cpp
+ :caption: functions: reference comparators
+
+ bool operator==(const reference&, const reference&);
+ bool operator!=(const reference&, const reference&);
+
+Compares two references using the Lua API's `lua_compare`_ for equality.
+
+
+.. _lua_compare: https://www.lua.org/manual/5.3/manual.html#lua_compare
\ No newline at end of file
diff --git a/docs/source/api/userdata.rst b/docs/source/api/userdata.rst
index a4ee7673..6bc64791 100644
--- a/docs/source/api/userdata.rst
+++ b/docs/source/api/userdata.rst
@@ -1,5 +1,5 @@
userdata
-===========
+========
reference to a userdata
-----------------------
diff --git a/docs/source/api/usertype.rst b/docs/source/api/usertype.rst
index b654b357..17b53d3f 100644
--- a/docs/source/api/usertype.rst
+++ b/docs/source/api/usertype.rst
@@ -149,6 +149,10 @@ The constructor of usertype takes a variable number of arguments. It takes an ev
* ``"{name}", sol::initializers( func1, func2, ... )``
- Creates initializers that, given one or more functions, provides an overloaded lua function for creating a the specified type.
+ The function must have the argument signature ``func( T*, Arguments... )`` or ``func( T&, Arguments... )``, where the pointer or reference will point to a place of allocated memory that has an uninitialized ``T``. Note that lua controls the memory.
+* ``"{name}", sol::no_constructor``
+ - Specifically tells Sol not to create a `.new()` if one is not specified and the type is default-constructible.
+* ``sol::call_constructor, {any constructor type}``
+ - Specifies a function that makes the call turn into ``{usertype-name}( ... constructor arguments ... )``. This is compatible with luabind syntax.
.. _destructor:
diff --git a/sol/function_types_allocator.hpp b/sol/function_types_allocator.hpp
index e9470985..5d463700 100644
--- a/sol/function_types_allocator.hpp
+++ b/sol/function_types_allocator.hpp
@@ -60,7 +60,7 @@ inline int construct(Match&& matchfx, lua_State* L, int fxarity, int start) {
template
inline int construct(lua_State* L) {
static const auto& meta = usertype_traits::metatable;
- call_syntax syntax = stack::get_call_syntax(L, meta);
+ call_syntax syntax = stack::get_call_syntax(L, meta, 1);
int argcount = lua_gettop(L) - static_cast(syntax);
T** pointerpointer = reinterpret_cast(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
diff --git a/sol/object.hpp b/sol/object.hpp
index 5b73fa30..471f4c53 100644
--- a/sol/object.hpp
+++ b/sol/object.hpp
@@ -70,6 +70,22 @@ public:
}
};
+template
+object make_object(lua_State* L, T&& value) {
+ int backpedal = stack::push(L, std::forward(value));
+ object r = stack::get