2013-11-25 17:56:27 +08:00
// The MIT License (MIT)
2016-02-27 15:43:53 +08:00
// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
2013-11-25 17:56:27 +08:00
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# ifndef SOL_TYPES_HPP
# define SOL_TYPES_HPP
2015-05-25 09:29:21 +08:00
# include "compatibility.hpp"
2014-08-09 19:54:58 +08:00
# include "traits.hpp"
2015-05-25 09:29:21 +08:00
# include <string>
2013-11-25 17:56:27 +08:00
namespace sol {
2016-02-27 20:56:28 +08:00
namespace detail {
template < lua_CFunction f >
inline int static_trampoline ( lua_State * L ) {
try {
return f ( L ) ;
}
catch ( const char * s ) { // Catch and convert exceptions.
lua_pushstring ( L , s ) ;
}
catch ( const std : : exception & e ) {
lua_pushstring ( L , e . what ( ) ) ;
}
catch ( . . . ) {
lua_pushstring ( L , " caught (...) exception " ) ;
}
return lua_error ( L ) ;
}
template < typename Fx >
inline int trampoline ( lua_State * L , Fx & & f ) {
2016-02-27 21:04:02 +08:00
try {
return f ( L ) ;
}
catch ( const char * s ) { // Catch and convert exceptions.
lua_pushstring ( L , s ) ;
}
catch ( const std : : exception & e ) {
lua_pushstring ( L , e . what ( ) ) ;
}
catch ( . . . ) {
lua_pushstring ( L , " caught (...) exception " ) ;
}
return lua_error ( L ) ;
2016-02-27 20:56:28 +08:00
}
inline int c_trampoline ( lua_State * L , lua_CFunction f ) {
return trampoline ( L , f ) ;
}
}
2013-11-25 17:56:27 +08:00
struct nil_t { } ;
2013-12-03 12:33:23 +08:00
const nil_t nil { } ;
2015-03-02 10:14:42 +08:00
inline bool operator = = ( nil_t , nil_t ) { return true ; }
inline bool operator ! = ( nil_t , nil_t ) { return false ; }
struct void_type : types < void > { } ; // This is important because it allows myobject.call( Void, ... ) to work
2013-12-03 12:33:23 +08:00
const void_type Void { } ;
2014-06-29 14:16:48 +08:00
2016-02-03 05:18:44 +08:00
template < typename . . . Args >
struct function_sig { } ;
2014-06-29 14:16:48 +08:00
2015-03-02 10:14:42 +08:00
struct upvalue {
2014-06-07 12:24:48 +08:00
void * value ;
2015-03-02 10:14:42 +08:00
upvalue ( void * data ) : value ( data ) { }
2014-08-11 08:49:34 +08:00
operator void * ( ) const { return value ; }
2014-06-07 12:24:48 +08:00
} ;
2015-03-02 10:14:42 +08:00
struct light_userdata {
2014-04-26 08:20:35 +08:00
void * value ;
2015-03-02 10:14:42 +08:00
light_userdata ( void * data ) : value ( data ) { }
2014-08-11 08:49:34 +08:00
operator void * ( ) const { return value ; }
2014-04-26 08:20:35 +08:00
} ;
2015-03-02 10:14:42 +08:00
struct userdata {
2014-04-26 08:20:35 +08:00
void * value ;
2015-03-02 10:14:42 +08:00
userdata ( void * data ) : value ( data ) { }
2014-08-11 08:49:34 +08:00
operator void * ( ) const { return value ; }
2014-04-26 08:20:35 +08:00
} ;
2013-11-25 17:56:27 +08:00
2016-02-17 10:22:07 +08:00
struct c_closure {
2016-02-22 08:26:58 +08:00
lua_CFunction c_function ;
int upvalues ;
c_closure ( lua_CFunction f , int upvalues = 0 ) : c_function ( f ) , upvalues ( upvalues ) { }
2016-02-17 10:22:07 +08:00
} ;
2014-04-27 06:23:56 +08:00
enum class call_syntax {
dot = 0 ,
colon = 1
} ;
2016-02-27 15:43:53 +08:00
enum class call_status : int {
ok = LUA_OK ,
yielded = LUA_YIELD ,
2016-01-29 08:57:02 +08:00
runtime = LUA_ERRRUN ,
2016-02-27 15:43:53 +08:00
memory = LUA_ERRMEM ,
2016-01-29 08:57:02 +08:00
handler = LUA_ERRERR ,
2016-02-27 15:43:53 +08:00
gc = LUA_ERRGCMM
} ;
enum class thread_status : int {
2016-02-27 15:49:40 +08:00
normal = LUA_OK ,
yielded = LUA_YIELD ,
error_runtime = LUA_ERRRUN ,
error_memory = LUA_ERRMEM ,
error_gc = LUA_ERRGCMM ,
error_handler = LUA_ERRERR ,
dead ,
2015-10-22 23:20:32 +08:00
} ;
2013-11-25 17:56:27 +08:00
enum class type : int {
2013-12-03 12:33:23 +08:00
none = LUA_TNONE ,
nil = LUA_TNIL ,
string = LUA_TSTRING ,
number = LUA_TNUMBER ,
thread = LUA_TTHREAD ,
boolean = LUA_TBOOLEAN ,
function = LUA_TFUNCTION ,
userdata = LUA_TUSERDATA ,
2013-11-25 17:56:27 +08:00
lightuserdata = LUA_TLIGHTUSERDATA ,
2013-12-03 12:33:23 +08:00
table = LUA_TTABLE ,
2015-10-21 09:38:28 +08:00
poly = none | nil | string | number | thread |
2013-12-03 12:33:23 +08:00
table | boolean | function | userdata | lightuserdata
2013-11-25 17:56:27 +08:00
} ;
2015-03-02 10:14:42 +08:00
inline int type_panic ( lua_State * L , int index , type expected , type actual ) {
return luaL_error ( L , " stack index %d, expected %s, received %s " , index , lua_typename ( L , static_cast < int > ( expected ) ) , lua_typename ( L , static_cast < int > ( actual ) ) ) ;
}
// Specify this function as the handler for lua::check if you know there's nothing wrong
inline int no_panic ( lua_State * , int , type , type ) {
return 0 ;
}
2013-11-25 17:56:27 +08:00
inline void type_error ( lua_State * L , int expected , int actual ) {
luaL_error ( L , " expected %s, received %s " , lua_typename ( L , expected ) , lua_typename ( L , actual ) ) ;
}
2015-03-02 10:14:42 +08:00
inline void type_error ( lua_State * L , type expected , type actual ) {
type_error ( L , static_cast < int > ( expected ) , static_cast < int > ( actual ) ) ;
}
inline void type_assert ( lua_State * L , int index , type expected , type actual ) {
2015-05-25 09:38:39 +08:00
if ( expected ! = type : : poly & & expected ! = actual ) {
2015-10-21 09:38:28 +08:00
type_panic ( L , index , expected , actual ) ;
2015-05-25 09:38:39 +08:00
}
2015-03-02 10:14:42 +08:00
}
2013-11-25 17:56:27 +08:00
inline void type_assert ( lua_State * L , int index , type expected ) {
int actual = lua_type ( L , index ) ;
2013-12-01 10:12:50 +08:00
if ( expected ! = type : : poly & & static_cast < int > ( expected ) ! = actual ) {
2015-10-21 09:38:28 +08:00
type_error ( L , static_cast < int > ( expected ) , actual ) ;
2013-11-25 17:56:27 +08:00
}
}
2014-04-27 06:23:56 +08:00
inline std : : string type_name ( lua_State * L , type t ) {
return lua_typename ( L , static_cast < int > ( t ) ) ;
}
2016-02-27 15:43:53 +08:00
class reference ;
2014-04-27 06:23:56 +08:00
template < typename T >
2014-09-19 23:08:44 +08:00
class usertype ;
2016-01-09 05:16:06 +08:00
template < bool >
class table_core ;
typedef table_core < false > table ;
typedef table_core < true > global_table ;
2016-02-01 16:27:06 +08:00
class function ;
class protected_function ;
2016-02-27 15:43:53 +08:00
class coroutine ;
class thread ;
2013-12-01 10:12:50 +08:00
class object ;
2013-11-25 17:56:27 +08:00
2015-03-02 10:14:42 +08:00
template < typename T , typename = void >
2015-06-18 06:33:58 +08:00
struct lua_type_of : std : : integral_constant < type , type : : userdata > { } ;
2013-11-25 17:56:27 +08:00
2015-03-02 10:14:42 +08:00
template < >
2015-06-18 06:33:58 +08:00
struct lua_type_of < std : : string > : std : : integral_constant < type , type : : string > { } ;
2013-11-25 17:56:27 +08:00
2015-03-02 10:14:42 +08:00
template < std : : size_t N >
2015-06-18 06:33:58 +08:00
struct lua_type_of < char [ N ] > : std : : integral_constant < type , type : : string > { } ;
2013-12-01 10:12:50 +08:00
2015-03-02 10:14:42 +08:00
template < >
2015-06-18 06:33:58 +08:00
struct lua_type_of < const char * > : std : : integral_constant < type , type : : string > { } ;
2013-11-25 17:56:27 +08:00
2015-03-02 10:14:42 +08:00
template < >
2015-06-18 06:33:58 +08:00
struct lua_type_of < bool > : std : : integral_constant < type , type : : boolean > { } ;
2015-03-02 10:14:42 +08:00
template < >
2016-01-16 15:30:49 +08:00
struct lua_type_of < nil_t > : std : : integral_constant < type , type : : nil > { } ;
template < >
struct lua_type_of < table > : std : : integral_constant < type , type : : table > { } ;
2015-03-02 10:14:42 +08:00
template < >
2016-01-16 15:30:49 +08:00
struct lua_type_of < global_table > : std : : integral_constant < type , type : : table > { } ;
2015-03-02 10:14:42 +08:00
template < >
2015-06-18 06:33:58 +08:00
struct lua_type_of < object > : std : : integral_constant < type , type : : poly > { } ;
2015-03-02 10:14:42 +08:00
template < >
2015-06-18 06:33:58 +08:00
struct lua_type_of < light_userdata > : std : : integral_constant < type , type : : lightuserdata > { } ;
2015-03-02 10:14:42 +08:00
2016-02-17 10:22:07 +08:00
template < >
struct lua_type_of < lua_CFunction > : std : : integral_constant < type , type : : function > { } ;
2015-03-02 10:14:42 +08:00
template < >
2015-06-18 06:33:58 +08:00
struct lua_type_of < function > : std : : integral_constant < type , type : : function > { } ;
2015-03-02 10:14:42 +08:00
2016-02-27 15:43:53 +08:00
template < >
struct lua_type_of < coroutine > : std : : integral_constant < type , type : : function > { } ;
template < >
struct lua_type_of < thread > : std : : integral_constant < type , type : : thread > { } ;
2016-01-16 15:30:49 +08:00
template < >
2016-02-01 16:27:06 +08:00
struct lua_type_of < protected_function > : std : : integral_constant < type , type : : function > { } ;
2016-01-16 15:30:49 +08:00
2015-06-18 06:33:58 +08:00
template < typename Signature >
struct lua_type_of < std : : function < Signature > > : std : : integral_constant < type , type : : function > { } ;
2015-03-02 10:14:42 +08:00
template < typename T >
2015-06-18 06:33:58 +08:00
struct lua_type_of < T * > : std : : integral_constant < type , type : : userdata > { } ;
2015-03-02 10:14:42 +08:00
template < typename T >
2016-02-09 16:38:11 +08:00
struct lua_type_of < T , std : : enable_if_t < std : : is_arithmetic < T > : : value > > : std : : integral_constant < type , type : : number > { } ;
2015-03-02 10:14:42 +08:00
template < typename T >
2016-02-17 10:22:07 +08:00
struct lua_type_of < T , std : : enable_if_t < std : : is_enum < T > : : value > > : std : : integral_constant < type , type : : number > { } ;
2015-03-02 10:14:42 +08:00
2016-01-16 15:30:49 +08:00
template < typename T >
2016-02-27 15:43:53 +08:00
struct is_lua_primitive : std : : integral_constant < bool , type : : userdata ! = lua_type_of < meta : : Unqualified < T > > : : value | | std : : is_base_of < reference , meta : : Unqualified < T > > : : value > { } ;
2016-01-16 15:30:49 +08:00
2016-02-01 16:27:06 +08:00
template < typename T >
struct is_proxy_primitive : is_lua_primitive < T > { } ;
template < typename T >
struct is_proxy_primitive < std : : reference_wrapper < T > > : std : : true_type { } ;
2016-02-09 16:38:11 +08:00
template < typename . . . Args >
struct is_proxy_primitive < std : : tuple < Args . . . > > : std : : true_type { } ;
2016-02-17 10:22:07 +08:00
template < typename T >
inline type type_of ( ) {
2016-02-24 12:39:46 +08:00
return lua_type_of < meta : : Unqualified < T > > : : value ;
2016-02-17 10:22:07 +08:00
}
inline type type_of ( lua_State * L , int index ) {
return static_cast < type > ( lua_type ( L , index ) ) ;
}
2013-11-25 17:56:27 +08:00
} // sol
2014-05-31 07:10:08 +08:00
# endif // SOL_TYPES_HPP