Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61958 - in sandbox/python_extensions: . boost/mpl/adapted boost/python/from_python boost/python/to_python libs/python/test
From: talljimbo_at_[hidden]
Date: 2010-05-13 20:41:43


Author: jbosch
Date: 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
New Revision: 61958
URL: http://svn.boost.org/trac/boost/changeset/61958

Log:
python_extensions - added readme, more tests; generally cleaned up for public use
Added:
   sandbox/python_extensions/README (contents, props changed)
   sandbox/python_extensions/boost/python/to_python/const_cast_shared_ptr.hpp
      - copied, changed from r61851, /sandbox/python_extensions/boost/python/to_python/implicit.hpp
   sandbox/python_extensions/boost/python/to_python/copy_to_dict.hpp
      - copied, changed from r61851, /sandbox/python_extensions/boost/python/to_python/copy_to_list.hpp
   sandbox/python_extensions/boost/python/to_python/copy_to_tuple.hpp
      - copied, changed from r61851, /sandbox/python_extensions/boost/python/to_python/copy_to_list.hpp
Removed:
   sandbox/python_extensions/boost/python/to_python/std_auto_ptr.hpp
Properties modified:
   sandbox/python_extensions/libs/python/test/ (props changed)
Text files modified:
   sandbox/python_extensions/boost/mpl/adapted/std_pair.hpp | 6 +
   sandbox/python_extensions/boost/python/from_python/boost_fusion.hpp | 14 +++-
   sandbox/python_extensions/boost/python/from_python/container.hpp | 59 +++++++++++++++++
   sandbox/python_extensions/boost/python/from_python/iterator.hpp | 25 +++++++
   sandbox/python_extensions/boost/python/from_python/std_pair.hpp | 11 ++
   sandbox/python_extensions/boost/python/to_python/boost_fusion.hpp | 5 +
   sandbox/python_extensions/boost/python/to_python/const_cast_shared_ptr.hpp | 29 +++++---
   sandbox/python_extensions/boost/python/to_python/copy_to_dict.hpp | 28 ++++----
   sandbox/python_extensions/boost/python/to_python/copy_to_list.hpp | 10 +-
   sandbox/python_extensions/boost/python/to_python/copy_to_tuple.hpp | 24 +++----
   sandbox/python_extensions/boost/python/to_python/implicit.hpp | 8 ++
   sandbox/python_extensions/boost/python/to_python/std_pair.hpp | 11 +++
   sandbox/python_extensions/libs/python/test/test_mod.cpp | 127 +++++++++++++++++++++++++++++++++++++--
   sandbox/python_extensions/libs/python/test/test_script.py | 62 +++++++++++++++++--
   14 files changed, 351 insertions(+), 68 deletions(-)

