⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 class.cpp

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.

#include <boost/python/detail/prefix.hpp>
#include <boost/mpl/lambda.hpp> // #including this first is an intel6 workaround

#include <boost/python/object/class.hpp>
#include <boost/python/object/instance.hpp>
#include <boost/python/object/class_detail.hpp>
#include <boost/python/scope.hpp>
#include <boost/python/converter/registry.hpp>
#include <boost/python/object/find_instance.hpp>
#include <boost/python/object/pickle_support.hpp>
#include <boost/python/detail/map_entry.hpp>
#include <boost/python/object.hpp>
#include <boost/python/object_protocol.hpp>
#include <boost/detail/binary_search.hpp>
#include <boost/python/self.hpp>
#include <boost/python/dict.hpp>
#include <boost/python/str.hpp>
#include <functional>
#include <vector>
#include <cstddef>
#include <new>
#include <structmember.h>

namespace boost { namespace python {

# ifdef BOOST_PYTHON_SELF_IS_CLASS
namespace self_ns
{
  self_t self;
}
# endif 

instance_holder::instance_holder()
    : m_next(0)
{
}

instance_holder::~instance_holder()
{
}

extern "C"
{
  // This is copied from typeobject.c in the Python sources. Even though
  // class_metatype_object doesn't set Py_TPFLAGS_HAVE_GC, that bit gets
  // filled in by the base class initialization process in
  // PyType_Ready(). However, tp_is_gc is *not* copied from the base
  // type, making it assume that classes are GC-able even if (like
  // class_type_object) they're statically allocated.
  static int
  type_is_gc(PyTypeObject *python_type)
  {
      return python_type->tp_flags & Py_TPFLAGS_HEAPTYPE;
  }

  // This is also copied from the Python sources.  We can't implement
  // static_data as a subclass property effectively without it.
  typedef struct {
      PyObject_HEAD
      PyObject *prop_get;
      PyObject *prop_set;
      PyObject *prop_del;
      PyObject *prop_doc;
  } propertyobject;

  static PyObject *
  static_data_descr_get(PyObject *self, PyObject *obj, PyObject * /*type*/)
  {
      propertyobject *gs = (propertyobject *)self;

      return PyObject_CallFunction(gs->prop_get, "()");
  }

  static int
  static_data_descr_set(PyObject *self, PyObject *obj, PyObject *value)
  {
      propertyobject *gs = (propertyobject *)self;
      PyObject *func, *res;

      if (value == NULL)
          func = gs->prop_del;
      else
          func = gs->prop_set;
      if (func == NULL) {
          PyErr_SetString(PyExc_AttributeError,
                          value == NULL ?
                          "can't delete attribute" :
                          "can't set attribute");
          return -1;
      }
      if (value == NULL)
          res = PyObject_CallFunction(func, "()");
      else
          res = PyObject_CallFunction(func, "(O)", value);
      if (res == NULL)
          return -1;
      Py_DECREF(res);
      return 0;
  }
}

static PyTypeObject static_data_object = {
    PyObject_HEAD_INIT(0)//&PyType_Type)
    0,
    "Boost.Python.StaticProperty",
    PyType_Type.tp_basicsize,
    0,
    0,                                      /* tp_dealloc */
    0,                                      /* tp_print */
    0,                                      /* tp_getattr */
    0,                                      /* tp_setattr */
    0,                                      /* tp_compare */
    0,                                      /* tp_repr */
    0,                                      /* tp_as_number */
    0,                                      /* tp_as_sequence */
    0,                                      /* tp_as_mapping */
    0,                                      /* tp_hash */
    0,                                      /* tp_call */
    0,                                      /* tp_str */
    0,                                      /* tp_getattro */
    0,                                      /* tp_setattro */
    0,                                      /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC
    | Py_TPFLAGS_BASETYPE,          /* tp_flags */
    0,                                      /* tp_doc */
    0,                                      /* tp_traverse */
    0,                                      /* tp_clear */
    0,                                      /* tp_richcompare */
    0,                                      /* tp_weaklistoffset */
    0,                                      /* tp_iter */
    0,                                      /* tp_iternext */
    0,                                      /* tp_methods */
    0,                                      /* tp_members */
    0,                                      /* tp_getset */
    0, //&PyProperty_Type,                           /* tp_base */
    0,                                      /* tp_dict */
    static_data_descr_get,                                      /* tp_descr_get */
    static_data_descr_set,                                      /* tp_descr_set */
    0,                                      /* tp_dictoffset */
    0,                                      /* tp_init */
    0,                                      /* tp_alloc */
    0, // filled in with type_new           /* tp_new */
    0, // filled in with __PyObject_GC_Del  /* tp_free */
    (inquiry)type_is_gc,                    /* tp_is_gc */
};

namespace objects
{
  extern "C"
  {
      // This declaration needed due to broken Python 2.2 headers
      extern DL_IMPORT(PyTypeObject) PyProperty_Type;
  }

