📄 object.cpp
字号:
// 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.
extern "C"
{
#include "lua.h"
}
#include <luabind/luabind.hpp>
#include <luabind/detail/implicit_cast.hpp>
using namespace luabind::detail;
namespace luabind
{
namespace detail
{
// *************************************
// PROXY OBJECT
#define LUABIND_PROXY_ASSIGNMENT_OPERATOR(rhs)\
proxy_object& proxy_object::operator=(const rhs& p) \
{ \
assert((lua_state() == p.lua_state()) && "you cannot assign a value from a different lua state"); \
lua_State* L = lua_state(); \
m_obj->pushvalue(); \
detail::getref(L, m_key_ref); \
p.pushvalue(); \
lua_settable(L, -3); \
lua_pop(L, 1); \
return *this; \
}
LUABIND_PROXY_ASSIGNMENT_OPERATOR(object)
LUABIND_PROXY_ASSIGNMENT_OPERATOR(proxy_object)
LUABIND_PROXY_ASSIGNMENT_OPERATOR(proxy_raw_object)
LUABIND_PROXY_ASSIGNMENT_OPERATOR(proxy_array_object)
#undef LUABIND_PROXY_ASSIGNMENT_OPERATOR
void proxy_object::pushvalue() const
{
assert((m_key_ref != LUA_NOREF) && "you cannot call pushvalue() on an uninitialized object");
lua_State* L = m_obj->lua_state();
m_obj->pushvalue();
detail::getref(L, m_key_ref);
lua_gettable(L, -2);
// remove the table and leave the value on top of the stack
lua_remove(L, -2);
}
void proxy_object::set() const
{
lua_State* L = lua_state();
m_obj->pushvalue();
detail::getref(L, m_key_ref);
lua_pushvalue(L, -3);
lua_settable(L, -3);
// pop table and value
lua_pop(L, 2);
}
// *************************************
// PROXY ARRAY OBJECT
#define LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(rhs)\
proxy_array_object& proxy_array_object::operator=(const rhs& p) \
{ \
assert((lua_state() == p.lua_state()) && "you cannot assign a value from a different lua state"); \
lua_State* L = lua_state(); \
m_obj->pushvalue(); \
p.pushvalue(); \
lua_rawseti(L, -2, m_key); \
lua_pop(L, 1); \
return *this; \
}
LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(object)
LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(proxy_object)
LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(proxy_raw_object)
LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(proxy_array_object)
#undef LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR
void proxy_array_object::pushvalue() const
{
// you are trying to dereference an invalid object
assert((m_key != LUA_NOREF) && "you cannot call pushvalue() on an uninitialized object");
lua_State* L = m_obj->lua_state();
m_obj->pushvalue();
lua_rawgeti(L, -1, m_key);
lua_remove(L, -2);
}
void proxy_array_object::set() const
{
lua_State* L = lua_state();
m_obj->pushvalue();
lua_pushvalue(L, -2);
lua_rawseti(L, -2, m_key);
// pop table and value
lua_pop(L, 2);
}
// *************************************
// PROXY RAW OBJECT
#define LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(rhs)\
proxy_raw_object& proxy_raw_object::operator=(const rhs& p) \
{ \
assert((lua_state() == p.lua_state()) && "you cannot assign a value from a different lua state"); \
lua_State* L = lua_state(); \
m_obj->pushvalue(); \
detail::getref(L, m_key_ref); \
p.pushvalue(); \
lua_rawset(L, -3); \
lua_pop(L, 1); \
return *this; \
}
LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(object)
LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(proxy_object)
LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(proxy_raw_object)
LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(proxy_array_object)
#undef LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR
void proxy_raw_object::pushvalue() const
{
assert((m_key_ref != LUA_NOREF) && "you cannot call pushvalue() on an uninitiallized object");
lua_State* L = lua_state();
m_obj->pushvalue();
detail::getref(L, m_key_ref);
lua_rawget(L, -2);
// remove the table and leave the value on top of the stack
lua_remove(L, -2);
}
void proxy_raw_object::set() const
{
lua_State* L = lua_state();
m_obj->pushvalue();
detail::getref(L, m_key_ref);
lua_pushvalue(L, -3);
lua_rawset(L, -3);
// pop table and value
lua_pop(L, 2);
}
} // detail
#define LUABIND_DECLARE_OPERATOR(MACRO)\
MACRO(object, object) \
MACRO(object, detail::proxy_object) \
MACRO(object, detail::proxy_array_object) \
MACRO(object, detail::proxy_raw_object) \
MACRO(detail::proxy_object, object) \
MACRO(detail::proxy_object, detail::proxy_object) \
MACRO(detail::proxy_object, detail::proxy_array_object) \
MACRO(detail::proxy_object, detail::proxy_raw_object) \
MACRO(detail::proxy_array_object, object) \
MACRO(detail::proxy_array_object, detail::proxy_object) \
MACRO(detail::proxy_array_object, detail::proxy_array_object) \
MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
MACRO(detail::proxy_raw_object, object) \
MACRO(detail::proxy_raw_object, detail::proxy_object) \
MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
// *****************************
// OPERATOR ==
#define LUABIND_EQUALITY_OPERATOR(lhs_t, rhs_t)\
bool operator==(const lhs_t& lhs, const rhs_t& rhs) \
{ \
if (!lhs.is_valid()) return false; \
if (!rhs.is_valid()) return false; \
assert((lhs.lua_state() == rhs.lua_state()) && "you cannot compare objects from different lua states"); \
lua_State* L = lhs.lua_state(); \
lhs.pushvalue(); \
rhs.pushvalue(); \
bool result = lua_equal(L, -1, -2) != 0; \
lua_pop(L, 2); \
return result; \
}
LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
#undef LUABIND_EQUALITY_OPERATOR
// *****************************
// OPERATOR =
#define LUABIND_ASSIGNMENT_OPERATOR(rhs)\
object& object::operator=(const rhs& o) const \
{ \
m_state = o.lua_state(); \
o.pushvalue(); \
set(); \
return const_cast<luabind::object&>(*this); \
}
LUABIND_ASSIGNMENT_OPERATOR(object)
LUABIND_ASSIGNMENT_OPERATOR(proxy_object)
LUABIND_ASSIGNMENT_OPERATOR(proxy_array_object)
LUABIND_ASSIGNMENT_OPERATOR(proxy_raw_object)
// *****************************
// OPERATOR ==
#define LUABIND_LESSTHAN_OPERATOR(lhs_t, rhs_t)\
bool operator<(const lhs_t& lhs, const rhs_t& rhs) \
{ \
if (!lhs.is_valid()) return false; \
if (!rhs.is_valid()) return false; \
assert((lhs.lua_state() == rhs.lua_state()) && "you cannot compare objects from different lua states"); \
lua_State* L = lhs.lua_state(); \
lhs.pushvalue(); \
rhs.pushvalue(); \
bool result = lua_lessthan(L, -1, -2) != 0; \
lua_pop(L, 2); \
return result; \
}
LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR)
#undef LUABIND_LESSTHAN_OPERATOR
#define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t)\
bool operator<=(const lhs_t& lhs, const rhs_t& rhs) \
{ \
if (!lhs.is_valid()) return false; \
if (!rhs.is_valid()) return false; \
assert((lhs.lua_state() == rhs.lua_state()) && "you cannot compare objects from different lua states"); \
lua_State* L = lhs.lua_state(); \
lhs.pushvalue(); \
rhs.pushvalue(); \
bool result1 = lua_lessthan(L, -1, -2) != 0; \
bool result2 = lua_equal(L, -1, -2) != 0; \
lua_pop(L, 2); \
return result1 || result2; \
}
LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR)
#undef LUABIND_LESSOREQUAL_OPERATOR
#undef LUABIND_GREATERTHAN_OPERATOR
#undef LUABIND_DECLARE_OPERATOR
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -