[C++-sig] Patch implementing void * support
Niall Douglas
s_sourceforge at nedprod.com
Sun Nov 6 18:55:28 CET 2005
The enclosed patch adds void * support to Boost.Python by making void
an opaque type. Code that uses void * "just works" with this patch
with no further effort required.
Also enclosed is a testcase and the docs have been modified.
Ran full testsuite on msvc7.1 and msvc6 - everything works. I don't
have GCC to hand ATM, but apart from maybe a missing typename
specifier I can't see anything which would fault.
Cheers,
Niall
-------------- next part --------------
Only in boost: bin
diff -aur boost_1_33_0/boost/python/converter/registered.hpp boost/boost/python/converter/registered.hpp
--- boost_1_33_0/boost/python/converter/registered.hpp 2005-05-18 02:34:36.000000000 +0100
+++ boost/boost/python/converter/registered.hpp 2005-11-06 15:18:14.000000000 +0000
@@ -77,15 +77,35 @@
}
template <class T>
- registration const&
- registry_lookup(T&(*)())
+ inline registration const&
+ registry_lookup2(T&(*)())
{
detail::register_shared_ptr1((T*)0);
return registry::lookup(type_id<T&>());
}
template <class T>
- registration const& registered_base<T>::converters = detail::registry_lookup((T(*)())0);
+ inline registration const&
+ registry_lookup1()
+ {
+ return registry_lookup2((T(*)())0);
+ }
+
+ template <>
+ inline registration const&
+#ifdef BOOST_NO_CV_VOID_SPECIALIZATIONS
+ registry_lookup1<void>()
+#else
+ registry_lookup1<const volatile void>()
+#endif
+ {
+ detail::register_shared_ptr1((void*)0);
+ return registry::lookup(type_id<void>());
+ }
+
+ template <class T>
+ registration const& registered_base<T>::converters = detail::registry_lookup1<T>();
+
}
}}} // namespace boost::python::converter
diff -aur boost_1_33_0/boost/python/lvalue_from_pytype.hpp boost/boost/python/lvalue_from_pytype.hpp
--- boost_1_33_0/boost/python/lvalue_from_pytype.hpp 2004-08-20 12:09:16.000000000 +0100
+++ boost/boost/python/lvalue_from_pytype.hpp 2005-11-06 16:53:14.000000000 +0000
@@ -15,12 +15,25 @@
namespace detail
{
+ struct voidptrholder; // Used to indicate a void * is being extracted
+
+ template <class T>
+ inline type_info extractor_type_id2()
+ {
+ return type_id<T>();
+ }
+ template <>
+ inline type_info extractor_type_id2<voidptrholder>()
+ {
+ return type_id<void>();
+ }
+
// Given a pointer-to-function of 1 parameter returning a reference
// type, return the type_id of the function's return type.
template <class T, class U>
inline type_info extractor_type_id(T&(*)(U))
{
- return type_id<T>();
+ return extractor_type_id2<T>();
}
// A function generator whose static execute() function is an lvalue
diff -aur boost_1_33_0/boost/python/opaque_pointer_converter.hpp boost/boost/python/opaque_pointer_converter.hpp
--- boost_1_33_0/boost/python/opaque_pointer_converter.hpp 2004-08-20 12:09:16.000000000 +0100
+++ boost/boost/python/opaque_pointer_converter.hpp 2005-11-06 17:16:25.000000000 +0000
@@ -15,6 +15,7 @@
# include <boost/python/detail/none.hpp>
# include <boost/type_traits/remove_pointer.hpp>
# include <boost/type_traits/is_pointer.hpp>
+# include <boost/type_traits/is_void.hpp>
// opaque_pointer_converter --
//
@@ -54,6 +55,15 @@
, detail::opaque_pointer_converter_requires_a_pointer_type<Pointer>
>::type ptr_type;
+ typedef typename ::boost::remove_pointer<ptr_type>::type noptr_type;
+ typedef typename mpl::if_c<
+ ::boost::is_void<typename noptr_type>::value,
+ detail::voidptrholder,
+ typename noptr_type
+ >::type fixed_type;
+
+ typedef typename ::boost::add_reference<typename fixed_type>::type ref_type;
+
private:
struct instance;
@@ -84,10 +94,10 @@
return (result);
}
- static typename ::boost::remove_pointer<ptr_type>::type&
+ static typename ref_type
execute(instance &p_)
{
- return *p_.x;
+ return *(typename fixed_type *) p_.x;
}
private:
@@ -132,4 +142,8 @@
} \
}}
# endif
+
+// Declare void as an opaque type for automatic void * usage
+BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(void)
+
# endif // OPAQUE_POINTER_CONVERTER_HPP_
Only in boost/libs/python/build/VisualStudio: Debug
Only in boost_1_33_0/libs/python/build/VisualStudio: boost_python.dsp
Only in boost_1_33_0/libs/python/build/VisualStudio: boost_python.dsw
Only in boost/libs/python/build/VisualStudio: boost_python.ncb
Only in boost/libs/python/build/VisualStudio: boost_python.sln
Only in boost/libs/python/build/VisualStudio: boost_python.suo
Only in boost/libs/python/build/VisualStudio: boost_python.vcproj
Only in boost/libs/python/build: bin-stage
diff -aur boost_1_33_0/libs/python/doc/v2/faq.html boost/libs/python/doc/v2/faq.html
--- boost_1_33_0/libs/python/doc/v2/faq.html 2004-11-28 03:54:58.000000000 +0000
+++ boost/libs/python/doc/v2/faq.html 2005-11-06 17:17:31.000000000 +0000
@@ -67,8 +67,6 @@
>error C2064: term does not evaluate to a function taking 2 arguments</a>
</dt>
- <dt><a href="#voidptr">How do I handle <tt>void *</tt> conversion?</a></dt>
-
<dt><a href="#custom_string"
>How can I automatically convert my custom string type to
and from a Python string?</a></dt>
@@ -694,29 +692,6 @@
<p>(The bug has been reported to Microsoft.)</p>
<hr>
- <h2><a name="voidptr"></a>How do I handle <tt>void *</tt> conversion?</h2>
- <font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
- For several reasons Boost.Python does not support <tt>void *</tt> as
- an argument or as a return value. However, it is possible to wrap
- functions with <tt>void *</tt> arguments or return values using
- thin wrappers and the <i>opaque pointer</i> facility. E.g.:
- <pre>// Declare the following in each translation unit
-struct void_ {};
-BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(void_);
-
-void *foo(int par1, void *par2);
-
-void_ *foo_wrapper(int par1, void_ *par2)
-{
- return (void_ *) foo(par1, par2);
-}
-...
-BOOST_PYTHON_MODULE(bar)
-{
- def("foo", &foo_wrapper);
-}</pre>
-
- <hr>
<h2><a name="custom_string"></a>How can I automatically
convert my custom string type to and from a Python string?</h2>
<font size="-1"><i>Ralf W. Grosse-Kunstleve provides these
diff -aur boost_1_33_0/libs/python/test/Jamfile boost/libs/python/test/Jamfile
--- boost_1_33_0/libs/python/test/Jamfile 2005-07-07 15:00:30.000000000 +0100
+++ boost/libs/python/test/Jamfile 2005-11-06 15:28:29.000000000 +0000
@@ -151,6 +151,7 @@
[ bpl-test extract ]
[ bpl-test opaque ]
+[ bpl-test voidptr ]
[ bpl-test pickle1 ]
[ bpl-test pickle2 ]
Only in boost/libs/python/test: bjam.exe
Only in boost/libs/python/test: hello.txt
Only in boost/libs/python/test: voidptr
Only in boost/libs/python/test: voidptr.cpp
Only in boost/libs/python/test: voidptr.py
Only in boost/tools/build/jam_src: bin.ntx86
Only in boost/tools/build/jam_src: bootstrap
Only in boost/tools/build/jam_src: builtins.obj
Only in boost/tools/build/jam_src: class.obj
Only in boost/tools/build/jam_src: command.obj
Only in boost/tools/build/jam_src: compile.obj
Only in boost/tools/build/jam_src: execnt.obj
Only in boost/tools/build/jam_src: execunix.obj
Only in boost/tools/build/jam_src: execvms.obj
Only in boost/tools/build/jam_src: expand.obj
Only in boost/tools/build/jam_src: filent.obj
Only in boost/tools/build/jam_src: fileos2.obj
Only in boost/tools/build/jam_src: filesys.obj
Only in boost/tools/build/jam_src: fileunix.obj
Only in boost/tools/build/jam_src: filevms.obj
Only in boost/tools/build/jam_src: glob.obj
Only in boost/tools/build/jam_src: hash.obj
Only in boost/tools/build/jam_src: hcache.obj
Only in boost/tools/build/jam_src: hdrmacro.obj
Only in boost/tools/build/jam_src: headers.obj
Only in boost/tools/build/jam_src: jam.obj
Only in boost/tools/build/jam_src: jambase.obj
Only in boost/tools/build/jam_src: jamgram.obj
Only in boost/tools/build/jam_src: lists.obj
Only in boost/tools/build/jam_src: make.obj
Only in boost/tools/build/jam_src: make1.obj
Only in boost/tools/build/jam_src: modules.obj
Only in boost/tools/build/jam_src: native.obj
Only in boost/tools/build/jam_src: newstr.obj
Only in boost/tools/build/jam_src: option.obj
Only in boost/tools/build/jam_src: order.obj
Only in boost/tools/build/jam_src: parse.obj
Only in boost/tools/build/jam_src: path.obj
Only in boost/tools/build/jam_src: pathunix.obj
Only in boost/tools/build/jam_src: pathvms.obj
Only in boost/tools/build/jam_src: property-set.obj
Only in boost/tools/build/jam_src: pwd.obj
Only in boost/tools/build/jam_src: regex.obj
Only in boost/tools/build/jam_src: regexp.obj
Only in boost/tools/build/jam_src: rules.obj
Only in boost/tools/build/jam_src: scan.obj
Only in boost/tools/build/jam_src: search.obj
Only in boost/tools/build/jam_src: sequence.obj
Only in boost/tools/build/jam_src: set.obj
Only in boost/tools/build/jam_src: strings.obj
Only in boost/tools/build/jam_src: subst.obj
Only in boost/tools/build/jam_src: timestamp.obj
Only in boost/tools/build/jam_src: variable.obj
Only in boost/tools/build/jam_src: vc70.pdb
Only in boost/tools/build/jam_src: w32_getreg.obj
-------------- next part --------------
# Copyright Niall Douglas 2005.
# 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)
"""
>>> from voidptr_ext import *
Check for correct conversion
>>> use(get())
Check that None is converted to a NULL void pointer
>>> useany(get())
1
>>> useany(None)
0
Check that we don't lose type information by converting NULL
opaque pointers to None
>>> assert getnull() is None
>>> useany(getnull())
0
Check that there is no conversion from integers ...
>>> try: use(0)
... except TypeError: pass
... else: print 'expected a TypeError'
... and from strings to opaque objects
>>> try: use("")
... except TypeError: pass
... else: print 'expected a TypeError'
"""
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
status = run()[0]
if (status == 0): print "Done."
sys.exit(status)
-------------- next part --------------
The following section of this message contains a file attachment
prepared for transmission using the Internet MIME message format.
If you are using Pegasus Mail, or any other MIME-compliant system,
you should be able to save it or view it from within your mailer.
If you cannot, please ask your system administrator for assistance.
---- File information -----------
File: voidptr.cpp
Date: 6 Nov 2005, 17:38
Size: 892 bytes.
Type: Program-source
-------------- next part --------------
A non-text attachment was scrubbed...
Name: voidptr.cpp
Type: application/octet-stream
Size: 892 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20051106/6ddaeb9e/attachment.obj>
More information about the Cplusplus-sig
mailing list