$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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()