x
Yes
No
Do you want to visit DriveHQ English website?
Inicio
Características
Precios
Prueba gratuita
Software cliente
Acerca de nosotros
Servidor de archivos
|
Solución de copias de seguridad
|
Servidor FTP
|
Servidor de correo electrónico
|
Alojamiento web
|
Software cliente
Servidor de archivos
Solución de copia de seguridad
Servidor FTP
Servidor de correo electrónico
Alojamiento web
Software cliente
class.hpp - Hosted on DriveHQ Cloud IT Platform
Arriba
Subir
Descargar
Compartir
Publicar
Nueva carpeta
Nuevo archivo
Copiar
Cortar
Eliminar
Pegar
Clasificación
Actualizar
Ruta de la carpeta: \\game3dprogramming\materials\GameFactory\GameFactoryDemo\references\luabind\luabind\class.hpp
Girar
Efecto
Propiedad
Historial
// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // 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 LUABIND_CLASS_HPP_INCLUDED #define LUABIND_CLASS_HPP_INCLUDED /* ISSUES: ------------------------------------------------------ * solved for member functions, not application operator * if we have a base class that defines a function a derived class must be able to override that function (not just overload). Right now we just add the other overload to the overloads list and will probably get an ambiguity. If we want to support this each method_rep must include a vector of type_info pointers for each parameter. Operators do not have this problem, since operators always have to have it's own type as one of the arguments, no ambiguity can occur. Application operator, on the other hand, would have this problem. Properties cannot be overloaded, so they should always be overridden. If this is to work for application operator, we really need to specify if an application operator is const or not. If one class registers two functions with the same name and the same signature, there's currently no error. The last registered function will be the one that's used. How do we know which class registered the function? If the function was defined by the base class, it is a legal operation, to override it. we cannot look at the pointer offset, since it always will be zero for one of the bases. TODO: ------------------------------------------------------ finish smart pointer support * the adopt policy should not be able to adopt pointers to held_types. This must be prohibited. * name_of_type must recognize holder_types and not return "custom" document custom policies, custom converters store the instance object for policies. support the __concat metamethod. This is a bit tricky, since it cannot be treated as a normal operator. It is a binary operator but we want to use the __tostring implementation for both arguments. */ #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// to remove the 'this' used in initialization list-warning #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4355) #endif namespace luabind { namespace detail { struct unspecified {}; template
struct operator_; struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {}; } template
struct class_; // TODO: this function will only be invoked if the user hasn't defined a correct overload // maybe we should have a static assert in here? inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr* get_const_holder(...) { return 0; } namespace detail { template
double is_bases_helper(const bases
&); #ifndef BOOST_MSVC template
char is_bases_helper(const T&); #else char is_bases_helper(...); #endif template
struct is_bases { static const T& t; BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double)); typedef boost::mpl::bool_
type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T)) }; double is_not_unspecified_helper(const unspecified*); char is_not_unspecified_helper(...); template
struct is_not_unspecified { BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast
(0))) == sizeof(char)); typedef boost::mpl::bool_
type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T)) }; template
struct get_predicate { typedef typename boost::mpl::and_< is_not_unspecified
, Predicate > type; }; template
struct extract_parameter { typedef typename get_predicate
::type pred; typedef typename boost::mpl::find_if
::type iterator; typedef typename boost::mpl::eval_if< boost::is_same< iterator , typename boost::mpl::end
::type > , boost::mpl::identity
, boost::mpl::deref
>::type type; }; template
struct mem_fn_callback { typedef int result_type; int operator()(lua_State* L) const { return call(fn, (Class*)0, L, (Policies*)0); } mem_fn_callback(Fn fn_) : fn(fn_) { } Fn fn; }; template
struct mem_fn_matcher { typedef int result_type; int operator()(lua_State* L) const { return match(fn, L, (Class*)0, (Policies*)0); } mem_fn_matcher(Fn fn_) : fn(fn_) { } Fn fn; }; struct pure_virtual_tag { static void precall(lua_State*, index_map const&) {} static void postcall(lua_State*, index_map const&) {} }; template
struct has_pure_virtual { typedef typename boost::mpl::eval_if< boost::is_same
, boost::mpl::true_ , has_pure_virtual
>::type type; BOOST_STATIC_CONSTANT(bool, value = type::value); }; template<> struct has_pure_virtual
{ BOOST_STATIC_CONSTANT(bool, value = false); typedef boost::mpl::bool_
type; }; // prints the types of the values on the stack, in the // range [start_index, lua_gettop()] LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); struct LUABIND_API create_class { static int stage1(lua_State* L); static int stage2(lua_State* L); }; // if the class is held by a smart pointer, we need to be able to // implicitly dereference the pointer when needed. template
struct extract_underlying_type { static void* extract(void* ptr) { HeldT& held_obj = *reinterpret_cast
(ptr); UnderlyingT* underlying_ptr = static_cast
(get_pointer(held_obj)); return underlying_ptr; } }; template
struct extract_underlying_const_type { static const void* extract(void* ptr) { HeldT& held_obj = *reinterpret_cast
(ptr); const UnderlyingT* underlying_ptr = static_cast
(get_pointer(held_obj)); return underlying_ptr; } }; template
struct internal_holder_extractor { typedef void*(*extractor_fun)(void*); template
static extractor_fun apply(detail::type_
) { return &detail::extract_underlying_type
::extract; } }; template<> struct internal_holder_extractor
{ typedef void*(*extractor_fun)(void*); template
static extractor_fun apply(detail::type_
) { return 0; } }; template
struct convert_holder { static void apply(void* holder, void* target) { new(target) ConstHolderType(*reinterpret_cast
(holder)); }; }; template
struct const_converter { typedef void(*converter_fun)(void*, void*); template
static converter_fun apply(ConstHolderType*) { return &detail::convert_holder
::apply; } }; template<> struct const_converter
{ typedef void(*converter_fun)(void*, void*); template
static converter_fun apply(T*) { return 0; } }; template
struct internal_const_holder_extractor { typedef const void*(*extractor_fun)(void*); template
static extractor_fun apply(detail::type_
) { return get_extractor(detail::type_
(), get_const_holder(static_cast
(0))); } private: template
static extractor_fun get_extractor(detail::type_
, ConstHolderType*) { return &detail::extract_underlying_const_type
::extract; } }; template<> struct internal_const_holder_extractor
{ typedef const void*(*extractor_fun)(void*); template
static extractor_fun apply(detail::type_
) { return 0; } }; // this is simply a selector that returns the type_info // of the held type, or invalid_type_info if we don't have // a held_type template
struct internal_holder_type { static LUABIND_TYPE_INFO apply() { return LUABIND_TYPEID(HeldType); } }; template<> struct internal_holder_type
{ static LUABIND_TYPE_INFO apply() { return LUABIND_INVALID_TYPE_INFO; } }; // this is the actual held_type constructor template
struct internal_construct_holder { static void apply(void* target, void* raw_pointer) { new(target) HeldType(static_cast
(raw_pointer)); } }; // this is the actual held_type default constructor template
struct internal_default_construct_holder { static void apply(void* target) { new(target) HeldType(); } }; // the following two functions are the ones that returns // a pointer to a held_type_constructor, or 0 if there // is no held_type template
struct holder_constructor { typedef void(*constructor)(void*,void*); template
static constructor apply(detail::type_
) { return &internal_construct_holder
::apply; } }; template<> struct holder_constructor
{ typedef void(*constructor)(void*,void*); template
static constructor apply(detail::type_
) { return 0; } }; // the following two functions are the ones that returns // a pointer to a const_held_type_constructor, or 0 if there // is no held_type template
struct const_holder_constructor { typedef void(*constructor)(void*,void*); template
static constructor apply(detail::type_
) { return get_const_holder_constructor(detail::type_
(), get_const_holder(static_cast
(0))); } private: template
static constructor get_const_holder_constructor(detail::type_
, ConstHolderType*) { return &internal_construct_holder
::apply; } }; template<> struct const_holder_constructor
{ typedef void(*constructor)(void*,void*); template
static constructor apply(detail::type_
) { return 0; } }; // the following two functions are the ones that returns // a pointer to a held_type_constructor, or 0 if there // is no held_type. The holder_type is default constructed template
struct holder_default_constructor { typedef void(*constructor)(void*); template
static constructor apply(detail::type_
) { return &internal_default_construct_holder
::apply; } }; template<> struct holder_default_constructor
{ typedef void(*constructor)(void*); template
static constructor apply(detail::type_
) { return 0; } }; // the following two functions are the ones that returns // a pointer to a const_held_type_constructor, or 0 if there // is no held_type. The constructed held_type is default // constructed template
struct const_holder_default_constructor { typedef void(*constructor)(void*); template
static constructor apply(detail::type_
) { return get_const_holder_default_constructor(detail::type_
(), get_const_holder(static_cast
(0))); } private: template
static constructor get_const_holder_default_constructor(detail::type_
, ConstHolderType*) { return &internal_default_construct_holder
::apply; } }; template<> struct const_holder_default_constructor
{ typedef void(*constructor)(void*); template
static constructor apply(detail::type_
) { return 0; } }; // this is a selector that returns the size of the held_type // or 0 if we don't have a held_type template
struct internal_holder_size { static int apply() { return get_internal_holder_size(get_const_holder(static_cast
(0))); } private: template
static int get_internal_holder_size(ConstHolderType*) { return max_c
::value; } }; template <> struct internal_holder_size
{ static int apply() { return 0; } }; // if we have a held type, return the destructor to it // note the difference. The held_type should only be destructed (not deleted) // since it's constructed in the lua userdata template
struct internal_holder_destructor { typedef void(*destructor_t)(void*); template
static destructor_t apply(detail::type_
) { return &detail::destruct_only_s
::apply; } }; // if we don't have a held type, return the destructor of the raw type template<> struct internal_holder_destructor
{ typedef void(*destructor_t)(void*); template
static destructor_t apply(detail::type_
) { return &detail::delete_s
::apply; } }; // if we have a held type, return the destructor to it's const version template
struct internal_const_holder_destructor { typedef void(*destructor_t)(void*); template
static destructor_t apply(detail::type_
) { return const_holder_type_destructor(get_const_holder(static_cast
(0))); } private: template
static destructor_t const_holder_type_destructor(ConstHolderType*) { return &detail::destruct_only_s
::apply; } }; // if we don't have a held type, return the destructor of the raw type template<> struct internal_const_holder_destructor
{ typedef void(*destructor_t)(void*); template
static destructor_t apply(detail::type_
) { return 0; } }; template
struct get_holder_alignment { static int apply() { return internal_alignment(get_const_holder(static_cast
(0))); } private: template
static int internal_alignment(ConstHolderType*) { return detail::max_c
::value , boost::alignment_of
::value>::value; } }; template<> struct get_holder_alignment
{ static int apply() { return 1; } }; } // detail namespace detail { template
struct static_scope { static_scope(T& self_) : self(self_) { } T& operator[](scope s) const { self.add_inner_scope(s); return self; } private: template
void operator,(U const&) const; void operator=(static_scope const&); T& self; }; struct class_registration; struct LUABIND_API class_base : scope { public: class_base(char const* name); struct base_desc { LUABIND_TYPE_INFO type; int ptr_offset; }; void init( LUABIND_TYPE_INFO type , LUABIND_TYPE_INFO holder_type , LUABIND_TYPE_INFO const_holder_type , void*(*extractor)(void*) , const void*(*const_extractor)(void*) , void(*const_converter)(void*,void*) , void(*holder_constructor)(void*,void*) , void(*const_holder_constructor)(void*,void*) , void(*holder_default_constructor)(void*) , void(*const_holder_default_constructor)(void*) , void(*destructor)(void*) , void(*const_holder_destructor)(void*) , void(*m_adopt_fun)(void*) , int holder_size , int holder_alignment); void add_getter( const char* name , const boost::function2
& g); #ifdef LUABIND_NO_ERROR_CHECKING void add_setter( const char* name , const boost::function2
& s); #else void add_setter( const char* name , const boost::function2
& s , int (*match)(lua_State*, int) , void (*get_sig_ptr)(lua_State*, std::string&)); #endif void add_base(const base_desc& b); void add_constructor(const detail::construct_rep::overload_t& o); void add_method(const char* name, const detail::overload_rep& o); #ifndef LUABIND_NO_ERROR_CHECKING void add_operator( int op_id , int(*func)(lua_State*) , int(*matcher)(lua_State*) , void(*sig)(lua_State* , std::string&) , int arity); #else void add_operator( int op_id , int(*func)(lua_State*) , int(*matcher)(lua_State*) , int arity); #endif const char* name() const; void add_static_constant(const char* name, int val); void add_inner_scope(scope& s); private: class_registration* m_registration; }; template
struct adopt_function { static void execute(void* p) { wrapped_self_t& self = wrap_access::ref( *static_cast
(static_cast
(p)) ); LUABIND_CHECK_STACK(self.state()); self.get(self.state()); self.m_strong_ref.set(self.state()); } }; } // namespace detail // registers a class in the lua environment template
struct class_: detail::class_base { typedef class_
self_t; private: template
class_(const class_
&); public: // WrappedType MUST inherit from T typedef typename detail::extract_parameter< boost::mpl::vector3
, boost::is_base_and_derived
, detail::null_type >::type WrappedType; typedef typename detail::extract_parameter< boost::mpl::list3
, boost::mpl::not_< boost::mpl::or_< boost::mpl::or_< detail::is_bases
, boost::is_base_and_derived
> , boost::is_base_and_derived
> > , detail::null_type >::type HeldType; // this function generates conversion information // in the given class_rep structure. It will be able // to implicitly cast to the given template type template
void gen_base_info(detail::type_
) { // fist, make sure the given base class is registered. // if it's not registered we can't push it's lua table onto // the stack because it doesn't have a table // try to cast this type to the base type and remember // the pointer offset. For multiple inheritance the pointer // may change when casting. Since we need to be able to // cast we need this pointer offset. // store the information in this class' base class-vector base_desc base; base.type = LUABIND_TYPEID(To); base.ptr_offset = detail::ptr_offset(detail::type_
(), detail::type_
()); add_base(base); } void gen_base_info(detail::type_
) {} #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_
()); template
void generate_baseclass_list(detail::type_
>) { BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _) } #undef LUABIND_GEN_BASE_INFO class_(const char* name): class_base(name), scope(*this) { #ifndef NDEBUG detail::check_link_compatibility(); #endif init(); } template
class_& def(const char* name, F f) { return this->virtual_def( name, f, detail::null_type() , detail::null_type(), boost::mpl::true_()); } // virtual functions template
class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies) { return this->virtual_def( name, fn, default_or_policies, detail::null_type() , LUABIND_MSVC_TYPENAME detail::is_policy_cons
::type()); } template
class_& def(char const* name, F fn , Default default_, Policies const& policies) { return this->virtual_def( name, fn, default_ , policies, boost::mpl::false_()); } template
class_& def(constructor
sig) { return this->def_constructor( boost::is_same
() , &sig , detail::null_type() ); } template
class_& def(constructor
sig, const Policies& policies) { return this->def_constructor( boost::is_same
() , &sig , policies ); } template
class_& property(const char* name, Getter g) { add_getter(name, boost::bind
(detail::get_caller
(), _1, _2, g)); return *this; } template
class_& property(const char* name, Getter g, MaybeSetter s) { return property_impl(name, g, s, boost::mpl::bool_
::value>()); } template
class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies) { add_getter(name, boost::bind
(detail::get_caller
(get_policies), _1, _2, g)); #ifndef LUABIND_NO_ERROR_CHECKING add_setter( name , boost::bind
(detail::set_caller
(), _1, _2, s) , detail::gen_set_matcher((Setter)0, (detail::null_type*)0) , &detail::get_member_signature
::apply); #else add_setter( name , boost::bind
(detail::set_caller
(), _1, _2, s)); #endif return *this; } template
class_& property(const char* name , Getter g, Setter s , const GetPolicies& get_policies , const SetPolicies& set_policies) { add_getter(name, boost::bind
(detail::get_caller
(get_policies), _1, _2, g)); #ifndef LUABIND_NO_ERROR_CHECKING add_setter( name , boost::bind
(detail::set_caller
(), _1, _2, s) , detail::gen_set_matcher((Setter)0, (SetPolicies*)0) , &detail::get_member_signature
::apply); #else add_setter(name, boost::bind
(detail::set_caller
(set_policies), _1, _2, s)); #endif return *this; } template
class_& def_readonly(const char* name, D T::*member_ptr) { add_getter(name, boost::bind
(detail::auto_get
(), _1, _2, member_ptr)); return *this; } template
class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies) { add_getter(name, boost::bind
(detail::auto_get
(policies), _1, _2, member_ptr)); return *this; } template
class_& def_readwrite(const char* name, D T::*member_ptr) { add_getter(name, boost::bind
(detail::auto_get
(), _1, _2, member_ptr)); #ifndef LUABIND_NO_ERROR_CHECKING add_setter( name , boost::bind
(detail::auto_set
(), _1, _2, member_ptr) , &detail::set_matcher
::apply , &detail::get_setter_signature
::apply); #else add_setter(name, boost::bind
(detail::auto_set
(), _1, _2, member_ptr)); #endif return *this; } template
class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies) { add_getter(name, boost::bind
(detail::auto_get
(get_policies), _1, _2, member_ptr)); #ifndef LUABIND_NO_ERROR_CHECKING add_setter( name , boost::bind
(detail::auto_set
(), _1, _2, member_ptr) , &detail::set_matcher