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

📄 class.cpp

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      {"__dict__",  instance_get_dict,  instance_set_dict, NULL},
      {0}
  };

  
  static PyMemberDef instance_members[] = {
      {"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0},
      {0}
  };

  static PyTypeObject class_type_object = {
      PyObject_HEAD_INIT(0) //&class_metatype_object)
      0,
      "Boost.Python.instance",
      offsetof(instance<>,storage),           /* tp_basicsize */
      1,                                      /* tp_itemsize */
      instance_dealloc,                       /* 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 */
      offsetof(instance<>,weakrefs),          /* tp_weaklistoffset */
      0,                                      /* tp_iter */
      0,                                      /* tp_iternext */
      0,                                      /* tp_methods */
      instance_members,                       /* tp_members */
      instance_getsets,                       /* tp_getset */
      0, //&PyBaseObject_Type,                /* tp_base */
      0,                                      /* tp_dict */
      0,                                      /* tp_descr_get */
      0,                                      /* tp_descr_set */
      offsetof(instance<>,dict),              /* tp_dictoffset */
      0,                                      /* tp_init */
      PyType_GenericAlloc,                    /* tp_alloc */
      instance_new                            /* tp_new */
  };

  BOOST_PYTHON_DECL type_handle class_type()
  {
      if (class_type_object.tp_dict == 0)
      {
          class_type_object.ob_type = incref(class_metatype().get());
          class_type_object.tp_base = &PyBaseObject_Type;
          if (PyType_Ready(&class_type_object))
              return type_handle();
//          class_type_object.tp_setattro = class_setattro;
      }
      return type_handle(borrowed(&class_type_object));
  }

  BOOST_PYTHON_DECL void*
  find_instance_impl(PyObject* inst, type_info type)
  {
      if (inst->ob_type->ob_type != &class_metatype_object)
          return 0;
    
      instance<>* self = reinterpret_cast<instance<>*>(inst);

      for (instance_holder* match = self->objects; match != 0; match = match->next())
      {
          void* const found = match->holds(type);
          if (found)
              return found;
      }
      return 0;
  }

  object module_prefix()
  {
      return object(
          PyObject_IsInstance(scope().ptr(), upcast<PyObject>(&PyModule_Type))
          ? object(scope().attr("__name__"))
          : api::getattr(scope(), "__module__", str())
          );
  }

  namespace
  {
    // Find a registered class object corresponding to id. Return a
    // null handle if no such class is registered.
    inline type_handle query_class(type_info id)
    {
        converter::registration const* p = converter::registry::query(id);
        return type_handle(
            python::borrowed(
                python::allow_null(p ? p->m_class_object : 0))
            );
    }

    // Find a registered class corresponding to id. If not found,
    // throw an appropriate exception.
    type_handle get_class(type_info id)
    {
        type_handle result(query_class(id));

        if (result.get() == 0)
        {
            object report("extension class wrapper for base class ");
            report = report + id.name() + " has not been created yet";
            PyErr_SetObject(PyExc_RuntimeError, report.ptr());
            throw_error_already_set();
        }
        return result;
    }

    // class_base constructor
    //
    // name -      the name of the new Python class
    //
    // num_types - one more than the number of declared bases
    //
    // types -     array of python::type_info, the first item
    //             corresponding to the class being created, and the
    //             rest corresponding to its declared bases.
    //
    inline object
    new_class(char const* name, std::size_t num_types, type_info const* const types, char const* doc)
    {
      assert(num_types >= 1);
      
      // Build a tuple of the base Python type objects. If no bases
      // were declared, we'll use our class_type() as the single base
      // class.
      std::size_t const num_bases = std::max(num_types - 1, static_cast<std::size_t>(1));
      handle<> bases(PyTuple_New(num_bases));

      for (std::size_t i = 1; i <= num_bases; ++i)
      {
          type_handle c = (i >= num_types) ? class_type() : get_class(types[i]);
          // PyTuple_SET_ITEM steals this reference
          PyTuple_SET_ITEM(bases.get(), i - 1, upcast<PyObject>(c.release()));
      }

      // Call the class metatype to create a new class
      dict d;
   
      object m = module_prefix();
      if (m) d["__module__"] = m;

      if (doc != 0)
          d["__doc__"] = doc;
      
      object result = object(class_metatype())(name, bases, d);
      assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type));
      
      if (scope().ptr() != Py_None)
          scope().attr(name) = result;

      return result;
    }
  }
  
  class_base::class_base(
      char const* name, std::size_t num_types, type_info const* const types, char const* doc)
      : object(new_class(name, num_types, types, doc))
  {
      // Insert the new class object in the registry
      converter::registration& converters = const_cast<converter::registration&>(
          converter::registry::lookup(types[0]));

      // Class object is leaked, for now
      converters.m_class_object = (PyTypeObject*)incref(this->ptr());
  }

  BOOST_PYTHON_DECL void copy_class_object(type_info const& src, type_info const& dst)
  {
      converter::registration& dst_converters
          = const_cast<converter::registration&>(converter::registry::lookup(dst));
      
      converter::registration const& src_converters = converter::registry::lookup(src);

      dst_converters.m_class_object = src_converters.m_class_object;
  }
  
  void class_base::set_instance_size(std::size_t instance_size)
  {
      this->attr("__instance_size__") = instance_size;
  }
  
  void class_base::add_property(char const* name, object const& fget)
  {
      object property(
          (python::detail::new_reference)
              PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.ptr()));
      
      this->setattr(name, property);
  }

  void class_base::add_property(char const* name, object const& fget, object const& fset)
  {
      object property(
          (python::detail::new_reference)
              PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.ptr(), fset.ptr()));
      
      this->setattr(name, property);
  }

  void class_base::add_static_property(char const* name, object const& fget)
  {
      object property(
          (python::detail::new_reference)
          PyObject_CallFunction(static_data(), "O", fget.ptr()));
      
      this->setattr(name, property);
  }

  void class_base::add_static_property(char const* name, object const& fget, object const& fset)
  {
      object property(
          (python::detail::new_reference)
          PyObject_CallFunction(static_data(), "OO", fget.ptr(), fset.ptr()));
      
      this->setattr(name, property);
  }

  void class_base::setattr(char const* name, object const& x)
  {
      if (PyObject_SetAttrString(this->ptr(), const_cast<char*>(name), x.ptr()) < 0)
          throw_error_already_set();
  }

  namespace
  {
    extern "C" PyObject* no_init(PyObject*, PyObject*)
    {
        ::PyErr_SetString(::PyExc_RuntimeError, "This class cannot be instantiated from Python");
        return NULL;
    }
    static ::PyMethodDef no_init_def = {
        "__init__", no_init, METH_VARARGS,
        "Raises an exception\n"
        "This class cannot be instantiated from Python\n"
    };
  }
  
  void class_base::def_no_init()
  {
      handle<> f(::PyCFunction_New(&no_init_def, 0));
      this->setattr("__init__", object(f));
  }

  void class_base::enable_pickling(bool getstate_manages_dict)
  {
      setattr("__reduce__", object(make_instance_reduce_function()));
      setattr("__safe_for_unpickling__", object(true));
      
      if (getstate_manages_dict)
      {
          setattr("__getstate_manages_dict__", object(true));
      }
  }

  namespace
  {
    PyObject* callable_check(PyObject* callable)
    {
        if (PyCallable_Check(expect_non_null(callable)))
            return callable;

        ::PyErr_Format(
            PyExc_TypeError
            , "staticmethod expects callable object; got an object of type %s, which is not callable"
            , callable->ob_type->tp_name
            );
        
        throw_error_already_set();
        return 0;
    }
  }
  
  void class_base::make_method_static(const char * method_name)
  {
      PyTypeObject* self = downcast<PyTypeObject>(this->ptr());
      dict d((handle<>(borrowed(self->tp_dict))));

      object method(d[method_name]);

      this->attr(method_name) = object(
          handle<>(
              PyStaticMethod_New((callable_check)(method.ptr()) )
              ));
  }

  BOOST_PYTHON_DECL type_handle registered_class_object(type_info id)
  {
      return query_class(id);
  }
} // namespace objects


void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size)
{
    assert(self_->ob_type->ob_type == &class_metatype_object);
    objects::instance<>* self = (objects::instance<>*)self_;
    
    int total_size_needed = holder_offset + holder_size;
    
    if (-self->ob_size >= total_size_needed)
    {
        // holder_offset should at least point into the variable-sized part
        assert(holder_offset >= offsetof(objects::instance<>,storage));

        // Record the fact that the storage is occupied, noting where it starts
        self->ob_size = holder_offset;
        return (char*)self + holder_offset;
    }
    else
    {
        void* const result = PyMem_Malloc(holder_size);
        if (result == 0)
            throw std::bad_alloc();
        return result;
    }
}

void instance_holder::deallocate(PyObject* self_, void* storage) throw()
{
    assert(self_->ob_type->ob_type == &class_metatype_object);
    objects::instance<>* self = (objects::instance<>*)self_;
    if (storage != (char*)self + self->ob_size)
    {
        PyMem_Free(storage);
    }
}

}} // namespace boost::python

⌨️ 快捷键说明

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