From 3de38f8da136621d9df72b869105b98a54b9fc08 Mon Sep 17 00:00:00 2001
From: ThePhD <phdofthehouse@gmail.com>
Date: Mon, 14 Mar 2016 16:10:08 -0400
Subject: [PATCH] Easier access to specific functions.

---
 sol/stack.hpp      | 14 +++++++++++---
 sol/state_view.hpp | 17 +++++++++++++++++
 sol/table_core.hpp |  9 +++++++++
 sol/thread.hpp     |  4 ++++
 sol/types.hpp      |  3 +++
 5 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/sol/stack.hpp b/sol/stack.hpp
index 6d18f497..86c71e7c 100644
--- a/sol/stack.hpp
+++ b/sol/stack.hpp
@@ -530,7 +530,7 @@ struct pusher<unique_usertype<T, Real>> {
         Real* mem = static_cast<Real*>(static_cast<void*>(fx + 1));
         *fx = detail::special_destruct<T, Real>;
         detail::default_construct::construct(mem, std::forward<Args>(args)...);
-        *pref = mem->get();
+	   *pref = std::addressof(detail::deref(*mem));
         if (luaL_newmetatable(L, &usertype_traits<unique_usertype<T>>::metatable[0]) == 1) {
             set_field(L, "__gc", detail::unique_destruct<T>);
         }
@@ -539,13 +539,21 @@ struct pusher<unique_usertype<T, Real>> {
     }
 };
 
+template<typename T>
+struct pusher<T, std::enable_if_t<is_unique_usertype<T>::value>> {
+    template <typename... Args>
+    static int push(lua_State* L, Args&&... args) {
+        typedef typename is_unique_usertype<T>::metatable_type meta_type;
+        return stack::push<unique_usertype<meta_type, T>>(L, std::forward<Args>(args)...);
+    }
+};
+
 template<typename T, typename D>
 struct pusher<std::unique_ptr<T, D>> {
     static int push(lua_State* L, std::unique_ptr<T, D> obj) {
-        typedef std::unique_ptr<T, D> ptr_t;
         if (obj == nullptr)
             return stack::push(L, nil);
-        return stack::push<unique_usertype<T, ptr_t>>(L, std::move(obj));
+        return stack::push<unique_usertype<T, std::unique_ptr<T, D>>>(L, std::move(obj));
     }
 };
 
diff --git a/sol/state_view.hpp b/sol/state_view.hpp
index 4825f89e..7fa1d64c 100644
--- a/sol/state_view.hpp
+++ b/sol/state_view.hpp
@@ -273,6 +273,15 @@ public:
         return *this;
     }
 
+    table create_table(int narr = 0, int nrec = 0) {
+        return create_table(lua_state(), narr, nrec);
+    }
+
+    template <typename Key, typename Value, typename... Args>
+    table create_table(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+        return create_table(lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+    }
+
     static inline table create_table(lua_State* L, int narr = 0, int nrec = 0) {
         return global_table::create(L, narr, nrec);
     }
@@ -281,6 +290,14 @@ public:
     static inline table create_table(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
         return global_table::create(L, narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
     }
+
+    thread create_thread() {
+        return create_thread(lua_state());
+    }
+
+    static inline thread create_thread(lua_State* L, int narr = 0, int nrec = 0) {
+        return thread::create(L);
+    }
 };
 } // sol
 
diff --git a/sol/table_core.hpp b/sol/table_core.hpp
index e5ae3026..13bbbdf2 100644
--- a/sol/table_core.hpp
+++ b/sol/table_core.hpp
@@ -271,6 +271,15 @@ private:
     }
 
 public:
+    table create(int narr = 0, int nrec = 0) {
+        return create(lua_state(), narr, nrec);
+    }
+
+    template <typename Key, typename Value, typename... Args>
+    table create(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+        return create(lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+    }
+
     static inline table create(lua_State* L, int narr = 0, int nrec = 0) {
         lua_createtable(L, narr, nrec);
         table result(L);
diff --git a/sol/thread.hpp b/sol/thread.hpp
index fb2cec04..9d5a44ff 100644
--- a/sol/thread.hpp
+++ b/sol/thread.hpp
@@ -50,6 +50,10 @@ public:
         return lstat;
     }
 
+    thread create () {
+        return create(lua_state());
+    }
+
     static thread create (lua_State* L) {
         lua_newthread(L);
         thread result(L);
diff --git a/sol/types.hpp b/sol/types.hpp
index 1d541950..c9fc88f4 100644
--- a/sol/types.hpp
+++ b/sol/types.hpp
@@ -286,6 +286,9 @@ struct is_proxy_primitive<std::reference_wrapper<T>> : std::true_type { };
 template <typename... Args>
 struct is_proxy_primitive<std::tuple<Args...>> : std::true_type { };
 
+template <typename T>
+struct is_unique_usertype : std::false_type {};
+
 template<typename T>
 inline type type_of() {
     return lua_type_of<meta::Unqualified<T>>::value;