Skip to content

Commit 3af0181

Browse files
committed
push nil if shared_ptr has null
1 parent 91f884d commit 3af0181

File tree

3 files changed

+82
-26
lines changed

3 files changed

+82
-26
lines changed

include/kaguya/type.hpp

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ namespace kaguya
8787
}
8888
static get_type get(lua_State* l, int index)
8989
{
90-
T* pointer = get_pointer(l, index, types::typetag<T>());
90+
T* pointer = get_pointer(l, index, types::typetag<T>());
9191
if (!pointer)
9292
{
9393
throw LuaTypeMismatch("type mismatch!!");
@@ -263,10 +263,17 @@ namespace kaguya
263263

264264
static int push(lua_State* l, push_type v)
265265
{
266-
typedef ObjectSharedPointerWrapper wrapper_type;
267-
void *storage = lua_newuserdata(l, sizeof(wrapper_type));
268-
new(storage) wrapper_type(v);
269-
class_userdata::setmetatable<T>(l);
266+
if (v)
267+
{
268+
typedef ObjectSharedPointerWrapper wrapper_type;
269+
void *storage = lua_newuserdata(l, sizeof(wrapper_type));
270+
new(storage) wrapper_type(v);
271+
class_userdata::setmetatable<T>(l);
272+
}
273+
else
274+
{
275+
lua_pushnil(l);
276+
}
270277
return 1;
271278
}
272279
};
@@ -294,16 +301,23 @@ namespace kaguya
294301

295302
static int push(lua_State* l, push_type v)
296303
{
297-
typedef ObjectSharedPointerWrapper wrapper_type;
298-
void *storage = lua_newuserdata(l, sizeof(wrapper_type));
299-
new(storage) wrapper_type(v);
304+
if (v)
305+
{
306+
typedef ObjectSharedPointerWrapper wrapper_type;
307+
void *storage = lua_newuserdata(l, sizeof(wrapper_type));
308+
new(storage) wrapper_type(v);
309+
}
310+
else
311+
{
312+
lua_pushnil(l);
313+
}
300314
return 1;
301315
}
302316
};
303317

304318
#if KAGUYA_USE_CPP11
305319
///! traits for unique_ptr
306-
template<typename T,typename Deleter> struct lua_type_traits<std::unique_ptr<T, Deleter> > {
320+
template<typename T, typename Deleter> struct lua_type_traits<std::unique_ptr<T, Deleter> > {
307321
typedef std::unique_ptr<T, Deleter>&& push_type;
308322
typedef std::unique_ptr<T, Deleter> get_type;
309323

@@ -331,10 +345,18 @@ namespace kaguya
331345

332346
static int push(lua_State* l, push_type v)
333347
{
334-
typedef ObjectSmartPointerWrapper<std::unique_ptr<T,Deleter> > wrapper_type;
335-
void *storage = lua_newuserdata(l, sizeof(wrapper_type));
336-
new(storage) wrapper_type(std::forward<push_type>(v));
337-
class_userdata::setmetatable<T>(l);
348+
if (v)
349+
{
350+
typedef ObjectSmartPointerWrapper<std::unique_ptr<T, Deleter> > wrapper_type;
351+
void *storage = lua_newuserdata(l, sizeof(wrapper_type));
352+
new(storage) wrapper_type(std::forward<push_type>(v));
353+
class_userdata::setmetatable<T>(l);
354+
}
355+
else
356+
{
357+
lua_pushnil(l);
358+
}
359+
return 1;
338360
return 1;
339361
}
340362
};
@@ -641,11 +663,12 @@ namespace kaguya
641663

642664
bool isNilref_()const {
643665
int t = type();
644-
return t == LUA_TNIL ||t == LUA_TNONE; }
666+
return t == LUA_TNIL || t == LUA_TNONE;
667+
}
645668

646669
typedef void (LuaBasicTypeFunctions::*bool_type)() const;
647670
void this_type_does_not_support_comparisons() const {}
648-
671+
649672
/**
650673
* @brief Equivalent to `#` operator for strings and tables with no metamethods.
651674
* Follows Lua's reference manual documentation of `lua_rawlen`, ie. types other
@@ -660,14 +683,14 @@ namespace kaguya
660683
return lua_rawlen(state, index);
661684
#else
662685

663-
int type = lua_type(state,index);
664-
if(type != TYPE_STRING && type != TYPE_TABLE && type != TYPE_USERDATA && type != TYPE_LIGHTUSERDATA)
686+
int type = lua_type(state, index);
687+
if (type != TYPE_STRING && type != TYPE_TABLE && type != TYPE_USERDATA && type != TYPE_LIGHTUSERDATA)
665688
{
666689
return 0;
667690
}
668691
return lua_objlen(state, index);
669692
#endif
670-
}
693+
}
671694

672695
//return type
673696
int type() const
@@ -735,7 +758,7 @@ namespace kaguya
735758
*/
736759
//@{
737760
template<typename OtherDrived>
738-
inline bool operator==( const LuaBasicTypeFunctions<OtherDrived>& rhs)const
761+
inline bool operator==(const LuaBasicTypeFunctions<OtherDrived>& rhs)const
739762
{
740763
if (isNilref_() || rhs.isNilref_()) { return !isNilref_() == !rhs.isNilref_(); }
741764
lua_State* state = state_();
@@ -749,7 +772,7 @@ namespace kaguya
749772
#endif
750773
}
751774
template<typename OtherDrived>
752-
inline bool operator<( const LuaBasicTypeFunctions<OtherDrived>& rhs)const
775+
inline bool operator<(const LuaBasicTypeFunctions<OtherDrived>& rhs)const
753776
{
754777
if (isNilref_() || rhs.isNilref_()) { return !isNilref_() != !rhs.isNilref_(); }
755778
lua_State* state = state_();
@@ -763,7 +786,7 @@ namespace kaguya
763786
#endif
764787
}
765788
template<typename OtherDrived>
766-
inline bool operator<=( const LuaBasicTypeFunctions<OtherDrived>& rhs)const
789+
inline bool operator<=(const LuaBasicTypeFunctions<OtherDrived>& rhs)const
767790
{
768791
if (isNilref_() || rhs.isNilref_()) { return !isNilref_() == !rhs.isNilref_(); }
769792
lua_State* state = state_();
@@ -777,17 +800,17 @@ namespace kaguya
777800
#endif
778801
}
779802
template<typename OtherDrived>
780-
inline bool operator>=( const LuaBasicTypeFunctions<OtherDrived>& rhs)const
803+
inline bool operator>=(const LuaBasicTypeFunctions<OtherDrived>& rhs)const
781804
{
782805
return rhs <= (*this);
783806
}
784807
template<typename OtherDrived>
785808
inline bool operator>(const LuaBasicTypeFunctions<OtherDrived>& rhs)const
786809
{
787-
return rhs < (*this);
810+
return rhs < (*this);
788811
}
789812
template<typename OtherDrived>
790-
inline bool operator!=( const LuaBasicTypeFunctions<OtherDrived>& rhs)const
813+
inline bool operator!=(const LuaBasicTypeFunctions<OtherDrived>& rhs)const
791814
{
792815
return !this->operator==(rhs);
793816
}
@@ -806,7 +829,7 @@ namespace kaguya
806829
return false;
807830
}
808831
template<typename T>
809-
inline typename traits::enable_if<!traits::is_convertible<T*, LuaBasicTypeFunctions<T>*>::value, bool>::type operator!=( const T& rhs)const
832+
inline typename traits::enable_if<!traits::is_convertible<T*, LuaBasicTypeFunctions<T>*>::value, bool>::type operator!=(const T& rhs)const
810833
{
811834
return !((*this) == rhs);
812835
}
@@ -828,7 +851,7 @@ namespace kaguya
828851
return static_cast<const Derived*>(this)->pushStackIndex(state);
829852
}
830853
private:
831-
};
854+
};
832855

833856

834857

test/test_02_classreg.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,4 +815,27 @@ KAGUYA_TEST_FUNCTION_DEF(object_take_const_pointer)(kaguya::State& state)
815815
// state["fn"](base, 54);//cannot assign
816816
TEST_EQUAL(base.a, 22);
817817
}
818+
819+
KAGUYA_TEST_FUNCTION_DEF(null_shared_ptr)(kaguya::State& state)
820+
{
821+
state["Base"].setClass(kaguya::ClassMetatable<Base>()
822+
.addConstructor()
823+
.addProperty("a", &Base::a)
824+
);
825+
826+
827+
state["test"] = kaguya::standard::shared_ptr<Base>();
828+
TEST_CHECK(state("assert(test==nil)"));
829+
830+
831+
state["test"] = kaguya::standard::shared_ptr<Derived>();
832+
833+
TEST_CHECK(state("assert(test==nil)"));
834+
835+
state["test"] = kaguya::standard::shared_ptr<void>();
836+
TEST_CHECK(state("assert(test==nil)"));
837+
838+
kaguya::standard::shared_ptr<void> sptr = state["test"];
839+
TEST_CHECK(!sptr);
840+
}
818841
KAGUYA_TEST_GROUP_END(test_02_classreg)

test/test_11_cxx11_feature.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ KAGUYA_TEST_FUNCTION_DEF(compare_null_ptr)(kaguya::State& state)
136136
TEST_CHECK(nullref == nullptr);
137137
}
138138

139+
140+
141+
KAGUYA_TEST_FUNCTION_DEF(null_unique_ptr)(kaguya::State& state)
142+
{
143+
state["Base"].setClass(kaguya::ClassMetatable<MoveOnlyClass>());
144+
145+
state["test"] =std::unique_ptr<MoveOnlyClass>();
146+
TEST_CHECK(state("assert(test==nil)"));
147+
}
148+
139149
KAGUYA_TEST_GROUP_END(test_11_cxx11_feature)
140150

141151
#endif

0 commit comments

Comments
 (0)