Boost logo

Boost :

From: scott snyder (snyder_at_[hidden])
Date: 2001-12-16 21:54:58


hi -

Here's a revised version of this patch that adds test code and
a mention in the documentation.

This just allows you to specify another class_builder as the first
argument of a class_builder constructor, in order to make a class be
an attribute of another class.

sss

Index: boost/python/class_builder.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/python/class_builder.hpp,v
retrieving revision 1.3
diff -u -p -r1.3 class_builder.hpp
--- boost/python/class_builder.hpp 2001/03/03 12:55:53 1.3
+++ boost/python/class_builder.hpp 2001/12/16 21:08:16
@@ -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()
     {}
 
Index: libs/python/doc/exporting_classes.html
===================================================================
RCS file: /cvsroot/boost/boost/libs/python/doc/exporting_classes.html,v
retrieving revision 1.1
diff -u -p -r1.1 exporting_classes.html
--- libs/python/doc/exporting_classes.html 2001/03/07 03:39:31 1.1
+++ libs/python/doc/exporting_classes.html 2001/12/16 21:08:16
@@ -98,6 +98,11 @@ 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>The first argument to the <tt>class_builder</tt> constructor
+may be another <tt>class_builder</tt> instance, as well as a
+<tt>module_builder</tt>. This defines a nested class, as you'd expect.
+
 </ul>
       <p>
          We can even make a subclass of <code>hello.world</code>:
Index: libs/python/test/comprehensive.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/python/test/comprehensive.cpp,v
retrieving revision 1.14
diff -u -p -r1.14 comprehensive.cpp
--- libs/python/test/comprehensive.cpp 2001/12/16 17:58:23 1.14
+++ libs/python/test/comprehensive.cpp 2001/12/16 21:08:16
@@ -67,6 +67,16 @@ Foo::PythonClass::PythonClass(boost::pyt
     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)
@@ -221,6 +231,16 @@ IntPair make_pair(int x, int y)
 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)
Index: libs/python/test/comprehensive.hpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/python/test/comprehensive.hpp,v
retrieving revision 1.2
diff -u -p -r1.2 comprehensive.hpp
--- libs/python/test/comprehensive.hpp 2000/11/27 07:23:15 1.2
+++ libs/python/test/comprehensive.hpp 2001/12/16 21:08:16
@@ -42,6 +42,10 @@ class Foo // prohibit cop
     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;
Index: libs/python/test/comprehensive.py
===================================================================
RCS file: /cvsroot/boost/boost/libs/python/test/comprehensive.py,v
retrieving revision 1.13
diff -u -p -r1.13 comprehensive.py
--- libs/python/test/comprehensive.py 2001/12/15 22:59:48 1.13
+++ libs/python/test/comprehensive.py 2001/12/16 21:08:16
@@ -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__


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk