C++ containers support¶
Introduction¶
C++ has a bunch of container classes:
- list
- deque
- queue
- priority_queue
- vector
- stack
- map
- multimap
- hash_map
- hash_multimap
- set
- hash_set
- multiset
- hash_multiset
It is not a trivial task to expose C++ container to Python. Boost.Python has a functionality that will help you to expose some of STL containers to Python. This functionality called - “indexing suite”. If you want, you can read more about indexing suite here.
Boost.Python, out of the box, supports only vector
, map
and hash_map
containers. In October 2003, Raoul Gough implemented support for the rest of
containers. Well, actually he did much more - he implemented new framework.
This framework provides support for almost all C++ containers and also an easy
way to add support for custom ones. You’d better read his post to
Boost.Python mailing list or documentation for the new indexing suite.
Now, I am sure you have the following question: if this suite is so good, why it is not in the main branch? The short answer is that this suite has some problems on MSVC 6.0 compiler and there are few users, that still use that compiler. The long answer is here:
Py++ and indexing suites¶
Py++ implements support for both indexing suites. More over, you can
freely mix indexing suites. For example you can expose std::vector<int>
using
Boost.Python built-in indexing suite and std::map< int, std::string>
using
Raoul Gough’s indexing suite.
How does it work?¶
In both cases, Py++ provides almost “hands free” solution.
Py++ keeps track of all exported functions and variables,
and if it sees that there is a usage of stl container, it exports the container.
In both cases, Py++ analyzes the container value_type
( or in case of mapping container mapped_type
), in order to set reasonable
defaults, when it generates the code.
Indexing suite version 2 installation¶
None :-)
Py++ version 1.1, introduceds few breaking changes to this indexing suite:
the suite implements all functionality in the header files only. Few .cpp files were dropped
header files include directive was changed from
#include "boost/python/suite/indexing/..."
to
#include "indexing_suite/..."
The change was done to simplify the indexing suite installation and redistribution. The gain list:
no need to deal with patching and rebuilding Boost
it is possible to use Boost libraries, which comes with your system
you can put the library anywhere you want - just update the include paths in your build script
it is easier to redistribute it - just include the library with your sources
If you are a happy Py++ user:
The bottom line: Py++ makes C++ STL containers handling fully transparent for its users.
Indexing suites API¶
By default, Py++ works with built-in indexing suite. If you want to use
indexing suite version 2, you should tell this to the module_builder_t.__init__
method:
mb = module_builder_t( ..., indexing_suite_version=2 )
Every declared class has indexing_suite
property. If the class is an
instantiation of STL container, this property contains reference to an instance
of indexing_suite1_t
or indexing_suite2_t
class.
How does Py++ know, that a class represents STL container instantiation?
Well, it uses pygccxml.declarations.container_traits
to find out this.
pygccxml.declarations.container_traits
class, provides all functionality
needed to identify container and to find out its value_type
( mapped_type
).
Built-in indexing suite API¶
Py++ defines indexing_suite1_t
class. This class allows configure
any detail of generated code:
no_proxy
- a boolean, ifvalue_type
is one of the the following types- fundamental type
- enumeration
- std::string or std::wstring
- boost::shared_ptr<?>
then,
no_proxy
will be set toTrue
, otherwise toFalse
.derived_policies
- a string, that will be added as is to generated codeelement_type
- is a reference to containervalue_type
ormapped_type
.
Indexing suite version 2 API¶
In this case there is no single place, where you can configure exported container functionality. Please take a look on the following C++ code:
struct item{
...
private:
bool operator==( const item& ) const;
bool operator<( const item& ) const;
};
struct my_data{
std::vector<item> items;
std::map< std::string, item > name2item_mapping;
};
Py++ declarations tree will contains item
, my_data
,
vector<item>
and map<string,item>
class declarations.
If value_type
does not support “equal” or “less than” functionality, sort
and search functionality could not be exported.
Py++ class declaration has two properties: equality_comparable
and
less_than_comparable
. The value of those properties is calculated on first
invocation. If Py++ can find operator==
, that works on value_type
,
then, equality_comparable
property value will be set to True
, otherwise
to False
. Same process is applied on less_than_comparable
property.
In our case, Py++ will set both properties to False
, thus sort and
search functionality will not be exported.
It is the time to introduce indexing_suite2_t
class:
container_class
- read only property, returns reference to container class declarationcontainer_traits
- read only property, returns reference to the relevant container traits class. Container traits classes are defined inpygccxml.declarations
package.element_type
- is a reference to containervalue_type
ormapped_type
.call_policies
- read/write property, in near future I will add code to Py++ that will analyze containervalue_type
and will decide about default call policies. Just an example: for non-copy constructable classescall_policies
should be set toreturn_internal_reference
.[disable|enable]_method
- new indexing suite, allows one to configure functionality exported to Python, using simple bitwise operations on predefined flags. Py++ allows you to specify what methods you want to disable or enable.indexing_suite2_t.METHODS
contains names of all supported methods.[disable|enable]_methods_group
- almost same as above, but allows you to specify what group of methods you want to disable or enable.indexing_suite2_t.METHOD_GROUPS
contains names of all supported groups.
Small tips/hints¶
- If you set
equality_comparable
orless_than_comparable
toFalse
. The indexing suite will disable relevant functionality. You don’t have explicitly to disable method or methods group. - The documentation of new indexing suite contains few small mistakes. I hope, I will have time to fix them. Any way, Py++ generates correct code.