Added: sandbox/python_extensions/README
==============================================================================
--- (empty file)
+++ sandbox/python_extensions/README 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -0,0 +1,75 @@
+OVERVIEW
+
+This is a collection of fairly self-contained utilities I've
+I've found to be useful in wrapping C++ code using Boost.Python,
+posted here in the hopes that others might find them useful,
+and perhaps contribute their own utilitites in the same place.
+
+
+FEATURES
+
+ - Converting STL containers and other entities supported by
+ Boost.Range to Python builtins ('to_python/copy_to_list.hpp',
+ 'to_python/copy_to_tuple.hpp', 'to_python/copy_to_dict.hpp').
+
+ - Converting Python builtin sequences and mappings to STL
+ containers and iterators ('from_python/iterator.hpp',
+ 'from_python/container.hpp')
+
+ - Conversions involving Boost.Fusion sequences, including tuples
+ and std::pair ('(to|from)_python/(std_pair|boost_fusion).hpp').
+
+ - Implicit to-python conversions ('to_python/implicit.hpp').
+
+ - boost::shared_ptr<T const> conversions that work simply by
+ casting away constness ('to_python/const_cast_shared_ptr.hpp').
+
+
+INSTALLATION
+
+All the libraries are header only, and the SCons-based build system
+is only used to run tests (and it doesn't try very hard to locate
+Boost.Python if that's non-trivial on your system.
+
+While I have only tested these on gcc 4.4 in Linux, I don't have
+any reason to think they won't work on any other platform with
+a modern C++ compiler.
+
+As of this writing (May 2010), the latest version of this code
+is in the boost sandbox at
+http://svn.boost.org/svn/boost/sandbox/python_extensions
+
+Depending on how useful these utilites are to others, and how much
+time I have, some of these may eventually move into the core
+Boost.Python library.
+
+
+BUGS/SUPPORT/FEEDBACK
+
+If you have questions, find a bug, or have a suggestion for how to
+improve something, feel free to email the author (see below). If
+something doesn't work, and there's a reasonable chance your problem
+is with Boost.Python itself, and not this extension code, please
+post to cplusplus-sig_at_python.org.
+
+
+CONTRIBUTING
+
+If you have similarly simple-yet-useful and self-contained
+Boost.Python, I'd love to see it contributed here. However, I would
+rather not add code here whose purpose is to provide a Boost.Python
+interface for some other, non-Boost C++ library, or which depends
+on a non-Boost C++ library.
+
+If you already have such a collection posted somewhere, but would
+like to see it collected here instead, and don't have the time to
+do it, let me know; I might be willing to do the organizational work
+to drop it in here myself. However, I don't want to just maintain a
+perpetually out-of-date mirror of other people's code repositories;
+if you intend to maintain your utilities somewhere else, it's
+probably best if we just link to each other in our README files,
+or maybe use svn:external declarations.
+
+
+Jim Bosch
+talljimbo_at_[hidden]

Modified: sandbox/python_extensions/boost/mpl/adapted/std_pair.hpp
==============================================================================
--- sandbox/python_extensions/boost/mpl/adapted/std_pair.hpp (original)
+++ sandbox/python_extensions/boost/mpl/adapted/std_pair.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -6,6 +6,12 @@
 #ifndef BOOST_MPL_ADAPTED_STD_PAIR_HPP
 #define BOOST_MPL_ADAPTED_STD_PAIR_HPP
 
+/**
+ * @file boost/mpl/std_pair.hpp
+ *
+ * @brief Provides interface for std::pair as a valid MPL sequence.
+ */
+
 #include <utility>
 #include <boost/mpl/int.hpp>
 #include <boost/mpl/deref.hpp>

Modified: sandbox/python_extensions/boost/python/from_python/boost_fusion.hpp
==============================================================================
--- sandbox/python_extensions/boost/python/from_python/boost_fusion.hpp (original)
+++ sandbox/python_extensions/boost/python/from_python/boost_fusion.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -30,7 +30,7 @@
         }
         object item(item_handle);
         extract<T> can_extract(item);
- if (!can_extract) throw boost_fusion_from_python_failed();
+ if (!can_extract.check()) throw boost_fusion_from_python_failed();
         copy.append(item);
     }
 
@@ -40,10 +40,10 @@
 
 struct boost_fusion_from_python_set {
     list sequence;
- int index;
+ mutable int index;
 
     template <typename T> void operator()(T & x) const {
- x = extract<T>(sequence[index]);
+ x = extract<T>(sequence[index++]);
     }
 
     explicit boost_fusion_from_python_set(object const & sequence_) :
@@ -52,10 +52,16 @@
 
 } // namespace detail
 
+/**
+ * @brief An rvalue from-python converter that converts any Python iterable to a Boost.Fusion sequence.
+ *
+ * The converter will only match if all of the elements in the iterable are convertable to
+ * the corresponding types in the Boost.Fusion sequence.
+ */
 template <typename Sequence>
 struct boost_fusion_from_python {
 
- static void declare() {
+ boost_fusion_from_python() {
         converter::registry::push_back(
             &convertible,
             &construct,

Modified: sandbox/python_extensions/boost/python/from_python/container.hpp
==============================================================================
--- sandbox/python_extensions/boost/python/from_python/container.hpp (original)
+++ sandbox/python_extensions/boost/python/from_python/container.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -27,7 +27,7 @@
 template <typename Container, typename Value=typename Container::value_type>
 struct container_from_python_sequence {
 
- static void declare() {
+ container_from_python_sequence() {
         converter::registry::push_back(
             &convertible,
             &construct,
@@ -62,7 +62,62 @@
     }
 };
 
+/**
+ * @brief An rvalue from-python converter that creates a pair-associative container from an arbitrary
+ * Python mapping.
+ *
+ * If 'key' is an object of type Key and 'mapped' is an object of type Mapped,
+ * the statements
+ * @code
+ * Container c;
+ * c.insert(Value(key, mapped));
+ * @endcode
+ * must be valid for the given Container type.
+ *
+ * For overloaded functions, this converter will match for any object with a 'keys' attribute,
+ * and will raise an exception if an element is not convertible to the appropriate C++ type.
+ *
+ * When the key and/or mapped type are wrapped C++ types, explicitly setting the Key and/or Mapped template
+ * parameters to (const) reference types may eliminate some unnecessary copies.
+ */
+template <typename Container,
+ typename Key=typename Container::key_type,
+ typename Mapped=typename Container::mapped_type,
+ typename Value=typename Container::value_type
+ >
+struct container_from_python_mapping {
+
+ container_from_python_mapping() {
+ converter::registry::push_back(
+ &convertible,
+ &construct,
+ type_id< Container >()
+ );
+ }
+
+ static void* convertible(PyObject * obj) {
+ if (PyObject_HasAttrString(obj, "keys")) {
+ return obj;
+ }
+ return NULL;
+ }
+
+ static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data) {
+ object mapping(handle<>(borrowed(obj)));
+ typedef converter::rvalue_from_python_storage<Container> storage_t;
+ storage_t* storage = reinterpret_cast<storage_t*>(data);
+ void* bytes = storage->storage.bytes;
+ Container * result = new (bytes) Container();
+ from_python_iterator<Key> const end;
+ for (from_python_iterator<Key> iter(mapping.attr("keys")()); iter != end; ++iter) {
+ object mapped = mapping[iter.get_py()];
+ result->insert(Value(*iter, extract<Mapped>(mapped)));
+ }
+ data->convertible = bytes;
+ }
+};
+
 } // namespace boost::python
 } // namespace boost
 
-#endif // !BOOST_PYTHON_FROM_PYTHON_BOOST_FUSION_HPP
+#endif // !BOOST_PYTHON_FROM_PYTHON_CONTAINER_HPP

Modified: sandbox/python_extensions/boost/python/from_python/iterator.hpp
==============================================================================
--- sandbox/python_extensions/boost/python/from_python/iterator.hpp (original)
+++ sandbox/python_extensions/boost/python/from_python/iterator.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -12,6 +12,26 @@
 namespace boost {
 namespace python {
 
+/**
+ * @brief A C++ single-pass iterator that wraps a Python iterator.
+ *
+ * Will throw error_already_set when dereferenced if the current Python object cannot be converted to
+ * the desired C++ type.
+ *
+ * The default constructor for from_python_iterator creates the "end" C++ iterator.
+ *
+ * Example:
+ * @code
+ * int sum_ints(object const & py_iter) {
+ * from_python_iterator<int> const end;
+ * int total = 0;
+ * for (from_python_iterator<int> c_iter(py_iter); c_iter != end; ++c_iter) {
+ * total += *c_iter;
+ * }
+ * return total;
+ * }
+ * @endcode
+ */
 template <typename Value>
 class from_python_iterator : public boost::iterator_facade<from_python_iterator<Value>,
                                                            Value,
@@ -48,8 +68,13 @@
     friend class boost::iterator_core_access;
 public:
 
+ /// @brief Return the current element as a Python object.
+ object const & get_py() const { return _item; }
+
+ /// @brief Construct an iterator that equals any Python iterator that has reached its end.
     from_python_iterator() : _at_end(true), _iter(), _item() {}
 
+ /// @brief Construct a C++ iterator from a Python iterable.
     explicit from_python_iterator(object const & iterable) : _at_end(false), _iter(), _item() {
         PyObject * iter = PyObject_GetIter(iterable.ptr());
         if (iter == NULL) throw_error_already_set();

Modified: sandbox/python_extensions/boost/python/from_python/std_pair.hpp
==============================================================================
--- sandbox/python_extensions/boost/python/from_python/std_pair.hpp (original)
+++ sandbox/python_extensions/boost/python/from_python/std_pair.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -7,14 +7,21 @@
 #define BOOST_PYTHON_FROM_PYTHON_STD_PAIR_HPP
 
 #include <boost/python/from_python/boost_fusion.hpp>
-#include <boost/mpl/adapted/std_pair.hpp>
+#include <boost/mpl/adapted/std_pair.hpp> // distributed with python_extensions, not MPL
 #include <boost/fusion/include/std_pair.hpp>
 
 namespace boost {
 namespace python {
 
+/**
+ * @brief An rvalue from-python converter that converts a two-element Python iterable into an std::pair.
+ */
 template <typename T1, typename T2>
-struct std_pair_from_python : public boost_fusion_from_python< std::pair<T1,T2> > {};
+struct std_pair_from_python : public boost_fusion_from_python< std::pair<T1,T2> > {
+
+ std_pair_from_python() : boost_fusion_from_python< std::pair<T1,T2> >() {}
+
+};
 
 } // namespace boost::python
 } // namespace boost

Modified: sandbox/python_extensions/boost/python/to_python/boost_fusion.hpp
==============================================================================
--- sandbox/python_extensions/boost/python/to_python/boost_fusion.hpp (original)
+++ sandbox/python_extensions/boost/python/to_python/boost_fusion.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -21,6 +21,9 @@
 
 } // namespace boost::python::detail
 
+/**
+ * @brief A to-python converter for arbitrary Boost.Fusion sequences.
+ */
 template <typename Sequence>
 struct boost_fusion_to_python {
 
@@ -32,7 +35,7 @@
 
     static PyTypeObject const * get_pytype() { return &PyTuple_Type; }
 
- static void declare() {
+ boost_fusion_to_python() {
         boost::python::to_python_converter<Sequence,boost_fusion_to_python,true>();
     }
 

Copied: sandbox/python_extensions/boost/python/to_python/const_cast_shared_ptr.hpp (from r61851, /sandbox/python_extensions/boost/python/to_python/implicit.hpp)
==============================================================================
--- /sandbox/python_extensions/boost/python/to_python/implicit.hpp (original)
+++ sandbox/python_extensions/boost/python/to_python/const_cast_shared_ptr.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -3,21 +3,30 @@
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-#ifndef BOOST_PYTHON_TO_PYTHON_IMPLICIT_HPP
-#define BOOST_PYTHON_TO_PYTHON_IMPLICIT_HPP
+#ifndef BOOST_PYTHON_TO_PYTHON_CONST_CAST_SHARED_PTR_HPP
+#define BOOST_PYTHON_TO_PYTHON_CONST_CAST_SHARED_PTR_HPP
 
 #include <boost/python.hpp>
 
 namespace boost {
 namespace python {
 
-template <typename Source, typename Target>
-struct implicit_to_python {
- typedef typename boost::python::copy_const_reference::apply<Target const &>::type Converter;
+/**
+ * @brief A to-python converter that enables converting shared_ptr<Value const> to Python by
+ * casting away constness.
+ *
+ * A shared_ptr<Value> to-Python converter must be registered for this converter to work
+ * (this is typically done with register_ptr_to_python).
+ *
+ * This converter is particularly useful when a wrapped class is immutable in Python.
+ */
+template <typename Value>
+struct const_cast_shared_ptr_to_python {
+ typedef typename boost::python::copy_const_reference::apply<shared_ptr<Value> const &>::type Converter;
 
- static PyObject * convert(Source const & source) {
+ static PyObject * convert(shared_ptr<Value const> const & source) {
         Converter converter;
- Target target(source);
+ shared_ptr<Value> target = boost::const_pointer_cast<Value>(source);
         return converter(target);
     }
     
@@ -26,8 +35,8 @@
         return converter.get_pytype();
     }
 
- static void declare() {
- boost::python::to_python_converter<Source,implicit_to_python,true>();
+ const_cast_shared_ptr_to_python() {
+ boost::python::to_python_converter<shared_ptr<Value const>,const_cast_shared_ptr_to_python,true>();
     }
 
 };
@@ -35,4 +44,4 @@
 } // namespace boost::python
 } // namespace boost
 
-#endif // !BOOST_PYTHON_TO_PYTHON_IMPLICIT_HPP
+#endif // !BOOST_PYTHON_TO_PYTHON_CONST_CAST_SHARED_PTR_HPP

Copied: sandbox/python_extensions/boost/python/to_python/copy_to_dict.hpp (from r61851, /sandbox/python_extensions/boost/python/to_python/copy_to_list.hpp)
==============================================================================
--- /sandbox/python_extensions/boost/python/to_python/copy_to_list.hpp (original)
+++ sandbox/python_extensions/boost/python/to_python/copy_to_dict.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -3,22 +3,22 @@
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt
 
-#ifndef BOOST_PYTHON_COPY_TO_LIST_HPP
-#define BOOST_PYTHON_COPY_TO_LIST_HPP
+#ifndef BOOST_PYTHON_TO_PYTHON_COPY_TO_DICT_HPP
+#define BOOST_PYTHON_TO_PYTHON_COPY_TO_DICT_HPP
 
-#include <boost/python.hpp>
-#include <boost/range.hpp>
+#include <boost/python/to_python/copy_to_list.hpp>
 
 namespace boost { namespace python {
 
 /**
- * @brief A model of ResultConverterGenerator (see Boost.Python docs) that copies any valid iterator
- * range into a Python list.
+ * @brief A model of ResultConverterGenerator (see Boost.Python docs) that copies an arbitrary iterator
+ * range into a Python dict. The iterator must dereference to std::pair, or some other type
+ * with "first" and "second" data members.
  *
- * Useful for functions that return a STL container that one would like transformed into a Python list;
- * use return_value_policy<copy_to_list>().
+ * Useful for functions that return an STL pair-associative container (i.e. std::map) that one would
+ * like transformed into a Python dict; use return_value_policy<copy_to_dict>().
  */
-struct copy_to_list {
+struct copy_to_dict {
 
     template <typename Container>
     struct converter {
@@ -28,10 +28,12 @@
         inline bool convertible() const { return true; }
 
         inline PyObject * operator()(Container const & container) const {
- boost::python::list result;
+ dict result;
             try {
                 for (Iterator i = boost::begin(container); i != boost::end(container); ++i) {
- result.append(boost::python::object(*i));
+ object key(i->first);
+ object value(i->second);
+ result[key] = value;
                 }
             } catch (error_already_set & exc) {
                 handle_exception();
@@ -41,7 +43,7 @@
             return result.ptr();
         }
 
- inline PyTypeObject const * get_pytype() const { return &PyList_Type; }
+ inline PyTypeObject const * get_pytype() const { return &PyDict_Type; }
 
     };
 
@@ -54,4 +56,4 @@
 
 }}
 
-#endif // !BOOST_PYTHON_COPY_TO_LIST_HPP
+#endif // !BOOST_PYTHON_TO_PYTHON_COPY_TO_DICT_HPP

Modified: sandbox/python_extensions/boost/python/to_python/copy_to_list.hpp
==============================================================================
--- sandbox/python_extensions/boost/python/to_python/copy_to_list.hpp (original)
+++ sandbox/python_extensions/boost/python/to_python/copy_to_list.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -3,8 +3,8 @@
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt
 
-#ifndef BOOST_PYTHON_COPY_TO_LIST_HPP
-#define BOOST_PYTHON_COPY_TO_LIST_HPP
+#ifndef BOOST_PYTHON_TO_PYTHON_COPY_TO_LIST_HPP
+#define BOOST_PYTHON_TO_PYTHON_COPY_TO_LIST_HPP
 
 #include <boost/python.hpp>
 #include <boost/range.hpp>
@@ -12,10 +12,10 @@
 namespace boost { namespace python {
 
 /**
- * @brief A model of ResultConverterGenerator (see Boost.Python docs) that copies any valid iterator
+ * @brief A model of ResultConverterGenerator (see Boost.Python docs) that copies an arbirary iterator
  * range into a Python list.
  *
- * Useful for functions that return a STL container that one would like transformed into a Python list;
+ * Useful for functions that return an STL container that one would like transformed into a Python list;
  * use return_value_policy<copy_to_list>().
  */
 struct copy_to_list {
@@ -54,4 +54,4 @@
 
 }}
 
-#endif // !BOOST_PYTHON_COPY_TO_LIST_HPP
+#endif // !BOOST_PYTHON_TO_PYTHON_COPY_TO_LIST_HPP

Copied: sandbox/python_extensions/boost/python/to_python/copy_to_tuple.hpp (from r61851, /sandbox/python_extensions/boost/python/to_python/copy_to_list.hpp)
==============================================================================
--- /sandbox/python_extensions/boost/python/to_python/copy_to_list.hpp (original)
+++ sandbox/python_extensions/boost/python/to_python/copy_to_tuple.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -3,22 +3,21 @@
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt
 
-#ifndef BOOST_PYTHON_COPY_TO_LIST_HPP
-#define BOOST_PYTHON_COPY_TO_LIST_HPP
+#ifndef BOOST_PYTHON_TO_PYTHON_COPY_TO_TUPLE_HPP
+#define BOOST_PYTHON_TO_PYTHON_COPY_TO_TUPLE_HPP
 
-#include <boost/python.hpp>
-#include <boost/range.hpp>
+#include <boost/python/to_python/copy_to_list.hpp>
 
 namespace boost { namespace python {
 
 /**
- * @brief A model of ResultConverterGenerator (see Boost.Python docs) that copies any valid iterator
- * range into a Python list.
+ * @brief A model of ResultConverterGenerator (see Boost.Python docs) that copies an arbitrary iterator
+ * range into a Python tuple.
  *
- * Useful for functions that return a STL container that one would like transformed into a Python list;
- * use return_value_policy<copy_to_list>().
+ * Useful for functions that return an STL container that one would like transformed into a Python tuple;
+ * use return_value_policy<copy_to_tuple>().
  */
-struct copy_to_list {
+struct copy_to_tuple {
 
     template <typename Container>
     struct converter {
@@ -37,11 +36,10 @@
                 handle_exception();
                 return NULL;
             }
- Py_INCREF(result.ptr());
- return result.ptr();
+ return PySequence_Tuple(result.ptr());
         }
 
- inline PyTypeObject const * get_pytype() const { return &PyList_Type; }
+ inline PyTypeObject const * get_pytype() const { return &PyTuple_Type; }
 
     };
 
@@ -54,4 +52,4 @@
 
 }}
 
-#endif // !BOOST_PYTHON_COPY_TO_LIST_HPP
+#endif // !BOOST_PYTHON_TO_PYTHON_COPY_TO_TUPLE_HPP

Modified: sandbox/python_extensions/boost/python/to_python/implicit.hpp
==============================================================================
--- sandbox/python_extensions/boost/python/to_python/implicit.hpp (original)
+++ sandbox/python_extensions/boost/python/to_python/implicit.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -11,6 +11,12 @@
 namespace boost {
 namespace python {
 
+/**
+ * @brief A to-python converter that converts an object of type Source to Python by first converting
+ * it to an object of type Target (which must have a to-python converter registered).
+ *
+ * Source must be explicitly convertible to Target in C++.
+ */
 template <typename Source, typename Target>
 struct implicit_to_python {
     typedef typename boost::python::copy_const_reference::apply<Target const &>::type Converter;
@@ -26,7 +32,7 @@
         return converter.get_pytype();
     }
 
- static void declare() {
+ implicit_to_python() {
         boost::python::to_python_converter<Source,implicit_to_python,true>();
     }
 

Deleted: sandbox/python_extensions/boost/python/to_python/std_auto_ptr.hpp
==============================================================================
--- sandbox/python_extensions/boost/python/to_python/std_auto_ptr.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
+++ (empty file)
@@ -1,34 +0,0 @@
-// Copyright 2010 Jim Bosch.
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_PYTHON_TO_PYTHON_STD_AUTO_PTR_HPP
-#define BOOST_PYTHON_TO_PYTHON_STD_AUTO_PTR_HPP
-
-#include <boost/python.hpp>
-#include <memory>
-
-namespace boost {
-namespace python {
-
-template <typename U>
-struct to_python_value< std::auto_ptr<U> > : detail::builtin_to_python {
-
- typename boost::python::copy_const_reference::apply<boost::shared_ptr<U> const &>::type _shared_converter;
-
- inline PyObject* operator()(std::auto_ptr<U> x) const {
- boost::shared_ptr<U> shared(x);
- return _shared_converter(shared);
- }
-
- inline PyTypeObject const* get_pytype() const {
- return _shared_converter.get_pytype();
- }
-
-};
-
-} // namespace boost::python
-} // namespace boost
-
-#endif // !BOOST_PYTHON_TO_PYTHON_STD_AUTO_PTR_HPP

Modified: sandbox/python_extensions/boost/python/to_python/std_pair.hpp
==============================================================================
--- sandbox/python_extensions/boost/python/to_python/std_pair.hpp (original)
+++ sandbox/python_extensions/boost/python/to_python/std_pair.hpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -12,10 +12,19 @@
 namespace boost {
 namespace python {
 
+/**
+ * @brief A to-python converter for std::pair that yields a two-element Python tuple.
+ */
 template <typename T1, typename T2>
 struct std_pair_to_python
     : public boost_fusion_to_python< std::pair<T1,T2> >
-{};
+{
+
+ std_pair_to_python() {
+ boost::python::to_python_converter<std::pair<T1,T2>,std_pair_to_python,true>();
+ }
+
+};
 
 } // namespace boost::python
 } // namespace boost

Modified: sandbox/python_extensions/libs/python/test/test_mod.cpp
==============================================================================
--- sandbox/python_extensions/libs/python/test/test_mod.cpp (original)
+++ sandbox/python_extensions/libs/python/test/test_mod.cpp 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -1,35 +1,144 @@
 #include <boost/python.hpp>
 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+#include <boost/python/suite/indexing/map_indexing_suite.hpp>
 #include <boost/python/to_python/copy_to_list.hpp>
+#include <boost/python/to_python/copy_to_tuple.hpp>
+#include <boost/python/to_python/copy_to_dict.hpp>
 #include <boost/python/from_python/container.hpp>
+#include <boost/python/to_python/boost_fusion.hpp>
+#include <boost/python/from_python/boost_fusion.hpp>
+#include <boost/python/to_python/std_pair.hpp>
+#include <boost/python/from_python/std_pair.hpp>
+#include <boost/python/to_python/const_cast_shared_ptr.hpp>
+
+#include <boost/fusion/tuple.hpp>
+#include <boost/fusion/sequence/intrinsic/at_c.hpp>
+
+#include <string>
+#include <vector>
+#include <map>
 
 namespace bp = boost::python;
 
-static std::vector<int> return_int_vector() {
+static std::vector<int> return_vector() {
     std::vector<int> result;
     result.push_back(5);
     result.push_back(3);
     return result;
 }
 
-static bool accept_int_vector_cref(std::vector<int> const & v) {
+static bool accept_vector_cref(std::vector<int> const & v) {
     return v[0] == 5 && v[1] == 3;
 }
 
-static bool accept_int_vector_ref(std::vector<int> & v) {
+static bool accept_vector_ref(std::vector<int> & v) {
     return v[0] == 5 && v[1] == 3;
 }
 
+
+static std::map<int,std::string> return_map() {
+ std::map<int,std::string> result;
+ result.insert(std::make_pair(3,"three"));
+ result.insert(std::make_pair(5,"five"));
+ return result;
+}
+
+static bool accept_map_cref(std::map<int,std::string> const & v) {
+ std::map<int,std::string>::const_iterator i3 = v.find(3);
+ std::map<int,std::string>::const_iterator i5 = v.find(5);
+ if (i3 == v.end() || i5 == v.end()) return false;
+ return i3->second == "three" && i5->second == "five";
+}
+
+static bool accept_map_ref(std::map<int,std::string> & v) {
+ std::map<int,std::string>::const_iterator i3 = v.find(3);
+ std::map<int,std::string>::const_iterator i5 = v.find(5);
+ if (i3 == v.end() || i5 == v.end()) return false;
+ return i3->second == "three" && i5->second == "five";
+}
+
+
+typedef boost::fusion::tuple<int,double,std::string> test_tuple;
+
+static test_tuple return_tuple() {
+ return boost::fusion::make_tuple(3, 0.0, "test string");
+}
+
+static bool accept_tuple(test_tuple const & tuple) {
+ return boost::fusion::at_c<0>(tuple) == 3
+ && boost::fusion::at_c<1>(tuple) == 0.0
+ && boost::fusion::at_c<2>(tuple) == "test string";
+}
+
+
+typedef std::pair<int,std::string> test_pair;
+
+static test_pair return_pair() {
+ return test_pair(3, "test string");
+}
+
+static bool accept_pair(test_pair const & pair) {
+ return pair.first == 3
+ && pair.second == "test string";
+}
+
+
+struct shared_ptr_example_class {
+ static boost::shared_ptr<shared_ptr_example_class> return_shared_ptr() {
+ return boost::shared_ptr<shared_ptr_example_class>(new shared_ptr_example_class());
+ }
+ static boost::shared_ptr<shared_ptr_example_class const> return_const_shared_ptr() {
+ return boost::shared_ptr<shared_ptr_example_class const>(new shared_ptr_example_class());
+ }
+};
+
 BOOST_PYTHON_MODULE(test_mod) {
- bp::class_< std::vector<int> >("int_vector")
+ bp::class_< std::vector<int> >("vector")
         .def(bp::vector_indexing_suite< std::vector<int> >())
         ;
- bp::container_from_python_sequence< std::vector<int>, int >::declare();
+ bp::container_from_python_sequence< std::vector<int> >();
+
+ bp::def("return_vector_as_list", &return_vector, bp::return_value_policy<bp::copy_to_list>());
+ bp::def("return_vector_as_tuple", &return_vector, bp::return_value_policy<bp::copy_to_tuple>());
+ bp::def("return_vector_wrapped", &return_vector);
+
+ bp::def("accept_vector_cref", &accept_vector_cref);
+ bp::def("accept_vector_ref", &accept_vector_ref);
+
+
+ bp::class_< std::map<int,std::string> >("map")
+ .def(bp::map_indexing_suite< std::map<int,std::string> >())
+ ;
+ bp::container_from_python_mapping< std::map<int,std::string> >();
 
- bp::def("return_int_vector_as_list", &return_int_vector, bp::return_value_policy<bp::copy_to_list>());
- bp::def("return_int_vector_wrapped", &return_int_vector);
+ bp::def("return_map_as_dict", &return_map, bp::return_value_policy<bp::copy_to_dict>());
+ bp::def("return_map_wrapped", &return_map);
 
- bp::def("accept_int_vector_cref", &accept_int_vector_cref);
- bp::def("accept_int_vector_ref", &accept_int_vector_ref);
+ bp::def("accept_map_cref", &accept_map_cref);
+ bp::def("accept_map_ref", &accept_map_ref);
+
+
+ bp::boost_fusion_to_python<test_tuple>();
+ bp::boost_fusion_from_python<test_tuple>();
+
+ bp::def("return_tuple", &return_tuple);
+ bp::def("accept_tuple", &accept_tuple);
+
+
+ bp::std_pair_to_python<int,std::string>();
+ bp::std_pair_from_python<int,std::string>();
+
+ bp::def("return_pair", &return_pair);
+ bp::def("accept_pair", &accept_pair);
+
+
+ bp::class_<shared_ptr_example_class>("shared_ptr_example_class")
+ .def("return_shared_ptr", &shared_ptr_example_class::return_shared_ptr)
+ .staticmethod("return_shared_ptr")
+ .def("return_const_shared_ptr", &shared_ptr_example_class::return_const_shared_ptr)
+ .staticmethod("return_const_shared_ptr")
+ ;
+ bp::register_ptr_to_python< boost::shared_ptr<shared_ptr_example_class> >();
+ bp::const_cast_shared_ptr_to_python< shared_ptr_example_class >();
 }
 

Modified: sandbox/python_extensions/libs/python/test/test_script.py
==============================================================================
--- sandbox/python_extensions/libs/python/test/test_script.py (original)
+++ sandbox/python_extensions/libs/python/test/test_script.py 2010-05-13 20:41:41 EDT (Thu, 13 May 2010)
@@ -4,20 +4,68 @@
 class TestVector(unittest.TestCase):
 
     def testCopyToList(self):
- v = test_mod.return_int_vector_as_list()
+ v = test_mod.return_vector_as_list()
         self.assertEqual(type(v), list)
         self.assertEqual(v, [5,3])
 
+ def testCopyToTuple(self):
+ v = test_mod.return_vector_as_tuple()
+ self.assertEqual(type(v), tuple)
+ self.assertEqual(v, (5,3))
+
     def testWrapped(self):
- v = test_mod.return_int_vector_wrapped()
- self.assertEqual(type(v), test_mod.int_vector)
- self.assert_(test_mod.accept_int_vector_cref(v))
- self.assert_(test_mod.accept_int_vector_ref(v))
+ v = test_mod.return_vector_wrapped()
+ self.assertEqual(type(v), test_mod.vector)
+ self.assert_(test_mod.accept_vector_cref(v))
+ self.assert_(test_mod.accept_vector_ref(v))
 
     def testContainerFromPythonSequence(self):
         v = [5, 3]
- self.assert_(test_mod.accept_int_vector_cref(v))
- self.assertRaises(TypeError, test_mod.accept_int_vector_ref, v)
+ self.assert_(test_mod.accept_vector_cref(v))
+ self.assertRaises(TypeError, test_mod.accept_vector_ref, v)
+
+class TestMap(unittest.TestCase):
+
+ def testCopyToDict(self):
+ v = test_mod.return_map_as_dict()
+ self.assertEqual(type(v), dict)
+ self.assertEqual(v, {5:"five",3:"three"})
+
+ def testWrapped(self):
+ v = test_mod.return_map_wrapped()
+ self.assertEqual(type(v), test_mod.map)
+ self.assert_(test_mod.accept_map_cref(v))
+ self.assert_(test_mod.accept_map_ref(v))
+
+ def testContainerFromPythonMapping(self):
+ v = {5:"five",3:"three"}
+ self.assert_(test_mod.accept_map_cref(v))
+ self.assertRaises(TypeError, test_mod.accept_map_ref, v)
+
+class TestFusion(unittest.TestCase):
+
+ def testTuple(self):
+ v = test_mod.return_tuple()
+ self.assertEqual(type(v), tuple)
+ self.assertEqual(v, (3, 0.0, "test string"))
+ self.assert_(test_mod.accept_tuple(v))
+
+ def testPair(self):
+ v = test_mod.return_pair()
+ self.assertEqual(type(v), tuple)
+ self.assertEqual(v, (3, "test string"))
+ self.assert_(test_mod.accept_pair(v))
+
+class TestConstSharedPtr(unittest.TestCase):
+
+ def testSharedPtr(self):
+ # only relies on Boost.Python internals, not new code
+ v = test_mod.shared_ptr_example_class.return_shared_ptr()
+ self.assertEqual(type(v), test_mod.shared_ptr_example_class)
+
+ def testConstSharedPtr(self):
+ v = test_mod.shared_ptr_example_class.return_const_shared_ptr()
+ self.assertEqual(type(v), test_mod.shared_ptr_example_class)
 
 if __name__=="__main__":
     unittest.main()


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk