object.hpp.svn-base
来自「本人找过多个在linux下c++的lua5.1封装库,但很少.luabind已经」· SVN-BASE 代码 · 共 1,206 行 · 第 1/3 页
SVN-BASE
1,206 行
// Copyright (c) 2005 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_OBJECT_050419_HPP#define LUABIND_OBJECT_050419_HPP#include <boost/implicit_cast.hpp> // detail::push()#include <boost/ref.hpp> // detail::push()#include <boost/mpl/bool.hpp> // value_wrapper_traits specializations#include <boost/mpl/apply_wrap.hpp>#include <boost/tuple/tuple.hpp>#include <boost/optional.hpp>#include <luabind/nil.hpp>#include <luabind/value_wrapper.hpp>#include <luabind/detail/pcall.hpp>#include <luabind/handle.hpp>#include <luabind/from_stack.hpp>#include <luabind/detail/policy.hpp>#include <luabind/detail/stack_utils.hpp>#include <luabind/detail/convert_to_lua.hpp> // REFACTOR#include <boost/iterator/iterator_facade.hpp> // iterator#include <boost/python/detail/is_xxx.hpp>#include <boost/preprocessor/iteration/iterate.hpp>#include <boost/utility/enable_if.hpp>namespace luabind {namespace detail { namespace mpl = boost::mpl; template<class T, class ConverterGenerator> void push_aux(lua_State* interpreter, T& value, ConverterGenerator*) { typedef typename boost::mpl::if_< boost::is_reference_wrapper<T> , BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type& , T >::type unwrapped_type; typename mpl::apply_wrap2< ConverterGenerator,unwrapped_type,cpp_to_lua >::type cv; cv.apply( interpreter , boost::implicit_cast< BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type& >(value) ); } template<class T, class Policies> void push(lua_State* interpreter, T& value, Policies const&) { typedef typename find_conversion_policy< 0 , Policies >::type converter_policy; push_aux(interpreter, value, (converter_policy*)0); } template<class T> void push(lua_State* interpreter, T& value) { push(interpreter, value, null_type()); }} // namespace detailnamespace adl{ namespace mpl = boost::mpl; template <class T> class object_interface; namespace is_object_interface_aux { typedef char (&yes)[1]; typedef char (&no)[2]; template <class T> yes check(object_interface<T>*); no check(void*); template <class T> struct impl { BOOST_STATIC_CONSTANT(bool, value = sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes) ); typedef mpl::bool_<value> type; }; } // namespace detail template <class T> struct is_object_interface : is_object_interface_aux::impl<T>::type {}; template <class R, class T, class U> struct enable_binary# ifndef BOOST_NO_SFINAE : boost::enable_if< mpl::or_< is_object_interface<T> , is_object_interface<U> > , R > {};# else { typedef R type; };# endif template<class T, class U> int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs , boost::mpl::true_, boost::mpl::true_) { L = value_wrapper_traits<T>::interpreter(lhs); lua_State* L2 = value_wrapper_traits<U>::interpreter(rhs); // you are comparing objects with different interpreters // that's not allowed. assert(L == L2 || L == 0 || L2 == 0); // if the two objects we compare have different interpreters // then they if (L != L2) return -1; if (L == 0) return 1; return 0; } template<class T, class U> int binary_interpreter(lua_State*& L, T const& x, U const& , boost::mpl::true_, boost::mpl::false_) { L = value_wrapper_traits<T>::interpreter(x); return 0; } template<class T, class U> int binary_interpreter(lua_State*& L, T const&, U const& x, boost::mpl::false_, boost::mpl::true_) { L = value_wrapper_traits<U>::interpreter(x); return 0; } template<class T, class U> int binary_interpreter(lua_State*& L, T const& x, U const& y) { return binary_interpreter( L , x , y , is_value_wrapper<T>() , is_value_wrapper<U>() ); }#define LUABIND_BINARY_OP_DEF(op, fn) \ template<class LHS, class RHS> \ typename enable_binary<bool,LHS,RHS>::type \ operator op(LHS const& lhs, RHS const& rhs) \ { \ lua_State* L = 0; \ switch (binary_interpreter(L, lhs, rhs)) \ { \ case 1: \ return true; \ case -1: \ return false; \ } \\ assert(L); \\ detail::stack_pop pop1(L, 1); \ detail::push(L, lhs); \ detail::stack_pop pop2(L, 1); \ detail::push(L, rhs); \\ return fn(L, -1, -2) != 0; \ }LUABIND_BINARY_OP_DEF(==, lua_equal)LUABIND_BINARY_OP_DEF(<, lua_lessthan) template<class ValueWrapper> std::ostream& operator<<(std::ostream& os , object_interface<ValueWrapper> const& v) { using namespace luabind; lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter( static_cast<ValueWrapper const&>(v)); detail::stack_pop pop(interpreter, 1); value_wrapper_traits<ValueWrapper>::unwrap(interpreter , static_cast<ValueWrapper const&>(v)); char const* p = lua_tostring(interpreter, -1); int len = lua_strlen(interpreter, -1); std::copy(p, p + len, std::ostream_iterator<char>(os)); return os; }#undef LUABIND_BINARY_OP_DEF template<class LHS, class RHS> typename enable_binary<bool,LHS,RHS>::type operator>(LHS const& lhs, RHS const& rhs) { return !(lhs < rhs || lhs == rhs); } template<class LHS, class RHS> typename enable_binary<bool,LHS,RHS>::type operator<=(LHS const& lhs, RHS const& rhs) { return lhs < rhs || lhs == rhs; } template<class LHS, class RHS> typename enable_binary<bool,LHS,RHS>::type operator>=(LHS const& lhs, RHS const& rhs) { return !(lhs < rhs); } template<class LHS, class RHS> typename enable_binary<bool,LHS,RHS>::type operator!=(LHS const& lhs, RHS const& rhs) { return !(lhs < rhs); } template<class ValueWrapper, class Arguments> struct call_proxy; template<class Next> class index_proxy; class object; template<class Derived> class object_interface { public: ~object_interface() {} call_proxy<Derived, boost::tuples::tuple<> > operator()(); template<class A0> call_proxy< Derived , boost::tuples::tuple<A0 const*> > operator()(A0 const& a0) { typedef boost::tuples::tuple<A0 const*> arguments; return call_proxy<Derived, arguments>( derived() , arguments(&a0) ); } template<class A0, class A1> call_proxy< Derived , boost::tuples::tuple<A0 const*, A1 const*> > operator()(A0 const& a0, A1 const& a1) { typedef boost::tuples::tuple<A0 const*, A1 const*> arguments; return call_proxy<object, arguments>( derived() , arguments(&a0, &a1) ); } // The rest of the overloads are PP-generated. #define BOOST_PP_ITERATION_PARAMS_1 (3, \ (3, LUABIND_MAX_ARITY, <luabind/detail/object_call.hpp>)) #include BOOST_PP_ITERATE() private: Derived& derived() { return *static_cast<Derived*>(this); } Derived const& derived() const { return *static_cast<Derived const*>(this); } };#ifdef LUABIND_USE_VALUE_WRAPPER_TAG struct iterator_proxy_tag;#endif template<class AccessPolicy> class iterator_proxy : public object_interface<iterator_proxy<AccessPolicy> > { public:#ifdef LUABIND_USE_VALUE_WRAPPER_TAG typedef iterator_proxy_tag value_wrapper_tag;#endif iterator_proxy(lua_State* interpreter, handle const& table, handle const& key) : m_interpreter(interpreter) , m_table_index(lua_gettop(interpreter) + 1) , m_key_index(m_table_index + 1) { table.push(m_interpreter); key.push(m_interpreter); } iterator_proxy(iterator_proxy const& other) : m_interpreter(other.m_interpreter) , m_table_index(other.m_table_index) , m_key_index(other.m_key_index) { other.m_interpreter = 0; } ~iterator_proxy() { if (m_interpreter) lua_pop(m_interpreter, 2); } // this will set the value to nil iterator_proxy & operator=(luabind::detail::nil_type) { lua_pushvalue(m_interpreter, m_key_index); lua_pushnil(m_interpreter); AccessPolicy::set(m_interpreter, m_table_index); return *this; } template<class T> iterator_proxy& operator=(T const& value) { lua_pushvalue(m_interpreter, m_key_index); detail::push(m_interpreter, value); AccessPolicy::set(m_interpreter, m_table_index); return *this; } template<class Key> index_proxy<iterator_proxy<AccessPolicy> > operator[](Key const& key) { return index_proxy<iterator_proxy<AccessPolicy> >( *this, m_interpreter, key ); } // This is non-const to prevent conversion on lvalues. operator object(); lua_State* interpreter() const { return m_interpreter; } // TODO: Why is it non-const? void push(lua_State* interpreter) { assert(interpreter == m_interpreter); lua_pushvalue(m_interpreter, m_key_index); AccessPolicy::get(m_interpreter, m_table_index); } private:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?