📄 policy.hpp.svn-base
字号:
// 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_POLICY_HPP_INCLUDED#define LUABIND_POLICY_HPP_INCLUDED#include <luabind/config.hpp>#include <typeinfo>#include <string>#include <boost/type_traits/is_enum.hpp>#include <boost/type_traits/is_array.hpp>#include <boost/mpl/bool.hpp>#include <boost/mpl/integral_c.hpp>#include <boost/mpl/equal_to.hpp>#include <boost/mpl/eval_if.hpp>#include <boost/mpl/or.hpp>#include <boost/type_traits/add_reference.hpp>#include <boost/type_traits/is_pointer.hpp>#include <boost/type_traits/is_base_and_derived.hpp>#include <boost/bind/arg.hpp>#include <boost/limits.hpp>#include <boost/tuple/tuple.hpp>#include <boost/version.hpp>#include <luabind/detail/class_registry.hpp>#include <luabind/detail/primitives.hpp>#include <luabind/detail/object_rep.hpp>#include <luabind/detail/typetraits.hpp>#include <luabind/detail/class_cache.hpp>#include <luabind/detail/debug.hpp>#include <luabind/detail/class_rep.hpp>#include <boost/type_traits/add_reference.hpp>#include <luabind/detail/decorate_type.hpp>#include <luabind/weak_ref.hpp>#include <luabind/back_reference_fwd.hpp>#include <luabind/value_wrapper.hpp>#include <luabind/from_stack.hpp>namespace luabind{ namespace detail { struct conversion_policy_base {}; } template<int N, bool HasArg = true> struct conversion_policy : detail::conversion_policy_base { BOOST_STATIC_CONSTANT(int, index = N); BOOST_STATIC_CONSTANT(bool, has_arg = HasArg); }; class index_map { public: index_map(const int* m): m_map(m) {} int operator[](int index) const { return m_map[index]; } private: const int* m_map; }; namespace converters { using luabind::detail::yes_t; using luabind::detail::no_t; using luabind::detail::by_value; using luabind::detail::by_reference; using luabind::detail::by_const_reference; using luabind::detail::by_pointer; using luabind::detail::by_const_pointer; no_t is_user_defined(...); } namespace detail { template<class T> struct is_user_defined { BOOST_STATIC_CONSTANT(bool, value = sizeof(luabind::converters::is_user_defined(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t)); }; LUABIND_API int implicit_cast(const class_rep* crep, LUABIND_TYPE_INFO const&, int& pointer_offset); }// template<class T> class functor; class weak_ref;}namespace luabind { namespace detail{ template<class> struct is_primitive;/* template<class T> yes_t is_lua_functor_test(const functor<T>&);#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) no_t is_lua_functor_test(...);#else template<class T> no_t is_lua_functor_test(const T&);#endif template<class T> struct is_lua_functor { static T t; BOOST_STATIC_CONSTANT(bool, value = sizeof(is_lua_functor_test(t)) == sizeof(yes_t)); };*/ template<class H, class T> struct policy_cons { typedef H head; typedef T tail; template<class U> policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>) { return policy_cons<U, policy_cons<H,T> >(); } template<class U> policy_cons<U, policy_cons<H,T> > operator+(policy_cons<U,detail::null_type>) { return policy_cons<U, policy_cons<H,T> >(); } template<class U> policy_cons<U, policy_cons<H,T> > operator|(policy_cons<U,detail::null_type>) { return policy_cons<U, policy_cons<H,T> >(); } }; struct indirection_layer { template<class T> indirection_layer(const T&); }; yes_t is_policy_cons_test(const null_type&); template<class H, class T> yes_t is_policy_cons_test(const policy_cons<H,T>&); no_t is_policy_cons_test(...); template<class T> struct is_policy_cons { static const T& t; BOOST_STATIC_CONSTANT(bool, value = sizeof(is_policy_cons_test(t)) == sizeof(yes_t)); typedef boost::mpl::bool_<value> type; }; template<bool> struct is_string_literal { static no_t helper(indirection_layer); static yes_t helper(const char*); }; template<> struct is_string_literal<false> { static no_t helper(indirection_layer); }; template<class T> struct is_primitive/*: boost::mpl::bool_c<false>*/ { static T t; BOOST_STATIC_CONSTANT(bool, value = sizeof(is_string_literal<boost::is_array<T>::value>::helper(t)) == sizeof(yes_t)); };#define LUABIND_INTEGER_TYPE(type) \ template<> struct is_primitive<type> : boost::mpl::true_ {}; \ template<> struct is_primitive<type const> : boost::mpl::true_ {}; \ template<> struct is_primitive<type const&> : boost::mpl::true_ {}; \ template<> struct is_primitive<unsigned type> : boost::mpl::true_ {}; \ template<> struct is_primitive<unsigned type const> : boost::mpl::true_ {}; \ template<> struct is_primitive<unsigned type const&> : boost::mpl::true_ {}; LUABIND_INTEGER_TYPE(char) LUABIND_INTEGER_TYPE(short) LUABIND_INTEGER_TYPE(int) LUABIND_INTEGER_TYPE(long) template<> struct is_primitive<signed char> : boost::mpl::true_ {}; \ template<> struct is_primitive<signed char const> : boost::mpl::true_ {}; \ template<> struct is_primitive<signed char const&> : boost::mpl::true_ {}; \ #undef LUABIND_INTEGER_TYPE template<> struct is_primitive<luabind::weak_ref>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const luabind::weak_ref>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const luabind::weak_ref&>: boost::mpl::bool_<true> {}; template<> struct is_primitive<float>: boost::mpl::bool_<true> {}; template<> struct is_primitive<double>: boost::mpl::bool_<true> {}; template<> struct is_primitive<long double>: boost::mpl::bool_<true> {}; template<> struct is_primitive<char*>: boost::mpl::bool_<true> {}; template<> struct is_primitive<bool>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const float>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const double>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const long double>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const char*>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const char* const>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const bool>: boost::mpl::bool_<true> {}; // TODO: add more template<> struct is_primitive<const float&>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const double&>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const long double&>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const bool&>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const std::string&>: boost::mpl::bool_<true> {}; template<> struct is_primitive<std::string>: boost::mpl::bool_<true> {}; template<> struct is_primitive<const std::string>: boost::mpl::bool_<true> {}; template<class Direction> struct primitive_converter; template<> struct primitive_converter<cpp_to_lua> { typedef boost::mpl::bool_<false> is_value_converter; typedef primitive_converter type; void apply(lua_State* L, int v) { lua_pushnumber(L, (lua_Number)v); } void apply(lua_State* L, short v) { lua_pushnumber(L, (lua_Number)v); } void apply(lua_State* L, char v) { lua_pushnumber(L, (lua_Number)v); } void apply(lua_State* L, long v) { lua_pushnumber(L, (lua_Number)v); } void apply(lua_State* L, unsigned int v) { lua_pushnumber(L, (lua_Number)v); } void apply(lua_State* L, unsigned short v) { lua_pushnumber(L, (lua_Number)v); } void apply(lua_State* L, unsigned char v) { lua_pushnumber(L, (lua_Number)v); } void apply(lua_State* L, unsigned long v) { lua_pushnumber(L, (lua_Number)v); } void apply(lua_State* L, float v) { lua_pushnumber(L, (lua_Number)v); } void apply(lua_State* L, double v) { lua_pushnumber(L, (lua_Number)v); } void apply(lua_State* L, long double v) { lua_pushnumber(L, (lua_Number)v); } void apply(lua_State* L, const char* v) { if (v) { lua_pushstring(L, v); } else { lua_pushnil(L); } } void apply(lua_State* L, const std::string& v) { lua_pushlstring(L, v.data(), v.size()); } void apply(lua_State* L, bool b) { lua_pushboolean(L, b); } }; template<> struct primitive_converter<lua_to_cpp> { typedef boost::mpl::bool_<false> is_value_converter; typedef primitive_converter type; #define PRIMITIVE_CONVERTER(prim) \ prim apply(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \ prim apply(lua_State* L, luabind::detail::by_value<const prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \ prim apply(lua_State* L, luabind::detail::by_value<prim>, int index) #define PRIMITIVE_MATCHER(prim) \ static int match(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return match(L, detail::by_value<prim>(), index); } \ static int match(lua_State* L, luabind::detail::by_value<const prim>, int index) { return match(L, detail::by_value<prim>(), index); } \ static int match(lua_State* L, luabind::detail::by_value<prim>, int index) PRIMITIVE_CONVERTER(bool) { return lua_toboolean(L, index) == 1; } PRIMITIVE_MATCHER(bool) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1; } PRIMITIVE_CONVERTER(int) { return static_cast<int>(lua_tonumber(L, index)); } PRIMITIVE_MATCHER(int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; } PRIMITIVE_CONVERTER(unsigned int) { return static_cast<unsigned int>(lua_tonumber(L, index)); } PRIMITIVE_MATCHER(unsigned int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; } PRIMITIVE_CONVERTER(char) { return static_cast<char>(lua_tonumber(L, index)); } PRIMITIVE_MATCHER(char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; } PRIMITIVE_CONVERTER(signed char) { return static_cast<char>(lua_tonumber(L, index)); } PRIMITIVE_MATCHER(signed char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; } PRIMITIVE_CONVERTER(unsigned char) { return static_cast<unsigned char>(lua_tonumber(L, index)); } PRIMITIVE_MATCHER(unsigned char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; } PRIMITIVE_CONVERTER(short) { return static_cast<short>(lua_tonumber(L, index)); } PRIMITIVE_MATCHER(short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; } PRIMITIVE_CONVERTER(unsigned short) { return static_cast<unsigned short>(lua_tonumber(L, index)); } PRIMITIVE_MATCHER(unsigned short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; } PRIMITIVE_CONVERTER(long) { return static_cast<long>(lua_tonumber(L, index)); } PRIMITIVE_MATCHER(long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; } PRIMITIVE_CONVERTER(unsigned long) { return static_cast<unsigned long>(lua_tonumber(L, index)); } PRIMITIVE_MATCHER(unsigned long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; } PRIMITIVE_CONVERTER(float) { return static_cast<float>(lua_tonumber(L, index)); } PRIMITIVE_MATCHER(float) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; } PRIMITIVE_CONVERTER(double) { return static_cast<double>(lua_tonumber(L, index)); } PRIMITIVE_MATCHER(double) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; } PRIMITIVE_CONVERTER(lua_State*) { return lua_tothread(L, index); } PRIMITIVE_MATCHER(lua_State*) { if (lua_type(L, index) == LUA_TTHREAD) return 0; else return -1; } PRIMITIVE_CONVERTER(std::string) { return std::string(lua_tostring(L, index), lua_strlen(L, index)); } PRIMITIVE_MATCHER(std::string) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1; } PRIMITIVE_CONVERTER(luabind::weak_ref) { LUABIND_CHECK_STACK(L); return luabind::weak_ref(L, index); } PRIMITIVE_MATCHER(luabind::weak_ref) { (void)index; (void)L; return (std::numeric_limits<int>::max)() - 1; } const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); } const char* apply(lua_State* L, detail::by_const_pointer<const char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); } static int match(lua_State* L, by_const_pointer<char>, int index) { return lua_type(L, index) == LUA_TSTRING || lua_isnil(L, index) ? 0 : -1; } static int match(lua_State* L, by_const_pointer<const char>, int index) { return lua_type(L, index) == LUA_TSTRING || lua_isnil(L, index) ? 0 : -1; } template<class T> void converter_postcall(lua_State*, T, int) {} #undef PRIMITIVE_MATCHER #undef PRIMITIVE_CONVERTER };// ********** user defined converter *********** template<class Direction> struct user_defined_converter; template<> struct user_defined_converter<lua_to_cpp> { typedef boost::mpl::bool_<false> is_value_converter; typedef user_defined_converter type; template<class T> T apply(lua_State* L, detail::by_value<T>, int index) { using namespace converters; return convert_lua_to_cpp(L, detail::by_value<T>(), index); } template<class T> T apply(lua_State* L, detail::by_reference<T>, int index) { using namespace converters; return convert_lua_to_cpp(L, detail::by_reference<T>(), index); } template<class T> T apply(lua_State* L, detail::by_const_reference<T>, int index) { using namespace converters; return convert_lua_to_cpp(L, detail::by_const_reference<T>(), index); } template<class T> T* apply(lua_State* L, detail::by_pointer<T>, int index) { using namespace converters; return convert_lua_to_cpp(L, detail::by_pointer<T>(), index); } template<class T> const T* apply(lua_State* L, detail::by_const_pointer<T>, int index) { using namespace converters; return convert_lua_to_cpp(L, detail::by_pointer<T>(), index); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -