diff --git a/doc/tutorial/doc/basic_interface.html b/doc/tutorial/doc/basic_interface.html index a9326c80..8165b121 100644 --- a/doc/tutorial/doc/basic_interface.html +++ b/doc/tutorial/doc/basic_interface.html @@ -34,7 +34,7 @@ To illustrate, this Python code snippet:
def f(x, y):
if (y == 'foo'):
- x[3:7] = 'bar'
+ x[3:7] = 'bar'
else:
x.items += y(3, x)
return x
@@ -45,16 +45,16 @@ To illustrate, this Python code snippet:
Can be rewritten in C++ using Boost.Python facilities this way:
- object f(object x, object y) {
+ object f(object x, object y) {
if (y == "foo")
- x.slice(3,7) = "bar";
+ x.slice(3,7) = "bar";
else
- x.attr("items") += y(3, x);
+ x.attr("items") += y(3, x);
return x;
- }
- object getfunc() {
+ }
+ object getfunc() {
return object(f);
- }
+ }
Apart from cosmetic differences due to the fact that we are writing the
@@ -68,7 +68,7 @@ coder.
-
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/building_hello_world.html b/doc/tutorial/doc/building_hello_world.html
index 297757ea..09b7ba93 100644
--- a/doc/tutorial/doc/building_hello_world.html
+++ b/doc/tutorial/doc/building_hello_world.html
@@ -182,7 +182,7 @@ You may now fire up Python and run our hello module:
-
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/call_policies.html b/doc/tutorial/doc/call_policies.html
index 4f836700..47871700 100644
--- a/doc/tutorial/doc/call_policies.html
+++ b/doc/tutorial/doc/call_policies.html
@@ -43,9 +43,9 @@ How should the library wrap this function? A naive approach builds a
Python X object around result reference. This strategy might or might
not work out. Here's an example where it didn't
- >>> x = f(y, z) #x refers to some C++ X
+ >>> x = f(y, z) ##x refers to some C++ X
>>> del y
- >>> x.some_method() #CRASH!
+ >>> x.some_method() ##CRASH!
What's the problem?
@@ -53,10 +53,10 @@ What's the problem?
Well, what if f() was implemented as shown below:
X& f(Y& y, Z* z)
- {
+ {
y.z = z;
return y.x;
- }
+ }
The problem is that the lifetime of result X& is tied to the lifetime
@@ -70,8 +70,8 @@ Here's what's happening:
- f is called passing in a reference to y and a pointer to z
- A reference to y.x is returned
- y is deleted. x is a dangling reference
- x.some_method() is called
- BOOM!
We could copy result into a new object:
- >>> f(y, z).set(42) #Result disappears
- >>> y.x.get() #No crash, but still bad
+ >>> f(y, z).set(42) ##Result disappears
+ >>> y.x.get() ##No crash, but still bad
3.14
@@ -84,25 +84,25 @@ Our problems do not end there. Suppose Y is implemented as follows:
struct Y
{
X x; Z* z;
- int z_value() { return z->value(); }
- };
+ int z_value() { return z->value(); }
+ };
Notice that the data member z is held by class Y using a raw pointer. Now we have a potential dangling pointer problem inside Y:
- >>> x = f(y, z) #y refers to z
- >>> del z #Kill the z object
- >>> y.z_value() #CRASH!
+ >>> x = f(y, z) ##y refers to z
+ >>> del z ##Kill the z object
+ >>> y.z_value() ##CRASH!
For reference, here's the implementation of f again:
X& f(Y& y, Z* z)
- {
+ {
y.z = z;
return y.x;
- }
+ }
Here's what's happening:
@@ -113,7 +113,7 @@ are our friends:
def("f", f,
return_internal_reference<1,
- with_custodian_and_ward<1, 2> >());
+ with_custodian_and_ward<1, 2> >());
What are the 1 and 2 parameters, you ask?
@@ -138,7 +138,7 @@ or more policies can be composed by chaining. Here's the general syntax:
policy1<args...,
policy2<args...,
- policy3<args...> > >
+ policy3<args...> > >
Here is the list of predefined call policies. A complete reference detailing @@ -160,7 +160,7 @@ here.
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Our C++ Var class and its data members can be exposed to Python:
-Then, in Python:
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/class_data_members.html b/doc/tutorial/doc/class_data_members.html
index 39847ba8..b43bf83c 100644
--- a/doc/tutorial/doc/class_data_members.html
+++ b/doc/tutorial/doc/class_data_members.html
@@ -32,23 +32,24 @@ member that we wish to be exposed may be regarded as read-only or
struct Var
{
- Var(std::string name) : name(name), value() {}
+ Var(std::string name) : name(name), value() {}
std::string const name;
float value;
- };
+ };
class_<Var>("Var", init<std::string>())
- .def_readonly("name", &Var::name)
- .def_readwrite("value", &Var::value);
+ .def_readonly("name", &Var::name)
+ .def_readwrite("value", &Var::value);
- >>> x = Var('pi')
- >>> x.value = 3.14
+ >>> x = hello.Var('pi')
+ >>> x.value = 3.14
>>> print x.name, 'is around', x.value
pi is around 3.14
@@ -68,7 +69,7 @@ as read-write.
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/class_operators_special_functions.html b/doc/tutorial/doc/class_operators_special_functions.html
index 608f8ca9..e22bd2ff 100644
--- a/doc/tutorial/doc/class_operators_special_functions.html
+++ b/doc/tutorial/doc/class_operators_special_functions.html
@@ -32,7 +32,7 @@ this and makes it easy to wrap C++ operator-powered classes.
- class FilePos { /*...*/ };
+ class FilePos { /*...*/ };
FilePos operator+(FilePos, int);
FilePos operator+(int, FilePos);
@@ -47,13 +47,13 @@ The class and the various operators can be mapped to Python rather easily
and intuitively:
class_<FilePos>("FilePos")
- .def(self + int()) // __add__
- .def(int() + self) // __radd__
- .def(self - self) // __sub__
- .def(self - int()) // __sub__
- .def(self += int()) // __iadd__
+ .def(self + int()) // __add__
+ .def(int() + self) // __radd__
+ .def(self - self) // __sub__
+ .def(self - int()) // __sub__
+ .def(self += int()) // __iadd__
.def(self -= other<int>())
- .def(self < self); // __lt__
+ .def(self < self); // __lt__
The code snippet above is very clear and needs almost no explanation at
@@ -69,17 +69,17 @@ similar set of intuitive interfaces can also be used to wrap C++ functions
that correspond to these Python special functions. Example:
class Rational
- { operator double() const; };
+ { operator double() const; };
Rational pow(Rational, Rational);
Rational abs(Rational);
ostream& operator<<(ostream&,Rational);
class_<Rational>()
- .def(float_(self)) // __float__
- .def(pow(self, other<Rational>)) // __pow__
- .def(abs(self)) // __abs__
- .def(str(self)) // __str__
+ .def(float_(self)) // __float__
+ .def(pow(self, other<Rational>)) // __pow__
+ .def(abs(self)) // __abs__
+ .def(str(self)) // __str__
;
@@ -100,7 +100,7 @@ Well, the method str requires the operator<< to do its w
-
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/class_properties.html b/doc/tutorial/doc/class_properties.html
index 22d2921a..99f340c4 100644
--- a/doc/tutorial/doc/class_properties.html
+++ b/doc/tutorial/doc/class_properties.html
@@ -36,35 +36,33 @@ properties. Here's an example:
Num();
float get() const;
void set(float value);
- ...
- };
+ ...
+ };
However, in Python attribute access is fine; it doesn't neccessarily break encapsulation to let users handle attributes directly, because the attributes can just be a different syntax for a method call. Wrapping our Num class using Boost.Python:
-
-
+
class_<Num>("Num")
- .add_property("rovalue", &Num::get)
- .add_property("value", &Num::get, &Var::set);
-
-
+ .add_property("rovalue", &Num::get)
+ .add_property("value", &Num::get, &Num::set);
+
And at last, in Python:
>>> x = Num()
- >>> x.value = 3.14
+ >>> x.value = 3.14
>>> x.value, x.rovalue
(3.14, 3.14)
- >>> x.rovalue = 2.17 #error!
+ >>> x.rovalue = 2.17 ##error!
Take note that the class property rovalue is exposed as read-only since the rovalue setter member function is not passed in:
- .add_property("rovalue", &Var::get)
+ .add_property("rovalue", &Num::get)
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/class_virtual_functions.html b/doc/tutorial/doc/class_virtual_functions.html
index ebe943bf..46cb7837 100644
--- a/doc/tutorial/doc/class_virtual_functions.html
+++ b/doc/tutorial/doc/class_virtual_functions.html
@@ -31,8 +31,8 @@ add a virtual function to our Base class:
struct Base
{
- virtual int f() = 0;
- };
+ virtual int f() = 0;
+ };
Since f is a pure virtual function, Base is now an abstract @@ -40,7 +40,7 @@ class. Given an instance of our class, the free function call_f calls some implementation of this virtual function in a concrete derived class:
- int call_f(Base& b) { return b.f(); }
+ int call_f(Base& b) { return b.f(); }
To allow this function to be implemented in a Python derived class, we @@ -49,10 +49,10 @@ need to create a class wrapper:
struct BaseWrap : Base { BaseWrap(PyObject* self_) - : self(self_) {} - int f() { return call_method<int>(self, "f"); } + : self(self_) {} + int f() { return call_method<int>(self, "f"); } PyObject* self; - }; + };Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/constructors.html b/doc/tutorial/doc/constructors.html
index 79237526..809bfee3 100644
--- a/doc/tutorial/doc/constructors.html
+++ b/doc/tutorial/doc/constructors.html
@@ -38,11 +38,11 @@ build on our previous example:
struct World
{
- World(std::string msg): msg(msg) {} // added constructor
- void set(std::string msg) { this->msg = msg; }
- std::string greet() { return msg; }
+ World(std::string msg): msg(msg) {} // added constructor
+ void set(std::string msg) { this->msg = msg; }
+ std::string greet() { return msg; }
std::string msg;
- };
+ };
This time World has no default constructor; our previous @@ -54,12 +54,12 @@ expose instead.
using namespace boost::python; BOOST_PYTHON_MODULE(hello) - { + { class_<World>("World", init<std::string>()) - .def("greet", &World::greet) - .def("set", &World::set) - ; - } + .def("greet", &World::greet) + .def("set", &World::set) + ; + }init<std::string>() exposes the constructor taking in a @@ -71,10 +71,10 @@ the def() member function. Say for example we have another World constructor taking in two doubles:
class_<World>("World", init<std::string>())
- .def(init<double, double>())
- .def("greet", &World::greet)
- .def("set", &World::set)
- ;
+ .def(init<double, double>())
+ .def("greet", &World::greet)
+ .def("set", &World::set)
+ ;
On the other hand, if we do not wish to expose any constructors at @@ -93,7 +93,7 @@ Python RuntimeError exception.
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
@@ -29,43 +29,44 @@ Boost.Python wraps (member) function pointers. Unfortunately, C++ function
pointers carry no default argument info. Take a function f with default
arguments:
But the type of a pointer to the function f has no information
about its default arguments:
When we pass this function pointer to the def function, there is no way
to retrieve the default arguments:
Because of this, when wrapping C++ code in earlier versions of
Boost.Python, we had to resort to writing thin wrappers:
When you want to wrap functions (or member functions) that either:
-Boost.Python now has a way to make it easier.
-For instance, given a function:
+Boost.Python now has a way to make it easier. For instance, given a function:
The macro invocation:
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/default_arguments.html b/doc/tutorial/doc/default_arguments.html
index bfb3ce3b..8eaf8476 100644
--- a/doc/tutorial/doc/default_arguments.html
+++ b/doc/tutorial/doc/default_arguments.html
@@ -4,7 +4,7 @@
@@ -21,7 +21,7 @@