  BOOST_PYTHON_DECL PyObject* static_data()
  {
      if (static_data_object.tp_dict == 0)
      {
          static_data_object.ob_type = &PyType_Type;
          static_data_object.tp_base = &PyProperty_Type;
          if (PyType_Ready(&static_data_object))
              return 0;
      }
      return upcast<PyObject>(&static_data_object);
  }
}  

extern "C"
{
    // Ordinarily, descriptors have a certain assymetry: you can use
    // them to read attributes off the class object they adorn, but
    // writing the same attribute on the class object always replaces
    // the descriptor in the class __dict__.  In order to properly
    // represent C++ static data members, we need to allow them to be
    // written through the class instance.  This function of the
    // metaclass makes it possible.
    static int
    class_setattro(PyObject *obj, PyObject *name, PyObject* value)
    {
        // Must use "private" Python implementation detail
        // _PyType_Lookup instead of PyObject_GetAttr because the
        // latter will always end up calling the descr_get function on
        // any descriptor it finds; we need the unadulterated
        // descriptor here.
        PyObject* a = _PyType_Lookup(downcast<PyTypeObject>(obj), name);

        // a is a borrowed reference or 0
        
        // If we found a static data descriptor, call it directly to
        // force it to set the static data member
        if (a != 0 && PyObject_IsInstance(a, objects::static_data()))
            return a->ob_type->tp_descr_set(a, obj, value);
        else
            return PyType_Type.tp_setattro(obj, name, value);
    }
}

static PyTypeObject class_metatype_object = {
    PyObject_HEAD_INIT(0)//&PyType_Type)
    0,
    "Boost.Python.class",
    PyType_Type.tp_basicsize,
    0,
    0,                                      /* tp_dealloc */
    0,                                      /* tp_print */
    0,                                      /* tp_getattr */
    0,                                      /* tp_setattr */
    0,                                      /* tp_compare */
    0,                                      /* tp_repr */
    0,                                      /* tp_as_number */
    0,                                      /* tp_as_sequence */
    0,                                      /* tp_as_mapping */
    0,                                      /* tp_hash */
    0,                                      /* tp_call */
    0,                                      /* tp_str */
    0,                                      /* tp_getattro */
    class_setattro,                         /* tp_setattro */
    0,                                      /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC
    | Py_TPFLAGS_BASETYPE,          /* tp_flags */
    0,                                      /* tp_doc */
    0,                                      /* tp_traverse */
    0,                                      /* tp_clear */
    0,                                      /* tp_richcompare */
    0,                                      /* tp_weaklistoffset */
    0,                                      /* tp_iter */
    0,                                      /* tp_iternext */
    0,                                      /* tp_methods */
    0,                                      /* tp_members */
    0,                                      /* tp_getset */
    0, //&PyType_Type,                           /* tp_base */
    0,                                      /* tp_dict */
    0,                                      /* tp_descr_get */
    0,                                      /* tp_descr_set */
    0,                                      /* tp_dictoffset */
    0,                                      /* tp_init */
    0,                                      /* tp_alloc */
    0, // filled in with type_new           /* tp_new */
    0, // filled in with __PyObject_GC_Del  /* tp_free */
    (inquiry)type_is_gc,                    /* tp_is_gc */
};

// Install the instance data for a C++ object into a Python instance
// object.
void instance_holder::install(PyObject* self) throw()
{
    assert(self->ob_type->ob_type == &class_metatype_object);
    m_next = ((objects::instance<>*)self)->objects;
    ((objects::instance<>*)self)->objects = this;
}


namespace objects
{
// Get the metatype object for all extension classes.
  BOOST_PYTHON_DECL type_handle class_metatype()
  {
      if (class_metatype_object.tp_dict == 0)
      {
          class_metatype_object.ob_type = &PyType_Type;
          class_metatype_object.tp_base = &PyType_Type;
          if (PyType_Ready(&class_metatype_object))
              return type_handle();
      }
      return type_handle(borrowed(&class_metatype_object));
  }
  extern "C"
  {
      static void instance_dealloc(PyObject* inst)
      {
          instance<>* kill_me = (instance<>*)inst;

          for (instance_holder* p = kill_me->objects, *next; p != 0; p = next)
          {
              next = p->next();
              p->~instance_holder();
              instance_holder::deallocate(inst, dynamic_cast<void*>(p));
          }
        
          // Python 2.2.1 won't add weak references automatically when
          // tp_itemsize > 0, so we need to manage that
          // ourselves. Accordingly, we also have to clean up the
          // weakrefs ourselves.
          if (kill_me->weakrefs != NULL)
            PyObject_ClearWeakRefs(inst);

          Py_XDECREF(kill_me->dict);
          
          inst->ob_type->tp_free(inst);
      }

      static PyObject *
      instance_new(PyTypeObject* type_, PyObject* args, PyObject *kw)
      {
          // Attempt to find the __instance_size__ attribute. If not present, no problem.
          PyObject* d = type_->tp_dict;
          PyObject* instance_size_obj = PyObject_GetAttrString(d, "__instance_size__");

          long instance_size = 0;
          if (instance_size != 0)
              instance_size = PyInt_AsLong(instance_size_obj);
          
          if (instance_size < 0)
              instance_size = 0;
          PyErr_Clear(); // Clear any errors that may have occurred.

          instance<>* result = (instance<>*)type_->tp_alloc(type_, instance_size);
          if (result)
          {
              // Guido says we can use ob_size for any purpose we
              // like, so we'll store the total size of the object
              // there. A negative number indicates that the extra
              // instance memory is not yet allocated to any holders.
              result->ob_size = -(static_cast<int>(offsetof(instance<>,storage) + instance_size));
          }
          return (PyObject*)result;
      }

      static PyObject* instance_get_dict(PyObject* op, void*)
      {
          instance<>* inst = downcast<instance<> >(op);
          if (inst->dict == 0)
              inst->dict = PyDict_New();
          return python::xincref(inst->dict);
      }
    
      static int instance_set_dict(PyObject* op, PyObject* dict, void*)
      {
          instance<>* inst = downcast<instance<> >(op);
          python::xdecref(inst->dict);
          inst->dict = python::incref(dict);
          return 0;
      }

  }


  static PyGetSetDef instance_getsets[] = {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -