mirror of
https://github.com/boostorg/python.git
synced 2026-01-21 17:12:22 +00:00
added explanatory comments
[SVN r7979]
This commit is contained in:
21
extclass.cpp
21
extclass.cpp
@@ -218,6 +218,27 @@ ExtensionClassBase::ExtensionClassBase(const char* name)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
This function is used in from_python() to convert wrapped classes that are
|
||||
related by inheritance. The problem is this: although C++ provides all necessary
|
||||
conversion operators, source and target of a conversion must be known at compile
|
||||
time. However, in Python we want to convert classes at runtime. The solution is to
|
||||
generate conversion functions at compile time, register them within the appropriate
|
||||
class objects and call them when a particular runtime conversion is required.
|
||||
|
||||
If functions for any possible conversion have to be stored, their number will grow
|
||||
qudratically. To reduce this number, we actually store only conversion functions
|
||||
between adjacent levels in the inheritance tree. By traversing the tree recursively,
|
||||
we can build any allowed conversion as a concatenation of simple conversions. This
|
||||
traversal is done in the functions try_base_class_conversions() and
|
||||
try_derived_class_conversions(). If a particular conversion is impossible, all
|
||||
conversion functions will return a NULL pointer.
|
||||
|
||||
The function extract_from_holder() attempts to actually extract the pointer to
|
||||
the contained object from an InstanceHolderBase (a wrapper class). A conversion
|
||||
of the held object to 'T *' is allowed when the conversion
|
||||
'dynamic_cast<InstanceHolde<T> *>(an_instance_holder_base)' succeeds.
|
||||
*/
|
||||
void * ExtensionClassBase::try_class_conversions(InstanceHolderBase * object) const
|
||||
{
|
||||
void * result = try_derived_class_conversions(object);
|
||||
|
||||
15
extclass.h
15
extclass.h
@@ -154,6 +154,7 @@ class PyExtensionClassConverters
|
||||
if (held != 0)
|
||||
return held->target();
|
||||
|
||||
// see extclass.cpp for an explanation of try_class_conversions()
|
||||
void * target = py::ClassRegistry<T>::class_object()->try_class_conversions(*p);
|
||||
if(target)
|
||||
return static_cast<T *>(target);
|
||||
@@ -401,11 +402,13 @@ class ExtensionClass
|
||||
this->def_setter(pm, name);
|
||||
}
|
||||
|
||||
// declare the given class a base class of this and register
|
||||
// conversion functions
|
||||
// declare the given class a base class of this one and register
|
||||
// up and down conversion functions
|
||||
template <class S, class V>
|
||||
void declare_base(ExtensionClass<S, V> * base)
|
||||
{
|
||||
// see extclass.cpp for an explanation of why we need to register
|
||||
// conversion functions
|
||||
detail::BaseClassInfo baseInfo(base,
|
||||
&detail::DefineConversion<S, T>::downcast_ptr);
|
||||
ClassRegistry<T>::register_base_class(baseInfo);
|
||||
@@ -416,11 +419,13 @@ class ExtensionClass
|
||||
ClassRegistry<S>::register_derived_class(derivedInfo);
|
||||
}
|
||||
|
||||
// declare the given class a base class of this and register
|
||||
// only upcast function
|
||||
// declare the given class a base class of this one and register
|
||||
// only up conversion function
|
||||
template <class S, class V>
|
||||
void declare_base(ExtensionClass<S, V> * base, WithoutDowncast)
|
||||
{
|
||||
// see extclass.cpp for an explanation of why we need to register
|
||||
// conversion functions
|
||||
detail::BaseClassInfo baseInfo(base, 0);
|
||||
ClassRegistry<T>::register_base_class(baseInfo);
|
||||
add_base(Ptr(as_object(base), Ptr::new_ref));
|
||||
@@ -435,6 +440,8 @@ class ExtensionClass
|
||||
|
||||
virtual std::vector<detail::BaseClassInfo> const & base_classes() const;
|
||||
virtual std::vector<detail::DerivedClassInfo> const & derived_classes() const;
|
||||
|
||||
// the purpose of this function is explained in extclass.cpp
|
||||
virtual void * convert_from_holder(InstanceHolderBase * v) const;
|
||||
|
||||
template <class Signature>
|
||||
|
||||
@@ -73,6 +73,7 @@ class Class
|
||||
int setattr(const char* name, PyObject* value);
|
||||
PyObject* call(PyObject* args, PyObject* keywords);
|
||||
|
||||
// the purpose of these functions is explained in extclass.cpp
|
||||
virtual void * try_class_conversions(InstanceHolderBase*) const { return 0; }
|
||||
virtual void * try_base_class_conversions(InstanceHolderBase*) const { return 0; }
|
||||
virtual void * try_derived_class_conversions(InstanceHolderBase*) const { return 0; }
|
||||
|
||||
Reference in New Issue
Block a user