- 
+ 

- int f(int, double = 3.14, char const* = "hello");
+ int f(int, double = 3.14, char const* = "hello");
- int(*g)(int,double,char const*) = f; // defaults lost!
+ int(*g)(int,double,char const*) = f; // defaults lost!
- def("f", f); // defaults lost!
+ def("f", f); // defaults lost!
// write "thin wrappers"
- int f1(int x) { f(x); }
- int f2(int x, double y) { f(x,y); }
+ int f1(int x) { f(x); }
+ int f2(int x, double y) { f(x,y); }
- /*...*/
+ /*...*/
- // in module init
- def("f", f); // all arguments
- def("f", f2); // two arguments
- def("f", f1); // one argument
+ // in module init
+ def("f", f); // all arguments
+ def("f", f2); // two arguments
+ def("f", f1); // one argument
BOOST_PYTHON_FUNCTION_OVERLOADS
- int foo(int a, char b = 1, unsigned c = 2, double d = 3);
+ int foo(int a, char b = 1, unsigned c = 2, double d = 3)
+ {
+ /*...*/
+ }
-Will automatically create the thin wrappers for us. This macro will create +will automatically create the thin wrappers for us. This macro will create a class foo_overloads that can be passed on to def(...). The third and fourth macro argument are the minimum arguments and maximum arguments, respectively. In our foo function the minimum number of arguments is 1 @@ -82,21 +83,58 @@ automatically add all the foo variants for us:
.def("foo", foo, foo_overloads());
++Objects here, objects there, objects here there everywhere. More frequently +than anything else, we need to expose member functions of our classes to +Python. Then again, we have the same inconveniences as before when default +arguments or overloads with a common sequence of initial arguments come +into play. Another macro is provided to make this a breeze.
+Like BOOST_PYTHON_FUNCTION_OVERLOADS, +BOOST_PYTHON_FUNCTION_OVERLOADS may be used to automatically create +the thin wrappers for wrapping member functions. Let's have an example:
+
+ struct george
+ {
+ void
+ wack_em(int a, int b = 0, char c = 'x')
+ {
+ /*...*/
+ }
+ };
+
++The macro invocation:
+
+ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3)
+
++will generate a set of thin wrappers for george's wack_em member function +accepting a minimum of 1 and a maximum of 3 arguments (i.e. the third and +fourth macro argument). The thin wrappers are all enclosed in a class named +george_overloads that can then be used as an argument to def(...):
+
+ .def("wack_em", &george::wack_em, george_overloads());
+
++See the +overloads reference +for details.
+A similar facility is provided for class constructors, again, with -default arguments or a sequence of overloads. Remember init<...>? For example, +default arguments or a sequence of overloads. Remember init<...>? For example, given a class X with a constructor:
struct X
{
X(int a, char b = 'D', std::string c = "constructor", double d = 0.0);
- /*...*/
- }
+ /*...*/
+ }
You can easily add this constructor to Boost.Python in one shot:
- .def(init<int, optional<char, std::string, double> >())
+ .def(init<int, optional<char, std::string, double> >())
Notice the use of init<...> and optional<...> to signify the default @@ -105,11 +143,11 @@ Notice the use of init<...> and optional<...> to s




Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/derived_object_types.html b/doc/tutorial/doc/derived_object_types.html
index 54ffccb3..fbe44584 100644
--- a/doc/tutorial/doc/derived_object_types.html
+++ b/doc/tutorial/doc/derived_object_types.html
@@ -30,7 +30,7 @@ that of Python's:
These derived object types act like real Python types. For instance:
- str(1) ==> "1"
+ str(1) ==> "1"
Wherever appropriate, a particular derived object has corresponding @@ -50,11 +50,11 @@ declared below, is wrapped, it will only accept instances of Python's str type and subtypes.
void f(str name)
- {
- object n2 = name.attr("upper")(); // NAME = name.upper()
- str NAME = name.upper(); // better
+ {
+ object n2 = name.attr("upper")(); // NAME = name.upper()
+ str NAME = name.upper(); // better
object msg = "%s is bigger than %s" % make_tuple(NAME,name);
- }
+ }
In finer detail:
@@ -76,14 +76,14 @@ of most of Python's mutable types make copies, just as in Python.Python:
- >>> d = dict(x.__dict__) #copies x.__dict__
- >>> d['whatever'] #modifies the copy
+ >>> d = dict(x.__dict__) ##copies x.__dict__
+ >>> d['whatever'] ##modifies the copy
C++:
- dict d(x.attr("__dict__")); #copies x.__dict__
- d['whatever'] = 3; #modifies the copy
+ dict d(x.attr("__dict__")); ##copies x.__dict__
+ d['whatever'] = 3; ##modifies the copy
Due to the dynamic nature of Boost.Python objects, any class_<T> may @@ -92,13 +92,13 @@ also be one of these types! The following code snippet wraps the class
We can use this to create wrapped instances. Example:
- object vec345 = (
+ object vec345 = (
class_<Vec2>("Vec2", init<double, double>())
- .def_readonly("length", &Point::length)
- .def_readonly("angle", &Point::angle)
- )(3.0, 4.0);
+ .def_readonly("length", &Point::length)
+ .def_readonly("angle", &Point::angle)
+ )(3.0, 4.0);
- assert(vec345.attr("length") == 5.0);
+ assert(vec345.attr("length") == 5.0);
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/enums.html b/doc/tutorial/doc/enums.html
index 29c9623b..f9bc1272 100644
--- a/doc/tutorial/doc/enums.html
+++ b/doc/tutorial/doc/enums.html
@@ -38,9 +38,9 @@ enums). To illustrate, given a C++ enum:
enum_<choice>("choice")
- .value("red", red)
- .value("blue", blue)
- ;
+ .value("red", red)
+ .value("blue", blue)
+ ;
can be used to expose to Python. The new enum type is created in the @@ -67,16 +67,16 @@ You can access those values in Python as
where my_module is the module where the enum is declared. You can also create a new scope around a class:
- scope in_X = class_<X>("X")
- .def( ... )
- .def( ... )
- ;
+ scope in_X = class_<X>("X")
+ .def( ... )
+ .def( ... )
+ ;
- // Expose X::nested as X.nested
+ // Expose X::nested as X.nested
enum_<X::nested>("nested")
- .value("red", red)
- .value("blue", blue)
- ;
+ .value("red", red)
+ .value("blue", blue)
+ ;
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/exception_translation.html b/doc/tutorial/doc/exception_translation.html
index aaab2ec7..51c73560 100644
--- a/doc/tutorial/doc/exception_translation.html
+++ b/doc/tutorial/doc/exception_translation.html
@@ -33,16 +33,16 @@ then gives up:
Users may provide custom translation. Here's an example:
-
- struct PodBayDoorException;
- void translator(PodBayDoorException const& x) {
+
+ struct PodBayDoorException;
+ void translator(PodBayDoorException const& x) {
PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave...");
}
BOOST_PYTHON_MODULE(kubrick) {
register_exception_translator<
PodBayDoorException>(translator);
...
-
+
![]() |
@@ -51,7 +51,7 @@ Users may provide custom translation. Here's an example:
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/exposing_classes.html b/doc/tutorial/doc/exposing_classes.html
index 7a989346..18f2e8d0 100644
--- a/doc/tutorial/doc/exposing_classes.html
+++ b/doc/tutorial/doc/exposing_classes.html
@@ -31,10 +31,10 @@ Consider a C++ class/struct that we want to expose to Python:
struct World
{
- void set(std::string msg) { this->msg = msg; }
- std::string greet() { return msg; }
+ void set(std::string msg) { this->msg = msg; }
+ std::string greet() { return msg; }
std::string msg;
- };
+ };
We can expose this to Python by writing a corresponding Boost.Python @@ -44,12 +44,12 @@ C++ Wrapper:
using namespace boost::python; BOOST_PYTHON_MODULE(hello) - { + { class_<World>("World") - .def("greet", &World::greet) - .def("set", &World::set) - ; - } + .def("greet", &World::greet) + .def("set", &World::set) + ; + }Here, we wrote a C++ class wrapper that exposes the member functions @@ -58,8 +58,8 @@ may use our class World in Python. Here's a sample Python session:
>>> import hello
>>> planet = hello.World()
- >>> planet.set('howdy')
- >>> planet.greet()
+ >>> planet.set('howdy')
+ >>> planet.greet()
'howdy'
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/extracting_c___objects.html b/doc/tutorial/doc/extracting_c___objects.html
index 36b8bf85..82096e6d 100644
--- a/doc/tutorial/doc/extracting_c___objects.html
+++ b/doc/tutorial/doc/extracting_c___objects.html
@@ -28,7 +28,7 @@
At some point, we will need to get C++ values out of object instances. This
can be achieved with the extract<T> function. Consider the following:
- double x = o.attr("length"); // compile error
+ double x = o.attr("length"); // compile error
In the code above, we got a compiler error because Boost.Python @@ -52,15 +52,15 @@ appropriate exception is thrown. To avoid an exception, we need to test for extractibility:
extract<Vec2&> x(o);
- if (x.check()) {
- Vec2& v = x(); ...
+ if (x.check()) {
+ Vec2& v = x(); ...
The astute reader might have noticed that the extract<T>
facility in fact solves the mutable copying problem:
dict d = extract<dict>(x.attr("__dict__"));
- d['whatever'] = 3; #modifies x.__dict__ !
+ d['whatever'] = 3; ##modifies x.__dict__ !
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams Copyright © 2002 David Abrahams Copyright © 2002-2003 David Abrahams
Consider this trivial inheritance structure:
@@ -42,22 +42,22 @@ instances:
We've seen how we can wrap the base class Base:
Now we can inform Boost.Python of the inheritance relationship between
Derived and its base class Base. Thus:
Doing so, we get some things for free:
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/functions.html b/doc/tutorial/doc/functions.html
index 036242e2..6a29d89b 100644
--- a/doc/tutorial/doc/functions.html
+++ b/doc/tutorial/doc/functions.html
@@ -64,7 +64,7 @@ But before you do, you might want to fire up Python 2.2 or later and type
-
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/inheritance.html b/doc/tutorial/doc/inheritance.html
index 0f9fe33f..acd18942 100644
--- a/doc/tutorial/doc/inheritance.html
+++ b/doc/tutorial/doc/inheritance.html
@@ -33,7 +33,7 @@ abstract base classes.
- struct Base { virtual ~Base(); };
+ struct Base { virtual ~Base(); };
struct Derived : Base {};
void b(Base*);
void d(Derived*);
- Base* factory() { return new Derived; }
+ Base* factory() { return new Derived; }
class_<Base>("Base")
- /*...*/
- ;
+ /*...*/
+ ;
- class_<Derived, bases<Base> >("Derived")
- /*...*/
- ;
+ class_<Derived, bases<Base> >("Derived")
+ /*...*/
+ ;
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/iterators.html b/doc/tutorial/doc/iterators.html
index 00e8dc44..c0234efc 100644
--- a/doc/tutorial/doc/iterators.html
+++ b/doc/tutorial/doc/iterators.html
@@ -34,12 +34,12 @@ iterators, but these are two very different beasts.
The typical Python iteration protocol: for y in x... is as follows:
- iter = x.__iter__() #get iterator
+ iter = x.__iter__() ##get iterator
try:
while 1:
- y = iter.next() #get each item
- ... #process y
- except StopIteration: pass #iterator exhausted
+ y = iter.next() ##get each item
+ ... ##process y
+ except StopIteration: pass ##iterator exhausted
Boost.Python provides some mechanisms to make C++ iterators play along @@ -47,14 +47,14 @@ nicely as Python iterators. What we need to do is to produce appropriate __iter__ function from C++ iterators that is compatible with the Python iteration protocol. For example:
- object get_iterator = iterator<vector<int> >();
+ object get_iterator = iterator<vector<int> >();
object iter = get_iterator(v);
object first = iter.next();
Or for use in class_<>:
- .def("__iter__", iterator<vector<int> >())
+ .def("__iter__", iterator<vector<int> >())
range
@@ -81,8 +81,8 @@ bogon Particle accelerator code: Now, our C++ Wrapper:
class_<F>("Field")
- .property("pions", range(&F::p_begin, &F::p_end))
- .property("bogons", range(&F::b_begin, &F::b_end));
+ .property("pions", range(&F::p_begin, &F::p_end))
+ .property("bogons", range(&F::b_begin, &F::b_end));
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/object_interface.html b/doc/tutorial/doc/object_interface.html
index d18a40bb..1fd3a04d 100644
--- a/doc/tutorial/doc/object_interface.html
+++ b/doc/tutorial/doc/object_interface.html
@@ -3,7 +3,7 @@
@@ -40,12 +40,12 @@ should minimize the learning curve significantly.
- 
+ 


![]() |
- ![]() |
+ ![]() |
![]() |
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams
+It was mentioned in passing in the previous section that
+BOOST_PYTHON_FUNCTION_OVERLOADS and BOOST_PYTHON_FUNCTION_OVERLOADS
+can also be used for overloaded functions and member functions with a
+common sequence of initial arguments. Here is an example:
+Like in the previous section, we can generate thin wrappers for these
+overloaded functions in one-shot:
+Then...
+Notice though that we have a situation now where we have a minimum of zero
+(0) arguments and a maximum of 3 arguments.
+It is important to emphasize however that the overloaded functions must
+have a common sequence of initial arguments. Otherwise, our scheme above
+will not work.
+The following illustrates an alternate scheme for manually wrapping an
+overloaded member function instead of
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS. Obviously, the same technique
+can be applied to wrapping overloaded non- member functions.
+We have here our C++ classes:
+Notice that class X has two overloaded functions with different signatures.
+The types of the arguments, and the return are totally different, unlike
+above where we have a common sequence of initial arguments.
+We shall start by introducing some member function pointer variables:
+The first three member function pointers take care of the first X::f
+overload. The one with default arguments. The last member function pointer
+takes care of the second X::f overload.
+With these in hand, we can proceed to define and wrap this for Python:
+Actually, we can mix and match manual wrapping of overloaded functions and
+automatic wrapping through BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS and
+its sister, BOOST_PYTHON_FUNCTION_OVERLOADS. Since the first overload
+has default arguments, we can use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
+to automatically wrap the first three of the defs above and manually
+wrap just the last. Here's how we'll do this:
+Create a member function pointers as above for both X::f overloads:
+Then... Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/overloading.html b/doc/tutorial/doc/overloading.html
new file mode 100644
index 00000000..da0ad8ac
--- /dev/null
+++ b/doc/tutorial/doc/overloading.html
@@ -0,0 +1,152 @@
+
+
+
+
+
+
+
+
+
+
+ Overloading
+
+
+
+
+
+
+
+ 
+ 
+ 
+
+ void foo()
+ {
+ /*...*/
+ }
+
+ void foo(bool a)
+ {
+ /*...*/
+ }
+
+ void foo(bool a, int b)
+ {
+ /*...*/
+ }
+
+ void foo(bool a, int b, char c)
+ {
+ /*...*/
+ }
+
+
+ BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3)
+
+
+ .def("foo", foo, foo_overloads());
+
Manual Wrapping
+
+ struct X
+ {
+ bool f(int a, double b = 0, char c = 'x')
+ {
+ return true;
+ }
+
+ int f(int a, int b, int c)
+ {
+ return a + b + c;
+ };
+ };
+
+
+ bool (X::*fx1)(int) = &X::f;
+ bool (X::*fx2)(int, double) = &X::f;
+ bool (X::*fx3)(int, double, char)= &X::f;
+ int (X::*fx4)(int, int, int) = &X::f;
+
+
+ .def("f", fx1)
+ .def("f", fx2)
+ .def("f", fx3)
+ .def("f", fx4)
+
+
+ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)
+
+
+ bool (X::*fx1)(int, double, char) = &X::f;
+ int (X::*fx2)(int, int, int) = &X::f;
+
+
+ .def("f", fx1, xf_overloads());
+ .def("f", fx2)
+
+
+
+
+
+ 
+ 
+ 
+
Copyright © 2002-2003 Joel de Guzman
+Permission to copy, use, modify, sell and distribute this document
+ is granted provided this copyright notice appears in all copies. This document
+ is provided "as is" without express or implied warranty, and with
+ no claim as to its suitability for any purpose.
char const* greet()
- {
+ {
return "hello, world";
- }
+ }
can be exposed to Python by writing a Boost.Python wrapper:
@@ -50,9 +50,9 @@ can be exposed to Python by writing a Boost.Python wrapper: using namespace boost::python; BOOST_PYTHON_MODULE(hello) - { + { def("greet", greet); - } + }That's it. We're done. We can now build this as a shared library. The @@ -70,7 +70,7 @@ resulting DLL is now visible to Python. Here's a sample Python session:
Copyright © 2002 David Abrahams
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 David Abrahams Copyright © 2002 David Abrahams Copyright © 2002-2003 David Abrahams
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt
index a67e196e..3d4eb7ec 100644
--- a/doc/tutorial/doc/quickstart.txt
+++ b/doc/tutorial/doc/quickstart.txt
@@ -339,9 +339,10 @@ Our C++ [^Var] class and its data members can be exposed to Python:
.def_readonly("name", &Var::name)
.def_readwrite("value", &Var::value);
-Then, in Python:
+Then, in Python, assuming we have placed our Var class inside the namespace
+hello as we did before:
- >>> x = Var('pi')
+ >>> x = hello.Var('pi')
>>> x.value = 3.14
>>> print x.name, 'is around', x.value
pi is around 3.14
@@ -910,17 +911,20 @@ When you want to wrap functions (or member functions) that either:
* have default arguments, or
* are overloaded with a common sequence of initial arguments
-Boost.Python now has a way to make it easier.
+[h2 BOOST_PYTHON_FUNCTION_OVERLOADS]
-For instance, given a function:
+Boost.Python now has a way to make it easier. For instance, given a function:
- int foo(int a, char b = 1, unsigned c = 2, double d = 3);
+ int foo(int a, char b = 1, unsigned c = 2, double d = 3)
+ {
+ /*...*/
+ }
The macro invocation:
BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4)
-Will automatically create the thin wrappers for us. This macro will create
+will automatically create the thin wrappers for us. This macro will create
a class [^foo_overloads] that can be passed on to [^def(...)]. The third
and fourth macro argument are the minimum arguments and maximum arguments,
respectively. In our [^foo] function the minimum number of arguments is 1
@@ -929,8 +933,45 @@ automatically add all the foo variants for us:
.def("foo", foo, foo_overloads());
+[h2 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS]
+
+Objects here, objects there, objects here there everywhere. More frequently
+than anything else, we need to expose member functions of our classes to
+Python. Then again, we have the same inconveniences as before when default
+arguments or overloads with a common sequence of initial arguments come
+into play. Another macro is provided to make this a breeze.
+
+Like [^BOOST_PYTHON_FUNCTION_OVERLOADS],
+[^BOOST_PYTHON_FUNCTION_OVERLOADS] may be used to automatically create
+the thin wrappers for wrapping member functions. Let's have an example:
+
+ struct george
+ {
+ void
+ wack_em(int a, int b = 0, char c = 'x')
+ {
+ /*...*/
+ }
+ };
+
+The macro invocation:
+
+ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3)
+
+will generate a set of thin wrappers for george's [^wack_em] member function
+accepting a minimum of 1 and a maximum of 3 arguments (i.e. the third and
+fourth macro argument). The thin wrappers are all enclosed in a class named
+[^george_overloads] that can then be used as an argument to [^def(...)]:
+
+ .def("wack_em", &george::wack_em, george_overloads());
+
+See the [@../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec overloads reference]
+for details.
+
+[h2 init and optional]
+
A similar facility is provided for class constructors, again, with
-default arguments or a sequence of overloads. Remember init<...>? For example,
+default arguments or a sequence of overloads. Remember [^init<...>]? For example,
given a class X with a constructor:
struct X
@@ -946,6 +987,112 @@ You can easily add this constructor to Boost.Python in one shot:
Notice the use of [^init<...>] and [^optional<...>] to signify the default
(optional arguments).
+[page:1 Overloading]
+
+It was mentioned in passing in the previous section that
+[^BOOST_PYTHON_FUNCTION_OVERLOADS] and [^BOOST_PYTHON_FUNCTION_OVERLOADS]
+can also be used for overloaded functions and member functions with a
+common sequence of initial arguments. Here is an example:
+
+ void foo()
+ {
+ /*...*/
+ }
+
+ void foo(bool a)
+ {
+ /*...*/
+ }
+
+ void foo(bool a, int b)
+ {
+ /*...*/
+ }
+
+ void foo(bool a, int b, char c)
+ {
+ /*...*/
+ }
+
+Like in the previous section, we can generate thin wrappers for these
+overloaded functions in one-shot:
+
+ BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3)
+
+Then...
+
+ .def("foo", foo, foo_overloads());
+
+Notice though that we have a situation now where we have a minimum of zero
+(0) arguments and a maximum of 3 arguments.
+
+[h2 Manual Wrapping]
+
+It is important to emphasize however that [*the overloaded functions must
+have a common sequence of initial arguments]. Otherwise, our scheme above
+will not work.
+
+The following illustrates an alternate scheme for manually wrapping an
+overloaded member function instead of
+[^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS]. Obviously, the same technique
+can be applied to wrapping overloaded non- member functions.
+
+We have here our C++ classes:
+
+ struct X
+ {
+ bool f(int a, double b = 0, char c = 'x')
+ {
+ return true;
+ }
+
+ int f(int a, int b, int c)
+ {
+ return a + b + c;
+ };
+ };
+
+Notice that class X has two overloaded functions with different signatures.
+The types of the arguments, and the return are totally different, unlike
+above where we have a common sequence of initial arguments.
+
+We shall start by introducing some member function pointer variables:
+
+ bool (X::*fx1)(int) = &X::f;
+ bool (X::*fx2)(int, double) = &X::f;
+ bool (X::*fx3)(int, double, char)= &X::f;
+ int (X::*fx4)(int, int, int) = &X::f;
+
+The first three member function pointers take care of the first X::f
+overload. The one with default arguments. The last member function pointer
+takes care of the second X::f overload.
+
+With these in hand, we can proceed to define and wrap this for Python:
+
+ .def("f", fx1)
+ .def("f", fx2)
+ .def("f", fx3)
+ .def("f", fx4)
+
+Actually, we can mix and match manual wrapping of overloaded functions and
+automatic wrapping through [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] and
+its sister, [^BOOST_PYTHON_FUNCTION_OVERLOADS]. Since the first overload
+has default arguments, we can use [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS]
+to automatically wrap the first three of the [^def]s above and manually
+wrap just the last. Here's how we'll do this:
+
+ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)
+
+Create a member function pointers as above for both X::f overloads:
+
+ bool (X::*fx1)(int, double, char) = &X::f;
+ int (X::*fx2)(int, int, int) = &X::f;
+
+Then...
+
+ .def("f", fx1, xf_overloads());
+ .def("f", fx2)
+
[page Object Interface]
Python is dynamically typed, unlike C++ which is statically typed. Python
diff --git a/doc/tutorial/index.html b/doc/tutorial/index.html
index 4e1333da..108d25f6 100644
--- a/doc/tutorial/index.html
+++ b/doc/tutorial/index.html
@@ -80,6 +80,11 @@
Default Arguments
+
+
+ Overloading
+
+
Object Interface
@@ -117,7 +122,7 @@
-
Copyright © 2002 Joel de Guzman
+
Copyright © 2002-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with