1 #ifndef AWFUL_LUA_TYPECHECK_H
2 #define AWFUL_LUA_TYPECHECK_H
4 namespace awful
{ namespace LuaImpl
13 // The address of the dummy field of that class is unique
14 // for each class compiled in the executable.
15 // This provides a simple way to identify type, that can be embedded
16 // into a lua light user data to be used as keys in lua tables.
18 // This would not work portably with the address of std::type_info structures, because
19 // comparing type_info addresses is not portable (as with some systems/compiler/linkers
20 // you may end up with several instances of the same type_info in the final binary)
21 // and lua assumes that a light user data contains an address that it can directly
22 // hash when used as a table key.
23 template< typename T
> struct type_tag
27 template< typename T
> char type_tag
< T
>::dummy
;
29 // Structs come wrapped in two flavors: by value or by reference.
30 // This handy enum allows the struct typeconverter to distinguish both case.
31 enum e_TypeCheckResult
33 tcr_Fail
, // Not of the required type
34 tcr_Type1
, // Of the type represented by the first metatable index
35 tcr_Type2
// Of the type represented by the second metatable index
38 template< e_CheckingPolicy Checking
> struct TypeChecker
40 static bool CheckType( lua_State
* pLS
, int Index_
, int ExpectedType_
)
45 template< class C
> static e_TypeCheckResult
CheckObjectType( lua_State
* pLS
, int Index_
)
50 template< class C
> static e_TypeCheckResult
CheckStructType( lua_State
* pLS
, int Index_
)
55 /* template< class C > static e_TypeCheckResult CheckObjectType( lua_State* pLS, int Index_ )
57 return CheckUserDataAndMetatable
58 ( pLS, Index_, &type_tag< C& >::dummy );
61 template< class C > static e_TypeCheckResult CheckStructType( lua_State* pLS, int Index_ )
63 return CheckUserDataAndMetatable
64 ( pLS, Index_, &type_tag< C& >::dummy, &type_tag< C* >::dummy );
68 template<> struct TypeChecker
< cp_NoThrow
>
70 static bool CheckType( lua_State
* pLS
, int Index_
, int ExpectedType_
)
72 int type
= lua_type( pLS
, Index_
);
73 if( type
!= ExpectedType_
)
79 static e_TypeCheckResult
CheckUserDataAndMetatable( lua_State
* pLS
, int Index_
, void* MTRegistryIndex_
, void* MTRegistryIndex2_
= NULL
)
81 if( !CheckType( pLS
, Index_
, LUA_TUSERDATA
) )
84 if( !lua_getmetatable( pLS
, Index_
) )
87 lua_pushlightuserdata( pLS
, MTRegistryIndex_
);
88 lua_gettable( pLS
, LUA_REGISTRYINDEX
);
90 bool bRes
= lua_rawequal( pLS
, -1, -2 );
95 if( !bRes
&& MTRegistryIndex2_
)
97 lua_pushlightuserdata( pLS
, MTRegistryIndex2_
);
98 lua_gettable( pLS
, LUA_REGISTRYINDEX
);
100 bool bRes
= lua_rawequal( pLS
, -1, -2 );
109 template< class C
> static e_TypeCheckResult
CheckObjectType( lua_State
* pLS
, int Index_
)
111 return CheckUserDataAndMetatable
112 ( pLS
, Index_
, &type_tag
< C
& >::dummy
);
115 template< class C
> static e_TypeCheckResult
CheckStructType( lua_State
* pLS
, int Index_
)
117 return CheckUserDataAndMetatable
118 ( pLS
, Index_
, &type_tag
< C
& >::dummy
, &type_tag
< C
* >::dummy
);
122 template<> struct TypeChecker
< cp_Throw
>
124 static bool CheckType( lua_State
* pLS
, int Index_
, int ExpectedType_
)
126 int type
= lua_type( pLS
, Index_
);
127 if( type
!= ExpectedType_
)
128 throw Error::TypeMismatch( type
, ExpectedType_
);
133 static e_TypeCheckResult
CheckUserDataAndMetatable( lua_State
* pLS
, int Index_
, void* MTRegistryIndex_
, void* MTRegistryIndex2_
= NULL
)
135 CheckType( pLS
, Index_
, LUA_TUSERDATA
);
137 if( !lua_getmetatable( pLS
, Index_
) )
138 throw Error::TypeMismatch();
140 lua_pushlightuserdata( pLS
, MTRegistryIndex_
);
141 lua_gettable( pLS
, LUA_REGISTRYINDEX
);
143 bool bRes
= lua_rawequal( pLS
, -1, -2 );
148 if( !bRes
&& MTRegistryIndex2_
)
150 lua_pushlightuserdata( pLS
, MTRegistryIndex2_
);
151 lua_gettable( pLS
, LUA_REGISTRYINDEX
);
153 bool bRes
= lua_rawequal( pLS
, -1, -2 );
159 throw Error::TypeMismatch();
162 template< class C
> static e_TypeCheckResult
CheckObjectType( lua_State
* pLS
, int Index_
)
164 return CheckUserDataAndMetatable
165 ( pLS
, Index_
, &type_tag
< C
& >::dummy
);
168 template< class C
> static e_TypeCheckResult
CheckStructType( lua_State
* pLS
, int Index_
)
170 return CheckUserDataAndMetatable
171 ( pLS
, Index_
, &type_tag
< C
& >::dummy
, &type_tag
< C
* >::dummy
);
175 // bool CheckType_nothrow( lua_State* pLS, int Index_, int ExpectedType_ );
176 /* void CheckUserDataAndMetatable( lua_State* pLS, int Index_,
177 void* MTRegistryIndex_, void* MTRegistryIndex2_ = NULL );
178 e_TypeCheckResult CheckUserDataAndMetatable_nothrow( lua_State* pLS, int Index_,
179 void* MTRegistryIndex1_, void* MTRegistryIndex2_ = NULL );*/
181 /*template< class C > static void CheckObjectType( lua_State* pLS, int Index_ )
183 CheckUserDataAndMetatable
184 ( pLS, Index_, &type_tag< C& >::dummy );
187 template< class C > static void CheckStructType( lua_State* pLS, int Index_ )
189 CheckUserDataAndMetatable
190 ( pLS, Index_, &type_tag< C& >::dummy, &type_tag< C* >::dummy );