diff --git a/include/kaguya/type.hpp b/include/kaguya/type.hpp index 4441308..a311e7c 100644 --- a/include/kaguya/type.hpp +++ b/include/kaguya/type.hpp @@ -87,7 +87,7 @@ namespace kaguya } static get_type get(lua_State* l, int index) { - T* pointer = get_pointer(l, index, types::typetag()); + T* pointer = get_pointer(l, index, types::typetag()); if (!pointer) { throw LuaTypeMismatch("type mismatch!!"); @@ -263,10 +263,17 @@ namespace kaguya static int push(lua_State* l, push_type v) { - typedef ObjectSharedPointerWrapper wrapper_type; - void *storage = lua_newuserdata(l, sizeof(wrapper_type)); - new(storage) wrapper_type(v); - class_userdata::setmetatable(l); + if (v) + { + typedef ObjectSharedPointerWrapper wrapper_type; + void *storage = lua_newuserdata(l, sizeof(wrapper_type)); + new(storage) wrapper_type(v); + class_userdata::setmetatable(l); + } + else + { + lua_pushnil(l); + } return 1; } }; @@ -294,16 +301,23 @@ namespace kaguya static int push(lua_State* l, push_type v) { - typedef ObjectSharedPointerWrapper wrapper_type; - void *storage = lua_newuserdata(l, sizeof(wrapper_type)); - new(storage) wrapper_type(v); + if (v) + { + typedef ObjectSharedPointerWrapper wrapper_type; + void *storage = lua_newuserdata(l, sizeof(wrapper_type)); + new(storage) wrapper_type(v); + } + else + { + lua_pushnil(l); + } return 1; } }; #if KAGUYA_USE_CPP11 ///! traits for unique_ptr - template struct lua_type_traits > { + template struct lua_type_traits > { typedef std::unique_ptr&& push_type; typedef std::unique_ptr get_type; @@ -331,10 +345,18 @@ namespace kaguya static int push(lua_State* l, push_type v) { - typedef ObjectSmartPointerWrapper > wrapper_type; - void *storage = lua_newuserdata(l, sizeof(wrapper_type)); - new(storage) wrapper_type(std::forward(v)); - class_userdata::setmetatable(l); + if (v) + { + typedef ObjectSmartPointerWrapper > wrapper_type; + void *storage = lua_newuserdata(l, sizeof(wrapper_type)); + new(storage) wrapper_type(std::forward(v)); + class_userdata::setmetatable(l); + } + else + { + lua_pushnil(l); + } + return 1; return 1; } }; @@ -641,11 +663,12 @@ namespace kaguya bool isNilref_()const { int t = type(); - return t == LUA_TNIL ||t == LUA_TNONE; } + return t == LUA_TNIL || t == LUA_TNONE; + } typedef void (LuaBasicTypeFunctions::*bool_type)() const; void this_type_does_not_support_comparisons() const {} - + /** * @brief Equivalent to `#` operator for strings and tables with no metamethods. * Follows Lua's reference manual documentation of `lua_rawlen`, ie. types other @@ -660,14 +683,14 @@ namespace kaguya return lua_rawlen(state, index); #else - int type = lua_type(state,index); - if(type != TYPE_STRING && type != TYPE_TABLE && type != TYPE_USERDATA && type != TYPE_LIGHTUSERDATA) + int type = lua_type(state, index); + if (type != TYPE_STRING && type != TYPE_TABLE && type != TYPE_USERDATA && type != TYPE_LIGHTUSERDATA) { return 0; } return lua_objlen(state, index); #endif - } + } //return type int type() const @@ -735,7 +758,7 @@ namespace kaguya */ //@{ template - inline bool operator==( const LuaBasicTypeFunctions& rhs)const + inline bool operator==(const LuaBasicTypeFunctions& rhs)const { if (isNilref_() || rhs.isNilref_()) { return !isNilref_() == !rhs.isNilref_(); } lua_State* state = state_(); @@ -749,7 +772,7 @@ namespace kaguya #endif } template - inline bool operator<( const LuaBasicTypeFunctions& rhs)const + inline bool operator<(const LuaBasicTypeFunctions& rhs)const { if (isNilref_() || rhs.isNilref_()) { return !isNilref_() != !rhs.isNilref_(); } lua_State* state = state_(); @@ -763,7 +786,7 @@ namespace kaguya #endif } template - inline bool operator<=( const LuaBasicTypeFunctions& rhs)const + inline bool operator<=(const LuaBasicTypeFunctions& rhs)const { if (isNilref_() || rhs.isNilref_()) { return !isNilref_() == !rhs.isNilref_(); } lua_State* state = state_(); @@ -777,17 +800,17 @@ namespace kaguya #endif } template - inline bool operator>=( const LuaBasicTypeFunctions& rhs)const + inline bool operator>=(const LuaBasicTypeFunctions& rhs)const { return rhs <= (*this); } template inline bool operator>(const LuaBasicTypeFunctions& rhs)const { - return rhs < (*this); + return rhs < (*this); } template - inline bool operator!=( const LuaBasicTypeFunctions& rhs)const + inline bool operator!=(const LuaBasicTypeFunctions& rhs)const { return !this->operator==(rhs); } @@ -806,7 +829,7 @@ namespace kaguya return false; } template - inline typename traits::enable_if*>::value, bool>::type operator!=( const T& rhs)const + inline typename traits::enable_if*>::value, bool>::type operator!=(const T& rhs)const { return !((*this) == rhs); } @@ -828,7 +851,7 @@ namespace kaguya return static_cast(this)->pushStackIndex(state); } private: - }; +}; diff --git a/test/test_02_classreg.cpp b/test/test_02_classreg.cpp index 278f405..fb5c231 100644 --- a/test/test_02_classreg.cpp +++ b/test/test_02_classreg.cpp @@ -815,4 +815,27 @@ KAGUYA_TEST_FUNCTION_DEF(object_take_const_pointer)(kaguya::State& state) // state["fn"](base, 54);//cannot assign TEST_EQUAL(base.a, 22); } + +KAGUYA_TEST_FUNCTION_DEF(null_shared_ptr)(kaguya::State& state) +{ + state["Base"].setClass(kaguya::ClassMetatable() + .addConstructor() + .addProperty("a", &Base::a) + ); + + + state["test"] = kaguya::standard::shared_ptr(); + TEST_CHECK(state("assert(test==nil)")); + + + state["test"] = kaguya::standard::shared_ptr(); + + TEST_CHECK(state("assert(test==nil)")); + + state["test"] = kaguya::standard::shared_ptr(); + TEST_CHECK(state("assert(test==nil)")); + + kaguya::standard::shared_ptr sptr = state["test"]; + TEST_CHECK(!sptr); +} KAGUYA_TEST_GROUP_END(test_02_classreg) diff --git a/test/test_11_cxx11_feature.cpp b/test/test_11_cxx11_feature.cpp index fb327a1..173c240 100644 --- a/test/test_11_cxx11_feature.cpp +++ b/test/test_11_cxx11_feature.cpp @@ -136,6 +136,16 @@ KAGUYA_TEST_FUNCTION_DEF(compare_null_ptr)(kaguya::State& state) TEST_CHECK(nullref == nullptr); } + + +KAGUYA_TEST_FUNCTION_DEF(null_unique_ptr)(kaguya::State& state) +{ + state["Base"].setClass(kaguya::ClassMetatable()); + + state["test"] =std::unique_ptr(); + TEST_CHECK(state("assert(test==nil)")); +} + KAGUYA_TEST_GROUP_END(test_11_cxx11_feature) #endif