class.hpp

来自「这是整套横扫千军3D版游戏的源码」· HPP 代码 · 共 1,342 行 · 第 1/3 页

HPP
1,342
字号

		template<>
		struct holder_constructor<detail::null_type>
		{
			typedef void(*constructor)(void*,void*);
			template<class T>
			static constructor apply(detail::type_<T>)
			{
				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<class HolderType>
		struct const_holder_constructor
		{
			typedef void(*constructor)(void*,void*);
			template<class T>
			static constructor apply(detail::type_<T>)
			{
				return get_const_holder_constructor(detail::type_<T>(), get_const_holder(static_cast<HolderType*>(0)));
			}

		private:

			template<class T, class ConstHolderType>
			static constructor get_const_holder_constructor(detail::type_<T>, ConstHolderType*)
			{
				return &internal_construct_holder<ConstHolderType, T>::apply;
			}
		};

		template<>
		struct const_holder_constructor<detail::null_type>
		{
			typedef void(*constructor)(void*,void*);
			template<class T>
			static constructor apply(detail::type_<T>)
			{
				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<class HeldType>
		struct holder_default_constructor
		{
			typedef void(*constructor)(void*);
			template<class T>
			static constructor apply(detail::type_<T>)
			{
				return &internal_default_construct_holder<HeldType, T>::apply;
			}
		};

		template<>
		struct holder_default_constructor<detail::null_type>
		{
			typedef void(*constructor)(void*);
			template<class T>
			static constructor apply(detail::type_<T>)
			{
				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<class HolderType>
		struct const_holder_default_constructor
		{
			typedef void(*constructor)(void*);
			template<class T>
			static constructor apply(detail::type_<T>)
			{
				return get_const_holder_default_constructor(detail::type_<T>(), get_const_holder(static_cast<HolderType*>(0)));
			}

		private:

			template<class T, class ConstHolderType>
			static constructor get_const_holder_default_constructor(detail::type_<T>, ConstHolderType*)
			{
				return &internal_default_construct_holder<ConstHolderType, T>::apply;
			}
		};

		template<>
		struct const_holder_default_constructor<detail::null_type>
		{
			typedef void(*constructor)(void*);
			template<class T>
			static constructor apply(detail::type_<T>)
			{
				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 <class HolderType>
		struct internal_holder_size
		{
			static int apply() { return get_internal_holder_size(get_const_holder(static_cast<HolderType*>(0))); }
		private:
			template<class ConstHolderType>
			static int get_internal_holder_size(ConstHolderType*)
			{
				return max_c<sizeof(HolderType), sizeof(ConstHolderType)>::value;
			}
		};

		template <>
		struct internal_holder_size<detail::null_type>
		{
			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<class HeldType>
		struct internal_holder_destructor
		{
			typedef void(*destructor_t)(void*);
			template<class T>
			static destructor_t apply(detail::type_<T>)
			{
				return &detail::destruct_only_s<HeldType>::apply;
			}
		};

		// if we don't have a held type, return the destructor of the raw type
		template<>
		struct internal_holder_destructor<detail::null_type>
		{
			typedef void(*destructor_t)(void*);
			template<class T>
			static destructor_t apply(detail::type_<T>)
			{
				return &detail::delete_s<T>::apply;
			}
		};

		
		// if we have a held type, return the destructor to it's const version
		template<class HolderType>
		struct internal_const_holder_destructor
		{
			typedef void(*destructor_t)(void*);
			template<class T>
			static destructor_t apply(detail::type_<T>)
			{
				return const_holder_type_destructor(get_const_holder(static_cast<HolderType*>(0)));
			}

		private:

			template<class ConstHolderType>
			static destructor_t const_holder_type_destructor(ConstHolderType*)
			{
				return &detail::destruct_only_s<ConstHolderType>::apply;
			}

		};

		// if we don't have a held type, return the destructor of the raw type
		template<>
		struct internal_const_holder_destructor<detail::null_type>
		{
			typedef void(*destructor_t)(void*);
			template<class T>
			static destructor_t apply(detail::type_<T>)
			{
				return 0;
			}
		};




		template<class HolderType>
		struct get_holder_alignment
		{
			static int apply()
			{
				return internal_alignment(get_const_holder(static_cast<HolderType*>(0)));
			}

		private:

			template<class ConstHolderType>
			static int internal_alignment(ConstHolderType*)
			{
				return detail::max_c<boost::alignment_of<HolderType>::value
					, boost::alignment_of<ConstHolderType>::value>::value;
			}
		};

		template<>
		struct get_holder_alignment<detail::null_type>
		{
			static int apply()
			{
				return 1;
			}
		};


	} // detail

	namespace detail {

		template<class T>
		struct static_scope
		{
			static_scope(T& self_) : self(self_)
			{
			}

			T& operator[](scope s) const
			{
				self.add_inner_scope(s);
				return self;
			}

		private:
			template<class U> 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<int, lua_State*, int>& g);

#ifdef LUABIND_NO_ERROR_CHECKING
			void add_setter(
				const char* name
				, const boost::function2<int, lua_State*, int>& s);
#else
			void add_setter(
				const char* name
				, const boost::function2<int, lua_State*, int>& 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<class T, class W>
        struct adopt_function
		{
		    static void execute(void* p)
            {
			    wrapped_self_t& self = wrap_access::ref(
					*static_cast<W*>(static_cast<T*>(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<class T, class X1, class X2, class X3>
	struct class_: detail::class_base 
	{
		typedef class_<T, X1, X2, X3> self_t;

	private:

		template<class A, class B, class C, class D>
		class_(const class_<A,B,C,D>&);

	public:

		// WrappedType MUST inherit from T
		typedef typename detail::extract_parameter<
		    boost::mpl::vector3<X1,X2,X3>
		  , boost::is_base_and_derived<T, boost::mpl::_>
		  , detail::null_type
		>::type WrappedType;

		typedef typename detail::extract_parameter<
		    boost::mpl::list3<X1,X2,X3>
		  , boost::mpl::not_<
		        boost::mpl::or_<
				    boost::mpl::or_<
					    detail::is_bases<boost::mpl::_>
					  , boost::is_base_and_derived<boost::mpl::_, T>
					>
				  , boost::is_base_and_derived<T, boost::mpl::_>
				>
			>
		  , 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<class To>
		void gen_base_info(detail::type_<To>)
		{
			// 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_<T>(), detail::type_<To>());
			add_base(base);
		}

		void gen_base_info(detail::type_<detail::null_type>)
		{}

#define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<B##n>());

		template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
		void generate_baseclass_list(detail::type_<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
		{
			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 F>
		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 F, class DefaultOrPolicies>
		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<DefaultOrPolicies>::type());
		}

		template<class F, class Default, class Policies>
		class_& def(char const* name, F fn
			, Default default_, Policies const& policies)
		{
			return this->virtual_def(
				name, fn, default_
			  , policies, boost::mpl::false_());
		}

		template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
		class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
		{
            return this->def_constructor(
				boost::is_same<WrappedType, detail::null_type>()
			  , &sig
			  , detail::null_type()
			);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?