Boost logo

Boost-Commit :

From: seefeld_at_[hidden]
Date: 2008-07-27 15:41:41


Author: stefan
Date: 2008-07-27 15:41:41 EDT (Sun, 27 Jul 2008)
New Revision: 47846
URL: http://svn.boost.org/trac/boost/changeset/47846

Log:
Add generic call operator support.

Text files modified:
   trunk/boost/python/object_core.hpp | 67 ++++++++++++++++++++++++++++++++++++++++
   trunk/libs/python/doc/v2/object.html | 24 ++++++++++++++
   trunk/libs/python/test/object.cpp | 6 +++
   trunk/libs/python/test/object.py | 7 +++
   4 files changed, 103 insertions(+), 1 deletions(-)

Modified: trunk/boost/python/object_core.hpp
==============================================================================
--- trunk/boost/python/object_core.hpp (original)
+++ trunk/boost/python/object_core.hpp 2008-07-27 15:41:41 EDT (Sun, 27 Jul 2008)
@@ -42,6 +42,12 @@
 
 namespace boost { namespace python {
 
+namespace detail
+{
+ class kwds_proxy;
+ class args_proxy;
+}
+
 namespace converter
 {
   template <class T> struct arg_to_python;
@@ -102,6 +108,11 @@
 
 # define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, <boost/python/object_call.hpp>))
 # include BOOST_PP_ITERATE()
+
+ detail::args_proxy operator* () const;
+ object operator()(detail::args_proxy const &args) const;
+ object operator()(detail::args_proxy const &args,
+ detail::kwds_proxy const &kwds) const;
 
       // truth value testing
       //
@@ -416,6 +427,62 @@
 // implementation
 //
 
+namespace detail
+{
+
+class call_proxy
+{
+public:
+ call_proxy(object target) : m_target(target) {}
+ operator object() const { return m_target;}
+
+ private:
+ object m_target;
+};
+
+class kwds_proxy : public call_proxy
+{
+public:
+ kwds_proxy(object o = object()) : call_proxy(o) {}
+};
+class args_proxy : public call_proxy
+{
+public:
+ args_proxy(object o) : call_proxy(o) {}
+ kwds_proxy operator* () const { return kwds_proxy(*this);}
+};
+}
+
+template <typename U>
+detail::args_proxy api::object_operators<U>::operator* () const
+{
+ object_cref2 x = *static_cast<U const*>(this);
+ return detail::args_proxy(x);
+}
+
+template <typename U>
+object api::object_operators<U>::operator()(detail::args_proxy const &args) const
+{
+ U const& self = *static_cast<U const*>(this);
+ PyObject *result = PyObject_Call(get_managed_object(self, tag),
+ args.operator object().ptr(),
+ 0);
+ return object(detail::new_reference(result));
+
+}
+
+template <typename U>
+object api::object_operators<U>::operator()(detail::args_proxy const &args,
+ detail::kwds_proxy const &kwds) const
+{
+ U const& self = *static_cast<U const*>(this);
+ PyObject *result = PyObject_Call(get_managed_object(self, tag),
+ args.operator object().ptr(),
+ kwds.operator object().ptr());
+ return object(detail::new_reference(result));
+
+}
+
 inline object::object()
     : object_base(python::incref(Py_None))
 {}

Modified: trunk/libs/python/doc/v2/object.html
==============================================================================
--- trunk/libs/python/doc/v2/object.html (original)
+++ trunk/libs/python/doc/v2/object.html 2008-07-27 15:41:41 EDT (Sun, 27 Jul 2008)
@@ -655,6 +655,11 @@
       template &lt;class A0, class A1,...class An&gt;
       object operator()(A0 const&amp;, A1 const&amp;,...An const&amp;) const;
 
+ detail::args_proxy operator* () const;
+ object operator()(detail::args_proxy const &amp;args) const;
+ object operator()(detail::args_proxy const &amp;args,
+ detail::kwds_proxy const &amp;kwds) const;
+
       // truth value testing
       //
       typedef unspecified bool_type;
@@ -704,6 +709,25 @@
       call&lt;object&gt;(object(*static_cast&lt;U*&gt;(this)).ptr(), a1,
       a2,...aN)</dt>
     </dl>
+
+<pre>
+object operator()(detail::args_proxy const &amp;args) const;
+</pre>
+<dl class="function-semantics">
+ <dt><b>Effects:</b>
+ call object with arguments given by the tuple <varname>args</varname></dt>
+</dl>
+<pre>
+object operator()(detail::args_proxy const &amp;args,
+ detail::kwds_proxy const &amp;kwds) const;
+</pre>
+<dl class="function-semantics">
+ <dt><b>Effects:</b>
+ call object with arguments given by the tuple <varname>args</varname>, and named
+ arguments given by the dictionary <varname>kwds</varname></dt>
+</dl>
+
+
 <pre>
 operator bool_type() const;
 </pre>

Modified: trunk/libs/python/test/object.cpp
==============================================================================
--- trunk/libs/python/test/object.cpp (original)
+++ trunk/libs/python/test/object.cpp 2008-07-27 15:41:41 EDT (Sun, 27 Jul 2008)
@@ -187,6 +187,11 @@
     return s.slice(2,-1).slice(1,-1) == "lo, wor";
 }
 
+object test_call(object c, object args, object kwds)
+{
+ return c(*args, **kwds);
+}
+
 bool check_binary_operators()
 {
     int y;
@@ -377,6 +382,7 @@
     def("test_item", test_item);
     def("test_not_item", test_not_item);
 
+ def("test_call", test_call);
     def("check_binary_operators", check_binary_operators);
     def("check_inplace", check_inplace);
     def("check_string_slice", check_string_slice);

Modified: trunk/libs/python/test/object.py
==============================================================================
--- trunk/libs/python/test/object.py (original)
+++ trunk/libs/python/test/object.py 2008-07-27 15:41:41 EDT (Sun, 27 Jul 2008)
@@ -134,7 +134,12 @@
 
         Operators
 
-
+>>> def print_args(*args, **kwds):
+... print args, kwds
+>>> test_call(print_args, (0, 1, 2, 3), {'a':'A'})
+(0, 1, 2, 3) {'a': 'A'}
+
+
>>> assert check_binary_operators()
 
>>> class X: pass


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