diff --git a/class_wrapper.h b/class_wrapper.h index 4fedde09..b383d263 100644 --- a/class_wrapper.h +++ b/class_wrapper.h @@ -66,37 +66,45 @@ class ClassWrapper void def_read_write(MemberType T::*pm, const char* name) { m_class->def_read_write(pm, name); } - // declare the given class a base class of this and register + // declare the given class a base class of this one and register // conversion functions template void declare_base(ClassWrapper const & base) { - m_class->declare_base(base.m_class.get()); + m_class->declare_base(base.get_extension_class()); } - // 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 + // upcast conversion function template void declare_base(ClassWrapper const & base, WithoutDowncast) { - m_class->declare_base(base.m_class.get(), without_downcast); + m_class->declare_base(base.get_extension_class(), without_downcast); } + // declare the given class a base class of this one and register + // conversion functions template void declare_base(ExtensionClass * base) { m_class->declare_base(base); } - // 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 + // upcast conversion function template void declare_base(ExtensionClass * base, WithoutDowncast) { m_class->declare_base(base, without_downcast); } -// private: + // get the embedded ExtensioClass object + ExtensionClass * get_extension_class() const + { + return m_class.get(); + } + + private: PyPtr > m_class; }; diff --git a/extclass.cpp b/extclass.cpp index c8af3a4a..b37979d7 100644 --- a/extclass.cpp +++ b/extclass.cpp @@ -220,35 +220,41 @@ ExtensionClassBase::ExtensionClassBase(const char* name) void * ExtensionClassBase::try_class_conversions(InstanceHolderBase * object) const { - void * result = try_subclass_conversions(object); - if(result) return result; - result = try_superclass_conversions(object); + void * result = try_derived_class_conversions(object); + if(result) + return result; + result = try_base_class_conversions(object); return result; } -void * ExtensionClassBase::try_superclass_conversions(InstanceHolderBase * object) const +void * ExtensionClassBase::try_base_class_conversions(InstanceHolderBase * object) const { void * result = 0; for(int i=0; iconvert_from_holder(object); - if(result) return (*base_classes()[i].convert)(result); - result = base_classes()[i].class_object->try_superclass_conversions(object); - if(result) return (*base_classes()[i].convert)(result); + if(result) + return (*base_classes()[i].convert)(result); + result = base_classes()[i].class_object->try_base_class_conversions(object); + if(result) + return (*base_classes()[i].convert)(result); } return 0; } -void * ExtensionClassBase::try_subclass_conversions(InstanceHolderBase * object) const +void * ExtensionClassBase::try_derived_class_conversions(InstanceHolderBase * object) const { void * result = 0; - for(int i=0; iconvert_from_holder(object); - if(result) return (*sub_classes()[i].convert)(result); - result = sub_classes()[i].class_object->try_subclass_conversions(object); - if(result) return (*sub_classes()[i].convert)(result); + result = derived_classes()[i].class_object->convert_from_holder(object); + if(result) + return (*derived_classes()[i].convert)(result); + result = derived_classes()[i].class_object->try_derived_class_conversions(object); + if(result) + return (*derived_classes()[i].convert)(result); } return 0; } diff --git a/extclass.h b/extclass.h index 154d8506..62f105ca 100644 --- a/extclass.h +++ b/extclass.h @@ -52,18 +52,24 @@ T* check_non_null(T* p) } template class HeldInstance; -typedef void * (*ConversionFct)(void *); + +namespace detail +{ + +typedef void * (*ConversionFunction)(void *); struct BaseClassInfo { - BaseClassInfo(TypeObjectBase * t, ConversionFct f) + BaseClassInfo(Class * t, ConversionFunction f) :class_object(t), convert(f) {} - TypeObjectBase *class_object; - ConversionFct convert; + Class * class_object; + ConversionFunction convert; }; -typedef BaseClassInfo SubClassInfo; +typedef BaseClassInfo DerivedClassInfo; + +} class ExtensionClassBase : public Class { @@ -80,10 +86,10 @@ class ExtensionClassBase : public Class void add_getter_method(Function*, const char* name); virtual void * try_class_conversions(InstanceHolderBase*) const; - virtual void * try_superclass_conversions(InstanceHolderBase*) const; - virtual void * try_subclass_conversions(InstanceHolderBase*) const; - virtual std::vector const & base_classes() const = 0; - virtual std::vector const & sub_classes() const = 0; + virtual void * try_base_class_conversions(InstanceHolderBase*) const; + virtual void * try_derived_class_conversions(InstanceHolderBase*) const; + virtual std::vector const & base_classes() const = 0; + virtual std::vector const & derived_classes() const = 0; }; template @@ -94,14 +100,14 @@ class ClassRegistry { return static_class_object; } static void register_class(py::Class*); static void unregister_class(py::Class*); - static void register_base_class(BaseClassInfo const &); - static void register_sub_class(SubClassInfo const &); - static std::vector const & base_classes(); - static std::vector const & sub_classes(); + static void register_base_class(py::detail::BaseClassInfo const &); + static void register_derived_class(py::detail::DerivedClassInfo const &); + static std::vector const & base_classes(); + static std::vector const & derived_classes(); private: static py::Class* static_class_object; - static std::vector static_base_class_info; - static std::vector static_sub_class_info; + static std::vector static_base_class_info; + static std::vector static_derived_class_info; }; #ifdef PY_NO_INLINE_FRIENDS_IN_NAMESPACE // back to global namespace for this GCC bug @@ -278,8 +284,11 @@ class ReadOnlySetattrFunction : public Function String m_name; }; +namespace detail +{ + template -struct ConversionFunction +struct DefineConversion { static void * upcast_ptr(void * v) { @@ -292,6 +301,8 @@ struct ConversionFunction } }; +} + enum WithoutDowncast { without_downcast }; @@ -395,12 +406,14 @@ class ExtensionClass template void declare_base(ExtensionClass * base) { - BaseClassInfo baseInfo(base, &ConversionFunction::downcast_ptr); + detail::BaseClassInfo baseInfo(base, + &detail::DefineConversion::downcast_ptr); ClassRegistry::register_base_class(baseInfo); add_base(Ptr(as_object(base), Ptr::new_ref)); - SubClassInfo subInfo(this, &ConversionFunction::upcast_ptr); - ClassRegistry::register_sub_class(subInfo); + detail::DerivedClassInfo derivedInfo(this, + &detail::DefineConversion::upcast_ptr); + ClassRegistry::register_derived_class(derivedInfo); } // declare the given class a base class of this and register @@ -408,19 +421,20 @@ class ExtensionClass template void declare_base(ExtensionClass * base, WithoutDowncast) { - BaseClassInfo baseInfo(base, 0); + detail::BaseClassInfo baseInfo(base, 0); ClassRegistry::register_base_class(baseInfo); add_base(Ptr(as_object(base), Ptr::new_ref)); - SubClassInfo subInfo(this, &ConversionFunction::upcast_ptr); - ClassRegistry::register_sub_class(subInfo); + detail::DerivedClassInfo derivedInfo(this, + &detail::DefineConversion::upcast_ptr); + ClassRegistry::register_derived_class(derivedInfo); } private: typedef InstanceValueHolder Holder; - virtual std::vector const & base_classes() const; - virtual std::vector const & sub_classes() const; + virtual std::vector const & base_classes() const; + virtual std::vector const & derived_classes() const; virtual void * convert_from_holder(InstanceHolderBase * v) const; template @@ -541,16 +555,18 @@ ExtensionClass::ExtensionClass(const char* name) template inline -std::vector const & ExtensionClass::base_classes() const +std::vector const & +ExtensionClass::base_classes() const { return ClassRegistry::base_classes(); } template inline -std::vector const & ExtensionClass::sub_classes() const +std::vector const & +ExtensionClass::derived_classes() const { - return ClassRegistry::sub_classes(); + return ClassRegistry::derived_classes(); } template @@ -585,27 +601,27 @@ inline void ClassRegistry::unregister_class(Class* p) } template -void ClassRegistry::register_base_class(BaseClassInfo const & i) +void ClassRegistry::register_base_class(py::detail::BaseClassInfo const & i) { static_base_class_info.push_back(i); } template -void ClassRegistry::register_sub_class(SubClassInfo const & i) +void ClassRegistry::register_derived_class(py::detail::DerivedClassInfo const & i) { - static_sub_class_info.push_back(i); + static_derived_class_info.push_back(i); } template -std::vector const & ClassRegistry::base_classes() +std::vector const & ClassRegistry::base_classes() { return static_base_class_info; } template -std::vector const & ClassRegistry::sub_classes() +std::vector const & ClassRegistry::derived_classes() { - return static_sub_class_info; + return static_derived_class_info; } // @@ -614,9 +630,9 @@ std::vector const & ClassRegistry::sub_classes() template Class* ClassRegistry::static_class_object; template -std::vector ClassRegistry::static_base_class_info; +std::vector ClassRegistry::static_base_class_info; template -std::vector ClassRegistry::static_sub_class_info; +std::vector ClassRegistry::static_derived_class_info; } // namespace py diff --git a/newtypes.h b/newtypes.h index 083ffbc7..5458bcf6 100644 --- a/newtypes.h +++ b/newtypes.h @@ -61,11 +61,6 @@ class TypeObjectBase : public PythonType virtual PyObject* instance_getattr(PyObject* instance, const char* name) const; virtual int instance_setattr(PyObject* instance, const char* name, PyObject* value) const; - virtual void * try_class_conversions(InstanceHolderBase*) const { return 0; } - virtual void * try_superclass_conversions(InstanceHolderBase*) const { return 0; } - virtual void * try_subclass_conversions(InstanceHolderBase*) const { return 0; } - virtual void * convert_from_holder(InstanceHolderBase*) const { return 0; } - // Dealloc is a special case, since every type needs a nonzero tp_dealloc slot. virtual void instance_dealloc(PyObject*) const = 0; diff --git a/subclass.h b/subclass.h index 4d745bc0..32db3b9d 100644 --- a/subclass.h +++ b/subclass.h @@ -73,6 +73,11 @@ class Class int setattr(const char* name, PyObject* value); PyObject* call(PyObject* args, PyObject* keywords); + 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; } + virtual void * convert_from_holder(InstanceHolderBase*) const { return 0; } + protected: void add_base(Ptr base);