diff --git a/doc/v2/containers.html b/doc/v2/containers.html index 791edc86..f1c3927b 100755 --- a/doc/v2/containers.html +++ b/doc/v2/containers.html @@ -57,9 +57,6 @@
The container_suite object achieves this using the
- def_visitor interface, which provides a hook for
- the def function to install multiple Python methods
- in one call. If the container element type (int in
- the example above) is a user-defined type, you will have to
- expose this type to Python via a separate class_
- instance.
+ def_visitor interface, which
+ provides a hook for the def function to install
+ multiple Python methods in one call. If the container element
+ type (int in the example above) is a user-defined
+ type, you will have to expose this type to Python via a separate
+ class_ instance.
- [1] if your compiler does not support - partial template specializations, you will have to explicitly - select the right algorithms and traits information, as described - in the compiler workarounds section. + [1] Automatic operation with the standard + containers works poperly if your compiler supports partial + template specializations. Otherwise, refer to the compiler workarounds section.
-
- The normal interface to the container suite is via the
- container_suite.hpp header, which is summarized
- below:
+ The top-level interface to the container suite is via the container_suite.hpp
+ header which is summarized below:
+#include <boost/python/suite/indexing/algo_selector.hpp>
+#include <boost/python/suite/indexing/visitor.hpp>
+
#include <boost/python/return_by_value.hpp>
#include <boost/python/return_value_policy.hpp>
-#include "algo_selector.hpp"
-#include "visitor.hpp"
namespace boost { namespace python { namespace indexing {
typedef return_value_policy<return_by_value> default_container_policies;
@@ -335,19 +342,21 @@ namespace boost { namespace python { namespace indexing {
- The container_suite template relies on six main
- support templates, four of which are suitable for specialization
+ The container_suite template relies on seven main
+ support templates, five of which are suitable for specialization
or replacement by client code. The following diagram shows the
templates [2] and their dependencies, with
- the replaceable ones highlighted in grey.
+ the replaceable ones highlighted in grey. For full details,
+ refer to the specific section on each component – what
+ follows here is an overview.
-
-
|
@@ -363,16 +372,48 @@ namespace boost { namespace python { namespace indexing {
- enum IndexStyle
+ enum index_style_t
|
@@ -1017,7 +1058,7 @@ namespace boost { namespace python { namespace indexing {
The following block of code shows a simplistic implementation of
ContainerTraits for the container
- std::set<std::string, int>. The actual
+ std::map<std::string, int>. The actual
implementation used by the suite relies on template
metaprogramming techniques, whereas this example is designed to
show only the essential elements of a
@@ -1030,7 +1071,7 @@ namespace boost { namespace python { namespace indexing {
#include <map>
#include <string>
#include <boost/python/suite/indexing/iterator_traits.hpp>
-// Include iterator_traits to get IndexStyle
+// Include iterator_traits to get index_style_t
struct simple_map_traits {
// Traits information for std::map<std::string, int>
@@ -1057,7 +1098,7 @@ struct simple_map_traits {
static bool const has_push_back = false;
static bool const is_reorderable = false;
- static boost::python::indexing::IndexStyle const index_style
+ static boost::python::indexing::index_style_t const index_style
= boost::python::indexing::index_style_nonlinear;
struct value_traits_ {
@@ -1093,11 +1134,11 @@ struct simple_map_traits {
BOOST_PYTHON_MODULE(test_simple) {
using namespace boost::python;
- typedef std::map<std::string, int> Container;
- typedef indexing::map_algorithms<simple_map_traits> Algorithms;
+ typedef std::map<std::string, int> container_t;
+ typedef indexing::map_algorithms<simple_map_traits> algorithms_t;
- class_<Container> ("map")
- .def (indexing::container_suite<Container, Algorithms>());
+ class_<container_t> ("map")
+ .def (indexing::container_suite<container_t, algorithms_t>());
}
@@ -1114,7 +1155,7 @@ BOOST_PYTHON_MODULE(test_simple) {
interfaces to the functions can vary to some extent, since the
def function calls used internally by the
visitor deduce the function type
- automatically. However, certain points must be confomed to:
+ automatically. However, certain points should be confomed to:
|
+
+ The default_algorithms template attempts to place
+ as few restrictions as possible on the container type, by using
+ iterators and standard algorithms in most of its functions. It
+ accepts an optional second template parameter, which can be used
+ via the curiously recurring template idiom to replace any of its
+ functions that it relies on internally. For instance, if you've
+ created an iterator-style interface to a container that is not
+ at all STL-like (let's call it weird_container),
+ you might be able to re-use most of
+ default_algorithms by replacing its basic functions
+ like this:
+
+
+
+namespace indexing = boost::python::indexing;
+
+struct my_algorithms
+ : public indexing::default_algorithms <
+ weird_container_traits, my_algorithms
+ >
+{
+ size_t size (weird_container const &c) {
+ return ...;
+ }
+
+ my_iterator_t begin (weird_container &c) {
+ return ...;
+ }
+
+ my_iterator_t end (weird_container &c) {
+ return ...;
+ }
+};
+
+
+
+
+
+ Support code for Python slices is split into two portions, the
+ slice_handler template, and a "slice helper" that
+ can easily be replaced by client code via a typedef and factory
+ function in the Algorithms argument supplied to
+ container_suite. The slice helper object takes care
+ of reading and writing elements from a slice in a C++ container,
+ and optionally insertion and deletion. Effectively, the slice
+ helper object maintains a pointer to the current element of the
+ slice within the container, and provides a next
+ function to advance to the next element of the slice. The
+ container suite uses the following interface for slices:
+
+
+
| + + Expression + + | ++ + Return type + + | ++ + Notes + + | +
|---|---|---|
+
+ Algorithms::
+make_slice_helper
+(c, s)
+
+ |
+
+
+ Algorithms::
+slice_helper
+
+ |
+
+
+ Returns a newly constructed slice_helper
+ object by value, where c is of type
+ Algorithms::container & and s is
+ of type indexing::slice const &.
+
+ |
+
+
+ slice_helper.
+next()
+
+ |
+
+
+ bool
+
+ |
+ + + Advances the slice helper's current element pointer to the + next element of the slice. Returns true if such an element + exists, and false otherwise. The first time this function + is called, it should set the current pointer to the first + element of the slice (if any). + + | +
+
+ slice_helper.
+current()
+
+ |
+
+
+ Algorithms::
+reference
+
+ |
+
+
+ Returns a reference to the current element of the
+ slice. This will only be called after a prior successful
+ call to next().
+
+ |
+
+
+ slice_helper.
+write (v)
+
+ |
+
+
+ void
+
+ |
+
+
+ Advances to the next element of the slice, as defined in
+ next, and writes the given value
+ v at the new location in the
+ container. v will be convertible to
+ Algorthims::value_param. If the slice is
+ exhausted (i.e. next would return false) then
+ write either inserts the value into
+ the container at the next location (past the end of the
+ slice), or sets a Python exception and throws.
+
+ |
+
+
+ slice_helper.
+erase_remaining()
+
+ |
+
+
+ void
+
+ |
+
+
+ Either erases any remaining elements in the slice
+ not already consumed by calls to next or
+ write,
+ or sets a Python exception and throws.
+
+ |
+
+
+ The container suite provides a generic implementation of the
+ SliceHelper requirements for containers that have
+ integer-like indexes. It is parameterized with a
+ SliceType parameter that allows the integer index
+ values to come from various different sources, the default being
+ the PySlice_GetIndices function. Refer to the
+ header file int_slice_helper.hpp
+ and the references to it in the algorithms.hpp
+ header for details.
+
namespace boost { namespace python { namespace indexing {
template<class Container
@@ -1570,34 +1845,47 @@ namespace boost { namespace python { namespace indexing {
- The iterator_pair template provides a
+ The iterator_range template provides a
container-like interface to a range defined by two iterators.
- The interface is complete enough to allow the container suite to
- expose an iterator-defined range as a Python sequence type, with
- support for operations that do not require insertion or
- deletion. This can be used to expose a C++ array to Python, or
- with the result of an equal_range function, or any
- other source of two iterators marking out a range of values. See
- the getArray function in
- libs/python/test/testarray.cpp for an example usage.
+ The interface is complete enough to provide any Python method
+ that does not require insertion or deletion, e.g.
+ len, index and sort. See
+ the get_array_plain function in libs/python/test/test_array_ext.cpp
+ for an example usage. If you only need iteration over the values
+ in a range, consider using the simpler range
+ function provided by boost/python/iterator.hpp
- iterator_pair should work with any
+ Beware that C++ iterators are not very Python-like, since they
+ do not provide any guarantees about the lifetimes of the objects
+ they refer to. Invalidating either of the iterators stored in an
+ iterator_range object is dangerous, since
+ subsequently using the iterators (from Python or C++) results in
+ undefined behaviour.
+
+
+
+ iterator_range should work with any
ForwardIterator type.
namespace boost { namespace python { namespace indexing {
template<typename Iterator>
- class iterator_pair
+ class iterator_range
{
private:
typedef typename boost::call_traits<Iterator>::param_type iterator_param;
@@ -1611,8 +1899,8 @@ namespace boost { namespace python { namespace indexing {
typedef typename std_traits::value_type value_type;
typedef typename std_traits::pointer pointer;
- iterator_pair (iterator_param, iterator_param);
- iterator_pair (std::pair<iterator, iterator> const &);
+ iterator_range (iterator_param, iterator_param);
+ iterator_range (std::pair<iterator, iterator> const &);
iterator begin() const;
iterator end() const;
@@ -1723,19 +2011,6 @@ namespace boost { namespace python { namespace indexing {
The sort method (where provided) should allow an
optional comparison function from Python.
-
-
-
- The existing Algorithms should allow a derived
- class to replace any of the static member functions without
- having to reimplement all of them. For instance, it would be
- nice to be able to replace the low-level begin and
- end functions in default_algorithms
- and have all of the other functions use the replacements
- automatically. This would be fairly easy using static
- polymorphism, such as the Curiously Recurring Template
- Pattern.
-
References