📄 policy.hpp
字号:
{
return converters::TO<T*>::match(L, detail::type<T*>(), index);
}
template<class T>
const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
{
return converters::TO<const T*>::convert(L, detail::type<const T*>(), index);
}
template<class T>
static int match(lua_State* L, detail::by_const_pointer<T>, int index)
{
return converters::TO<const T*>::match(L, detail::type<const T*>(), index);
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
*/
// ********** user defined converter ***********
template<class Direction> struct user_defined_converter;
template<>
struct user_defined_converter<lua_to_cpp>
{
template<class T>
T apply(lua_State* L, detail::by_value<T>, int index)
{
// std::cerr << "user_defined_converter\n";
return converters::convert_lua_to_cpp(L, detail::by_value<T>(), index);
}
template<class T>
T apply(lua_State* L, detail::by_reference<T>, int index)
{
// std::cerr << "user_defined_converter\n";
return converters::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)
{
// std::cerr << "user_defined_converter\n";
return converters::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)
{
// std::cerr << "user_defined_converter\n";
return converters::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)
{
// std::cerr << "user_defined_converter\n";
return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
}
template<class T>
static int match(lua_State* L, T, int index)
{
return converters::match_lua_to_cpp(L, T(), index);
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
template<>
struct user_defined_converter<cpp_to_lua>
{
template<class T>
void apply(lua_State* L, const T& v)
{
converters::convert_cpp_to_lua(L, v);
}
};
// ********** pointer converter ***********
template<class Direction> struct pointer_converter;
template<>
struct pointer_converter<cpp_to_lua>
{
template<class T>
void apply(lua_State* L, T* ptr)
{
if (ptr == 0)
{
lua_pushnil(L);
return;
}
class_registry* registry = class_registry::get_registry(L);
class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
// if you get caught in this assert you are
// trying to use an unregistered type
assert(crep && "you are trying to use an unregistered type");
// create the struct to hold the object
void* obj = lua_newuserdata(L, sizeof(object_rep));
//new(obj) object_rep(ptr, crep, object_rep::owner, destructor_s<T>::apply);
new(obj) object_rep(ptr, crep, 0, 0);
// set the meta table
detail::getref(L, crep->metatable_ref());
lua_setmetatable(L, -2);
}
};
template<class T> struct make_pointer { typedef T* type; };
template<>
struct pointer_converter<lua_to_cpp>
{
bool made_conversion;
char target[32];
template<class T>
typename make_pointer<T>::type apply(lua_State* L, by_pointer<T>, int index)
{
// preconditions:
// lua_isuserdata(L, index);
// getmetatable().__lua_class is true
// object_rep->flags() & object_rep::constant == 0
if (lua_isnil(L, index)) return 0;
object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
assert((obj != 0) && "internal error, please report"); // internal error
const class_rep* crep = obj->crep();
T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
made_conversion = (void*)ptr == (char*)target;
assert(!made_conversion || sizeof(T) <= 32);
// std::cerr << "pointer_converter<lua_to_cpp>: " << ptr << " " << offset << "\n";
return ptr;
}
template<class T>
static int match(lua_State* L, by_pointer<T>, int index)
{
if (lua_isnil(L, index)) return 0;
object_rep* obj = is_class_object(L, index);
if (obj == 0) return -1;
// cannot cast a constant object to nonconst
if (obj->flags() & object_rep::constant) return -1;
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?-1:0;
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?0:-1;
int d;
return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
}
template<class T>
void converter_postcall(lua_State*, by_pointer<T>, int)
{
if (made_conversion)
reinterpret_cast<T*>(target)->~T();
}
};
// ******* value converter *******
template<class Direction> struct value_converter;
template<>
struct value_converter<cpp_to_lua>
{
template<class T>
void apply(lua_State* L, const T& ref)
{
class_registry* registry = class_registry::get_registry(L);
class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
// if you get caught in this assert you are
// trying to use an unregistered type
assert(crep && "you are trying to use an unregistered type");
void* obj_rep;
void* held;
boost::tie(obj_rep,held) = crep->allocate(L);
void* object_ptr;
void(*destructor)(void*);
destructor = crep->destructor();
int flags = object_rep::owner;
if (crep->has_holder())
{
new(held) T(ref);
object_ptr = held;
if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
{
flags |= object_rep::constant;
destructor = crep->const_holder_destructor();
}
}
else
{
object_ptr = new T(ref);
}
new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
// set the meta table
detail::getref(L, crep->metatable_ref());
lua_setmetatable(L, -2);
}
};
template<class T> struct make_const_reference { typedef const T& type; };
template<class T>
struct destruct_guard
{
T* ptr;
bool dismiss;
destruct_guard(T* p): ptr(p), dismiss(false) {}
~destruct_guard()
{
if (!dismiss)
ptr->~T();
}
};
template<>
struct value_converter<lua_to_cpp>
{
template<class T>
/*typename make_const_reference<T>::type*/T apply(lua_State* L, by_value<T>, int index)
{
// preconditions:
// lua_isuserdata(L, index);
// getmetatable().__lua_class is true
// object_rep->flags() & object_rep::constant == 0
assert((lua_isnil(L, index) == false) && "internal error, please report");
object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
assert((obj != 0) && "internal error, please report"); // internal error
const class_rep* crep = obj->crep();
// TODO: align?
char target[sizeof(T)];
T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
destruct_guard<T> guard(ptr);
if ((void*)ptr != (void*)target) guard.dismiss = true;
return *ptr;
}
template<class T>
static int match(lua_State* L, by_value<T>, int index)
{
if (lua_isnil(L, index)) return 0;
object_rep* obj = is_class_object(L, index);
if (obj == 0) return -1;
int d;
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?-1:0;
// if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
// return 0;
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?0:1;
return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
// ******* const pointer converter *******
template<class Direction> struct const_pointer_converter;
template<>
struct const_pointer_converter<cpp_to_lua>
{
template<class T>
void apply(lua_State* L, const T* ptr)
{
if (ptr == 0)
{
lua_pushnil(L);
return;
}
class_registry* registry = class_registry::get_registry(L);
class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
// if you get caught in this assert you are
// trying to use an unregistered type
assert(crep && "you are trying to use an unregistered type");
// create the struct to hold the object
void* obj = lua_newuserdata(L, sizeof(object_rep));
assert(obj && "internal error, please report");
// we send 0 as destructor since we know it will never be called
new(obj) object_rep(const_cast<T*>(ptr), crep, object_rep::constant, 0);
// set the meta table
detail::getref(L, crep->metatable_ref());
lua_setmetatable(L, -2);
}
};
template<class T> struct make_const_pointer { typedef const T* type; };
template<>
struct const_pointer_converter<lua_to_cpp>
: private pointer_converter<lua_to_cpp>
{
template<class T>
typename make_const_pointer<T>::type apply(lua_State* L, by_const_pointer<T>, int index)
{
// std::cerr << "const_pointer_converter\n";
return pointer_converter<lua_to_cpp>::apply(L, by_pointer<T>(), index);
}
template<class T>
static int match(lua_State* L, by_const_pointer<T>, int index)
{
if (lua_isnil(L, index)) return 0;
object_rep* obj = is_class_object(L, index);
if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?-1:0;
if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
return (obj->flags() & object_rep::constant)?0:1;
int d;
return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
}
template<class T>
void converter_postcall(lua_State* L, by_const_pointer<T>, int index)
{
pointer_converter<lua_to_cpp>::converter_postcall(L, by_pointer<T>(), index);
}
};
// ******* reference converter *******
template<class Direction> struct ref_converter;
template<>
struct ref_converter<cpp_to_lua>
{
template<class T>
void apply(lua_State* L, T& ref)
{
class_registry* registry = class_registry::get_registry(L);
class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
// if you get caught in this assert you are
// trying to use an unregistered type
assert(crep && "you are trying to use an unregistered type");
T* ptr = &ref;
// create the struct to hold the object
void* obj = lua_newuserdata(L, sizeof(object_rep));
assert(obj && "internal error, please report");
new(obj) object_rep(ptr, crep, 0, 0);
// set the meta table
detail::getref(L, crep->metatable_ref());
lua_setmetatable(L, -2);
}
};
template<class T> struct make_reference { typedef T& type; };
template<>
struct ref_converter<lua_to_cpp>
{
template<class T>
typename make_reference<T>::type apply(lua_State* L, by_reference<T>, int index)
{
// std::cerr << "ref_converter<lua_to_cpp>\n";
return *pointer_converter<lua_to_cpp>().apply(L, by_pointer<T>(), index);
}
template<class T>
static int match(lua_State* L, by_reference<T>, int index)
{
return pointer_converter<lua_to_cpp>::match(L, by_pointer<T>(), index);
}
template<class T>
void converter_postcall(lua_State*, T, int) {}
};
// ******** const reference converter *********
template<class Direction> struct const_ref_converter;
template<>
struct const_ref_converter<cpp_to_lua>
{
template<class T>
void apply(lua_State* L, const T& ref)
{
class_registry* registry = class_registry::get_registry(L);
class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
// if you get caught in this assert you are
// trying to use an unregistered type
assert(crep && "you are trying to use an unregistered type");
void* obj_rep;
void* held;
boost::tie(obj_rep,held) = crep->allocate(L);
void* object_ptr;
void(*destructor)(void*);
destructor = crep->destructor();
int flags = 0;
if (crep->has_holder())
{
flags = object_rep::owner;
new(held) T(ref);
object_ptr = held;
if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
{
flags |= object_rep::constant;
destructor = crep->const_holder_destructor();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -