2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-23 05:42:30 +00:00

Integrated Scott Snyder's nested class patch

[SVN r12080]
This commit is contained in:
Dave Abrahams
2001-12-17 05:49:24 +00:00
parent bed2c8a371
commit 291c36df05
5 changed files with 55 additions and 1 deletions

View File

@@ -98,6 +98,12 @@ Notes:<ul>
<li>Any function added to a class whose initial argument matches the class (or
any base) will act like a member function in Python.
<li>To define a nested class, just pass the enclosing
<tt>class_builder</tt> (instead of a <tt>module_builder</tt>) as the
first argument to the nested <tt>class_builder</tt>'s constructor.
</ul>
<p>
We can even make a subclass of <code>hello.world</code>:

View File

@@ -25,6 +25,22 @@ class class_builder
module.add(ref(as_object(m_class.get()), ref::increment_count), name);
}
template <class OtherT, class OtherU>
class_builder(class_builder<OtherT, OtherU>& cls, const char* name)
: m_class(new detail::extension_class<T, U>(name))
{
cls.add(ref(as_object(m_class.get()), ref::increment_count), name);
}
template <class OtherT, class OtherU>
class_builder(detail::extension_class<OtherT, OtherU>* cls,
const char* name)
: m_class(new detail::extension_class<T, U>(name))
{
cls->set_attribute(name,
ref(as_object(m_class.get()), ref::increment_count));
}
~class_builder()
{}

View File

@@ -67,6 +67,16 @@ Foo::PythonClass::PythonClass(boost::python::module_builder& m)
def(&Foo::add_len, "add_len", &FooCallback::default_add_len);
// Since pure() is pure virtual, we are leaving it undefined.
// And the nested classes.
boost::python::class_builder<Foo::Foo_A> foo_a(*this, "Foo_A");
foo_a.def(boost::python::constructor<>());
foo_a.def(&Foo::Foo_A::mumble, "mumble");
boost::python::class_builder<Foo::Foo_B> foo_b(get_extension_class(),
"Foo_B");
foo_b.def(boost::python::constructor<>());
foo_b.def(&Foo::Foo_B::mumble, "mumble");
}
BarPythonClass::BarPythonClass(boost::python::module_builder& m)
@@ -223,6 +233,16 @@ const char* Foo::mumble()
return "mumble";
}
const char* Foo::Foo_A::mumble()
{
return "mumble a";
}
const char* Foo::Foo_B::mumble()
{
return "mumble b";
}
void Foo::set(long x)
{
m_x = x;

View File

@@ -42,6 +42,10 @@ class Foo // prohibit copying, proving that it doesn't choke
std::string call_pure(); // call a pure virtual fuction
int call_add_len(const char* s) const; // virtual function with a default implementation
// A couple nested classs.
struct Foo_A { const char* mumble(); };
struct Foo_B { const char* mumble(); };
private:
// by default, sum the held value and the length of s
virtual int add_len(const char* s) const;

View File

@@ -230,6 +230,14 @@ Polymorphism also works:
>>> baz.get_foo_value(polymorphic_foo)
1000
Simple nested class test:
>>> foo_a = Foo.Foo_A()
>>> foo_a.mumble()
'mumble a'
>>> foo_b = Foo.Foo_B()
>>> foo_b.mumble()
'mumble b'
Pickling tests:
>>> world.__module__
@@ -343,7 +351,7 @@ Special member attributes. Tests courtesy of Barry Scott <barry@scottb.demon.co.
... '__doc__', '__module__', 'fred', 'i_am_derived_from_base']
... else:
... assert dir(df) == [
... '__del__', '__doc__', '__init__', '__module__', 'add_len',
... 'Foo_A', 'Foo_B', '__del__', '__doc__', '__init__', '__module__', 'add_len',
... 'call_add_len', 'call_pure', 'fred', 'mumble', 'set']
... assert dir(db) == ['__doc__', '__module__', 'fred'
... , 'i_am_base', 'i_am_derived_from_base']