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++ 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.
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.
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.
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 ).
Py++ defines indexing_suite1_t class. This class allows configure any detail of generated code:
no_proxy - a boolean, if value_type is one of the the following types
then, no_proxy will be set to True, otherwise to False.
derived_policies - a string, that will be added as is to generated code
element_type - is a reference to container value_type or mapped_type.
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: