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 + -
显示快捷键?