diff --git a/doc/special.html b/doc/special.html index 286dc396..525b0a56 100644 --- a/doc/special.html +++ b/doc/special.html @@ -41,12 +41,17 @@ __init__(self)
Initialize the class instance. For extension classes not subclassed in - Python, this is provided by the - boost::python::constructor<...>() construct and should not be explicitly defed. + Python, __init__ is defined by + +
    my_class.def(boost::python::constructor<...>())
+ + (see section "A Simple Example Using BPL").

__del__(self)
- Called when the extension instance is about to be destroyed. + Called when the extension instance is about to be destroyed. For extension classes + not subclassed in Python, __del__ is always defined automatically by + means of the class' destructor.
__repr__(self)
@@ -111,7 +116,7 @@ foo_class.def(&to_string, "__str__"); Numeric operators can be exposed manually, by defing C++ [member] functions that support the standard Python numeric - protocols. This is the basic same technique used to expose + protocols. This is the same basic technique used to expose to_string() as __str__() above, and is covered in detail below. BPL also supports automatic wrapping of numeric operators whenever they have already @@ -121,7 +126,7 @@ foo_class.def(&to_string, "__str__");

Supose we wanted to expose a C++ class - BigNum which supports addition, so that we can write (in C++): + BigNum which supports addition. That is, in C++ we can write:

 BigNum a, b, c;
 ...
@@ -196,7 +201,7 @@ BigNum operator+(BigNum, BigNum)
 
or as member functions
-BigNum::operator+(BigNum).
+BigNum BigNum::operator+(BigNum).
 

@@ -218,8 +223,7 @@ namespace boost { namespace python {

In some cases, automatic wrapping of operators may be impossible or undesirable. Suppose, for example, that the modulo operation for BigNums - is defined by a set of functions mod() (for automatic - wrapping, we would need operator%()): + is defined by a set of functions called mod():

 BigNum mod(BigNum const& left, BigNum const& right);
@@ -228,8 +232,9 @@ BigNum mod(int left, BigNum const& right);
 

- In order to create the Python operator "__mod__" from these functions, we - have to wrap them manually: + For automatic wrapping of the modulo function, operator%() would be needed. + Therefore, the mod()-functions must be wrapped manually. That is, we have + to export them explicitly with the Python special name "__mod__":

 bignum_class.def((BigNum (*)(BigNum const&, BigNum const&))&mod, "__mod__");
@@ -237,8 +242,8 @@ bignum_class.def((BigNum (*)(BigNum const&, int))&mod, "__mod__");
 

- The third form (with int as left operand) cannot be wrapped - this way. We must first create a function rmod() with the + The third form of mod() (with int as left operand) cannot + be wrapped directly. We must first create a function rmod() with the operands reversed:

@@ -248,7 +253,7 @@ BigNum rmod(BigNum const& right, int left)
 }
 
- This function must be wrapped under the name "__rmod__": + This function must be wrapped under the name "__rmod__" (standing for "reverse mod"):
 bignum_class.def(&rmod,  "__rmod__");
@@ -271,7 +276,7 @@ bignum_class.def(&rmod,  "__rmod__");
 
       Plain Python can only execute operators with identical types on the left
       and right hand side. If it encounters an expression where the types of
-      the left and right operand differ, it tries to coerce these type to a
+      the left and right operand differ, it tries to coerce these types to a
       common type before invoking the actual operator. Implementing good
       coercion functions can be difficult if many type combinations must be
       supported. 
@@ -295,7 +300,7 @@ bignum_class.def_standard_coerce();
 
If you encounter a situation where you absolutely need a customized - coercion, you can overload the "__coerce__" operator itself. The signature + coercion, you can still define the "__coerce__" operator manually. The signature of a coercion function should look like one of the following (the first is the safest): @@ -310,13 +315,22 @@ PyObject* custom_coerce(PyObject* left, PyObject* right); converted to the same type. Such a function is wrapped as usual:
+// this must be called before any use of automatic operator  
+// wrapping or a call to some_class.def_standard_coerce()
 some_class.def(&custom_coerce, "__coerce__");
 
- Note that the later use of automatic operator wrapping on a + Note that the standard coercion (defined by use of automatic operator wrapping on a class_builder or a call to - ``some_class.def_standard_coerce()'' will cause any - custom coercion function to be replaced by the standard one. + “some_class.def_standard_coerce()”) will never be applied + if a custom coercion function has been registered. Therefore, in your coercion function + you should call + +
+boost::python::detail::extension_class_coerce(left, right);
+
+ + for all cases that you don't want to handle yourself.

The Ternary pow() Operator

@@ -330,7 +344,7 @@ some_class.def(&custom_coerce, "__coerce__"); this is done as usual:
-BigNum power(BigNum const& first, BigNum const& second, BigNum const& module);
+BigNum power(BigNum const& first, BigNum const& second, BigNum const& modulus);
 typedef BigNum (ternary_function1)(const BigNum&, const BigNum&, const BigNum&);
 ...
 bignum_class.def((ternary_function1)&power,  "__pow__");
@@ -353,19 +367,19 @@ bignum_class.def((ternary_function2)&power,  "__pow__");
 
In the second variant, however, BigNum appears only as second - argument, and in the last one it is the third argument. These functions + argument, and in the last one it's the third argument. These functions must be presented to BPL such that that the BigNum argument appears in first position:
 BigNum rpower(BigNum const& second, int first, int modulus)
 {
-    return power(first, second, third);
+    return power(first, second, modulus);
 }
 
-BigNum rrpower(BigNum const& third, int first, int second)
+BigNum rrpower(BigNum const& modulus, int first, int second)
 {
-    return power(first, second, third);
+    return power(first, second, modulus);
 }
 
@@ -637,7 +651,7 @@ for i in S: while in C++ one writes
-for (iterator i = S.begin(), end = S.end(); i != end)
+for (iterator i = S.begin(), end = S.end(); i != end; ++i)
 

One could try to wrap C++ iterators in order to carry the C++ idiom into