⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 class.hpp

📁 魔兽世界的私服源程序
💻 HPP
📖 第 1 页 / 共 3 页
字号:
		// destructive copy
		virtual luabind::detail::scoped_object* clone()
		{
			assert(m_cloned == false);

#ifndef NDEBUG
			m_cloned = true;
#endif

			class_base* ret = new class_base(m_name);

			std::swap(ret->m_getters, m_getters);
			std::swap(ret->m_setters, m_setters);

			for(int i = 0; i < detail::number_of_operators; ++i)
				std::swap(ret->m_operators[i], m_operators[i]);
	
			std::swap(ret->m_static_constants, m_static_constants);

			ret->init(m_type
				, m_holder_type
				, m_extractor
				, m_const_extractor
				, m_const_converter
				, m_construct_holder
				, m_construct_const_holder
				, m_destructor
				, m_const_holder_destructor
				, m_holder_size
				, m_holder_alignment);

			ret->m_const_holder_type = m_const_holder_type;

			std::swap(ret->m_bases, m_bases);
			std::swap(ret->m_methods, m_methods);
			m_constructor.swap(ret->m_constructor);

			ret->m_name = m_name;

#ifndef LUABIND_DONT_COPY_STRINGS
			std::swap(ret->m_strings, m_strings);
#endif

			return ret;
		}

	};











	// registers a class in the lua environment
	template<class T, class X1, class X2, class X3>
	struct class_: class_base 
	{
		typedef class_<T, X1, X2, X3> self_t;

		lua_State* m_L;

	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::_>
	/*		,	boost::mpl::not_<
						boost::mpl::or_<
								detail::is_bases<boost::mpl::_>
							,	boost::is_base_and_derived<boost::mpl::_, T>
						>
				>*/
				,	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
	
		// this is the internal version of def() it is run from both overloads
		// of def. It has two versions, one where a contstructor is registered
		// and one where a function is registered
		template<class Policies>
		struct internal_def_s
		{
			template<class F>
			static void apply(const char* name, F f, class_base* c)
			{
//				std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";

				detail::overload_rep o(f, static_cast<Policies*>(0));

				typedef LUABIND_MSVC_TYPENAME detail::function_callback_s<HeldType,T,F,Policies>::type call_t;

				o.set_match_fun(&detail::match_function_callback_s<T,F,Policies>::apply);
				o.call_fun = boost::bind<int>(call_t(f), _1, _2);

#ifndef LUABIND_NO_ERROR_CHECKING

				o.set_sig_fun(&detail::get_member_signature<F>::apply);

#endif

				c->add_method(name, o);
			}

			template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
			static void apply(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>, class_base* c)
			{
//				std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";

				detail::construct_rep::overload_t o;

				o.set_constructor(
					&detail::construct_class<
						 T
						,Policies
						,constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
					>::apply
				);

				// if we have a WrappedType, we have to register it's constructor
				// but if it's null_type (no WrappedType) we should not register it
				detail::register_wrapped_type<WrappedType>::apply(o,
						static_cast<const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>*>(0),
						static_cast<const Policies*>(0));


				o.set_match_fun(
					&detail::constructor_match<
						 constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
						,2
						,Policies
					>::apply);

#ifndef LUABIND_NO_ERROR_CHECKING

				o.set_sig_fun(&detail::get_signature<constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> >::apply);

#endif

				typedef constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> con_t;

				o.set_arity(detail::calc_arity<con_t::arity>::apply(con_t(), static_cast<Policies*>(0)));

				c->add_constructor(o);
			}
		};

		class_(lua_State* L, const char* name): class_base(name), m_L(L) { init(); }
		class_(const char* name): class_base(name), m_L(0) { init(); }

		~class_()
		{
			if (m_L != 0)
			{
				scope::init(m_L);
				lua_pushvalue(m_L, LUA_GLOBALSINDEX);
				scope_stack::push(m_L);
				commit(m_L);
				scope_stack::pop(m_L);
			}
		}

		template<class F>
		class_& def(const char* name, F f)
		{
			internal_def_s<detail::null_type>::apply(name, f, this);
			return *this;
		}

		template<class F, class Policies>
		class_& def(const char* name, F f, const Policies&)
		{
			internal_def_s<Policies>::apply(name, f, this);
			return *this;
		}

		template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
		class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
		{
			internal_def_s<detail::null_type>::apply(sig, this);
			return *this;
		}

		template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
		class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
		{
			internal_def_s<Policies>::apply(sig, this);
			return *this;
		}

		template<class Getter>
		class_& property(const char* name, Getter g)
		{
			add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
			return *this;
		}

		template<class Getter, class MaybeSetter>
		class_& property(const char* name, Getter g, MaybeSetter s)
		{
			return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
		}

		template<class Getter, class Setter, class GetPolicies>
		class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
		{
			add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
			add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
			return *this;
		}

		template<class Getter, class Setter, class GetPolicies, class SetPolicies>
		class_& property(const char* name
									, Getter g, Setter s
									, const GetPolicies& get_policies
									, const SetPolicies& set_policies)
		{
			add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
			add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, GetPolicies>(set_policies), _1, _2, s));
			return *this;
		}

		template<class D>
		class_& def_readonly(const char* name, D T::*member_ptr)
		{
			add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
			return *this;
		}

		template<class D, class Policies>
		class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
		{
			add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
			return *this;
		}

		template<class D>
		class_& def_readwrite(const char* name, D T::*member_ptr)
		{
			add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
			add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
			return *this;
		}

		template<class D, class GetPolicies>
		class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
		{
			add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
			add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
			return *this;
		}

		template<class D, class GetPolicies, class SetPolicies>
		class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
		{
			add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
			add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
			return *this;
		}

		template<class op_id, class Left, class Right, class Policies>
		class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
		{
			typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
#ifndef LUABIND_NO_ERROR_CHECKING
			add_operator(op_type::get_id()
									, &op_type::execute
									, &op_type::match
									, &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
									, detail::is_unary(op_type::get_id()) ? 1 : 2);
#else
			add_operator(op_type::get_id()
									, &op_type::execute
									, &op_type::match
									, detail::is_unary(op_type::get_id()) ? 1 : 2);
#endif
			return *this;
		}

		template<class op_id, class Left, class Right>
		class_& def(detail::operator_<op_id, Left, Right>)
		{
			typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;

#ifndef LUABIND_NO_ERROR_CHECKING
			add_operator(op_type::get_id()
									, &op_type::execute
									, &op_type::match
									, &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
									, detail::is_unary(op_type::get_id()) ? 1 : 2);
#else
			add_operator(op_type::get_id()
									, &op_type::execute
									, &op_type::match
									, detail::is_unary(op_type::get_id()) ? 1 : 2);
#endif
			return *this;
		}

		template<class Signature, bool Constant>
		class_& def(detail::application_operator<Signature, Constant>*)
		{
			typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;

			int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<detail::null_type*>(0));

#ifndef LUABIND_NO_ERROR_CHECKING
			add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
#else
			add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
#endif

			return *this;
		}

		template<class Signature, bool Constant, class Policies>
		class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
		{
			typedef detail::application_operator<Signature, Constant, Policies> op_t;

			int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));

#ifndef LUABIND_NO_ERROR_CHECKING
			add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
#else
			add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
#endif

			return *this;
		}

		detail::enum_maker<self_t> enum_(const char*)
		{
			return detail::enum_maker<self_t>(*this);
		}

	private:

		void init()
		{
			typedef typename detail::extract_parameter<
					boost::mpl::list3<X1,X2,X3>
				,	boost::mpl::or_<
							detail::is_bases<boost::mpl::_>
						,	boost::is_base_and_derived<boost::mpl::_, T>
					>
				,	no_bases
			>::type bases_t;

			typedef typename 
				boost::mpl::if_<detail::is_bases<bases_t>
					,	bases_t
					,	bases<bases_t>
				>::type Base;
	
			HeldType* crap = 0;

			class_base::init(LUABIND_TYPEID(T)
				, detail::internal_holder_type<HeldType>::apply()
				, detail::internal_holder_extractor<HeldType>::apply(detail::type<T>())
				, detail::internal_const_holder_extractor<HeldType>::apply(detail::type<T>())
				, detail::const_converter<HeldType>::apply(luabind::get_const_holder(crap))
				, detail::holder_constructor<HeldType>::apply(detail::type<T>())
				, detail::const_holder_constructor<HeldType>::apply(detail::type<T>())
				, detail::internal_holder_destructor<HeldType>::apply(detail::type<T>())
				, detail::internal_const_holder_destructor<HeldType>::apply(detail::type<T>())
				, detail::internal_holder_size<HeldType>::apply()
				, detail::get_holder_alignment<HeldType>::apply());

			set_const_holder_type(luabind::get_const_holder(static_cast<HeldType*>(0)));

			generate_baseclass_list(detail::type<Base>());
		}

		template<class Getter, class GetPolicies>
		class_& property_impl(const char* name,
									 Getter g,
									 GetPolicies policies,
									 boost::mpl::bool_<true>)
		{
			add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
			return *this;
		}

		template<class Getter, class Setter>
		class_& property_impl(const char* name,
									 Getter g,
									 Setter s,
									 boost::mpl::bool_<false>)
		{
			add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
			add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
			return *this;
		}

	};
}

#endif // LUABIND_CLASS_HPP_INCLUDED

⌨️ 快捷键说明

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