mirror of
https://github.com/boostorg/python.git
synced 2026-01-26 18:52:26 +00:00
This commit was manufactured by cvs2svn to create tag
'merged_to_RC_1_28_2'. [SVN r17842]
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/args.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/overloads.hpp>
|
||||
#include <boost/python/raw_function.hpp>
|
||||
#include <boost/python/return_internal_reference.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
|
||||
{
|
||||
return make_tuple(x, y, z);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3)
|
||||
|
||||
typedef test_class<> Y;
|
||||
|
||||
struct X
|
||||
{
|
||||
X(int a0 = 0, int a1 = 1) : inner0(a0), inner1(a1) {}
|
||||
tuple f(int x = 1, double y = 4.25, char const* z = "wow")
|
||||
{
|
||||
return make_tuple(x, y, z);
|
||||
}
|
||||
|
||||
Y const& inner(bool n) const { return n ? inner1 : inner0; }
|
||||
|
||||
Y inner0;
|
||||
Y inner1;
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3)
|
||||
|
||||
|
||||
tuple raw_func(tuple args, dict kw)
|
||||
{
|
||||
return make_tuple(args, kw);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(args_ext)
|
||||
{
|
||||
def("f", f, args("x", "y", "z")
|
||||
, "This is f's docstring"
|
||||
);
|
||||
|
||||
def("raw", raw_function(raw_func));
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1200
|
||||
// MSVC6 gives a fatal error LNK1179: invalid or corrupt file:
|
||||
// duplicate comdat error if we try to re-use the exact type of f
|
||||
// here, so substitute long for int.
|
||||
tuple (*f)(long,double,char const*) = 0;
|
||||
#endif
|
||||
def("f1", f, f_overloads("f1's docstring", args("x", "y", "z")));
|
||||
def("f2", f, f_overloads(args("x", "y", "z")));
|
||||
def("f3", f, f_overloads(args("x", "y", "z"), "f3's docstring"));
|
||||
|
||||
class_<Y>("Y", init<int>(args("value"), "Y's docstring"))
|
||||
.def("value", &Y::value)
|
||||
.def("raw", raw_function(raw_func))
|
||||
;
|
||||
|
||||
class_<X>("X", "This is X's docstring")
|
||||
.def(init<int, optional<int> >(args("a0", "a1")))
|
||||
.def("f", &X::f
|
||||
, "This is X.f's docstring"
|
||||
, args("x", "y", "z"))
|
||||
|
||||
// Just to prove that all the different argument combinations work
|
||||
.def("inner0", &X::inner, return_internal_reference<>(), args("n"), "docstring")
|
||||
.def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("n"))
|
||||
|
||||
.def("inner2", &X::inner, args("n"), return_internal_reference<>(), "docstring")
|
||||
.def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("n"))
|
||||
|
||||
.def("inner4", &X::inner, args("n"), "docstring", return_internal_reference<>())
|
||||
.def("inner5", &X::inner, "docstring", args("n"), return_internal_reference<>())
|
||||
|
||||
.def("f1", &X::f, X_f_overloads(args("x", "y", "z")))
|
||||
;
|
||||
|
||||
def("inner", &X::inner, "docstring", args("self", "n"), return_internal_reference<>());
|
||||
}
|
||||
169
test/args.py
169
test/args.py
@@ -1,169 +0,0 @@
|
||||
"""
|
||||
>>> from args_ext import *
|
||||
|
||||
>>> raw(3, 4, foo = 'bar', baz = 42)
|
||||
((3, 4), {'foo': 'bar', 'baz': 42})
|
||||
|
||||
>>> f(x= 1, y = 3, z = 'hello')
|
||||
(1, 3.0, 'hello')
|
||||
|
||||
>>> f(z = 'hello', x = 3, y = 2.5)
|
||||
(3, 2.5, 'hello')
|
||||
|
||||
>>> f(1, z = 'hi', y = 3)
|
||||
(1, 3.0, 'hi')
|
||||
|
||||
>>> try: f(1, 2, 'hello', bar = 'baz')
|
||||
... except TypeError: pass
|
||||
... else: print 'expected an exception: unknown keyword'
|
||||
|
||||
|
||||
Exercise the functions using default stubs
|
||||
|
||||
>>> f1(z = 'nix', y = .125, x = 2)
|
||||
(2, 0.125, 'nix')
|
||||
>>> f1(y = .125, x = 2)
|
||||
(2, 0.125, 'wow')
|
||||
>>> f1(x = 2)
|
||||
(2, 4.25, 'wow')
|
||||
>>> f1()
|
||||
(1, 4.25, 'wow')
|
||||
|
||||
>>> f2(z = 'nix', y = .125, x = 2)
|
||||
(2, 0.125, 'nix')
|
||||
>>> f2(y = .125, x = 2)
|
||||
(2, 0.125, 'wow')
|
||||
>>> f2(x = 2)
|
||||
(2, 4.25, 'wow')
|
||||
>>> f2()
|
||||
(1, 4.25, 'wow')
|
||||
|
||||
>>> f3(z = 'nix', y = .125, x = 2)
|
||||
(2, 0.125, 'nix')
|
||||
>>> f3(y = .125, x = 2)
|
||||
(2, 0.125, 'wow')
|
||||
>>> f3(x = 2)
|
||||
(2, 4.25, 'wow')
|
||||
>>> f3()
|
||||
(1, 4.25, 'wow')
|
||||
|
||||
Member function tests
|
||||
|
||||
>>> q = X()
|
||||
>>> q.f(x= 1, y = 3, z = 'hello')
|
||||
(1, 3.0, 'hello')
|
||||
|
||||
>>> q.f(z = 'hello', x = 3, y = 2.5)
|
||||
(3, 2.5, 'hello')
|
||||
|
||||
>>> q.f(1, z = 'hi', y = 3)
|
||||
(1, 3.0, 'hi')
|
||||
|
||||
>>> try: q.f(1, 2, 'hello', bar = 'baz')
|
||||
... except TypeError: pass
|
||||
... else: print 'expected an exception: unknown keyword'
|
||||
|
||||
Exercise member functions using default stubs
|
||||
|
||||
>>> q.f1(z = 'nix', y = .125, x = 2)
|
||||
(2, 0.125, 'nix')
|
||||
>>> q.f1(y = .125, x = 2)
|
||||
(2, 0.125, 'wow')
|
||||
>>> q.f1(x = 2)
|
||||
(2, 4.25, 'wow')
|
||||
>>> q.f1()
|
||||
(1, 4.25, 'wow')
|
||||
|
||||
>>> X.f.__doc__
|
||||
"This is X.f's docstring"
|
||||
|
||||
>>> xfuncs = (X.inner0, X.inner1, X.inner2, X.inner3, X.inner4, X.inner5)
|
||||
>>> for f in xfuncs:
|
||||
... print f(q,1).value(),
|
||||
... print f(q, n = 1).value(),
|
||||
... print f(q, n = 0).value(),
|
||||
... print f.__doc__
|
||||
1 1 0 docstring
|
||||
1 1 0 docstring
|
||||
1 1 0 docstring
|
||||
1 1 0 docstring
|
||||
1 1 0 docstring
|
||||
1 1 0 docstring
|
||||
|
||||
>>> x = X(a1 = 44, a0 = 22)
|
||||
>>> x.inner0(0).value()
|
||||
22
|
||||
>>> x.inner0(1).value()
|
||||
44
|
||||
|
||||
>>> x = X(a0 = 7)
|
||||
>>> x.inner0(0).value()
|
||||
7
|
||||
>>> x.inner0(1).value()
|
||||
1
|
||||
|
||||
>>> inner(n = 1, self = q).value()
|
||||
1
|
||||
|
||||
>>> y = Y(value = 33)
|
||||
>>> y.raw(this = 1, that = 'the other')[1]
|
||||
{'this': 1, 'that': 'the other'}
|
||||
|
||||
"""
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/converter/to_python_function_type.hpp>
|
||||
|
||||
struct hopefully_illegal
|
||||
{
|
||||
static PyObject* convert(int&);
|
||||
};
|
||||
|
||||
PyObject* x = boost::python::converter::as_to_python_function<int, hopefully_illegal>::convert(0);
|
||||
@@ -1,91 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/implicit.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include "test_class.hpp"
|
||||
#include <memory>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
typedef test_class<> X;
|
||||
|
||||
struct Y : X
|
||||
{
|
||||
Y(int n) : X(n) {};
|
||||
};
|
||||
|
||||
int look(std::auto_ptr<X> const& x)
|
||||
{
|
||||
return (x.get()) ? x->value() : -1;
|
||||
}
|
||||
|
||||
int steal(std::auto_ptr<X> x)
|
||||
{
|
||||
return x->value();
|
||||
}
|
||||
|
||||
int maybe_steal(std::auto_ptr<X>& x, bool doit)
|
||||
{
|
||||
int n = x->value();
|
||||
if (doit)
|
||||
x.release();
|
||||
return n;
|
||||
}
|
||||
|
||||
std::auto_ptr<X> make()
|
||||
{
|
||||
return std::auto_ptr<X>(new X(77));
|
||||
}
|
||||
|
||||
std::auto_ptr<X> callback(object f)
|
||||
{
|
||||
std::auto_ptr<X> x(new X(77));
|
||||
return call<std::auto_ptr<X> >(f.ptr(), x);
|
||||
}
|
||||
|
||||
std::auto_ptr<X> extract_(object o)
|
||||
{
|
||||
return extract<std::auto_ptr<X>&>(o)
|
||||
#if BOOST_MSVC <= 1300
|
||||
()
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(auto_ptr_ext)
|
||||
{
|
||||
class_<X, std::auto_ptr<X>, boost::noncopyable>("X", init<int>())
|
||||
.def("value", &X::value)
|
||||
;
|
||||
|
||||
class_<Y, std::auto_ptr<Y>, bases<X>, boost::noncopyable>("Y", init<int>())
|
||||
;
|
||||
|
||||
// VC6 auto_ptrs do not have converting constructors
|
||||
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 306)
|
||||
scope().attr("broken_auto_ptr") = 1;
|
||||
#else
|
||||
scope().attr("broken_auto_ptr") = 0;
|
||||
implicitly_convertible<std::auto_ptr<Y>, std::auto_ptr<X> >();
|
||||
#endif
|
||||
|
||||
def("look", look);
|
||||
def("steal", steal);
|
||||
def("maybe_steal", maybe_steal);
|
||||
def("make", make);
|
||||
def("callback", callback);
|
||||
def("extract", extract_);
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
'''
|
||||
>>> from auto_ptr_ext import *
|
||||
>>> x = X(42)
|
||||
>>> x.value()
|
||||
42
|
||||
>>> look(x), look(x)
|
||||
(42, 42)
|
||||
|
||||
>>> maybe_steal(x, 0)
|
||||
42
|
||||
>>> look(x)
|
||||
42
|
||||
|
||||
>>> maybe_steal(x, 1)
|
||||
42
|
||||
>>> broken_auto_ptr and -1 or look(x)
|
||||
-1
|
||||
|
||||
>>> x = X(69)
|
||||
>>> steal(x)
|
||||
69
|
||||
>>> broken_auto_ptr and -1 or look(x)
|
||||
-1
|
||||
|
||||
>>> if not broken_auto_ptr:
|
||||
... try: x.value()
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError exception'
|
||||
|
||||
>>> x = make()
|
||||
>>> look(x)
|
||||
77
|
||||
|
||||
>>> z = callback(lambda z: z)
|
||||
>>> z.value()
|
||||
77
|
||||
|
||||
>>> extract(x).value()
|
||||
77
|
||||
|
||||
#
|
||||
# Test derived to base conversions
|
||||
#
|
||||
|
||||
>>> y = Y(42)
|
||||
>>> y.value()
|
||||
42
|
||||
|
||||
>>> try: maybe_steal(y, 0)
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError exception'
|
||||
|
||||
>>> y.value()
|
||||
42
|
||||
|
||||
>>> broken_auto_ptr and 42 or steal(y)
|
||||
42
|
||||
|
||||
>>> if not broken_auto_ptr:
|
||||
... try: y.value()
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError exception'
|
||||
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,111 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/has_back_reference.hpp>
|
||||
#include <boost/python/back_reference.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
#include <boost/python/copy_const_reference.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
|
||||
// This test shows that a class can be wrapped "as itself" but also
|
||||
// acquire a back-reference iff has_back_reference<> is appropriately
|
||||
// specialized.
|
||||
using namespace boost::python;
|
||||
|
||||
struct X
|
||||
{
|
||||
explicit X(int x) : x(x), magic(7654321) { ++counter; }
|
||||
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
|
||||
virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int x) { assert(magic == 7654321); this->x = x; }
|
||||
int value() const { assert(magic == 7654321); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
void operator=(X const&);
|
||||
private:
|
||||
int x;
|
||||
long magic;
|
||||
static int counter;
|
||||
};
|
||||
|
||||
int X::counter;
|
||||
|
||||
struct Y : X
|
||||
{
|
||||
Y(PyObject* self, int x) : X(x) {};
|
||||
Y(PyObject* self, Y const& rhs) : X(rhs), self(self) {};
|
||||
private:
|
||||
Y(Y const&);
|
||||
PyObject* self;
|
||||
};
|
||||
|
||||
struct Z : X
|
||||
{
|
||||
Z(PyObject* self, int x) : X(x) {};
|
||||
Z(PyObject* self, Z const& rhs) : X(rhs), self(self) {};
|
||||
private:
|
||||
Z(Z const&);
|
||||
PyObject* self;
|
||||
};
|
||||
|
||||
Y const& copy_Y(Y const& y) { return y; }
|
||||
Z const& copy_Z(Z const& z) { return z; }
|
||||
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template <>
|
||||
struct has_back_reference<Y>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct has_back_reference<Z>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
}}
|
||||
|
||||
// prove that back_references get initialized with the right PyObject*
|
||||
object y_identity(back_reference<Y const&> y)
|
||||
{
|
||||
return y.source();
|
||||
}
|
||||
|
||||
// prove that back_references contain the right value
|
||||
bool y_equality(back_reference<Y const&> y1, Y const& y2)
|
||||
{
|
||||
return &y1.get() == &y2;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(back_reference_ext)
|
||||
{
|
||||
def("copy_Y", copy_Y, return_value_policy<copy_const_reference>());
|
||||
def("copy_Z", copy_Z, return_value_policy<copy_const_reference>());
|
||||
def("x_instances", &X::count);
|
||||
|
||||
class_<Y>("Y", init<int>())
|
||||
.def("value", &Y::value)
|
||||
.def("set", &Y::set)
|
||||
;
|
||||
|
||||
class_<Z,std::auto_ptr<Z> >("Z", init<int>())
|
||||
.def("value", &Z::value)
|
||||
.def("set", &Z::set)
|
||||
;
|
||||
|
||||
def("y_identity", y_identity);
|
||||
def("y_equality", y_equality);
|
||||
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,29 +0,0 @@
|
||||
'''
|
||||
>>> from back_reference_ext import *
|
||||
>>> y = Y(3)
|
||||
>>> z = Z(4)
|
||||
>>> x_instances()
|
||||
2
|
||||
>>> y2 = copy_Y(y)
|
||||
>>> x_instances()
|
||||
3
|
||||
>>> z2 = copy_Z(z)
|
||||
>>> x_instances()
|
||||
4
|
||||
>>> assert y_identity(y) is y
|
||||
>>> y_equality(y, y)
|
||||
1
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,63 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/bases.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
|
||||
struct A;
|
||||
struct B;
|
||||
|
||||
template <class X, class Y, class Z>
|
||||
struct choose_bases
|
||||
: boost::python::detail::select_bases<
|
||||
X
|
||||
, typename boost::python::detail::select_bases<
|
||||
Y
|
||||
, typename boost::python::detail::select_bases<Z>::type
|
||||
>::type>
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::python::detail::specifies_bases<
|
||||
boost::python::bases<A,B> >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases<
|
||||
boost::python::bases<A,B>& >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases<
|
||||
void* >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases<
|
||||
int >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases<
|
||||
int[5] >::value));
|
||||
|
||||
typedef boost::python::detail::select_bases<
|
||||
int
|
||||
, boost::python::detail::select_bases<char*>::type > collected1;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<collected1::type,boost::python::bases<> >::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose_bases<int,char*,long>::type,boost::python::bases<> >::value));
|
||||
|
||||
typedef boost::python::detail::select_bases<
|
||||
int
|
||||
, boost::python::detail::select_bases<
|
||||
boost::python::bases<A,B>
|
||||
, boost::python::detail::select_bases<
|
||||
A
|
||||
>::type
|
||||
>::type
|
||||
> collected2;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<collected2::type,boost::python::bases<A,B> >::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose_bases<int,boost::python::bases<A,B>,long>::type,boost::python::bases<A,B> >::value));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
#include <boost/python.hpp>
|
||||
#include <iostream>
|
||||
using namespace boost::python;
|
||||
using namespace boost;
|
||||
|
||||
struct Product {};
|
||||
typedef shared_ptr<Product> ProductPtr;
|
||||
|
||||
|
||||
struct Creator
|
||||
{
|
||||
virtual ~Creator() {}
|
||||
virtual ProductPtr create() = 0;
|
||||
};
|
||||
|
||||
|
||||
struct Factory
|
||||
{
|
||||
void reg(Creator* c) { mC = c; }
|
||||
ProductPtr create()
|
||||
{
|
||||
std::cout << "Name: " << (typeid(*mC)).name() << std::endl;
|
||||
return mC->create();
|
||||
}
|
||||
|
||||
private:
|
||||
Creator* mC;
|
||||
};
|
||||
|
||||
struct CreatorWrap : public Creator
|
||||
{
|
||||
CreatorWrap(PyObject* self) : mSelf(self) {}
|
||||
ProductPtr create() { return call_method<ProductPtr>(mSelf, "create"); }
|
||||
PyObject* mSelf;
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(ben_scott1_ext)
|
||||
{
|
||||
class_<Product, ProductPtr>("Product");
|
||||
|
||||
class_<Creator, CreatorWrap, noncopyable>("Creator")
|
||||
.def("create", &CreatorWrap::create)
|
||||
;
|
||||
|
||||
class_<Factory>("Factory")
|
||||
.def("reg", &Factory::reg, with_custodian_and_ward<1,2>())
|
||||
.def("create", &Factory::create)
|
||||
;
|
||||
}
|
||||
|
||||
#include "../test/module_tail.cpp"
|
||||
@@ -1,14 +0,0 @@
|
||||
# This regression test checks that call_method<T>(...) where T is a
|
||||
# non-reference, non-pointer type that happens to be held inside the
|
||||
# result object (and thus is found as an lvalue) works.
|
||||
from ben_scott1_ext import *
|
||||
|
||||
class CreatorImpl(Creator):
|
||||
def create(self):
|
||||
return Product()
|
||||
|
||||
factory = Factory()
|
||||
c = CreatorImpl()
|
||||
factory.reg(c)
|
||||
|
||||
a = factory.create()
|
||||
@@ -1,37 +0,0 @@
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/reference_existing_object.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
|
||||
struct A {};
|
||||
|
||||
struct V
|
||||
{
|
||||
|
||||
virtual void f() = 0;
|
||||
|
||||
const A* inside() {return &a;}
|
||||
|
||||
A a;
|
||||
};
|
||||
|
||||
const A* outside(const V& v) {return &v.a;}
|
||||
|
||||
BOOST_PYTHON_MODULE(bienstman1_ext)
|
||||
{
|
||||
using namespace boost::python;
|
||||
using boost::shared_ptr;
|
||||
using boost::python::return_value_policy;
|
||||
using boost::python::reference_existing_object;
|
||||
|
||||
class_<A>("A");
|
||||
|
||||
class_<V, boost::noncopyable>("V", no_init)
|
||||
.def("inside", &V::inside,
|
||||
return_value_policy<reference_existing_object>())
|
||||
.def("outside", outside,
|
||||
return_value_policy<reference_existing_object>())
|
||||
;
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
'''
|
||||
# Try to reproduce a Numeric interaction bug if Numeric is installed.
|
||||
>>> from bienstman1_ext import *
|
||||
>>> try: from Numeric import *
|
||||
... except: pass
|
||||
'''
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,25 +0,0 @@
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
|
||||
struct C {};
|
||||
|
||||
struct D {};
|
||||
|
||||
struct E
|
||||
{
|
||||
const D fe (const C&) {return D();}
|
||||
const D fe2(const C&, const C&) {return D();}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(bienstman2_ext)
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
class_<C>("C");
|
||||
class_<D>("D");
|
||||
class_<E>("E")
|
||||
.def("fe", &E::fe) // this compiles.
|
||||
.def("fe2", &E::fe2) // this doesn't... well, now it does ;-)
|
||||
;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
'''
|
||||
>>> import bienstman2_ext
|
||||
'''
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
|
||||
struct V
|
||||
{
|
||||
virtual void f() = 0;
|
||||
};
|
||||
|
||||
struct B
|
||||
{
|
||||
B(const V&) {}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(bienstman3_ext)
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
class_<V, boost::noncopyable>("V", no_init);
|
||||
class_<B>("B", init<const V&>());
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
'''
|
||||
>>> from bienstman3_ext import *
|
||||
|
||||
>>> try:
|
||||
... V()
|
||||
... except RuntimeError, x:
|
||||
... print x
|
||||
... else:
|
||||
... print 'expected an exception'
|
||||
...
|
||||
This class cannot be instantiated from Python
|
||||
|
||||
'''
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,40 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/implicit.hpp>
|
||||
#include <boost/mpl/list.hpp>
|
||||
|
||||
struct Type1 {};
|
||||
|
||||
struct Term {Term(Type1 const&) {} };
|
||||
|
||||
struct Expression {void add(Term const&) {} };
|
||||
|
||||
BOOST_PYTHON_MODULE(bienstman4_ext)
|
||||
{
|
||||
using namespace boost::python;
|
||||
using boost::mpl::list;
|
||||
|
||||
implicitly_convertible<Type1,Term>();
|
||||
|
||||
class_<Expression>("Expression")
|
||||
.def("add", &Expression::add)
|
||||
;
|
||||
|
||||
class_<Type1>("T1")
|
||||
;
|
||||
|
||||
class_<Term>("Term", init<Type1&>())
|
||||
;
|
||||
|
||||
Type1 t1;
|
||||
Expression e;
|
||||
e.add(t1);
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
'''
|
||||
>>> from bienstman4_ext import *
|
||||
>>> t1 = T1()
|
||||
>>> e = Expression()
|
||||
>>> e.add(t1)
|
||||
'''
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/mpl/list.hpp>
|
||||
|
||||
#include <complex>
|
||||
|
||||
struct M {M(const std::complex<double>&) {} };
|
||||
|
||||
BOOST_PYTHON_MODULE(bienstman5_ext)
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
class_<M>("M", init<std::complex<double> const&>())
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
'''
|
||||
>>> from bienstman5_ext import *
|
||||
>>> m = M(1j)
|
||||
'''
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,34 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/detail/wrap_python.hpp>
|
||||
#include <boost/python/borrowed.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
template <class T>
|
||||
void assert_borrowed_ptr(T const& x)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(boost::python::detail::is_borrowed_ptr<T>::value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void assert_not_borrowed_ptr(T const& x)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(!boost::python::detail::is_borrowed_ptr<T>::value);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
assert_borrowed_ptr(borrowed((PyObject*)0));
|
||||
assert_borrowed_ptr(borrowed((PyTypeObject*)0));
|
||||
assert_borrowed_ptr((detail::borrowed<PyObject> const*)0);
|
||||
assert_borrowed_ptr((detail::borrowed<PyObject> volatile*)0);
|
||||
assert_borrowed_ptr((detail::borrowed<PyObject> const volatile*)0);
|
||||
assert_not_borrowed_ptr((PyObject*)0);
|
||||
assert_not_borrowed_ptr(0);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/python/ptr.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
#include <boost/python/reference_existing_object.hpp>
|
||||
#include <boost/python/call.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
BOOST_STATIC_ASSERT(converter::is_object_manager<handle<> >::value);
|
||||
|
||||
int apply_int_int(PyObject* f, int x)
|
||||
{
|
||||
return call<int>(f, x);
|
||||
}
|
||||
|
||||
void apply_void_int(PyObject* f, int x)
|
||||
{
|
||||
call<void>(f, x);
|
||||
}
|
||||
|
||||
struct X
|
||||
{
|
||||
explicit X(int x) : x(x), magic(7654321) { ++counter; }
|
||||
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
|
||||
~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int x) { assert(magic == 7654321); this->x = x; }
|
||||
int value() const { assert(magic == 7654321); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
void operator=(X const&);
|
||||
private:
|
||||
int x;
|
||||
long magic;
|
||||
static int counter;
|
||||
};
|
||||
|
||||
X apply_X_X(PyObject* f, X x)
|
||||
{
|
||||
return call<X>(f, x);
|
||||
}
|
||||
|
||||
void apply_void_X_ref(PyObject* f, X& x)
|
||||
{
|
||||
call<void>(f, boost::ref(x));
|
||||
}
|
||||
|
||||
X& apply_X_ref_handle(PyObject* f, handle<> obj)
|
||||
{
|
||||
return call<X&>(f, obj);
|
||||
}
|
||||
|
||||
X* apply_X_ptr_handle_cref(PyObject* f, handle<> const& obj)
|
||||
{
|
||||
return call<X*>(f, obj);
|
||||
}
|
||||
|
||||
void apply_void_X_cref(PyObject* f, X const& x)
|
||||
{
|
||||
call<void>(f, boost::cref(x));
|
||||
}
|
||||
|
||||
void apply_void_X_ptr(PyObject* f, X* x)
|
||||
{
|
||||
call<void>(f, ptr(x));
|
||||
}
|
||||
|
||||
void apply_void_X_deep_ptr(PyObject* f, X* x)
|
||||
{
|
||||
call<void>(f, x);
|
||||
}
|
||||
|
||||
char const* apply_cstring_cstring(PyObject* f, char const* s)
|
||||
{
|
||||
return call<char const*>(f, s);
|
||||
}
|
||||
|
||||
char const* apply_cstring_pyobject(PyObject* f, PyObject* s)
|
||||
{
|
||||
return call<char const*>(f, borrowed(s));
|
||||
}
|
||||
|
||||
char apply_char_char(PyObject* f, char c)
|
||||
{
|
||||
return call<char>(f, c);
|
||||
}
|
||||
|
||||
char const* apply_to_string_literal(PyObject* f)
|
||||
{
|
||||
return call<char const*>(f, "hello, world");
|
||||
}
|
||||
|
||||
handle<> apply_to_own_type(handle<> x)
|
||||
{
|
||||
// Tests that we can return handle<> from a callback and that we
|
||||
// can pass arbitrary handle<T>.
|
||||
return call<handle<> >(x.get(), type_handle(borrowed(x->ob_type)));
|
||||
}
|
||||
|
||||
object apply_object_object(PyObject* f, object x)
|
||||
{
|
||||
return call<object>(f, x);
|
||||
}
|
||||
|
||||
int X::counter;
|
||||
|
||||
BOOST_PYTHON_MODULE(callbacks_ext)
|
||||
{
|
||||
def("apply_object_object", apply_object_object);
|
||||
def("apply_to_own_type", apply_to_own_type);
|
||||
def("apply_int_int", apply_int_int);
|
||||
def("apply_void_int", apply_void_int);
|
||||
def("apply_X_X", apply_X_X);
|
||||
def("apply_void_X_ref", apply_void_X_ref);
|
||||
def("apply_void_X_cref", apply_void_X_cref);
|
||||
def("apply_void_X_ptr", apply_void_X_ptr);
|
||||
def("apply_void_X_deep_ptr", apply_void_X_deep_ptr);
|
||||
|
||||
def("apply_X_ptr_handle_cref", apply_X_ptr_handle_cref
|
||||
, return_value_policy<reference_existing_object>());
|
||||
|
||||
def("apply_X_ref_handle", apply_X_ref_handle
|
||||
, return_value_policy<reference_existing_object>());
|
||||
|
||||
def("apply_cstring_cstring", apply_cstring_cstring);
|
||||
def("apply_cstring_pyobject", apply_cstring_pyobject);
|
||||
def("apply_char_char", apply_char_char);
|
||||
def("apply_to_string_literal", apply_to_string_literal);
|
||||
|
||||
|
||||
class_<X>("X", init<int>())
|
||||
.def(init<X const&>())
|
||||
.def("value", &X::value)
|
||||
.def("set", &X::set)
|
||||
;
|
||||
|
||||
def("x_count", &X::count);
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,133 +0,0 @@
|
||||
'''
|
||||
>>> from callbacks_ext import *
|
||||
|
||||
>>> def double(x):
|
||||
... return x + x
|
||||
...
|
||||
>>> apply_int_int(double, 42)
|
||||
84
|
||||
>>> apply_void_int(double, 42)
|
||||
|
||||
>>> def identity(x):
|
||||
... return x
|
||||
|
||||
Once we have array conversion support, this test will fail. Er,
|
||||
succeed<wink>:
|
||||
|
||||
>>> try: apply_to_string_literal(identity)
|
||||
... except: pass # expected
|
||||
... else: print 'expected an exception!'
|
||||
|
||||
>>> x = apply_X_X(identity, X(42))
|
||||
>>> x.value()
|
||||
42
|
||||
>>> x_count()
|
||||
1
|
||||
>>> del x
|
||||
>>> x_count()
|
||||
0
|
||||
|
||||
>>> def increment(x):
|
||||
... x.set(x.value() + 1)
|
||||
...
|
||||
>>> x = X(42)
|
||||
>>> apply_void_X_ref(increment, x)
|
||||
>>> x.value()
|
||||
43
|
||||
|
||||
>>> apply_void_X_cref(increment, x)
|
||||
>>> x.value() # const-ness is not respected, sorry!
|
||||
44
|
||||
|
||||
>>> last_x = 1
|
||||
>>> def decrement(x):
|
||||
... global last_x
|
||||
... last_x = x
|
||||
... if x is not None:
|
||||
... x.set(x.value() - 1)
|
||||
|
||||
>>> apply_void_X_ptr(decrement, x)
|
||||
>>> x.value()
|
||||
43
|
||||
>>> last_x.value()
|
||||
43
|
||||
>>> increment(last_x)
|
||||
>>> x.value()
|
||||
44
|
||||
>>> last_x.value()
|
||||
44
|
||||
|
||||
>>> apply_void_X_ptr(decrement, None)
|
||||
>>> assert last_x is None
|
||||
>>> x.value()
|
||||
44
|
||||
|
||||
>>> last_x = 1
|
||||
>>> apply_void_X_deep_ptr(decrement, None)
|
||||
>>> assert last_x is None
|
||||
>>> x.value()
|
||||
44
|
||||
|
||||
>>> apply_void_X_deep_ptr(decrement, x)
|
||||
>>> x.value()
|
||||
44
|
||||
>>> last_x.value()
|
||||
43
|
||||
|
||||
>>> y = apply_X_ref_handle(identity, x)
|
||||
>>> assert y.value() == x.value()
|
||||
>>> increment(x)
|
||||
>>> assert y.value() == x.value()
|
||||
|
||||
>>> y = apply_X_ptr_handle_cref(identity, x)
|
||||
>>> assert y.value() == x.value()
|
||||
>>> increment(x)
|
||||
>>> assert y.value() == x.value()
|
||||
|
||||
>>> y = apply_X_ptr_handle_cref(identity, None)
|
||||
>>> y
|
||||
|
||||
>>> def new_x(ignored):
|
||||
... return X(666)
|
||||
...
|
||||
>>> try: apply_X_ref_handle(new_x, 1)
|
||||
... except ReferenceError: pass
|
||||
... else: print 'no error'
|
||||
|
||||
>>> try: apply_X_ptr_handle_cref(new_x, 1)
|
||||
... except ReferenceError: pass
|
||||
... else: print 'no error'
|
||||
|
||||
>>> try: apply_cstring_cstring(identity, 'hello')
|
||||
... except ReferenceError: pass
|
||||
... else: print 'no error'
|
||||
|
||||
>>> apply_char_char(identity, 'x')
|
||||
'x'
|
||||
|
||||
>>> apply_cstring_pyobject(identity, 'hello')
|
||||
'hello'
|
||||
|
||||
>>> apply_cstring_pyobject(identity, None)
|
||||
|
||||
|
||||
>>> apply_char_char(identity, 'x')
|
||||
'x'
|
||||
|
||||
>>> assert apply_to_own_type(identity) is type(identity)
|
||||
|
||||
>>> assert apply_object_object(identity, identity) is identity
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,70 +0,0 @@
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
/* Non-modifiable definitions */
|
||||
|
||||
class basic {
|
||||
public:
|
||||
basic() { name = "cltree.basic"; }
|
||||
std::string repr() { return name+"()"; }
|
||||
protected:
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class constant: public basic {
|
||||
public:
|
||||
constant() { name = "cltree.constant"; }
|
||||
};
|
||||
|
||||
class symbol: public basic {
|
||||
public:
|
||||
symbol() { name = "cltree.symbol"; }
|
||||
};
|
||||
|
||||
class variable: public basic {
|
||||
public:
|
||||
variable() { name = "cltree.variable"; }
|
||||
};
|
||||
|
||||
/* EOF: Non-modifiable definitions */
|
||||
|
||||
class symbol_wrapper: public symbol {
|
||||
public:
|
||||
symbol_wrapper(PyObject* self): symbol() {
|
||||
name = "cltree.wrapped_symbol";
|
||||
}
|
||||
};
|
||||
|
||||
class variable_wrapper: public variable {
|
||||
public:
|
||||
variable_wrapper(PyObject* self): variable() {
|
||||
name = "cltree.wrapped_variable";
|
||||
}
|
||||
|
||||
// This constructor is introduced only because cannot use
|
||||
// boost::noncopyable, see below.
|
||||
variable_wrapper(PyObject* self,variable v): variable(v) {}
|
||||
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(cltree)
|
||||
{
|
||||
boost::python::class_<basic>("basic")
|
||||
.def("__repr__",&basic::repr)
|
||||
;
|
||||
|
||||
boost::python::class_<constant, boost::python::bases<basic>, boost::noncopyable>("constant")
|
||||
;
|
||||
|
||||
|
||||
boost::python::class_<symbol, symbol_wrapper, boost::noncopyable>("symbol")
|
||||
;
|
||||
|
||||
boost::python::class_<variable, boost::python::bases<basic>, variable_wrapper>("variable")
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef COMPLICATED_DWA20011215_HPP
|
||||
# define COMPLICATED_DWA20011215_HPP
|
||||
# include <iostream>
|
||||
|
||||
# include "simple_type.hpp"
|
||||
|
||||
struct complicated
|
||||
{
|
||||
complicated(simple const&, int = 0);
|
||||
~complicated();
|
||||
|
||||
int get_n() const;
|
||||
|
||||
char* s;
|
||||
int n;
|
||||
};
|
||||
|
||||
inline complicated::complicated(simple const&s, int n)
|
||||
: s(s.s), n(n)
|
||||
{
|
||||
std::cout << "constructing complicated: " << this->s << ", " << n << std::endl;
|
||||
}
|
||||
|
||||
inline complicated::~complicated()
|
||||
{
|
||||
std::cout << "destroying complicated: " << this->s << ", " << n << std::endl;
|
||||
}
|
||||
|
||||
inline int complicated::get_n() const
|
||||
{
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif // COMPLICATED_DWA20011215_HPP
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright David Abrahams 2003. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
struct foo
|
||||
{
|
||||
operator std::auto_ptr<int>&() const;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::python::detail;
|
||||
BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<int>::value);
|
||||
BOOST_STATIC_ASSERT(copy_ctor_mutates_rhs<std::auto_ptr<int> >::value);
|
||||
BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<std::string>::value);
|
||||
BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<foo>::value);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
#include <boost/python/return_by_value.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
|
||||
# include <iostream> // works around a KCC intermediate code generation bug
|
||||
#endif
|
||||
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
typedef test_class<> X;
|
||||
|
||||
typedef test_class<1> Y;
|
||||
|
||||
double get_fair_value(X const& x) { return x.value(); }
|
||||
|
||||
|
||||
struct VarBase
|
||||
{
|
||||
VarBase(std::string name_) : name(name_) {}
|
||||
|
||||
std::string const name;
|
||||
std::string get_name1() const { return name; }
|
||||
};
|
||||
|
||||
struct Var : VarBase
|
||||
{
|
||||
Var(std::string name_) : VarBase(name_), value(), name2(name.c_str()), y(6) {}
|
||||
std::string const& get_name2() const { return name; }
|
||||
float value;
|
||||
char const* name2;
|
||||
Y y;
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(data_members_ext)
|
||||
{
|
||||
class_<X>("X", init<int>())
|
||||
.def("value", &X::value)
|
||||
.def("set", &X::set)
|
||||
.def_readonly("x", &X::x)
|
||||
.add_property("fair_value", get_fair_value)
|
||||
;
|
||||
|
||||
class_<Y>("Y", init<int>())
|
||||
.def("value", &Y::value)
|
||||
.def("set", &Y::set)
|
||||
.def_readwrite("x", &Y::x)
|
||||
;
|
||||
|
||||
class_<Var>("Var", init<std::string>())
|
||||
.def_readonly("name", &Var::name)
|
||||
.def_readonly("name2",
|
||||
#if __MWERKS__ <= 0x2407 // Old MWerks mis-deduces the type here as `char* Var::*'
|
||||
(char const* Var::*)
|
||||
#endif
|
||||
&Var::name2
|
||||
)
|
||||
.def_readwrite("value", &Var::value)
|
||||
.def_readonly("y", &Var::y)
|
||||
|
||||
// Test return_by_value for plain values and for
|
||||
// pointers... return_by_value was implemented as a
|
||||
// side-effect of implementing data member support, so it made
|
||||
// sense to add the test here.
|
||||
.def("get_name1", &Var::get_name1, return_value_policy<return_by_value>())
|
||||
.def("get_name2", &Var::get_name2, return_value_policy<return_by_value>())
|
||||
|
||||
.add_property("name3", &Var::get_name1)
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,55 +0,0 @@
|
||||
'''
|
||||
>>> from data_members_ext import *
|
||||
|
||||
>>> x = X(42)
|
||||
>>> x.x
|
||||
42
|
||||
>>> try: x.x = 77
|
||||
... except AttributeError: pass
|
||||
... else: print 'no error'
|
||||
|
||||
>>> x.fair_value
|
||||
42.0
|
||||
>>> y = Y(69)
|
||||
>>> y.x
|
||||
69
|
||||
>>> y.x = 77
|
||||
>>> y.x
|
||||
77
|
||||
|
||||
>>> v = Var("pi")
|
||||
>>> v.value = 3.14
|
||||
>>> v.name
|
||||
'pi'
|
||||
>>> v.name2
|
||||
'pi'
|
||||
|
||||
>>> v.get_name1()
|
||||
'pi'
|
||||
|
||||
>>> v.get_name2()
|
||||
'pi'
|
||||
|
||||
>>> v.y.x
|
||||
6
|
||||
>>> v.y.x = -7
|
||||
>>> v.y.x
|
||||
-7
|
||||
|
||||
>>> v.name3
|
||||
'pi'
|
||||
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,173 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/list.hpp>
|
||||
#include <boost/python/overloads.hpp>
|
||||
#include <boost/python/return_internal_reference.hpp>
|
||||
|
||||
#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
|
||||
# include <iostream> // works around a KCC intermediate code generation bug
|
||||
#endif
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
char const* const format = "int(%s); char(%s); string(%s); double(%s); ";
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Overloaded functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
object
|
||||
bar(int a, char b, std::string c, double d)
|
||||
{
|
||||
return format % make_tuple(a, b, c, d);
|
||||
}
|
||||
|
||||
object
|
||||
bar(int a, char b, std::string c)
|
||||
{
|
||||
return format % make_tuple(a, b, c, 0.0);
|
||||
}
|
||||
|
||||
object
|
||||
bar(int a, char b)
|
||||
{
|
||||
return format % make_tuple(a, b, "default", 0.0);
|
||||
}
|
||||
|
||||
object
|
||||
bar(int a)
|
||||
{
|
||||
return format % make_tuple(a, 'D', "default", 0.0);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS(bar_stubs, bar, 1, 4)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Functions with default arguments
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
object
|
||||
foo(int a, char b = 'D', std::string c = "default", double d = 0.0)
|
||||
{
|
||||
return format % make_tuple(a, b, c, d);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Overloaded member functions with default arguments
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct Y {
|
||||
|
||||
Y() {}
|
||||
|
||||
object
|
||||
get_state() const
|
||||
{
|
||||
return format % make_tuple(a, b, c, d);
|
||||
}
|
||||
|
||||
int a; char b; std::string c; double d;
|
||||
};
|
||||
|
||||
|
||||
struct X {
|
||||
|
||||
X() {}
|
||||
|
||||
X(int a, char b = 'D', std::string c = "constructor", double d = 0.0)
|
||||
: state(format % make_tuple(a, b, c, d))
|
||||
{}
|
||||
|
||||
X(std::string s, bool b)
|
||||
: state("Got exactly two arguments from constructor: string(%s); bool(%s); " % make_tuple(s, b))
|
||||
{}
|
||||
|
||||
object
|
||||
bar(int a, char b = 'D', std::string c = "default", double d = 0.0) const
|
||||
{
|
||||
return format % make_tuple(a, b, c, d);
|
||||
}
|
||||
|
||||
Y const&
|
||||
bar2(int a = 0, char b = 'D', std::string c = "default", double d = 0.0)
|
||||
{
|
||||
// tests zero arg member function and return_internal_reference policy
|
||||
y.a = a;
|
||||
y.b = b;
|
||||
y.c = c;
|
||||
y.d = d;
|
||||
return y;
|
||||
}
|
||||
|
||||
object
|
||||
foo(int a, bool b=false) const
|
||||
{
|
||||
return "int(%s); bool(%s); " % make_tuple(a, b);
|
||||
}
|
||||
|
||||
object
|
||||
foo(std::string a, bool b=false) const
|
||||
{
|
||||
return "string(%s); bool(%s); " % make_tuple(a, b);
|
||||
}
|
||||
|
||||
object
|
||||
foo(list a, list b, bool c=false) const
|
||||
{
|
||||
return "list(%s); list(%s); bool(%s); " % make_tuple(a, b, c);
|
||||
}
|
||||
|
||||
object
|
||||
get_state() const
|
||||
{
|
||||
return state;
|
||||
}
|
||||
|
||||
Y y;
|
||||
object state;
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar_stubs, bar, 1, 4)
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar_stubs2, bar2, 0, 4)
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_2_stubs, foo, 1, 2)
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_3_stubs, foo, 2, 3)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOST_PYTHON_MODULE(defaults_ext)
|
||||
{
|
||||
def("foo", foo, foo_stubs());
|
||||
def("bar", (object(*)(int, char, std::string, double))0, bar_stubs());
|
||||
|
||||
class_<Y>("Y", init<>("doc of Y init")) // this should work
|
||||
.def("get_state", &Y::get_state)
|
||||
;
|
||||
|
||||
class_<X>("X")
|
||||
|
||||
.def(init<int, optional<char, std::string, double> >("doc of init"))
|
||||
.def(init<std::string, bool>()[default_call_policies()]) // what's a good policy here?
|
||||
.def("get_state", &X::get_state)
|
||||
.def("bar", &X::bar, X_bar_stubs())
|
||||
.def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()])
|
||||
.def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs())
|
||||
.def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs())
|
||||
.def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs())
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
174
test/defaults.py
174
test/defaults.py
@@ -1,174 +0,0 @@
|
||||
"""
|
||||
>>> False = 0 # Python 2.2 needs these
|
||||
>>> True = 1
|
||||
|
||||
>>> from defaults_ext import *
|
||||
>>> bar(1)
|
||||
'int(1); char(D); string(default); double(0.0); '
|
||||
|
||||
>>> bar(2, 'X')
|
||||
'int(2); char(X); string(default); double(0.0); '
|
||||
|
||||
>>> bar(3, 'Y', "Hello World")
|
||||
'int(3); char(Y); string(Hello World); double(0.0); '
|
||||
|
||||
>>> bar(4, 'Z', "Hi There", 3.3)
|
||||
'int(4); char(Z); string(Hi There); double(3.3); '
|
||||
|
||||
>>> foo(1)
|
||||
'int(1); char(D); string(default); double(0.0); '
|
||||
|
||||
>>> foo(2, 'X')
|
||||
'int(2); char(X); string(default); double(0.0); '
|
||||
|
||||
>>> foo(3, 'Y', "Hello World")
|
||||
'int(3); char(Y); string(Hello World); double(0.0); '
|
||||
|
||||
>>> foo(4, 'Z', "Hi There", 3.3)
|
||||
'int(4); char(Z); string(Hi There); double(3.3); '
|
||||
|
||||
>>> x = X()
|
||||
>>> x.bar(1)
|
||||
'int(1); char(D); string(default); double(0.0); '
|
||||
|
||||
>>> x.bar(2, 'X')
|
||||
'int(2); char(X); string(default); double(0.0); '
|
||||
|
||||
>>> x.bar(3, 'Y', "Hello World")
|
||||
'int(3); char(Y); string(Hello World); double(0.0); '
|
||||
|
||||
>>> x.bar(4, 'Z', "Hi There", 3.3)
|
||||
'int(4); char(Z); string(Hi There); double(3.3); '
|
||||
|
||||
>>> x.foo(5)
|
||||
'int(5); bool(0); '
|
||||
|
||||
>>> x.foo(6, 0)
|
||||
'int(6); bool(0); '
|
||||
|
||||
>>> x.foo(7, 1)
|
||||
'int(7); bool(1); '
|
||||
|
||||
>>> x.foo("A")
|
||||
'string(A); bool(0); '
|
||||
|
||||
>>> x.foo("B", False)
|
||||
'string(B); bool(0); '
|
||||
|
||||
>>> x.foo("C", True)
|
||||
'string(C); bool(1); '
|
||||
|
||||
>>> x.foo([0,1,2], [2,3,4])
|
||||
'list([0, 1, 2]); list([2, 3, 4]); bool(0); '
|
||||
|
||||
>>> x.foo([0,1,2], [2,3,4], False)
|
||||
'list([0, 1, 2]); list([2, 3, 4]); bool(0); '
|
||||
|
||||
>>> x.foo([0,1,2], [2,3,4], True)
|
||||
'list([0, 1, 2]); list([2, 3, 4]); bool(1); '
|
||||
|
||||
>>> x = X(1)
|
||||
>>> x.get_state()
|
||||
'int(1); char(D); string(constructor); double(0.0); '
|
||||
|
||||
>>> x = X(1, 'X')
|
||||
>>> x.get_state()
|
||||
'int(1); char(X); string(constructor); double(0.0); '
|
||||
|
||||
>>> x = X(1, 'X', "Yabadabadoo")
|
||||
>>> x.get_state()
|
||||
'int(1); char(X); string(Yabadabadoo); double(0.0); '
|
||||
|
||||
>>> x = X(1, 'X', "Phoenix", 3.65)
|
||||
>>> x.get_state()
|
||||
'int(1); char(X); string(Phoenix); double(3.65); '
|
||||
|
||||
>>> x.bar2().get_state()
|
||||
'int(0); char(D); string(default); double(0.0); '
|
||||
|
||||
>>> x.bar2(1).get_state()
|
||||
'int(1); char(D); string(default); double(0.0); '
|
||||
|
||||
>>> x.bar2(1, 'K').get_state()
|
||||
'int(1); char(K); string(default); double(0.0); '
|
||||
|
||||
>>> x.bar2(1, 'K', "Kim").get_state()
|
||||
'int(1); char(K); string(Kim); double(0.0); '
|
||||
|
||||
>>> x.bar2(1, 'K', "Kim", 9.9).get_state()
|
||||
'int(1); char(K); string(Kim); double(9.9); '
|
||||
|
||||
>>> x = X("Phoenix", 1)
|
||||
>>> x.get_state()
|
||||
'Got exactly two arguments from constructor: string(Phoenix); bool(1); '
|
||||
|
||||
>>> def printdoc(x):
|
||||
... print x.__doc__
|
||||
|
||||
>>> printdoc(X.__init__)
|
||||
doc of init
|
||||
|
||||
>>> printdoc(Y.__init__)
|
||||
doc of Y init
|
||||
|
||||
>>> printdoc(X.bar2)
|
||||
doc of X::bar2
|
||||
|
||||
"""
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
#include <boost/python/detail/destroy.hpp>
|
||||
#include <cassert>
|
||||
|
||||
struct bar;
|
||||
|
||||
namespace boost
|
||||
{
|
||||
// lie to the library about bar so we can show that its destructor is optimized away.
|
||||
template <>
|
||||
struct has_trivial_destructor<bar>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value=true);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
int count;
|
||||
int marks[] = {
|
||||
-1
|
||||
, -1, -1
|
||||
, -1, -1, -1, -1
|
||||
, -1
|
||||
};
|
||||
int* kills = marks;
|
||||
|
||||
struct foo
|
||||
{
|
||||
foo() : n(count++) {}
|
||||
~foo()
|
||||
{
|
||||
*kills++ = n;
|
||||
}
|
||||
int n;
|
||||
};
|
||||
|
||||
struct bar : foo {};
|
||||
|
||||
void assert_destructions(int n)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
assert(marks[i] == i);
|
||||
assert(marks[n] == -1);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
assert_destructions(0);
|
||||
typedef int a[2];
|
||||
|
||||
foo* f1 = new foo;
|
||||
boost::python::detail::destroy_referent<foo const volatile&>(f1);
|
||||
assert_destructions(1);
|
||||
|
||||
foo* f2 = new foo[2];
|
||||
typedef foo x[2];
|
||||
|
||||
boost::python::detail::destroy_referent<x const&>(f2);
|
||||
assert_destructions(3);
|
||||
|
||||
typedef foo y[2][2];
|
||||
x* f3 = new y;
|
||||
boost::python::detail::destroy_referent<y&>(f3);
|
||||
assert_destructions(7);
|
||||
|
||||
bar* b1 = new bar;
|
||||
boost::python::detail::destroy_referent<bar&>(b1);
|
||||
assert_destructions(7);
|
||||
|
||||
bar* b2 = new bar[2];
|
||||
typedef bar xb[2];
|
||||
|
||||
boost::python::detail::destroy_referent<xb&>(b2);
|
||||
assert_destructions(7);
|
||||
|
||||
typedef bar yb[2][2];
|
||||
xb* b3 = new yb;
|
||||
boost::python::detail::destroy_referent<yb&>(b3);
|
||||
assert_destructions(7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/dict.hpp>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
object new_dict()
|
||||
{
|
||||
return dict();
|
||||
}
|
||||
|
||||
object data_dict()
|
||||
{
|
||||
dict tmp1;
|
||||
tmp1["key1"] = "value1";
|
||||
|
||||
dict tmp2;
|
||||
tmp2["key2"] = "value2";
|
||||
tmp1[1] = tmp2;
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
object dict_from_sequence(object sequence)
|
||||
{
|
||||
return dict(sequence);
|
||||
}
|
||||
|
||||
object dict_keys(dict data)
|
||||
{
|
||||
return data.keys();
|
||||
}
|
||||
|
||||
object dict_values(dict data)
|
||||
{
|
||||
return data.values();
|
||||
}
|
||||
|
||||
object dict_items(dict data)
|
||||
{
|
||||
return data.items();
|
||||
}
|
||||
|
||||
void work_with_dict(dict data1, dict data2)
|
||||
{
|
||||
if (!data1.has_key("k1")) {
|
||||
throw std::runtime_error("dict does not have key 'k1'");
|
||||
}
|
||||
data1.update(data2);
|
||||
}
|
||||
|
||||
void test_templates(object print)
|
||||
{
|
||||
std::string key = "key";
|
||||
|
||||
dict tmp;
|
||||
tmp[1] = "a test string";
|
||||
print(tmp.get(1));
|
||||
//print(tmp[1]);
|
||||
tmp[1.5] = 13;
|
||||
print(tmp.get(1.5));
|
||||
print(tmp.get(44));
|
||||
print(tmp);
|
||||
print(tmp.get(2,"default"));
|
||||
print(tmp.has_key(key));
|
||||
print(tmp.setdefault(3,"default"));
|
||||
//print(tmp[3]);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(dict_ext)
|
||||
{
|
||||
def("new_dict", new_dict);
|
||||
def("data_dict", data_dict);
|
||||
def("dict_keys", dict_keys);
|
||||
def("dict_values", dict_values);
|
||||
def("dict_items", dict_items);
|
||||
def("dict_from_sequence", dict_from_sequence);
|
||||
def("work_with_dict", work_with_dict);
|
||||
def("test_templates", test_templates);
|
||||
}
|
||||
41
test/dict.py
41
test/dict.py
@@ -1,41 +0,0 @@
|
||||
"""
|
||||
>>> from dict_ext import *
|
||||
>>> def printer(*args):
|
||||
... for x in args: print x,
|
||||
... print
|
||||
...
|
||||
>>> print new_dict()
|
||||
{}
|
||||
>>> print data_dict()
|
||||
{1: {'key2': 'value2'}, 'key1': 'value1'}
|
||||
>>> tmp = data_dict()
|
||||
>>> print dict_keys(tmp)
|
||||
[1, 'key1']
|
||||
>>> print dict_values(tmp)
|
||||
[{'key2': 'value2'}, 'value1']
|
||||
>>> print dict_items(tmp)
|
||||
[(1, {'key2': 'value2'}), ('key1', 'value1')]
|
||||
>>> print dict_from_sequence([(1,1),(2,2),(3,3)])
|
||||
{1: 1, 2: 2, 3: 3}
|
||||
>>> test_templates(printer)
|
||||
a test string
|
||||
13
|
||||
None
|
||||
{1.5: 13, 1: 'a test string'}
|
||||
default
|
||||
0
|
||||
default
|
||||
"""
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,60 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <string>
|
||||
#include <boost/python/operators.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/scope.hpp>
|
||||
#include <boost/python/manage_new_object.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
// Just use math.h here; trying to use std::pow() causes too much
|
||||
// trouble for non-conforming compilers and libraries.
|
||||
#include <math.h>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
typedef test_class<> X;
|
||||
|
||||
X* create(int x)
|
||||
{
|
||||
return new X(x);
|
||||
}
|
||||
|
||||
unsigned long fact(unsigned long n)
|
||||
{
|
||||
return n <= 1 ? n : n * fact(n - 1);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(docstring_ext)
|
||||
{
|
||||
scope().attr("__doc__") =
|
||||
"A simple test module for documentation strings\n"
|
||||
"Exercised by docstring.py"
|
||||
;
|
||||
|
||||
class_<X>("X",
|
||||
"A simple class wrapper around a C++ int\n"
|
||||
"includes some error-checking"
|
||||
|
||||
, init<int>(
|
||||
"this is the __init__ function\n"
|
||||
"its documentation has two lines."
|
||||
)
|
||||
|
||||
)
|
||||
.def("value", &X::value,
|
||||
"gets the value of the object")
|
||||
;
|
||||
|
||||
def("create", create, return_value_policy<manage_new_object>(),
|
||||
"creates a new X object");
|
||||
|
||||
def("fact", fact, "compute the factorial");
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,54 +0,0 @@
|
||||
'''
|
||||
>>> from docstring_ext import *
|
||||
|
||||
>>> def printdoc(x):
|
||||
... print x.__doc__
|
||||
|
||||
>>> printdoc(X)
|
||||
A simple class wrapper around a C++ int
|
||||
includes some error-checking
|
||||
|
||||
>>> printdoc(X.__init__)
|
||||
this is the __init__ function
|
||||
its documentation has two lines.
|
||||
|
||||
>>> printdoc(X.value)
|
||||
gets the value of the object
|
||||
|
||||
>>> printdoc(create)
|
||||
creates a new X object
|
||||
|
||||
>>> printdoc(fact)
|
||||
compute the factorial
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
|
||||
import docstring_ext
|
||||
|
||||
result = doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
import pydoc
|
||||
import re
|
||||
docmodule = lambda m: re.sub(".\10", "", pydoc.text.docmodule(m))
|
||||
try:
|
||||
print 'printing module help:'
|
||||
print docmodule(docstring_ext)
|
||||
except object, x:
|
||||
print '********* failed **********'
|
||||
print x
|
||||
result = list(result)
|
||||
result[0] += 1
|
||||
return tuple(result)
|
||||
|
||||
return result
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
@@ -1,122 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// embedded_hello -- A simple Boost.Python embedding example -- by
|
||||
// Dirk Gerrits
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
namespace python = boost::python;
|
||||
|
||||
// An abstract base class
|
||||
class Base : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~Base() {};
|
||||
|
||||
virtual std::string hello() = 0;
|
||||
};
|
||||
|
||||
// C++ derived class
|
||||
class CppDerived : public Base
|
||||
{
|
||||
public:
|
||||
virtual ~CppDerived() {}
|
||||
|
||||
std::string hello()
|
||||
{
|
||||
return "Hello from C++!";
|
||||
}
|
||||
};
|
||||
|
||||
// Familiar Boost.Python wrapper class for Base
|
||||
struct BaseWrap : public Base
|
||||
{
|
||||
BaseWrap(PyObject* self_)
|
||||
: self(self_) {}
|
||||
|
||||
std::string hello() { return python::call_method<std::string>(self, "hello"); }
|
||||
|
||||
PyObject* self;
|
||||
};
|
||||
|
||||
// Pack the Base class wrapper into a module
|
||||
BOOST_PYTHON_MODULE(embedded_hello)
|
||||
{
|
||||
python::class_<Base, BaseWrap, boost::noncopyable>("Base")
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test()
|
||||
{
|
||||
//- INITIALIZATION -----------------------------------------------------------//
|
||||
|
||||
// Register the module with the interpreter
|
||||
if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1)
|
||||
throw std::runtime_error("Failed to add embedded_hello to the interpreter's "
|
||||
"builtin modules");
|
||||
|
||||
// Initialize the interpreter
|
||||
Py_Initialize();
|
||||
|
||||
// Retrieve the main module
|
||||
python::handle<> main_module(
|
||||
python::borrowed(PyImport_AddModule("__main__")) );
|
||||
|
||||
// Retrieve the main modules namespace
|
||||
python::handle<> main_namespace(
|
||||
python::borrowed(PyModule_GetDict(main_module.get())) );
|
||||
|
||||
// Define the derived class in Python.
|
||||
// (You'll normally want to put this in a .py file.)
|
||||
python::handle<> result(
|
||||
PyRun_String(
|
||||
"from embedded_hello import * \n"
|
||||
"class PythonDerived(Base): \n"
|
||||
" def hello(self): \n"
|
||||
" return 'Hello from Python!' \n",
|
||||
Py_file_input, main_namespace.get(), main_namespace.get())
|
||||
);
|
||||
// Result is not needed
|
||||
result.reset();
|
||||
|
||||
// Extract the raw Python object representing the just defined derived class
|
||||
python::handle<> class_ptr(
|
||||
PyRun_String("PythonDerived\n", Py_eval_input,
|
||||
main_namespace.get(), main_namespace.get()) );
|
||||
|
||||
// Wrap the raw Python object in a Boost.Python object
|
||||
python::object PythonDerived(class_ptr);
|
||||
|
||||
//- MAIN PROGRAM -------------------------------------------------------------//
|
||||
|
||||
// Creating and using instances of the C++ class is as easy as always.
|
||||
CppDerived cpp;
|
||||
std::cout << cpp.hello() << std::endl;
|
||||
|
||||
// But now creating and using instances of the Python class is almost
|
||||
// as easy!
|
||||
python::object py_base = PythonDerived();
|
||||
Base& py = python::extract<Base&>(py_base)();
|
||||
std::cout << py.hello() << std::endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
if (python::handle_exception(test))
|
||||
{
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Print();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,48 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/enum.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
# include <boost/type_traits/is_enum.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
#endif
|
||||
using namespace boost::python;
|
||||
|
||||
enum color { red = 1, green = 2, blue = 4 };
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
namespace boost // Pro7 has a hard time detecting enums
|
||||
{
|
||||
template <> struct is_enum<color> : boost::mpl::true_ {};
|
||||
}
|
||||
#endif
|
||||
|
||||
color identity_(color x) { return x; }
|
||||
|
||||
struct colorized {
|
||||
colorized() : x(red) {}
|
||||
color x;
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(enum_ext)
|
||||
{
|
||||
enum_<color>("color")
|
||||
.value("red", red)
|
||||
.value("green", green)
|
||||
.value("blue", blue)
|
||||
.export_values()
|
||||
;
|
||||
|
||||
def("identity", identity_);
|
||||
|
||||
class_<colorized>("colorized")
|
||||
.def_readwrite("x", &colorized::x)
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
59
test/enum.py
59
test/enum.py
@@ -1,59 +0,0 @@
|
||||
'''
|
||||
>>> from enum_ext import *
|
||||
|
||||
>>> identity(color.red)
|
||||
enum_ext.color.red
|
||||
|
||||
>>> identity(color.green)
|
||||
enum_ext.color.green
|
||||
|
||||
>>> identity(color.blue)
|
||||
enum_ext.color.blue
|
||||
|
||||
>>> identity(color(1))
|
||||
enum_ext.color.red
|
||||
|
||||
>>> identity(color(2))
|
||||
enum_ext.color.green
|
||||
|
||||
>>> identity(color(3))
|
||||
enum_ext.color(3)
|
||||
|
||||
>>> identity(color(4))
|
||||
enum_ext.color.blue
|
||||
|
||||
--- check export to scope ---
|
||||
|
||||
>>> identity(red)
|
||||
enum_ext.color.red
|
||||
|
||||
>>> identity(green)
|
||||
enum_ext.color.green
|
||||
|
||||
>>> identity(blue)
|
||||
enum_ext.color.blue
|
||||
|
||||
>>> try: identity(1)
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError'
|
||||
|
||||
>>> c = colorized()
|
||||
>>> c.x
|
||||
enum_ext.color.red
|
||||
>>> c.x = green
|
||||
>>> c.x
|
||||
enum_ext.color.green
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,25 +0,0 @@
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/exception_translator.hpp>
|
||||
|
||||
struct error {};
|
||||
|
||||
void translate(error const& e)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "!!!error!!!");
|
||||
}
|
||||
|
||||
void throw_error()
|
||||
{
|
||||
throw error();
|
||||
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(exception_translator_ext)
|
||||
{
|
||||
using namespace boost::python;
|
||||
register_exception_translator<error>(&translate);
|
||||
|
||||
def("throw_error", throw_error);
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
'''
|
||||
>>> from exception_translator_ext import *
|
||||
>>> try:
|
||||
... throw_error();
|
||||
... except RuntimeError, x:
|
||||
... print x
|
||||
... else:
|
||||
... print 'Expected a RuntimeError!'
|
||||
!!!error!!!
|
||||
'''
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
140
test/extract.cpp
140
test/extract.cpp
@@ -1,140 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include "test_class.hpp"
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/list.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/reference_existing_object.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
#include <boost/python/implicit.hpp>
|
||||
#include <string>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <cassert>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
typedef test_class<> X;
|
||||
|
||||
bool extract_bool(object x) { return extract<bool>(x); }
|
||||
|
||||
boost::python::list extract_list(object x)
|
||||
{
|
||||
extract<list> get_list((x));
|
||||
|
||||
// Make sure we always have the right idea about whether it's a list
|
||||
bool is_list_1 = get_list.check();
|
||||
bool is_list_2 = PyObject_IsInstance(x.ptr(), (PyObject*)&PyList_Type);
|
||||
assert(is_list_1 == is_list_2);
|
||||
|
||||
return get_list();
|
||||
}
|
||||
|
||||
char const* extract_cstring(object x)
|
||||
{
|
||||
return extract<char const*>(x);
|
||||
}
|
||||
|
||||
std::string extract_string(object x)
|
||||
{
|
||||
std::string s = extract<std::string>(x);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string const& extract_string_cref(object x)
|
||||
{
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4172) // msvc lies about returning a reference to temporary
|
||||
#elif defined(_MSC_VER) && defined(__ICL) && __ICL <= 700
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:473) // intel/win32 does too
|
||||
#endif
|
||||
|
||||
return extract<std::string const&>(x);
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 700
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
X extract_X(object x)
|
||||
{
|
||||
return extract<X>(x);
|
||||
}
|
||||
|
||||
X* extract_X_ptr(object x) { return extract<X*>(x); }
|
||||
|
||||
X& extract_X_ref(object x)
|
||||
{
|
||||
extract<X&> get_x(x);
|
||||
return get_x;
|
||||
}
|
||||
|
||||
int double_X(object n)
|
||||
{
|
||||
extract<X> x(n);
|
||||
return x().value() + x().value();
|
||||
}
|
||||
|
||||
bool check_bool(object x) { return extract<bool>(x).check(); }
|
||||
bool check_list(object x) { return extract<list>(x).check(); }
|
||||
bool check_cstring(object x) { return extract<char const*>(x).check(); }
|
||||
bool check_string(object x) { return extract<std::string>(x).check(); }
|
||||
bool check_string_cref(object x) { return extract<std::string const&>(x).check(); }
|
||||
bool check_X(object x) { return extract<X>(x).check(); }
|
||||
bool check_X_ptr(object x) { return extract<X*>(x).check(); }
|
||||
bool check_X_ref(object x) { return extract<X&>(x).check(); }
|
||||
|
||||
std::string x_rep(X const& x)
|
||||
{
|
||||
return "X(" + boost::lexical_cast<std::string>(x.value()) + ")";
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(extract_ext)
|
||||
{
|
||||
implicitly_convertible<int, X>();
|
||||
|
||||
def("extract_bool", extract_bool);
|
||||
def("extract_list", extract_list);
|
||||
def("extract_cstring", extract_cstring);
|
||||
def("extract_string", extract_string);
|
||||
def("extract_string_cref", extract_string_cref, return_value_policy<reference_existing_object>());
|
||||
def("extract_X", extract_X);
|
||||
def("extract_X_ptr", extract_X_ptr, return_value_policy<reference_existing_object>());
|
||||
def("extract_X_ref", extract_X_ref, return_value_policy<reference_existing_object>());
|
||||
|
||||
def("check_bool", check_bool);
|
||||
def("check_list", check_list);
|
||||
def("check_cstring", check_cstring);
|
||||
def("check_string", check_string);
|
||||
def("check_string_cref", check_string_cref);
|
||||
def("check_X", check_X);
|
||||
def("check_X_ptr", check_X_ptr);
|
||||
def("check_X_ref", check_X_ref);
|
||||
|
||||
def("double_X", double_X);
|
||||
|
||||
def("count_Xs", &X::count);
|
||||
;
|
||||
|
||||
object x_class(
|
||||
class_<X>("X", init<int>())
|
||||
.def( "__repr__", x_rep));
|
||||
|
||||
// Instantiate an X object through the Python interface
|
||||
object x_obj = x_class(3);
|
||||
|
||||
// Get the C++ object out of the Python object
|
||||
X const& x = extract<X&>(x_obj);
|
||||
assert(x.value() == 3);
|
||||
}
|
||||
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
102
test/extract.py
102
test/extract.py
@@ -1,102 +0,0 @@
|
||||
'''
|
||||
>>> from extract_ext import *
|
||||
|
||||
Just about anything has a truth value in Python
|
||||
|
||||
>>> assert check_bool(None)
|
||||
>>> extract_bool(None)
|
||||
0
|
||||
|
||||
>>> assert check_bool(2)
|
||||
>>> extract_bool(2)
|
||||
1
|
||||
|
||||
>>> assert not check_bool('')
|
||||
|
||||
Check that object manager types work properly. These are a different
|
||||
case because they wrap Python objects instead of being wrapped by them.
|
||||
|
||||
>>> assert not check_list(2)
|
||||
>>> try: x = extract_list(2)
|
||||
... except TypeError, x:
|
||||
... if str(x) != 'Expecting an object of type list; got an object of type int instead':
|
||||
... print x
|
||||
... else:
|
||||
... print 'expected an exception, got', x, 'instead'
|
||||
|
||||
Can't extract a list from a tuple. Use list(x) to convert a sequence
|
||||
to a list:
|
||||
|
||||
>>> assert not check_list((1, 2, 3))
|
||||
>>> assert check_list([1, 2, 3])
|
||||
>>> extract_list([1, 2, 3])
|
||||
[1, 2, 3]
|
||||
|
||||
Can get a char const* from a Python string:
|
||||
|
||||
>>> assert check_cstring('hello')
|
||||
>>> extract_cstring('hello')
|
||||
'hello'
|
||||
|
||||
Can't get a char const* from a Python int:
|
||||
|
||||
>>> assert not check_cstring(1)
|
||||
>>> try: x = extract_cstring(1)
|
||||
... except TypeError: pass
|
||||
... else:
|
||||
... print 'expected an exception, got', x, 'instead'
|
||||
|
||||
Extract an std::string (class) rvalue from a native Python type
|
||||
|
||||
>>> assert check_string('hello')
|
||||
>>> extract_string('hello')
|
||||
'hello'
|
||||
|
||||
Constant references are not treated as rvalues for the purposes of
|
||||
extract:
|
||||
|
||||
>>> assert not check_string_cref('hello')
|
||||
|
||||
We can extract lvalues where appropriate:
|
||||
|
||||
>>> x = X(42)
|
||||
>>> check_X(x)
|
||||
1
|
||||
>>> extract_X(x)
|
||||
X(42)
|
||||
|
||||
>>> check_X_ptr(x)
|
||||
1
|
||||
>>> extract_X_ptr(x)
|
||||
X(42)
|
||||
>>> extract_X_ref(x)
|
||||
X(42)
|
||||
|
||||
Demonstrate that double-extraction of an rvalue works, and all created
|
||||
copies of the object are destroyed:
|
||||
|
||||
>>> n = count_Xs()
|
||||
>>> double_X(333)
|
||||
666
|
||||
>>> count_Xs() - n
|
||||
0
|
||||
|
||||
General check for cleanliness:
|
||||
|
||||
>>> del x
|
||||
>>> count_Xs()
|
||||
0
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,45 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/python/detail/if_else.hpp>
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
|
||||
typedef char c1;
|
||||
typedef char c2[2];
|
||||
typedef char c3[3];
|
||||
typedef char c4[4];
|
||||
|
||||
template <unsigned size>
|
||||
struct choose
|
||||
{
|
||||
typedef typename boost::python::detail::if_<
|
||||
(sizeof(c1) == size)
|
||||
>::template then<
|
||||
c1
|
||||
>::template elif<
|
||||
(sizeof(c2) == size)
|
||||
>::template then<
|
||||
c2
|
||||
>::template elif<
|
||||
(sizeof(c3) == size)
|
||||
>::template then<
|
||||
c3
|
||||
>::template elif<
|
||||
(sizeof(c4) == size)
|
||||
>::template then<
|
||||
c4
|
||||
>::template else_<void*>::type type;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose<1>::type,c1>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose<2>::type,c2>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose<3>::type,c3>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose<4>::type,c4>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<choose<5>::type,void*>::value));
|
||||
return 0;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/implicit.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
typedef test_class<> X;
|
||||
|
||||
int x_value(X const& x)
|
||||
{
|
||||
return x.value();
|
||||
}
|
||||
|
||||
X make_x(int n) { return X(n); }
|
||||
|
||||
|
||||
// foo/bar -- a regression for a vc7 bug workaround
|
||||
struct bar {};
|
||||
struct foo
|
||||
{
|
||||
virtual void f() = 0;
|
||||
operator bar() const { return bar(); }
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(implicit_ext)
|
||||
{
|
||||
implicitly_convertible<foo,bar>();
|
||||
implicitly_convertible<int,X>();
|
||||
|
||||
def("x_value", x_value);
|
||||
def("make_x", make_x);
|
||||
|
||||
class_<X>("X", init<int>())
|
||||
.def("value", &X::value)
|
||||
.def("set", &X::set)
|
||||
;
|
||||
|
||||
implicitly_convertible<X,int>();
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,26 +0,0 @@
|
||||
'''
|
||||
>>> from implicit_ext import *
|
||||
>>> x_value(X(42))
|
||||
42
|
||||
>>> x_value(42)
|
||||
42
|
||||
>>> x = make_x(X(42))
|
||||
>>> x.value()
|
||||
42
|
||||
>>> try: make_x('fool')
|
||||
... except TypeError: pass
|
||||
... else: print 'no error'
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,105 +0,0 @@
|
||||
//#include <stdio.h>
|
||||
#include <cassert>
|
||||
#include <boost/python/detail/indirect_traits.hpp>
|
||||
|
||||
//#define print(expr) printf("%s ==> %s\n", #expr, expr)
|
||||
|
||||
// not all the compilers can handle an incomplete class type here.
|
||||
struct X {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::python::detail;
|
||||
|
||||
typedef void (X::*pmf)();
|
||||
|
||||
assert(is_reference_to_function<int (&)()>::value);
|
||||
assert(!is_reference_to_function<int (*)()>::value);
|
||||
assert(!is_reference_to_function<int&>::value);
|
||||
assert(!is_reference_to_function<pmf>::value);
|
||||
|
||||
assert(!is_pointer_to_function<int (&)()>::value);
|
||||
assert(is_pointer_to_function<int (*)()>::value);
|
||||
assert(!is_pointer_to_function<int (*&)()>::value);
|
||||
assert(!is_pointer_to_function<int (*const&)()>::value);
|
||||
assert(!is_pointer_to_function<pmf>::value);
|
||||
|
||||
assert(!is_reference_to_function_pointer<int (&)()>::value);
|
||||
assert(!is_reference_to_function_pointer<int (*)()>::value);
|
||||
assert(!is_reference_to_function_pointer<int&>::value);
|
||||
assert(is_reference_to_function_pointer<int (*&)()>::value);
|
||||
assert(is_reference_to_function_pointer<int (*const&)()>::value);
|
||||
assert(!is_reference_to_function_pointer<pmf>::value);
|
||||
|
||||
assert(is_reference_to_pointer<int*&>::value);
|
||||
assert(is_reference_to_pointer<int* const&>::value);
|
||||
assert(is_reference_to_pointer<int*volatile&>::value);
|
||||
assert(is_reference_to_pointer<int*const volatile&>::value);
|
||||
assert(is_reference_to_pointer<int const*&>::value);
|
||||
assert(is_reference_to_pointer<int const* const&>::value);
|
||||
assert(is_reference_to_pointer<int const*volatile&>::value);
|
||||
assert(is_reference_to_pointer<int const*const volatile&>::value);
|
||||
assert(!is_reference_to_pointer<pmf>::value);
|
||||
|
||||
assert(!is_reference_to_pointer<int const volatile>::value);
|
||||
assert(!is_reference_to_pointer<int>::value);
|
||||
assert(!is_reference_to_pointer<int*>::value);
|
||||
|
||||
assert(!is_reference_to_const<int*&>::value);
|
||||
assert(is_reference_to_const<int* const&>::value);
|
||||
assert(!is_reference_to_const<int*volatile&>::value);
|
||||
assert(is_reference_to_const<int*const volatile&>::value);
|
||||
|
||||
assert(!is_reference_to_const<int const volatile>::value);
|
||||
assert(!is_reference_to_const<int>::value);
|
||||
assert(!is_reference_to_const<int*>::value);
|
||||
|
||||
assert(is_reference_to_non_const<int*&>::value);
|
||||
assert(!is_reference_to_non_const<int* const&>::value);
|
||||
assert(is_reference_to_non_const<int*volatile&>::value);
|
||||
assert(!is_reference_to_non_const<int*const volatile&>::value);
|
||||
|
||||
assert(!is_reference_to_non_const<int const volatile>::value);
|
||||
assert(!is_reference_to_non_const<int>::value);
|
||||
assert(!is_reference_to_non_const<int*>::value);
|
||||
|
||||
assert(!is_reference_to_volatile<int*&>::value);
|
||||
assert(!is_reference_to_volatile<int* const&>::value);
|
||||
assert(is_reference_to_volatile<int*volatile&>::value);
|
||||
assert(is_reference_to_volatile<int*const volatile&>::value);
|
||||
|
||||
assert(!is_reference_to_volatile<int const volatile>::value);
|
||||
assert(!is_reference_to_volatile<int>::value);
|
||||
assert(!is_reference_to_volatile<int*>::value);
|
||||
|
||||
assert(!is_reference_to_class<int>::value);
|
||||
assert(!is_reference_to_class<int&>::value);
|
||||
assert(!is_reference_to_class<int*>::value);
|
||||
|
||||
assert(!is_reference_to_class<X>::value);
|
||||
assert(is_reference_to_class<X&>::value);
|
||||
assert(is_reference_to_class<X const&>::value);
|
||||
assert(is_reference_to_class<X volatile&>::value);
|
||||
assert(is_reference_to_class<X const volatile&>::value);
|
||||
|
||||
assert(!is_pointer_to_class<int>::value);
|
||||
assert(!is_pointer_to_class<int*>::value);
|
||||
assert(!is_pointer_to_class<int&>::value);
|
||||
|
||||
assert(!is_pointer_to_class<X>::value);
|
||||
assert(!is_pointer_to_class<X&>::value);
|
||||
assert(is_pointer_to_class<X*>::value);
|
||||
assert(is_pointer_to_class<X const*>::value);
|
||||
assert(is_pointer_to_class<X volatile*>::value);
|
||||
assert(is_pointer_to_class<X const volatile*>::value);
|
||||
|
||||
assert(is_reference_to_member_function_pointer<pmf&>::value);
|
||||
assert(is_reference_to_member_function_pointer<pmf const&>::value);
|
||||
assert(is_reference_to_member_function_pointer<pmf volatile&>::value);
|
||||
assert(is_reference_to_member_function_pointer<pmf const volatile&>::value);
|
||||
assert(!is_reference_to_member_function_pointer<pmf[2]>::value);
|
||||
assert(!is_reference_to_member_function_pointer<pmf(&)[2]>::value);
|
||||
assert(!is_reference_to_member_function_pointer<pmf>::value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/iterator.hpp>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
#include <list>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
typedef std::list<int> list_int;
|
||||
|
||||
// Prove that we can handle InputIterators which return rvalues.
|
||||
struct doubler
|
||||
{
|
||||
typedef int result_type;
|
||||
int operator()(int x) const { return x * 2; }
|
||||
};
|
||||
|
||||
typedef boost::transform_iterator_generator<doubler, list_int::iterator>::type doubling_iterator;
|
||||
typedef std::pair<doubling_iterator,doubling_iterator> list_range2;
|
||||
|
||||
list_range2 range2(list_int& x)
|
||||
{
|
||||
return list_range2(
|
||||
boost::make_transform_iterator<doubler>(x.begin(), doubler())
|
||||
, boost::make_transform_iterator<doubler>(x.end(), doubler()));
|
||||
}
|
||||
|
||||
// We do this in a separate module from iterators_ext (iterators.cpp)
|
||||
// to work around an MSVC6 linker bug, which causes it to complain
|
||||
// about a "duplicate comdat" if the input iterator is instantiated in
|
||||
// the same module with the others.
|
||||
BOOST_PYTHON_MODULE(input_iterator)
|
||||
{
|
||||
def("range2", &::range2);
|
||||
|
||||
class_<list_range2>("list_range2")
|
||||
// We can wrap InputIterators which return by-value
|
||||
.def("__iter__"
|
||||
, range(&list_range2::first, &list_range2::second))
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,138 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/return_internal_reference.hpp>
|
||||
#include <boost/python/copy_non_const_reference.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
#include <boost/python/iterator.hpp>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
typedef std::list<int> list_int;
|
||||
typedef std::list<list_int> list_list;
|
||||
|
||||
|
||||
void push_back(list_int& x, int y)
|
||||
{
|
||||
x.push_back(y);
|
||||
}
|
||||
|
||||
void push_list_back(list_list& x, list_int const& y)
|
||||
{
|
||||
x.push_back(y);
|
||||
}
|
||||
|
||||
int back(list_int& x)
|
||||
{
|
||||
return x.back();
|
||||
}
|
||||
|
||||
typedef std::pair<list_int::iterator,list_int::iterator> list_range;
|
||||
|
||||
struct list_range2 : list_range
|
||||
{
|
||||
list_int::iterator& begin() { return this->first; }
|
||||
list_int::iterator& end() { return this->second; }
|
||||
};
|
||||
|
||||
list_range range(list_int& x)
|
||||
{
|
||||
return list_range(x.begin(), x.end());
|
||||
}
|
||||
|
||||
struct two_lists
|
||||
{
|
||||
two_lists()
|
||||
{
|
||||
int primes[] = { 2, 3, 5, 7, 11, 13 };
|
||||
std::copy(primes, primes + sizeof(primes)/sizeof(*primes), std::back_inserter(one));
|
||||
int evens[] = { 2, 4, 6, 8, 10, 12 };
|
||||
std::copy(evens, evens + sizeof(evens)/sizeof(*evens), std::back_inserter(two));
|
||||
}
|
||||
|
||||
struct two_start
|
||||
{
|
||||
typedef list_int::iterator result_type;
|
||||
result_type operator()(two_lists& ll) const { return ll.two.begin(); }
|
||||
};
|
||||
friend struct two_start;
|
||||
|
||||
list_int::iterator one_begin() { return one.begin(); }
|
||||
list_int::iterator two_begin() { return two.begin(); }
|
||||
|
||||
list_int::iterator one_end() { return one.end(); }
|
||||
list_int::iterator two_end() { return two.end(); }
|
||||
|
||||
private:
|
||||
list_int one;
|
||||
list_int two;
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(iterator_ext)
|
||||
{
|
||||
using boost::python::iterator; // gcc 2.96 bug workaround
|
||||
def("range", &::range);
|
||||
|
||||
class_<list_int>("list_int")
|
||||
.def("push_back", push_back)
|
||||
.def("back", back)
|
||||
.def("__iter__", iterator<list_int>())
|
||||
;
|
||||
|
||||
class_<list_range>("list_range")
|
||||
|
||||
// We can specify data members
|
||||
.def("__iter__"
|
||||
, range(&list_range::first, &list_range::second))
|
||||
;
|
||||
|
||||
// No runtime tests for this one yet
|
||||
class_<list_range2>("list_range2")
|
||||
|
||||
// We can specify member functions returning a non-const reference
|
||||
.def("__iter__", range(&list_range2::begin, &list_range2::end))
|
||||
;
|
||||
|
||||
class_<two_lists>("two_lists")
|
||||
|
||||
// We can spcify member functions
|
||||
.add_property(
|
||||
"primes"
|
||||
, range(&two_lists::one_begin, &two_lists::one_end))
|
||||
|
||||
// Prove that we can explicitly specify call policies
|
||||
.add_property(
|
||||
"evens"
|
||||
, range<return_value_policy<copy_non_const_reference> >(
|
||||
&two_lists::two_begin, &two_lists::two_end))
|
||||
|
||||
// Prove that we can specify call policies and target
|
||||
.add_property(
|
||||
"twosies"
|
||||
, range<return_value_policy<copy_non_const_reference>, two_lists>(
|
||||
// And we can use adaptable function objects when
|
||||
// partial specialization is available.
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
two_lists::two_start()
|
||||
# else
|
||||
&two_lists::two_begin
|
||||
# endif
|
||||
, &two_lists::two_end))
|
||||
;
|
||||
|
||||
class_<list_list>("list_list")
|
||||
.def("push_back", push_list_back)
|
||||
.def("__iter__", iterator<list_list,return_internal_reference<> >())
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,72 +0,0 @@
|
||||
'''
|
||||
>>> from iterator_ext import *
|
||||
>>> from input_iterator import *
|
||||
>>> x = list_int()
|
||||
>>> x.push_back(1)
|
||||
>>> x.back()
|
||||
1
|
||||
>>> x.push_back(3)
|
||||
>>> x.push_back(5)
|
||||
>>> for y in x:
|
||||
... print y
|
||||
1
|
||||
3
|
||||
5
|
||||
>>> z = range(x)
|
||||
>>> for y in z:
|
||||
... print y
|
||||
1
|
||||
3
|
||||
5
|
||||
|
||||
Range2 wraps a transform_iterator which doubles the elements it
|
||||
traverses. This proves we can wrap input iterators
|
||||
|
||||
>>> z2 = range2(x)
|
||||
>>> for y in z2:
|
||||
... print y
|
||||
2
|
||||
6
|
||||
10
|
||||
|
||||
>>> l2 = two_lists()
|
||||
>>> for y in l2.primes:
|
||||
... print y
|
||||
2
|
||||
3
|
||||
5
|
||||
7
|
||||
11
|
||||
13
|
||||
>>> for y in l2.evens:
|
||||
... print y
|
||||
2
|
||||
4
|
||||
6
|
||||
8
|
||||
10
|
||||
12
|
||||
>>> ll = list_list()
|
||||
>>> ll.push_back(x)
|
||||
>>> x.push_back(7)
|
||||
>>> ll.push_back(x)
|
||||
>>> for a in ll:
|
||||
... for b in a:
|
||||
... print b,
|
||||
... print
|
||||
...
|
||||
1 3 5
|
||||
1 3 5 7
|
||||
'''
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
145
test/list.cpp
145
test/list.cpp
@@ -1,145 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/list.hpp>
|
||||
#include <boost/python/make_function.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
object new_list()
|
||||
{
|
||||
return list();
|
||||
}
|
||||
|
||||
list listify(object x)
|
||||
{
|
||||
return list(x);
|
||||
}
|
||||
|
||||
object listify_string(char const* s)
|
||||
{
|
||||
return list(s);
|
||||
}
|
||||
|
||||
std::string x_rep(test_class<> const& x)
|
||||
{
|
||||
return "X(" + boost::lexical_cast<std::string>(x.value()) + ")";
|
||||
}
|
||||
|
||||
object apply_object_list(object f, list x)
|
||||
{
|
||||
return f(x);
|
||||
}
|
||||
|
||||
list apply_list_list(object f, list x)
|
||||
{
|
||||
return call<list>(f.ptr(), x);
|
||||
}
|
||||
|
||||
void append_object(list& x, object y)
|
||||
{
|
||||
x.append(y);
|
||||
}
|
||||
|
||||
void append_list(list& x, list const& y)
|
||||
{
|
||||
x.append(y);
|
||||
}
|
||||
|
||||
typedef test_class<> X;
|
||||
|
||||
int notcmp(object const& x, object const& y)
|
||||
{
|
||||
return y < x ? -1 : y > x ? 1 : 0;
|
||||
}
|
||||
|
||||
void exercise(list x, object y, object print)
|
||||
{
|
||||
x.append(y);
|
||||
x.append(5);
|
||||
x.append(X(3));
|
||||
|
||||
print("after append:");
|
||||
print(x);
|
||||
|
||||
print("number of", y, "instances:", x.count(y));
|
||||
|
||||
print("number of 5s:", x.count(5));
|
||||
|
||||
x.extend("xyz");
|
||||
print("after extend:");
|
||||
print(x);
|
||||
print("index of", y, "is:", x.index(y));
|
||||
print("index of 'l' is:", x.index("l"));
|
||||
|
||||
x.insert(4, 666);
|
||||
print("after inserting 666:");
|
||||
print(x);
|
||||
print("inserting with object as index:");
|
||||
x.insert(x[x.index(5)], "---");
|
||||
print(x);
|
||||
|
||||
print("popping...");
|
||||
x.pop();
|
||||
print(x);
|
||||
x.pop(x[x.index(5)]);
|
||||
print(x);
|
||||
x.pop(x.index(5));
|
||||
print(x);
|
||||
|
||||
print("removing", y);
|
||||
x.remove(y);
|
||||
print(x);
|
||||
print("removing", 666);
|
||||
x.remove(666);
|
||||
print(x);
|
||||
|
||||
print("reversing...");
|
||||
x.reverse();
|
||||
print(x);
|
||||
|
||||
print("sorted:");
|
||||
x.pop(2); // make sorting predictable
|
||||
x.sort();
|
||||
print(x);
|
||||
|
||||
print("reverse sorted:");
|
||||
x.sort(¬cmp);
|
||||
print(x);
|
||||
|
||||
list w;
|
||||
w.append(5);
|
||||
w.append(6);
|
||||
w += "hi";
|
||||
assert(w[0] == 5);
|
||||
assert(w[1] == 6);
|
||||
assert(w[2] == 'h');
|
||||
assert(w[3] == 'i');
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(list_ext)
|
||||
{
|
||||
def("new_list", new_list);
|
||||
def("listify", listify);
|
||||
def("listify_string", listify_string);
|
||||
def("apply_object_list", apply_object_list);
|
||||
def("apply_list_list", apply_list_list);
|
||||
|
||||
def("append_object", append_object);
|
||||
def("append_list", append_list);
|
||||
|
||||
def("exercise", exercise);
|
||||
|
||||
class_<X>("X", init<int>())
|
||||
.def( "__repr__", x_rep)
|
||||
;
|
||||
}
|
||||
|
||||
113
test/list.py
113
test/list.py
@@ -1,113 +0,0 @@
|
||||
'''
|
||||
>>> from list_ext import *
|
||||
|
||||
>>> new_list()
|
||||
[]
|
||||
|
||||
>>> listify((1,2,3))
|
||||
[1, 2, 3]
|
||||
|
||||
>>> letters = listify_string('hello')
|
||||
>>> letters
|
||||
['h', 'e', 'l', 'l', 'o']
|
||||
|
||||
>>> X(22)
|
||||
X(22)
|
||||
|
||||
>>> def identity(x):
|
||||
... return x
|
||||
>>> assert apply_object_list(identity, letters) is letters
|
||||
|
||||
5 is not convertible to a list
|
||||
|
||||
>>> try: result = apply_object_list(identity, 5)
|
||||
... except TypeError: pass
|
||||
... else: print 'expected an exception, got', result, 'instead'
|
||||
|
||||
>>> assert apply_list_list(identity, letters) is letters
|
||||
|
||||
5 is not convertible to a list as a return value
|
||||
|
||||
>>> try: result = apply_list_list(len, letters)
|
||||
... except TypeError: pass
|
||||
... else: print 'expected an exception, got', result, 'instead'
|
||||
|
||||
>>> append_object(letters, '.')
|
||||
>>> letters
|
||||
['h', 'e', 'l', 'l', 'o', '.']
|
||||
|
||||
tuples do not automatically convert to lists when passed as arguments
|
||||
|
||||
>>> try: append_list(letters, (1,2))
|
||||
... except TypeError: pass
|
||||
... else: print 'expected an exception'
|
||||
|
||||
>>> append_list(letters, [1,2])
|
||||
>>> letters
|
||||
['h', 'e', 'l', 'l', 'o', '.', [1, 2]]
|
||||
|
||||
Check that subclass functions are properly called
|
||||
|
||||
>>> class mylist(list):
|
||||
... def append(self, o):
|
||||
... list.append(self, o)
|
||||
... if not hasattr(self, 'nappends'):
|
||||
... self.nappends = 1
|
||||
... else:
|
||||
... self.nappends += 1
|
||||
...
|
||||
>>> l2 = mylist()
|
||||
>>> append_object(l2, 'hello')
|
||||
>>> append_object(l2, 'world')
|
||||
>>> l2
|
||||
['hello', 'world']
|
||||
>>> l2.nappends
|
||||
2
|
||||
|
||||
>>> def printer(*args):
|
||||
... for x in args: print x,
|
||||
... print
|
||||
...
|
||||
|
||||
>>> y = X(42)
|
||||
>>> exercise(letters, y, printer)
|
||||
after append:
|
||||
['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3)]
|
||||
number of X(42) instances: 1
|
||||
number of 5s: 1
|
||||
after extend:
|
||||
['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z']
|
||||
index of X(42) is: 7
|
||||
index of 'l' is: 2
|
||||
after inserting 666:
|
||||
['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z']
|
||||
inserting with object as index:
|
||||
['h', 'e', 'l', 'l', 666, '---', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z']
|
||||
popping...
|
||||
['h', 'e', 'l', 'l', 666, '---', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y']
|
||||
['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y']
|
||||
['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), X(3), 'x', 'y']
|
||||
removing X(42)
|
||||
['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(3), 'x', 'y']
|
||||
removing 666
|
||||
['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(3), 'x', 'y']
|
||||
reversing...
|
||||
['y', 'x', X(3), [1, 2], '.', 'o', 'l', 'l', 'e', 'h']
|
||||
sorted:
|
||||
[[1, 2], '.', 'e', 'h', 'l', 'l', 'o', 'x', 'y']
|
||||
reverse sorted:
|
||||
['y', 'x', 'o', 'l', 'l', 'h', 'e', '.', [1, 2]]
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/long.hpp>
|
||||
#include <cassert>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
object new_long()
|
||||
{
|
||||
return long_();
|
||||
}
|
||||
|
||||
long_ longify(object x)
|
||||
{
|
||||
return long_(x);
|
||||
}
|
||||
|
||||
object longify_string(char const* s)
|
||||
{
|
||||
return long_(s);
|
||||
}
|
||||
|
||||
char const* is_long1(long_& x)
|
||||
{
|
||||
long_ y = x;
|
||||
x += 50;
|
||||
assert(x == y + 50);
|
||||
return "yes";
|
||||
}
|
||||
|
||||
int is_long2(char const*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(long_ext)
|
||||
{
|
||||
def("new_long", new_long);
|
||||
def("longify", longify);
|
||||
def("longify_string", longify_string);
|
||||
def("is_long", is_long1);
|
||||
def("is_long", is_long2);
|
||||
;
|
||||
}
|
||||
|
||||
26
test/long.py
26
test/long.py
@@ -1,26 +0,0 @@
|
||||
'''
|
||||
>>> from long_ext import *
|
||||
>>> new_long()
|
||||
0L
|
||||
>>> longify(42)
|
||||
42L
|
||||
>>> longify_string('300')
|
||||
300L
|
||||
>>> is_long(20L)
|
||||
'yes'
|
||||
>>> is_long('20')
|
||||
0
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
276
test/m1.cpp
276
test/m1.cpp
@@ -1,276 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
|
||||
#include "simple_type.hpp"
|
||||
#include "complicated.hpp"
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/lvalue_from_pytype.hpp>
|
||||
#include <boost/python/copy_const_reference.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
#include <boost/python/to_python_converter.hpp>
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/manage_new_object.hpp>
|
||||
#include <string.h>
|
||||
|
||||
// Declare some straightforward extension types
|
||||
extern "C" void
|
||||
dealloc(PyObject* self)
|
||||
{
|
||||
PyObject_Del(self);
|
||||
}
|
||||
|
||||
// Noddy is a type we got from one of the Python sample files
|
||||
struct NoddyObject : PyObject
|
||||
{
|
||||
int x;
|
||||
};
|
||||
|
||||
PyTypeObject NoddyType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0,
|
||||
"Noddy",
|
||||
sizeof(NoddyObject),
|
||||
0,
|
||||
dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash */
|
||||
};
|
||||
|
||||
// Create a Noddy containing 42
|
||||
PyObject* new_noddy()
|
||||
{
|
||||
NoddyObject* noddy = PyObject_New(NoddyObject, &NoddyType);
|
||||
noddy->x = 42;
|
||||
return (PyObject*)noddy;
|
||||
}
|
||||
|
||||
// Simple is a wrapper around a struct simple, which just contains a char*
|
||||
struct SimpleObject
|
||||
{
|
||||
PyObject_HEAD
|
||||
simple x;
|
||||
};
|
||||
|
||||
struct extract_simple_object
|
||||
{
|
||||
static simple& execute(SimpleObject& o) { return o.x; }
|
||||
};
|
||||
|
||||
PyTypeObject SimpleType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0,
|
||||
"Simple",
|
||||
sizeof(SimpleObject),
|
||||
0,
|
||||
dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash */
|
||||
};
|
||||
|
||||
// Create a Simple containing "hello, world"
|
||||
PyObject* new_simple()
|
||||
{
|
||||
SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType);
|
||||
simple->x.s = "hello, world";
|
||||
return (PyObject*)simple;
|
||||
}
|
||||
|
||||
//
|
||||
// Declare some wrappers/unwrappers to test the low-level conversion
|
||||
// mechanism.
|
||||
//
|
||||
using boost::python::to_python_converter;
|
||||
|
||||
// Wrap a simple by copying it into a Simple
|
||||
struct simple_to_python
|
||||
: to_python_converter<simple, simple_to_python>
|
||||
{
|
||||
static PyObject* convert(simple const& x)
|
||||
{
|
||||
SimpleObject* p = PyObject_New(SimpleObject, &SimpleType);
|
||||
p->x = x;
|
||||
return (PyObject*)p;
|
||||
}
|
||||
};
|
||||
|
||||
struct int_from_noddy
|
||||
{
|
||||
static int& execute(NoddyObject& p)
|
||||
{
|
||||
return p.x;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Some C++ functions to expose to Python
|
||||
//
|
||||
|
||||
// Returns the length of s's held string
|
||||
int f(simple const& s)
|
||||
{
|
||||
return strlen(s.s);
|
||||
}
|
||||
|
||||
int f_mutable_ref(simple& s)
|
||||
{
|
||||
return strlen(s.s);
|
||||
}
|
||||
|
||||
int f_mutable_ptr(simple* s)
|
||||
{
|
||||
return strlen(s->s);
|
||||
}
|
||||
|
||||
int f_const_ptr(simple const* s)
|
||||
{
|
||||
return strlen(s->s);
|
||||
}
|
||||
|
||||
int f2(SimpleObject const& s)
|
||||
{
|
||||
return strlen(s.x.s);
|
||||
}
|
||||
|
||||
// A trivial passthru function for simple objects
|
||||
simple const& g(simple const& x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
struct A
|
||||
{
|
||||
A() : x(0) {}
|
||||
virtual ~A() {}
|
||||
char const* name() { return "A"; }
|
||||
int x;
|
||||
};
|
||||
|
||||
struct B : A
|
||||
{
|
||||
B() : x(1) {}
|
||||
static char const* name(B*) { return "B"; }
|
||||
int x;
|
||||
};
|
||||
|
||||
struct C : A
|
||||
{
|
||||
C() : x(2) {}
|
||||
char const* name() { return "C"; }
|
||||
virtual ~C() {}
|
||||
int x;
|
||||
};
|
||||
|
||||
struct D : B, C
|
||||
{
|
||||
D() : x(3) {}
|
||||
char const* name() { return "D"; }
|
||||
int x;
|
||||
};
|
||||
|
||||
A take_a(A const& a) { return a; }
|
||||
B take_b(B& b) { return b; }
|
||||
C take_c(C* c) { return *c; }
|
||||
D take_d(D* const& d) { return *d; }
|
||||
|
||||
D take_d_shared_ptr(boost::shared_ptr<D> d) { return *d; }
|
||||
|
||||
boost::shared_ptr<A> d_factory() { return boost::shared_ptr<B>(new D); }
|
||||
|
||||
struct Unregistered {};
|
||||
Unregistered make_unregistered(int) { return Unregistered(); }
|
||||
|
||||
Unregistered* make_unregistered2(int) { return new Unregistered; }
|
||||
|
||||
BOOST_PYTHON_MODULE(m1)
|
||||
{
|
||||
using namespace boost::python;
|
||||
using boost::shared_ptr;
|
||||
|
||||
simple_to_python();
|
||||
|
||||
lvalue_from_pytype<int_from_noddy,&NoddyType>();
|
||||
|
||||
lvalue_from_pytype<
|
||||
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // doesn't support non-type member pointer parameters
|
||||
extract_member<SimpleObject, simple, &SimpleObject::x>
|
||||
#else
|
||||
extract_simple_object
|
||||
#endif
|
||||
, &SimpleType
|
||||
>();
|
||||
|
||||
lvalue_from_pytype<extract_identity<SimpleObject>,&SimpleType>();
|
||||
|
||||
def("new_noddy", new_noddy);
|
||||
def("new_simple", new_simple);
|
||||
|
||||
def("make_unregistered", make_unregistered);
|
||||
def("make_unregistered2", make_unregistered2, return_value_policy<manage_new_object>());
|
||||
|
||||
// Expose f() in all its variations
|
||||
def("f", f);
|
||||
def("f_mutable_ref", f_mutable_ref);
|
||||
def("f_mutable_ptr", f_mutable_ptr);
|
||||
def("f_const_ptr", f_const_ptr);
|
||||
|
||||
def("f2", f2);
|
||||
|
||||
// Expose g()
|
||||
def("g", g , return_value_policy<copy_const_reference>()
|
||||
);
|
||||
|
||||
def("take_a", take_a);
|
||||
def("take_b", take_b);
|
||||
def("take_c", take_c);
|
||||
def("take_d", take_d);
|
||||
|
||||
|
||||
def("take_d_shared_ptr", take_d_shared_ptr);
|
||||
def("d_factory", d_factory);
|
||||
|
||||
class_<A, shared_ptr<A> >("A")
|
||||
.def("name", &A::name)
|
||||
;
|
||||
|
||||
// sequence points don't ensure that "A" is constructed before "B"
|
||||
// or "C" below if we make them part of the same chain
|
||||
class_<B,bases<A> >("B")
|
||||
.def("name", &B::name)
|
||||
;
|
||||
|
||||
class_<C,bases<A> >("C")
|
||||
.def("name", &C::name)
|
||||
;
|
||||
|
||||
class_<D, bases<B,C> >("D")
|
||||
.def("name", &D::name)
|
||||
;
|
||||
|
||||
class_<complicated>("complicated",
|
||||
init<simple const&,int>())
|
||||
.def(init<simple const&>())
|
||||
.def("get_n", &complicated::get_n)
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
99
test/m2.cpp
99
test/m2.cpp
@@ -1,99 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// This module exercises the converters exposed in m1 at a low level
|
||||
// by exposing raw Python extension functions that use wrap<> and
|
||||
// unwrap<> objects.
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/copy_non_const_reference.hpp>
|
||||
#include <boost/python/copy_const_reference.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
#include "simple_type.hpp"
|
||||
|
||||
// Get a simple (by value) from the argument, and return the
|
||||
// string it holds.
|
||||
PyObject* unwrap_simple(simple x)
|
||||
{
|
||||
return PyString_FromString(x.s);
|
||||
}
|
||||
|
||||
// Likewise, but demands that its possible to get a non-const
|
||||
// reference to the simple.
|
||||
PyObject* unwrap_simple_ref(simple& x)
|
||||
{
|
||||
return PyString_FromString(x.s);
|
||||
}
|
||||
|
||||
// Likewise, with a const reference to the simple object.
|
||||
PyObject* unwrap_simple_const_ref(simple const& x)
|
||||
{
|
||||
return PyString_FromString(x.s);
|
||||
}
|
||||
|
||||
// Get an int (by value) from the argument, and convert it to a
|
||||
// Python Int.
|
||||
PyObject* unwrap_int(int x)
|
||||
{
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
// Get a non-const reference to an int from the argument
|
||||
PyObject* unwrap_int_ref(int& x)
|
||||
{
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
// Get a const reference to an int from the argument.
|
||||
PyObject* unwrap_int_const_ref(int const& x)
|
||||
{
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
// rewrap<T> extracts a T from the argument, then converts the T back
|
||||
// to a PyObject* and returns it.
|
||||
template <class T>
|
||||
struct rewrap
|
||||
{
|
||||
static T f(T x) { return x; }
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(m2)
|
||||
{
|
||||
using boost::python::return_value_policy;
|
||||
using boost::python::copy_const_reference;
|
||||
using boost::python::copy_non_const_reference;
|
||||
using boost::python::def;
|
||||
|
||||
def("unwrap_int", unwrap_int);
|
||||
def("unwrap_int_ref", unwrap_int_ref);
|
||||
def("unwrap_int_const_ref", unwrap_int_const_ref);
|
||||
def("unwrap_simple", unwrap_simple);
|
||||
def("unwrap_simple_ref", unwrap_simple_ref);
|
||||
def("unwrap_simple_const_ref", unwrap_simple_const_ref);
|
||||
|
||||
def("wrap_int", &rewrap<int>::f);
|
||||
|
||||
def("wrap_int_ref", &rewrap<int&>::f
|
||||
, return_value_policy<copy_non_const_reference>()
|
||||
);
|
||||
|
||||
def("wrap_int_const_ref", &rewrap<int const&>::f
|
||||
, return_value_policy<copy_const_reference>()
|
||||
);
|
||||
|
||||
def("wrap_simple", &rewrap<simple>::f);
|
||||
|
||||
def("wrap_simple_ref", &rewrap<simple&>::f
|
||||
, return_value_policy<copy_non_const_reference>()
|
||||
);
|
||||
|
||||
def("wrap_simple_const_ref", &rewrap<simple const&>::f
|
||||
, return_value_policy<copy_const_reference>()
|
||||
);
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,55 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/detail/member_function_cast.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/type.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
template <class T, class S>
|
||||
void assert_same(S, type<T>* = 0)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_same<T,S>::value));
|
||||
}
|
||||
|
||||
template <class Expected, class Target, class F>
|
||||
void assert_mf_cast(F f, type<Expected>* = 0, type<Target>* = 0)
|
||||
{
|
||||
assert_same<Expected>(
|
||||
python::detail::member_function_cast<Target,F>::stage1(f).stage2((Target*)0).stage3(f)
|
||||
);
|
||||
}
|
||||
|
||||
struct X
|
||||
{
|
||||
int f() const { return 0; }
|
||||
void g(char*) {}
|
||||
};
|
||||
|
||||
struct Y : X
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
struct Z : Y
|
||||
{
|
||||
int f() const { return 0; }
|
||||
void g(char*) {}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
assert_mf_cast<int (Y::*)() const, Y>(&X::f);
|
||||
assert_mf_cast<void (Y::*)(char*), Y>(&X::g);
|
||||
|
||||
assert_mf_cast<int (Z::*)() const, Y>(&Z::f);
|
||||
assert_mf_cast<void (Z::*)(char*), Y>(&Z::g);
|
||||
|
||||
assert_mf_cast<int, Y>(3);
|
||||
assert_mf_cast<X, Y>(X());
|
||||
return 0;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
|
||||
#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
|
||||
# include <iostream> // works around a KCC intermediate code generation bug
|
||||
#endif
|
||||
|
||||
BOOST_PYTHON_MODULE(minimal_ext)
|
||||
{
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,4 +0,0 @@
|
||||
print "IMPORTING minimal_ext"
|
||||
import minimal_ext
|
||||
print "DONE IMPORTING minimal_ext"
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#if defined(_WIN32)
|
||||
# ifdef __MWERKS__
|
||||
# pragma ANSI_strict off
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef __MWERKS__
|
||||
# pragma ANSI_strict reset
|
||||
# endif
|
||||
|
||||
extern "C" BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved );
|
||||
|
||||
# ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4297)
|
||||
extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
# pragma warning(pop)
|
||||
# endif
|
||||
|
||||
BOOL WINAPI DllMain(
|
||||
HINSTANCE, //hDllInst
|
||||
DWORD fdwReason,
|
||||
LPVOID // lpvReserved
|
||||
)
|
||||
{
|
||||
# ifdef BOOST_MSVC
|
||||
_set_se_translator(structured_exception_translator);
|
||||
# endif
|
||||
(void)fdwReason; // warning suppression.
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
|
||||
struct A
|
||||
{
|
||||
A(const double, const double, const double, const double, const double
|
||||
, const double, const double
|
||||
, const double, const double
|
||||
) {}
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(multi_arg_constructor_ext)
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
class_<A>(
|
||||
"A"
|
||||
, init<double, double, double, double, double, double, double, double, double>()
|
||||
)
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
'''
|
||||
>>> from multi_arg_constructor_ext import *
|
||||
>>> a = A(1.0, 2, 3, 4, 5, 6, 7.0, 8.1, 9.3)
|
||||
'''
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,52 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/operators.hpp>
|
||||
#include <boost/python/scope.hpp>
|
||||
#include "test_class.hpp"
|
||||
#if __GNUC__ != 2
|
||||
# include <ostream>
|
||||
#else
|
||||
# include <ostream.h>
|
||||
#endif
|
||||
|
||||
typedef test_class<> X;
|
||||
typedef test_class<1> Y;
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, X const& x)
|
||||
{
|
||||
return s << x.value();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, Y const& x)
|
||||
{
|
||||
return s << x.value();
|
||||
}
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(nested_ext)
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
// Establish X as the current scope.
|
||||
scope x_class
|
||||
= class_<X>("X", init<int>())
|
||||
.def(str(self))
|
||||
;
|
||||
|
||||
|
||||
// Y will now be defined in the current scope
|
||||
class_<Y>("Y", init<int>())
|
||||
.def(str(self))
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
'''
|
||||
>>> from nested_ext import *
|
||||
|
||||
>>> X
|
||||
<class 'nested_ext.X'>
|
||||
|
||||
>>> X.__module__
|
||||
'nested_ext'
|
||||
|
||||
>>> X.__name__
|
||||
'X'
|
||||
|
||||
>>> X.Y
|
||||
<class 'nested_ext.Y'>
|
||||
|
||||
>>> X.Y.__module__
|
||||
'nested_ext'
|
||||
|
||||
>>> X.Y.__name__
|
||||
'Y'
|
||||
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
199
test/newtest.py
199
test/newtest.py
@@ -1,199 +0,0 @@
|
||||
"""
|
||||
>>> from m1 import *
|
||||
|
||||
>>> from m2 import *
|
||||
|
||||
Prove that we get an appropriate error from trying to return a type
|
||||
for which we have no registered to_python converter
|
||||
|
||||
>>> def check_unregistered(f, msgprefix):
|
||||
... try:
|
||||
... f(1)
|
||||
... except TypeError, x:
|
||||
... if not str(x).startswith(msgprefix):
|
||||
... print str(x)
|
||||
... else:
|
||||
... print 'expected a TypeError'
|
||||
...
|
||||
>>> check_unregistered(make_unregistered, 'No to_python (by-value) converter found for C++ type')
|
||||
>>> check_unregistered(make_unregistered2, 'No Python class registered for C++ class')
|
||||
|
||||
>>> n = new_noddy()
|
||||
>>> s = new_simple()
|
||||
>>> unwrap_int(n)
|
||||
42
|
||||
>>> unwrap_int_ref(n)
|
||||
42
|
||||
>>> unwrap_int_const_ref(n)
|
||||
42
|
||||
>>> unwrap_simple(s)
|
||||
'hello, world'
|
||||
>>> unwrap_simple_ref(s)
|
||||
'hello, world'
|
||||
>>> unwrap_simple_const_ref(s)
|
||||
'hello, world'
|
||||
>>> unwrap_int(5)
|
||||
5
|
||||
|
||||
Can't get a non-const reference to a built-in integer object
|
||||
>>> try:
|
||||
... unwrap_int_ref(7)
|
||||
... except: pass
|
||||
... else: print 'no exception'
|
||||
|
||||
>>> unwrap_int_const_ref(9)
|
||||
9
|
||||
|
||||
>>> wrap_int(n)
|
||||
42
|
||||
|
||||
try: wrap_int_ref(n)
|
||||
... except: pass
|
||||
... else: print 'no exception'
|
||||
|
||||
>>> wrap_int_const_ref(n)
|
||||
42
|
||||
|
||||
>>> unwrap_simple_ref(wrap_simple(s))
|
||||
'hello, world'
|
||||
|
||||
>>> unwrap_simple_ref(wrap_simple_ref(s))
|
||||
'hello, world'
|
||||
|
||||
>>> unwrap_simple_ref(wrap_simple_const_ref(s))
|
||||
'hello, world'
|
||||
|
||||
>>> f(s)
|
||||
12
|
||||
|
||||
>>> unwrap_simple(g(s))
|
||||
'hello, world'
|
||||
|
||||
>>> f(g(s))
|
||||
12
|
||||
|
||||
>>> f_mutable_ref(g(s))
|
||||
12
|
||||
|
||||
>>> f_const_ptr(g(s))
|
||||
12
|
||||
|
||||
>>> f_mutable_ptr(g(s))
|
||||
12
|
||||
|
||||
>>> f2(g(s))
|
||||
12
|
||||
|
||||
Create an extension class which wraps "complicated" (init1 and get_n)
|
||||
are a complicated constructor and member function, respectively.
|
||||
|
||||
>>> c1 = complicated(s, 99)
|
||||
>>> c1.get_n()
|
||||
99
|
||||
>>> c2 = complicated(s)
|
||||
>>> c2.get_n()
|
||||
0
|
||||
|
||||
a quick regression test for a bug where None could be converted
|
||||
to the target of any member function. To see it, we need to
|
||||
access the __dict__ directly, to bypass the type check supplied
|
||||
by the Method property which wraps the method when accessed as an
|
||||
attribute.
|
||||
|
||||
>>> try: A.__dict__['name'](None)
|
||||
... except TypeError: pass
|
||||
... else: print 'expected an exception!'
|
||||
|
||||
|
||||
>>> a = A()
|
||||
>>> b = B()
|
||||
>>> c = C()
|
||||
>>> d = D()
|
||||
|
||||
|
||||
>>> take_a(a).name()
|
||||
'A'
|
||||
|
||||
>>> try:
|
||||
... take_b(a)
|
||||
... except: pass
|
||||
... else: print 'no exception'
|
||||
|
||||
>>> try:
|
||||
... take_c(a)
|
||||
... except: pass
|
||||
... else: print 'no exception'
|
||||
|
||||
>>> try:
|
||||
... take_d(a)
|
||||
... except: pass
|
||||
... else: print 'no exception'
|
||||
|
||||
------
|
||||
>>> take_a(b).name()
|
||||
'A'
|
||||
|
||||
>>> take_b(b).name()
|
||||
'B'
|
||||
|
||||
>>> try:
|
||||
... take_c(b)
|
||||
... except: pass
|
||||
... else: print 'no exception'
|
||||
|
||||
>>> try:
|
||||
... take_d(b)
|
||||
... except: pass
|
||||
... else: print 'no exception'
|
||||
|
||||
-------
|
||||
>>> take_a(c).name()
|
||||
'A'
|
||||
|
||||
>>> try:
|
||||
... take_b(c)
|
||||
... except: pass
|
||||
... else: print 'no exception'
|
||||
|
||||
>>> take_c(c).name()
|
||||
'C'
|
||||
|
||||
>>> try:
|
||||
... take_d(c)
|
||||
... except: pass
|
||||
... else: print 'no exception'
|
||||
|
||||
-------
|
||||
>>> take_a(d).name()
|
||||
'A'
|
||||
>>> take_b(d).name()
|
||||
'B'
|
||||
>>> take_c(d).name()
|
||||
'C'
|
||||
>>> take_d(d).name()
|
||||
'D'
|
||||
|
||||
>>> take_d_shared_ptr(d).name()
|
||||
'D'
|
||||
|
||||
>>> d_as_a = d_factory()
|
||||
>>> dd = take_d(d_as_a)
|
||||
>>> dd.name()
|
||||
'D'
|
||||
|
||||
"""
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
105
test/numpy.cpp
105
test/numpy.cpp
@@ -1,105 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/numeric.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
// See if we can invoke array() from C++
|
||||
object new_array()
|
||||
{
|
||||
return numeric::array(
|
||||
make_tuple(
|
||||
make_tuple(1,2,3)
|
||||
, make_tuple(4,5,6)
|
||||
, make_tuple(7,8,9)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// test argument conversion
|
||||
void take_array(numeric::array x)
|
||||
{
|
||||
}
|
||||
|
||||
// A separate function to invoke the info() member. Must happen
|
||||
// outside any doctests since this prints directly to stdout and the
|
||||
// result text includes the address of the 'self' array.
|
||||
void info(numeric::array const& z)
|
||||
{
|
||||
z.info();
|
||||
}
|
||||
|
||||
// Tests which work on both Numeric and numarray array objects. Of
|
||||
// course all of the operators "just work" since numeric::array
|
||||
// inherits that behavior from object.
|
||||
void exercise(numeric::array& y, object check)
|
||||
{
|
||||
y[make_tuple(2,1)] = 3;
|
||||
check(y);
|
||||
check(y.astype('D'));
|
||||
check(y.copy());
|
||||
check(y.typecode());
|
||||
}
|
||||
|
||||
// numarray-specific tests. check is a callable object which we can
|
||||
// use to record intermediate results, which are later compared with
|
||||
// the results of corresponding python operations.
|
||||
void exercise_numarray(numeric::array& y, object check)
|
||||
{
|
||||
check(y.astype());
|
||||
|
||||
check(y.argmax());
|
||||
check(y.argmax(0));
|
||||
|
||||
check(y.argmin());
|
||||
check(y.argmin(0));
|
||||
|
||||
check(y.argsort());
|
||||
check(y.argsort(1));
|
||||
|
||||
y.byteswap();
|
||||
check(y);
|
||||
|
||||
check(y.diagonal());
|
||||
check(y.diagonal(1));
|
||||
check(y.diagonal(0, 1));
|
||||
check(y.diagonal(0, 1, 0));
|
||||
|
||||
check(y.is_c_array());
|
||||
check(y.isbyteswapped());
|
||||
|
||||
check(y.trace());
|
||||
check(y.trace(1));
|
||||
check(y.trace(0, 1));
|
||||
check(y.trace(0, 1, 0));
|
||||
|
||||
check(y.new_('D'));
|
||||
y.sort();
|
||||
check(y);
|
||||
check(y.type());
|
||||
|
||||
check(y.factory(make_tuple(1.2, 3.4)));
|
||||
check(y.factory(make_tuple(1.2, 3.4), "Double"));
|
||||
check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(1,2,1)));
|
||||
check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(2,1,1), false));
|
||||
check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(2), true, true));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(numpy_ext)
|
||||
{
|
||||
def("new_array", new_array);
|
||||
def("take_array", take_array);
|
||||
def("exercise", exercise);
|
||||
def("exercise_numarray", exercise_numarray);
|
||||
def("set_module_and_type", &numeric::array::set_module_and_type);
|
||||
def("info", info);
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
175
test/numpy.py
175
test/numpy.py
@@ -1,175 +0,0 @@
|
||||
def numeric_tests():
|
||||
'''
|
||||
>>> from numpy_ext import *
|
||||
>>> x = new_array()
|
||||
>>> x[1,1] = 0.0
|
||||
|
||||
>>> try: take_array(3)
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError'
|
||||
|
||||
>>> take_array(x)
|
||||
|
||||
>>> print x
|
||||
[[1 2 3]
|
||||
[4 0 6]
|
||||
[7 8 9]]
|
||||
|
||||
>>> y = x.copy()
|
||||
|
||||
|
||||
>>> p = _printer()
|
||||
>>> check = p.check
|
||||
>>> exercise(x, p)
|
||||
>>> y[2,1] = 3
|
||||
>>> check(y);
|
||||
|
||||
>>> check(y.astype('D'));
|
||||
|
||||
>>> check(y.copy());
|
||||
|
||||
>>> check(y.typecode());
|
||||
|
||||
>>> p.results
|
||||
[]
|
||||
>>> del p
|
||||
'''
|
||||
pass
|
||||
|
||||
def _numarray_tests():
|
||||
'''
|
||||
>>> from numpy_ext import *
|
||||
>>> x = new_array()
|
||||
>>> y = x.copy()
|
||||
>>> p = _printer()
|
||||
>>> check = p.check
|
||||
>>> exercise_numarray(x, p)
|
||||
|
||||
>>> check(y.astype());
|
||||
|
||||
>>> check(y.argmax());
|
||||
>>> check(y.argmax(0));
|
||||
|
||||
>>> check(y.argmin());
|
||||
>>> check(y.argmin(0));
|
||||
|
||||
>>> check(y.argsort());
|
||||
>>> check(y.argsort(1));
|
||||
|
||||
>>> y.byteswap();
|
||||
>>> check(y);
|
||||
|
||||
>>> check(y.diagonal());
|
||||
>>> check(y.diagonal(1));
|
||||
>>> check(y.diagonal(0, 1));
|
||||
>>> check(y.diagonal(0, 1, 0));
|
||||
|
||||
>>> check(y.is_c_array());
|
||||
>>> check(y.isbyteswapped());
|
||||
|
||||
>>> check(y.trace());
|
||||
>>> check(y.trace(1));
|
||||
>>> check(y.trace(0, 1));
|
||||
>>> check(y.trace(0, 1, 0));
|
||||
|
||||
>>> check(y.new('D'));
|
||||
>>> y.sort();
|
||||
>>> check(y);
|
||||
>>> check(y.type());
|
||||
|
||||
>>> check(y.array((1.2, 3.4)));
|
||||
>>> check(y.array((1.2, 3.4), "Double"));
|
||||
>>> check(y.array((1.2, 3.4), "Double", (1,2,1)));
|
||||
>>> check(y.array((1.2, 3.4), "Double", (2,1,1), false));
|
||||
>>> check(y.array((1.2, 3.4), "Double", (2,), true, true));
|
||||
|
||||
>>> p.results
|
||||
[]
|
||||
>>> del p
|
||||
'''
|
||||
pass
|
||||
|
||||
false = 0;
|
||||
true = 1;
|
||||
class _printer(object):
|
||||
def __init__(self):
|
||||
self.results = [];
|
||||
def __call__(self, *stuff):
|
||||
self.results += [ str(x) for x in stuff ]
|
||||
def check(self, x):
|
||||
if self.results[0] == str(x):
|
||||
del self.results[0]
|
||||
else:
|
||||
print ' Expected:\n %s\n but got:\n %s' % (x, self.results[0])
|
||||
|
||||
def _run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
|
||||
# See which of the numeric modules are installed
|
||||
has_numeric = 0
|
||||
try:
|
||||
import Numeric
|
||||
m = Numeric
|
||||
has_numeric = 1
|
||||
except ImportError: pass
|
||||
|
||||
has_numarray = 0
|
||||
try:
|
||||
import numarray
|
||||
m = numarray
|
||||
has_numarray = 1
|
||||
except ImportError: pass
|
||||
|
||||
# Bail if neither one is installed
|
||||
if not (has_numeric or has_numarray):
|
||||
return 0
|
||||
|
||||
# test the info routine outside the doctest. See numpy.cpp for an
|
||||
# explanation
|
||||
import numpy_ext
|
||||
if (has_numarray):
|
||||
numpy_ext.info(m.array((1,2,3)))
|
||||
|
||||
failures = 0
|
||||
|
||||
#
|
||||
# Run tests 4 different ways if both modules are installed, just
|
||||
# to show that set_module_and_type() is working properly
|
||||
#
|
||||
|
||||
# run all the tests with default module search
|
||||
print 'testing default extension module'
|
||||
failures += doctest.testmod(sys.modules.get(__name__))[0]
|
||||
|
||||
# test against Numeric if installed
|
||||
if has_numeric:
|
||||
print 'testing Numeric module explicitly'
|
||||
numpy_ext.set_module_and_type('Numeric', 'ArrayType')
|
||||
failures += doctest.testmod(sys.modules.get(__name__))[0]
|
||||
|
||||
global __test__
|
||||
if has_numarray:
|
||||
# Add the _numarray_tests to the list of things to test in
|
||||
# this case.
|
||||
__test__ = { 'numarray_tests':_numarray_tests,
|
||||
'numeric_tests': numeric_tests }
|
||||
print 'testing numarray module explicitly'
|
||||
numpy_ext.set_module_and_type('numarray', 'NDArray')
|
||||
failures += doctest.testmod(sys.modules.get(__name__))[0]
|
||||
del __test__
|
||||
|
||||
# see that we can go back to the default
|
||||
print 'testing default module again'
|
||||
numpy_ext.set_module_and_type('', '')
|
||||
failures += doctest.testmod(sys.modules.get(__name__))[0]
|
||||
|
||||
return failures
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(_run())
|
||||
318
test/object.cpp
318
test/object.cpp
@@ -1,318 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
object call_object_3(object f)
|
||||
{
|
||||
return f(3);
|
||||
}
|
||||
|
||||
object message()
|
||||
{
|
||||
return object("hello, world!");
|
||||
}
|
||||
|
||||
object number()
|
||||
{
|
||||
return object(42);
|
||||
}
|
||||
|
||||
object obj_getattr(object x, char const* name)
|
||||
{
|
||||
return x.attr(name);
|
||||
}
|
||||
|
||||
object obj_const_getattr(object const& x, char const* name)
|
||||
{
|
||||
return x.attr(name);
|
||||
}
|
||||
|
||||
void obj_setattr(object x, char const* name, object value)
|
||||
{
|
||||
x.attr(name) = value;
|
||||
}
|
||||
|
||||
void obj_setattr42(object x, char const* name)
|
||||
{
|
||||
x.attr(name) = 42;
|
||||
}
|
||||
|
||||
void obj_moveattr(object& x, char const* src, char const* dst)
|
||||
{
|
||||
x.attr(dst) = x.attr(src);
|
||||
}
|
||||
|
||||
object obj_getitem(object x, object key)
|
||||
{
|
||||
return x[key];
|
||||
}
|
||||
|
||||
object obj_getitem3(object x)
|
||||
{
|
||||
return x[3];
|
||||
}
|
||||
|
||||
object obj_const_getitem(object const& x, object key)
|
||||
{
|
||||
return x[key];
|
||||
}
|
||||
|
||||
void obj_setitem(object x, object key, object value)
|
||||
{
|
||||
x[key] = value;
|
||||
}
|
||||
|
||||
void obj_setitem42(object x, object key)
|
||||
{
|
||||
x[key] = 42;
|
||||
}
|
||||
|
||||
void obj_moveitem(object& x, object src, object dst)
|
||||
{
|
||||
x[dst] = x[src];
|
||||
}
|
||||
|
||||
void obj_moveitem2(object const& x_src, object k_src, object& x_dst, object k_dst)
|
||||
{
|
||||
x_dst[k_dst] = x_src[k_src];
|
||||
}
|
||||
|
||||
bool test(object y)
|
||||
{
|
||||
return y;
|
||||
}
|
||||
|
||||
bool test_not(object y)
|
||||
{
|
||||
return !y;
|
||||
}
|
||||
|
||||
bool test_attr(object y, char* name)
|
||||
{
|
||||
return y.attr(name);
|
||||
}
|
||||
|
||||
bool test_not_attr(object y, char* name)
|
||||
{
|
||||
return !y.attr(name);
|
||||
}
|
||||
|
||||
bool test_item(object y, object key)
|
||||
{
|
||||
return y[key];
|
||||
}
|
||||
|
||||
bool test_not_item(object y, object key)
|
||||
{
|
||||
return !y[key];
|
||||
}
|
||||
|
||||
bool check_string_slice()
|
||||
{
|
||||
object s("hello, world");
|
||||
|
||||
if (s.slice(_,-3) != "hello, wo")
|
||||
return false;
|
||||
|
||||
if (s.slice(-3,_) != "rld")
|
||||
return false;
|
||||
|
||||
if (", " != s.slice(5,7))
|
||||
return false;
|
||||
|
||||
return s.slice(2,-1).slice(1,-1) == "lo, wor";
|
||||
}
|
||||
|
||||
bool check_binary_operators()
|
||||
{
|
||||
int y;
|
||||
|
||||
object x(3);
|
||||
|
||||
#define TEST_BINARY(op) \
|
||||
for (y = 1; y < 6; ++y) \
|
||||
{ \
|
||||
if ((x op y) != (3 op y)) \
|
||||
return false; \
|
||||
} \
|
||||
for (y = 1; y < 6; ++y) \
|
||||
{ \
|
||||
if ((y op x) != (y op 3)) \
|
||||
return false; \
|
||||
} \
|
||||
for (y = 1; y < 6; ++y) \
|
||||
{ \
|
||||
object oy(y); \
|
||||
if ((oy op x) != (oy op 3)) \
|
||||
return false; \
|
||||
}
|
||||
TEST_BINARY(>)
|
||||
TEST_BINARY(>=)
|
||||
TEST_BINARY(<)
|
||||
TEST_BINARY(<=)
|
||||
TEST_BINARY(==)
|
||||
TEST_BINARY(!=)
|
||||
|
||||
TEST_BINARY(+)
|
||||
TEST_BINARY(-)
|
||||
TEST_BINARY(*)
|
||||
TEST_BINARY(/)
|
||||
TEST_BINARY(%)
|
||||
TEST_BINARY(<<)
|
||||
TEST_BINARY(>>)
|
||||
TEST_BINARY(&)
|
||||
TEST_BINARY(^)
|
||||
TEST_BINARY(|)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool check_inplace(object l, object o)
|
||||
{
|
||||
int y;
|
||||
#define TEST_INPLACE(op) \
|
||||
for (y = 1; y < 6; ++y) \
|
||||
{ \
|
||||
object x(666); \
|
||||
x op##= y; \
|
||||
if (x != (666 op y)) \
|
||||
return false; \
|
||||
} \
|
||||
for (y = 1; y < 6; ++y) \
|
||||
{ \
|
||||
object x(666); \
|
||||
x op##= object(y); \
|
||||
if (!(x == (666 op y))) \
|
||||
return false; \
|
||||
}
|
||||
TEST_INPLACE(+)
|
||||
TEST_INPLACE(-)
|
||||
TEST_INPLACE(*)
|
||||
TEST_INPLACE(/)
|
||||
TEST_INPLACE(%)
|
||||
TEST_INPLACE(<<)
|
||||
TEST_INPLACE(>>)
|
||||
TEST_INPLACE(&)
|
||||
TEST_INPLACE(^)
|
||||
TEST_INPLACE(|)
|
||||
|
||||
l += l;
|
||||
for (y = 0; y < 6; ++y)
|
||||
{
|
||||
if (l[y] != y % 3)
|
||||
return false;
|
||||
}
|
||||
|
||||
#define TEST_ITEM_INPLACE(index, op, n, r1, r2) \
|
||||
l[index] op##= n; \
|
||||
if (l[index] != r1) \
|
||||
return false; \
|
||||
l[index] op##= object(n); \
|
||||
if (!(l[index] == r2)) \
|
||||
return false;
|
||||
|
||||
TEST_ITEM_INPLACE(0,+,7,7,14)
|
||||
TEST_ITEM_INPLACE(1,-,2,-1,-3)
|
||||
TEST_ITEM_INPLACE(2,*,3,6,18)
|
||||
TEST_ITEM_INPLACE(2,/,2,9,4)
|
||||
TEST_ITEM_INPLACE(0,%,4,2,2)
|
||||
l[0] += 1;
|
||||
TEST_ITEM_INPLACE(0,<<,2,12,48)
|
||||
TEST_ITEM_INPLACE(0,>>,1,24,12)
|
||||
l[4] = 15;
|
||||
TEST_ITEM_INPLACE(4,&,(16+4+1),5,5)
|
||||
TEST_ITEM_INPLACE(0,^,1,13,12)
|
||||
TEST_ITEM_INPLACE(0,|,1,13,13)
|
||||
|
||||
o.attr("x0") = 0;
|
||||
o.attr("x1") = 1;
|
||||
o.attr("x2") = 2;
|
||||
o.attr("x3") = 0;
|
||||
o.attr("x4") = 1;
|
||||
|
||||
#define TEST_ATTR_INPLACE(index, op, n, r1, r2) \
|
||||
o.attr("x" #index) op##= n; \
|
||||
if (o.attr("x" #index) != r1) \
|
||||
return false; \
|
||||
o.attr("x" #index) op##= object(n); \
|
||||
if (o.attr("x" #index) != r2) \
|
||||
return false;
|
||||
|
||||
TEST_ATTR_INPLACE(0,+,7,7,14)
|
||||
TEST_ATTR_INPLACE(1,-,2,-1,-3)
|
||||
TEST_ATTR_INPLACE(2,*,3,6,18)
|
||||
TEST_ATTR_INPLACE(2,/,2,9,4)
|
||||
TEST_ATTR_INPLACE(0,%,4,2,2)
|
||||
o.attr("x0") += 1;
|
||||
TEST_ATTR_INPLACE(0,<<,2,12,48)
|
||||
TEST_ATTR_INPLACE(0,>>,1,24,12)
|
||||
o.attr("x4") = 15;
|
||||
TEST_ATTR_INPLACE(4,&,(16+4+1),5,5)
|
||||
TEST_ATTR_INPLACE(0,^,1,13,12)
|
||||
TEST_ATTR_INPLACE(0,|,1,13,13)
|
||||
|
||||
if (l[0] != o.attr("x0"))
|
||||
return false;
|
||||
if (l[1] != o.attr("x1"))
|
||||
return false;
|
||||
if (l[2] != o.attr("x2"))
|
||||
return false;
|
||||
if (l[3] != o.attr("x3"))
|
||||
return false;
|
||||
if (l[4] != o.attr("x4"))
|
||||
return false;
|
||||
|
||||
// set item 5 to be a list, by calling l.__class__
|
||||
l[5] = l.attr("__class__")();
|
||||
// append an element
|
||||
l[5].attr("append")(2);
|
||||
// Check its value
|
||||
if (l[5][0] != 2)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(object_ext)
|
||||
{
|
||||
def("call_object_3", call_object_3);
|
||||
def("message", message);
|
||||
def("number", number);
|
||||
|
||||
def("obj_getattr", obj_getattr);
|
||||
def("obj_const_getattr", obj_const_getattr);
|
||||
def("obj_setattr", obj_setattr);
|
||||
def("obj_setattr42", obj_setattr42);
|
||||
def("obj_moveattr", obj_moveattr);
|
||||
|
||||
|
||||
def("obj_getitem", obj_getitem);
|
||||
def("obj_getitem3", obj_getitem);
|
||||
def("obj_const_getitem", obj_const_getitem);
|
||||
def("obj_setitem", obj_setitem);
|
||||
def("obj_setitem42", obj_setitem42);
|
||||
def("obj_moveitem", obj_moveitem);
|
||||
def("obj_moveitem2", obj_moveitem2);
|
||||
|
||||
def("test", test);
|
||||
def("test_not", test_not);
|
||||
|
||||
def("test_attr", test_attr);
|
||||
def("test_not_attr", test_not_attr);
|
||||
|
||||
def("test_item", test_item);
|
||||
def("test_not_item", test_not_item);
|
||||
|
||||
def("check_binary_operators", check_binary_operators);
|
||||
def("check_inplace", check_inplace);
|
||||
def("check_string_slice", check_string_slice);
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
126
test/object.py
126
test/object.py
@@ -1,126 +0,0 @@
|
||||
'''
|
||||
>>> from object_ext import *
|
||||
>>> def print1(x):
|
||||
... print x
|
||||
>>> call_object_3(print1)
|
||||
3
|
||||
>>> message()
|
||||
'hello, world!'
|
||||
>>> number()
|
||||
42
|
||||
|
||||
>>> test('hi')
|
||||
1
|
||||
>>> test(None)
|
||||
0
|
||||
>>> test_not('hi')
|
||||
0
|
||||
>>> test_not(0)
|
||||
1
|
||||
|
||||
Attributes
|
||||
|
||||
>>> class X: pass
|
||||
...
|
||||
>>> x = X()
|
||||
|
||||
>>> try: obj_getattr(x, 'foo')
|
||||
... except AttributeError: pass
|
||||
... else: print 'expected an exception'
|
||||
|
||||
>>> obj_setattr(x, 'foo', 1)
|
||||
>>> x.foo
|
||||
1
|
||||
>>> obj_getattr(x, 'foo')
|
||||
1
|
||||
>>> obj_const_getattr(x, 'foo')
|
||||
1
|
||||
>>> obj_setattr42(x, 'foo')
|
||||
>>> x.foo
|
||||
42
|
||||
>>> obj_moveattr(x, 'foo', 'bar')
|
||||
>>> x.bar
|
||||
42
|
||||
>>> test_attr(x, 'foo')
|
||||
1
|
||||
>>> test_not_attr(x, 'foo')
|
||||
0
|
||||
>>> x.foo = None
|
||||
>>> test_attr(x, 'foo')
|
||||
0
|
||||
>>> test_not_attr(x, 'foo')
|
||||
1
|
||||
|
||||
Items
|
||||
|
||||
>>> d = {}
|
||||
>>> obj_setitem(d, 'foo', 1)
|
||||
>>> d['foo']
|
||||
1
|
||||
>>> obj_getitem(d, 'foo')
|
||||
1
|
||||
>>> obj_const_getitem(d, 'foo')
|
||||
1
|
||||
>>> obj_setitem42(d, 'foo')
|
||||
>>> obj_getitem(d, 'foo')
|
||||
42
|
||||
>>> d['foo']
|
||||
42
|
||||
>>> obj_moveitem(d, 'foo', 'bar')
|
||||
>>> d['bar']
|
||||
42
|
||||
>>> obj_moveitem2(d, 'bar', d, 'baz')
|
||||
>>> d['baz']
|
||||
42
|
||||
>>> test_item(d, 'foo')
|
||||
1
|
||||
>>> test_not_item(d, 'foo')
|
||||
0
|
||||
>>> d['foo'] = None
|
||||
>>> test_item(d, 'foo')
|
||||
0
|
||||
>>> test_not_item(d, 'foo')
|
||||
1
|
||||
|
||||
Slices
|
||||
|
||||
>>> assert check_string_slice()
|
||||
|
||||
Operators
|
||||
|
||||
|
||||
>>> assert check_binary_operators()
|
||||
|
||||
>>> class X: pass
|
||||
...
|
||||
>>> assert check_inplace(range(3), X())
|
||||
|
||||
|
||||
Now make sure that object is actually managing reference counts
|
||||
|
||||
>>> import weakref
|
||||
>>> class Z: pass
|
||||
...
|
||||
>>> z = Z()
|
||||
>>> def death(r): print 'death'
|
||||
...
|
||||
>>> r = weakref.ref(z, death)
|
||||
>>> z.foo = 1
|
||||
>>> obj_getattr(z, 'foo')
|
||||
1
|
||||
>>> del z
|
||||
death
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,12 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/object.hpp>
|
||||
|
||||
int f(boost::python::object const& x)
|
||||
{
|
||||
x._("hello") = 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/converter/object_manager.hpp>
|
||||
#include <boost/python/borrowed.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace boost::python::converter;
|
||||
|
||||
struct X {};
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(is_object_manager<handle<> >::value);
|
||||
BOOST_STATIC_ASSERT(!is_object_manager<int>::value);
|
||||
BOOST_STATIC_ASSERT(!is_object_manager<X>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(is_reference_to_object_manager<handle<>&>::value);
|
||||
BOOST_STATIC_ASSERT(is_reference_to_object_manager<handle<> const&>::value);
|
||||
BOOST_STATIC_ASSERT(is_reference_to_object_manager<handle<> volatile&>::value);
|
||||
BOOST_STATIC_ASSERT(is_reference_to_object_manager<handle<> const volatile&>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(!is_reference_to_object_manager<handle<> >::value);
|
||||
BOOST_STATIC_ASSERT(!is_reference_to_object_manager<X>::value);
|
||||
BOOST_STATIC_ASSERT(!is_reference_to_object_manager<X&>::value);
|
||||
BOOST_STATIC_ASSERT(!is_reference_to_object_manager<X const&>::value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <string>
|
||||
#include <boost/python/operators.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include "test_class.hpp"
|
||||
#if __GNUC__ != 2
|
||||
# include <ostream>
|
||||
#else
|
||||
# include <ostream.h>
|
||||
#endif
|
||||
|
||||
// Just use math.h here; trying to use std::pow() causes too much
|
||||
// trouble for non-conforming compilers and libraries.
|
||||
#include <math.h>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
struct X : test_class<>
|
||||
{
|
||||
typedef test_class<> base_t;
|
||||
|
||||
X(int x) : base_t(x) {}
|
||||
X const operator+(X const& r) const { return X(value() + r.value()); }
|
||||
};
|
||||
|
||||
X operator-(X const& l, X const& r) { return X(l.value() - r.value()); }
|
||||
X operator-(int l, X const& r) { return X(l - r.value()); }
|
||||
X operator-(X const& l, int r) { return X(l.value() - r); }
|
||||
|
||||
X operator-(X const& x) { return X(-x.value()); }
|
||||
|
||||
X& operator-=(X& l, X const& r) { l.set(l.value() - r.value()); return l; }
|
||||
|
||||
bool operator<(X const& x, X const& y) { return x.value() < y.value(); }
|
||||
bool operator<(X const& x, int y) { return x.value() < y; }
|
||||
bool operator<(int x, X const& y) { return x < y.value(); }
|
||||
|
||||
X abs(X x) { return X(x.value() < 0 ? -x.value() : x.value()); }
|
||||
|
||||
X pow(X x, int y)
|
||||
{
|
||||
return X(int(pow(double(x.value()), double(y))));
|
||||
}
|
||||
|
||||
X pow(X x, X y)
|
||||
{
|
||||
return X(int(pow(double(x.value()), double(y.value()))));
|
||||
}
|
||||
|
||||
int pow(int x, X y)
|
||||
{
|
||||
return int(pow(double(x), double(y.value())));
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, X const& x)
|
||||
{
|
||||
return s << x.value();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(operators_ext)
|
||||
{
|
||||
class_<X>("X", init<int>())
|
||||
.def("value", &X::value)
|
||||
.def(self + self)
|
||||
.def(self - self)
|
||||
.def(self - int())
|
||||
.def(other<int>() - self)
|
||||
.def(-self)
|
||||
.def(self < other<int>())
|
||||
.def(self < self)
|
||||
.def(1 < self)
|
||||
.def(self -= self)
|
||||
.def(abs(self))
|
||||
.def(str(self))
|
||||
|
||||
.def(pow(self,self))
|
||||
.def(pow(self,int()))
|
||||
.def(pow(int(),self))
|
||||
;
|
||||
|
||||
class_<test_class<1> >("Z", init<int>())
|
||||
.def(int_(self))
|
||||
.def(float_(self))
|
||||
.def(complex_(self))
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,89 +0,0 @@
|
||||
'''
|
||||
>>> from operators_ext import *
|
||||
>>> x = X(42)
|
||||
>>> x.value()
|
||||
42
|
||||
>>> y = x - X(5)
|
||||
>>> y.value()
|
||||
37
|
||||
>>> y = x - 4
|
||||
>>> y.value()
|
||||
38
|
||||
>>> y = 3 - x
|
||||
>>> y.value()
|
||||
-39
|
||||
>>> (-y).value()
|
||||
39
|
||||
|
||||
>>> (x + y).value()
|
||||
3
|
||||
|
||||
>>> abs(y).value()
|
||||
39
|
||||
|
||||
>>> x < 10
|
||||
0
|
||||
>>> x < 43
|
||||
1
|
||||
|
||||
>>> 10 < x
|
||||
1
|
||||
>>> 43 < x
|
||||
0
|
||||
|
||||
>>> x < y
|
||||
0
|
||||
>>> y < x
|
||||
1
|
||||
|
||||
------
|
||||
>>> x > 10
|
||||
1
|
||||
>>> x > 43
|
||||
0
|
||||
|
||||
>>> 10 > x
|
||||
0
|
||||
>>> 43 > x
|
||||
1
|
||||
|
||||
>>> x > y
|
||||
1
|
||||
>>> y > x
|
||||
0
|
||||
|
||||
>>> y = x - 5
|
||||
>>> x -= y
|
||||
>>> x.value()
|
||||
5
|
||||
>>> str(x)
|
||||
'5'
|
||||
|
||||
>>> z = Z(10)
|
||||
>>> int(z)
|
||||
10
|
||||
>>> float(z)
|
||||
10.0
|
||||
>>> complex(z)
|
||||
(10+0j)
|
||||
|
||||
>>> pow(2,x)
|
||||
32
|
||||
>>> pow(x,2).value()
|
||||
25
|
||||
>>> pow(X(2),x).value()
|
||||
32
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,55 +0,0 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
|
||||
/*
|
||||
This example shows how to make an Extension Class "pickleable".
|
||||
|
||||
The world class below can be fully restored by passing the
|
||||
appropriate argument to the constructor. Therefore it is sufficient
|
||||
to define the pickle interface method __getinitargs__.
|
||||
|
||||
For more information refer to boost/libs/python/doc/pickle.html.
|
||||
*/
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
|
||||
// A friendly class.
|
||||
class world
|
||||
{
|
||||
private:
|
||||
std::string country;
|
||||
public:
|
||||
world(const std::string& country) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
};
|
||||
|
||||
struct world_pickle_suite : boost::python::pickle_suite
|
||||
{
|
||||
static
|
||||
boost::python::tuple
|
||||
getinitargs(const world& w)
|
||||
{
|
||||
using namespace boost::python;
|
||||
return make_tuple(w.get_country());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(pickle1_ext)
|
||||
{
|
||||
using namespace boost::python;
|
||||
class_<world>("world", init<const std::string&>())
|
||||
.def("greet", &world::greet)
|
||||
.def_pickle(world_pickle_suite())
|
||||
;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
r'''>>> import pickle1_ext
|
||||
>>> import pickle
|
||||
>>> pickle1_ext.world.__module__
|
||||
'pickle1_ext'
|
||||
>>> pickle1_ext.world.__safe_for_unpickling__
|
||||
1
|
||||
>>> pickle1_ext.world.__name__
|
||||
'world'
|
||||
>>> pickle1_ext.world('Hello').__reduce__()
|
||||
(<class 'pickle1_ext.world'>, ('Hello',))
|
||||
>>> wd = pickle1_ext.world('California')
|
||||
>>> pstr = pickle.dumps(wd)
|
||||
>>> wl = pickle.loads(pstr)
|
||||
>>> print wd.greet()
|
||||
Hello from California!
|
||||
>>> print wl.greet()
|
||||
Hello from California!
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,99 +0,0 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
|
||||
/*
|
||||
This example shows how to make an Extension Class "pickleable".
|
||||
|
||||
The world class below contains member data (secret_number) that
|
||||
cannot be restored by any of the constructors. Therefore it is
|
||||
necessary to provide the __getstate__/__setstate__ pair of pickle
|
||||
interface methods.
|
||||
|
||||
For simplicity, the __dict__ is not included in the result of
|
||||
__getstate__. This is not generally recommended, but a valid
|
||||
approach if it is anticipated that the object's __dict__ will
|
||||
always be empty. Note that safety guards are provided to catch
|
||||
the cases where this assumption is not true.
|
||||
|
||||
pickle3.cpp shows how to include the object's __dict__ in the
|
||||
result of __getstate__.
|
||||
|
||||
For more information refer to boost/libs/python/doc/pickle.html.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/detail/api_placeholder.hpp>
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A friendly class.
|
||||
class world
|
||||
{
|
||||
public:
|
||||
world(const std::string& country) : secret_number(0) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
void set_secret_number(int number) { secret_number = number; }
|
||||
int get_secret_number() const { return secret_number; }
|
||||
private:
|
||||
std::string country;
|
||||
int secret_number;
|
||||
};
|
||||
|
||||
struct world_pickle_suite : boost::python::pickle_suite
|
||||
{
|
||||
static
|
||||
boost::python::tuple
|
||||
getinitargs(const world& w)
|
||||
{
|
||||
using namespace boost::python;
|
||||
return make_tuple(w.get_country());
|
||||
}
|
||||
|
||||
static
|
||||
boost::python::tuple
|
||||
getstate(const world& w)
|
||||
{
|
||||
using namespace boost::python;
|
||||
return make_tuple(w.get_secret_number());
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
setstate(world& w, boost::python::tuple state)
|
||||
{
|
||||
using namespace boost::python;
|
||||
if (len(state) != 1)
|
||||
{
|
||||
PyErr_SetObject(PyExc_ValueError,
|
||||
("expected 1-item tuple in call to __setstate__; got %s"
|
||||
% state).ptr()
|
||||
);
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
long number = extract<long>(state[0]);
|
||||
if (number != 42)
|
||||
w.set_secret_number(number);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(pickle2_ext)
|
||||
{
|
||||
boost::python::class_<world>(
|
||||
"world", boost::python::init<const std::string&>())
|
||||
.def("greet", &world::greet)
|
||||
.def("get_secret_number", &world::get_secret_number)
|
||||
.def("set_secret_number", &world::set_secret_number)
|
||||
.def_pickle(world_pickle_suite())
|
||||
;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
r'''>>> import pickle2_ext
|
||||
>>> import pickle
|
||||
>>> pickle2_ext.world.__module__
|
||||
'pickle2_ext'
|
||||
>>> pickle2_ext.world.__safe_for_unpickling__
|
||||
1
|
||||
>>> pickle2_ext.world.__name__
|
||||
'world'
|
||||
>>> pickle2_ext.world('Hello').__reduce__()
|
||||
(<class 'pickle2_ext.world'>, ('Hello',), (0,))
|
||||
>>> for number in (24, 42):
|
||||
... wd = pickle2_ext.world('California')
|
||||
... wd.set_secret_number(number)
|
||||
... pstr = pickle.dumps(wd)
|
||||
... wl = pickle.loads(pstr)
|
||||
... print wd.greet(), wd.get_secret_number()
|
||||
... print wl.greet(), wl.get_secret_number()
|
||||
Hello from California! 24
|
||||
Hello from California! 24
|
||||
Hello from California! 42
|
||||
Hello from California! 0
|
||||
|
||||
# Now show that the __dict__ is not taken care of.
|
||||
>>> wd = pickle2_ext.world('California')
|
||||
>>> wd.x = 1
|
||||
>>> wd.__dict__
|
||||
{'x': 1}
|
||||
>>> try: pstr = pickle.dumps(wd)
|
||||
... except RuntimeError, err: print err[0]
|
||||
...
|
||||
Incomplete pickle support (__getstate_manages_dict__ not set)
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
107
test/pickle3.cpp
107
test/pickle3.cpp
@@ -1,107 +0,0 @@
|
||||
// Example by Ralf W. Grosse-Kunstleve
|
||||
|
||||
/*
|
||||
This example shows how to make an Extension Class "pickleable".
|
||||
|
||||
The world class below contains member data (secret_number) that
|
||||
cannot be restored by any of the constructors. Therefore it is
|
||||
necessary to provide the __getstate__/__setstate__ pair of pickle
|
||||
interface methods.
|
||||
|
||||
The object's __dict__ is included in the result of __getstate__.
|
||||
This requires more code (compare with pickle2.cpp), but is
|
||||
unavoidable if the object's __dict__ is not always empty.
|
||||
|
||||
For more information refer to boost/libs/python/doc/pickle.html.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/dict.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/detail/api_placeholder.hpp>
|
||||
#include <boost/python/back_reference.hpp>
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A friendly class.
|
||||
class world
|
||||
{
|
||||
public:
|
||||
world(const std::string& country) : secret_number(0) {
|
||||
this->country = country;
|
||||
}
|
||||
std::string greet() const { return "Hello from " + country + "!"; }
|
||||
std::string get_country() const { return country; }
|
||||
void set_secret_number(int number) { secret_number = number; }
|
||||
int get_secret_number() const { return secret_number; }
|
||||
private:
|
||||
std::string country;
|
||||
int secret_number;
|
||||
};
|
||||
|
||||
struct world_pickle_suite : boost::python::pickle_suite
|
||||
{
|
||||
static
|
||||
boost::python::tuple
|
||||
getinitargs(const world& w)
|
||||
{
|
||||
using namespace boost::python;
|
||||
return make_tuple(w.get_country());
|
||||
}
|
||||
|
||||
static
|
||||
boost::python::tuple
|
||||
getstate(boost::python::object w_obj)
|
||||
{
|
||||
using namespace boost::python;
|
||||
world const& w = extract<world const&>(w_obj)();
|
||||
|
||||
return make_tuple(w_obj.attr("__dict__"), w.get_secret_number());
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
setstate(boost::python::object w_obj, boost::python::tuple state)
|
||||
{
|
||||
using namespace boost::python;
|
||||
world& w = extract<world&>(w_obj)();
|
||||
|
||||
if (len(state) != 2)
|
||||
{
|
||||
PyErr_SetObject(PyExc_ValueError,
|
||||
("expected 2-item tuple in call to __setstate__; got %s"
|
||||
% state).ptr()
|
||||
);
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
// restore the object's __dict__
|
||||
dict d = extract<dict>(w_obj.attr("__dict__"))();
|
||||
d.update(state[0]);
|
||||
|
||||
// restore the internal state of the C++ object
|
||||
long number = extract<long>(state[1]);
|
||||
if (number != 42)
|
||||
w.set_secret_number(number);
|
||||
}
|
||||
|
||||
static bool getstate_manages_dict() { return true; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(pickle3_ext)
|
||||
{
|
||||
boost::python::class_<world>(
|
||||
"world", boost::python::init<const std::string&>())
|
||||
.def("greet", &world::greet)
|
||||
.def("get_secret_number", &world::get_secret_number)
|
||||
.def("set_secret_number", &world::set_secret_number)
|
||||
.def_pickle(world_pickle_suite())
|
||||
;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
r'''>>> import pickle3_ext
|
||||
>>> import pickle
|
||||
>>> pickle3_ext.world.__module__
|
||||
'pickle3_ext'
|
||||
>>> pickle3_ext.world.__safe_for_unpickling__
|
||||
1
|
||||
>>> pickle3_ext.world.__getstate_manages_dict__
|
||||
1
|
||||
>>> pickle3_ext.world.__name__
|
||||
'world'
|
||||
>>> pickle3_ext.world('Hello').__reduce__()
|
||||
(<class 'pickle3_ext.world'>, ('Hello',), ({}, 0))
|
||||
>>> for number in (24, 42):
|
||||
... wd = pickle3_ext.world('California')
|
||||
... wd.set_secret_number(number)
|
||||
... wd.x = 2 * number
|
||||
... wd.y = 'y' * number
|
||||
... wd.z = 3. * number
|
||||
... pstr = pickle.dumps(wd)
|
||||
... wl = pickle.loads(pstr)
|
||||
... print wd.greet(), wd.get_secret_number(), wd.x, wd.y, wd.z
|
||||
... print wl.greet(), wl.get_secret_number(), wl.x, wl.y, wl.z
|
||||
Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0
|
||||
Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0
|
||||
Hello from California! 42 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0
|
||||
Hello from California! 0 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/pointee.hpp>
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
#include <memory>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
struct A;
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<
|
||||
boost::python::pointee<std::auto_ptr<char**> >::type
|
||||
, char**
|
||||
>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<
|
||||
boost::python::pointee<boost::shared_ptr<A> >::type
|
||||
, A>::value));
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<
|
||||
boost::python::pointee<char*>::type
|
||||
, char
|
||||
>::value));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#include <boost/python/type_id.hpp>
|
||||
#include <cassert>
|
||||
#include <boost/python/converter/pointer_type_id.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::python::converter;
|
||||
|
||||
boost::python::type_info x
|
||||
= boost::python::type_id<int>();
|
||||
|
||||
|
||||
assert(pointer_type_id<int*>() == x);
|
||||
assert(pointer_type_id<int const*>() == x);
|
||||
assert(pointer_type_id<int volatile*>() == x);
|
||||
assert(pointer_type_id<int const volatile*>() == x);
|
||||
|
||||
assert(pointer_type_id<int*&>() == x);
|
||||
assert(pointer_type_id<int const*&>() == x);
|
||||
assert(pointer_type_id<int volatile*&>() == x);
|
||||
assert(pointer_type_id<int const volatile*&>() == x);
|
||||
|
||||
assert(pointer_type_id<int*const&>() == x);
|
||||
assert(pointer_type_id<int const*const&>() == x);
|
||||
assert(pointer_type_id<int volatile*const&>() == x);
|
||||
assert(pointer_type_id<int const volatile*const&>() == x);
|
||||
|
||||
assert(pointer_type_id<int*volatile&>() == x);
|
||||
assert(pointer_type_id<int const*volatile&>() == x);
|
||||
assert(pointer_type_id<int volatile*volatile&>() == x);
|
||||
assert(pointer_type_id<int const volatile*volatile&>() == x);
|
||||
|
||||
assert(pointer_type_id<int*const volatile&>() == x);
|
||||
assert(pointer_type_id<int const*const volatile&>() == x);
|
||||
assert(pointer_type_id<int volatile*const volatile&>() == x);
|
||||
assert(pointer_type_id<int const volatile*const volatile&>() == x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
#include <boost/python/manage_new_object.hpp>
|
||||
#include <boost/python/reference_existing_object.hpp>
|
||||
#include <boost/python/call_method.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
struct Callback
|
||||
{
|
||||
Callback(PyObject* o) : mSelf(o) {}
|
||||
PyObject* mSelf;
|
||||
};
|
||||
|
||||
struct A
|
||||
{
|
||||
virtual ~A(){}
|
||||
virtual std::string f() { return "A::f()"; }
|
||||
};
|
||||
|
||||
struct ACallback : A, Callback
|
||||
{
|
||||
ACallback (PyObject* self) : Callback(self) {}
|
||||
|
||||
|
||||
std::string f()
|
||||
{
|
||||
return call_method<std::string>(mSelf, "f");
|
||||
}
|
||||
|
||||
std::string default_f()
|
||||
{
|
||||
return A::f();
|
||||
}
|
||||
};
|
||||
|
||||
struct B : A
|
||||
{
|
||||
virtual std::string f() { return "B::f()"; }
|
||||
};
|
||||
|
||||
struct C : A
|
||||
{
|
||||
virtual std::string f() { return "C::f()"; }
|
||||
};
|
||||
|
||||
A& getBCppObj ()
|
||||
{
|
||||
static B b;
|
||||
return b;
|
||||
}
|
||||
|
||||
std::string call_f(A& a) { return a.f(); }
|
||||
|
||||
A* factory(unsigned choice)
|
||||
{
|
||||
switch (choice % 3)
|
||||
{
|
||||
case 0: return new A;
|
||||
break;
|
||||
case 1: return new B;
|
||||
break;
|
||||
default: return new C;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
C& getCCppObj ()
|
||||
{
|
||||
static C c;
|
||||
return c;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(polymorphism_ext)
|
||||
{
|
||||
class_<A,boost::noncopyable,ACallback>("A")
|
||||
.def("f", &A::f, &ACallback::default_f)
|
||||
;
|
||||
|
||||
def("getBCppObj", getBCppObj, return_value_policy<reference_existing_object>());
|
||||
|
||||
class_<C,bases<A>,boost::noncopyable>("C")
|
||||
.def("f", &C::f)
|
||||
;
|
||||
|
||||
def("getCCppObj", getCCppObj, return_value_policy<reference_existing_object>());
|
||||
|
||||
def("factory", factory, return_value_policy<manage_new_object>());
|
||||
|
||||
def("call_f", call_f);
|
||||
}
|
||||
|
||||
//#include "module_tail.cpp"
|
||||
@@ -1,52 +0,0 @@
|
||||
import unittest
|
||||
from polymorphism_ext import *
|
||||
|
||||
class PolymorphTest(unittest.TestCase):
|
||||
|
||||
def testReturnCpp(self):
|
||||
|
||||
# Python Created Object With Same Id As
|
||||
# Cpp Created B Object
|
||||
# b = B(872)
|
||||
|
||||
# Get Reference To Cpp Created B Object
|
||||
a = getBCppObj()
|
||||
|
||||
# Python Created B Object and Cpp B Object
|
||||
# Should have same result by calling f()
|
||||
self.failUnlessEqual ('B::f()', a.f())
|
||||
self.failUnlessEqual ('B::f()', call_f(a))
|
||||
self.failUnlessEqual ('A::f()', call_f(A()))
|
||||
|
||||
def test_references(self):
|
||||
# B is not exposed to Python
|
||||
a = getBCppObj()
|
||||
self.failUnlessEqual(type(a), A)
|
||||
|
||||
# C is exposed to Python
|
||||
c = getCCppObj()
|
||||
self.failUnlessEqual(type(c), C)
|
||||
|
||||
def test_factory(self):
|
||||
self.failUnlessEqual(type(factory(0)), A)
|
||||
self.failUnlessEqual(type(factory(1)), A)
|
||||
self.failUnlessEqual(type(factory(2)), C)
|
||||
|
||||
def testReturnPy(self):
|
||||
|
||||
class D(A):
|
||||
def f(self):
|
||||
return 'D.f'
|
||||
|
||||
d = D()
|
||||
|
||||
self.failUnlessEqual ('D.f', d.f())
|
||||
self.failUnlessEqual ('D.f', call_f(d))
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# remove the option which upsets unittest
|
||||
import sys
|
||||
sys.argv = [ x for x in sys.argv if x != '--broken-auto-ptr' ]
|
||||
|
||||
unittest.main()
|
||||
@@ -1,12 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/converter/arg_to_python.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::python::converter::arg_to_python<PyTypeObject*> x(0);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/converter/arg_to_python.hpp>
|
||||
|
||||
struct X : PyObject {};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::python::converter::arg_to_python<X*> x(0);
|
||||
return 0;
|
||||
}
|
||||
112
test/result.cpp
112
test/result.cpp
@@ -1,112 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/detail/result.hpp>
|
||||
#include <boost/type.hpp>
|
||||
#include <functional>
|
||||
|
||||
using boost::python::detail::result;
|
||||
using boost::type;
|
||||
|
||||
void expect_int(type<int>*) {}
|
||||
void expect_string(type<char*>*) {}
|
||||
|
||||
struct X {};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Test the usage which works for functions, member functions, and data members
|
||||
expect_int(
|
||||
result((int(*)())0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(*)(char))0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*)())0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*)(char))0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*))0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(*)())0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(*)(char))0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*)())0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*)(char))0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*))0)
|
||||
);
|
||||
|
||||
// Show that we can use the general version that works for
|
||||
// AdaptableFunctions
|
||||
expect_int(
|
||||
result((int(*)())0,0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(*)(char))0,0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*)())0,0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*)(char))0,0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result((int(X::*))0,0)
|
||||
);
|
||||
|
||||
expect_int(
|
||||
result(std::plus<int>(),0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(*)())0,0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(*)(char))0,0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*)())0,0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*)(char))0,0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result((char*(X::*))0,0)
|
||||
);
|
||||
|
||||
expect_string(
|
||||
result(std::plus<char*>(),0)
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#include <boost/python/converter/arg_to_python.hpp>
|
||||
#include <boost/python/type_id.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// gcc 2.95.x and MIPSpro 7.3.1.3 linker seem to demand this definition
|
||||
#if ((defined(__GNUC__) && __GNUC__ < 3)) \
|
||||
|| (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238))
|
||||
namespace boost { namespace python {
|
||||
BOOST_PYTHON_DECL bool handle_exception_impl(function0<void>)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}}
|
||||
#endif
|
||||
|
||||
int result;
|
||||
|
||||
#define ASSERT_SAME(T1,T2) \
|
||||
if (!is_same< T1, T2 >::value) { \
|
||||
std::cout << "*********************\n"; \
|
||||
std::cout << python::type_id< T1 >() << " != " << python::type_id< T2 >() << "\n"; \
|
||||
std::cout << "*********************\n"; \
|
||||
result = 1; \
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::python::converter::detail;
|
||||
using namespace boost::python::converter;
|
||||
using namespace boost::python;
|
||||
using namespace boost;
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_to_python<int>::type, value_arg_to_python<int>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_to_python<reference_wrapper<int> >::type, reference_arg_to_python<int>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_to_python<pointer_wrapper<int> >::type, pointer_shallow_arg_to_python<int>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_to_python<int*>::type, pointer_deep_arg_to_python<int*>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_to_python<handle<> >::type, object_manager_arg_to_python<handle<> >
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_to_python<object>::type, object_manager_arg_to_python<object>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_to_python<char[20]>::type, arg_to_python<char const*>
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
#include <boost/python/converter/arg_from_python.hpp>
|
||||
#include <boost/python/type_id.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// gcc 2.95.x and MIPSpro 7.3.1.3 linker seem to demand this definition
|
||||
#if ((defined(__GNUC__) && __GNUC__ < 3)) \
|
||||
|| (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238))
|
||||
namespace boost { namespace python {
|
||||
BOOST_PYTHON_DECL bool handle_exception_impl(function0<void>)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}}
|
||||
#endif
|
||||
|
||||
int result;
|
||||
|
||||
#define ASSERT_SAME(T1,T2) \
|
||||
if (!is_same< T1, T2 >::value) { \
|
||||
std::cout << "*********************\n"; \
|
||||
std::cout << python::type_id< T1 >() << " != " << python::type_id< T2 >() << "\n"; \
|
||||
std::cout << "*********************\n"; \
|
||||
result = 1; \
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::python::converter;
|
||||
using namespace boost;
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int>::type, arg_rvalue_from_python<int>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const>::type, arg_rvalue_from_python<int const>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile>::type, arg_rvalue_from_python<int volatile>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile>::type, arg_rvalue_from_python<int const volatile>
|
||||
);
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int*>::type, pointer_arg_from_python<int*>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const*>::type, pointer_arg_from_python<int const*>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile*>::type, pointer_arg_from_python<int volatile*>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile*>::type, pointer_arg_from_python<int const volatile*>
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int&>::type, reference_arg_from_python<int&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const&>::type, arg_rvalue_from_python<int const&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile&>::type, reference_arg_from_python<int volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile&>::type, reference_arg_from_python<int const volatile&>
|
||||
);
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int*&>::type, reference_arg_from_python<int*&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const*&>::type, reference_arg_from_python<int const*&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile*&>::type, reference_arg_from_python<int volatile*&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile*&>::type, reference_arg_from_python<int const volatile*&>
|
||||
);
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int* const&>::type, pointer_cref_arg_from_python<int*const&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const* const&>::type, pointer_cref_arg_from_python<int const*const&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile* const&>::type, pointer_cref_arg_from_python<int volatile*const&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile* const&>::type, pointer_cref_arg_from_python<int const volatile*const&>
|
||||
);
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int*volatile&>::type, reference_arg_from_python<int*volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const*volatile&>::type, reference_arg_from_python<int const*volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile*volatile&>::type, reference_arg_from_python<int volatile*volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile*volatile&>::type, reference_arg_from_python<int const volatile*volatile&>
|
||||
);
|
||||
|
||||
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int*const volatile&>::type, reference_arg_from_python<int*const volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const*const volatile&>::type, reference_arg_from_python<int const*const volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int volatile*const volatile&>::type, reference_arg_from_python<int volatile*const volatile&>
|
||||
);
|
||||
|
||||
ASSERT_SAME(
|
||||
select_arg_from_python<int const volatile*const volatile&>::type, reference_arg_from_python<int const volatile*const volatile&>
|
||||
);
|
||||
return result;
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
#include <boost/python/object/select_holder.hpp>
|
||||
#include <boost/python/has_back_reference.hpp>
|
||||
#include <boost/python/detail/not_specified.hpp>
|
||||
#include <boost/function/function0.hpp>
|
||||
#include <memory>
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
struct BR {};
|
||||
|
||||
struct Base {};
|
||||
struct Derived : Base {};
|
||||
|
||||
namespace boost { namespace python
|
||||
{
|
||||
// specialization
|
||||
template <>
|
||||
struct has_back_reference<BR>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
}} // namespace boost::python
|
||||
|
||||
template <class T, class U>
|
||||
void assert_same(U* = 0, T* = 0)
|
||||
{
|
||||
BOOST_TEST((boost::is_same<T,U>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<T,U>::value));
|
||||
|
||||
}
|
||||
|
||||
template <class T, class Held, class Holder>
|
||||
void assert_holder(T* = 0, Held* = 0, Holder* = 0)
|
||||
{
|
||||
assert_same<Holder>(
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
boost::python::objects::select_holder<T,Held>::execute((Held*)0).get()
|
||||
#else
|
||||
boost::python::objects::select_holder<T,Held>::type::get()
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
int test_main(int, char * [])
|
||||
{
|
||||
using namespace boost::python::detail;
|
||||
using namespace boost::python::objects;
|
||||
|
||||
assert_holder<Base,not_specified,value_holder<Base> >();
|
||||
|
||||
assert_holder<BR,not_specified,value_holder_back_reference<BR,BR> >();
|
||||
assert_holder<Base,Base,value_holder<Base> >();
|
||||
assert_holder<BR,BR,value_holder_back_reference<BR,BR> >();
|
||||
|
||||
assert_holder<Base,Derived
|
||||
,value_holder_back_reference<Base,Derived> >();
|
||||
|
||||
assert_holder<Base,std::auto_ptr<Base>
|
||||
,pointer_holder<std::auto_ptr<Base>,Base> >();
|
||||
|
||||
assert_holder<Base,std::auto_ptr<Derived>
|
||||
,pointer_holder_back_reference<std::auto_ptr<Derived>,Base> >();
|
||||
|
||||
assert_holder<BR,std::auto_ptr<BR>
|
||||
,pointer_holder_back_reference<std::auto_ptr<BR>,BR> > ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) || defined(__GNUC__)
|
||||
// This definition is needed for MinGW 2.95.2 and KCC on OSF for some
|
||||
// reason, but will break other Win32 compilers.
|
||||
namespace boost { namespace python
|
||||
{
|
||||
bool handle_exception_impl(boost::function0<void>) { return false; }
|
||||
}}
|
||||
#endif
|
||||
@@ -1,137 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/call_method.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include "test_class.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace boost::python;
|
||||
using boost::shared_ptr;
|
||||
|
||||
typedef test_class<> X;
|
||||
typedef test_class<1> Y;
|
||||
|
||||
template <class T>
|
||||
struct functions
|
||||
{
|
||||
static int look(shared_ptr<T> const& x)
|
||||
{
|
||||
return (x.get()) ? x->value() : -1;
|
||||
}
|
||||
|
||||
static void store(shared_ptr<T> x)
|
||||
{
|
||||
storage = x;
|
||||
}
|
||||
|
||||
static void release_store()
|
||||
{
|
||||
store(shared_ptr<T>());
|
||||
}
|
||||
|
||||
static void modify(shared_ptr<T>& x)
|
||||
{
|
||||
x.reset();
|
||||
}
|
||||
|
||||
static shared_ptr<T> get() { return storage; }
|
||||
|
||||
static int look_store()
|
||||
{
|
||||
return look(get());
|
||||
}
|
||||
|
||||
static void expose()
|
||||
{
|
||||
def("look", &look);
|
||||
def("store", &store);
|
||||
def("modify", &modify);
|
||||
def("look_store", &look_store);
|
||||
}
|
||||
|
||||
static shared_ptr<T> storage;
|
||||
};
|
||||
|
||||
template <class T> shared_ptr<T> functions<T>::storage;
|
||||
|
||||
struct Z : test_class<2>
|
||||
{
|
||||
Z(int x) : test_class<2>(x) {}
|
||||
virtual int v() { return this->value(); }
|
||||
};
|
||||
|
||||
struct ZWrap : Z
|
||||
{
|
||||
ZWrap(PyObject* self, int x)
|
||||
: Z(x), m_self(self) {}
|
||||
|
||||
|
||||
virtual int v() { return call_method<int>(m_self, "v"); }
|
||||
int default_v() { return Z::v(); }
|
||||
|
||||
|
||||
PyObject* m_self;
|
||||
};
|
||||
|
||||
struct YY : Y
|
||||
{
|
||||
YY(int n) : Y(n) {}
|
||||
};
|
||||
|
||||
shared_ptr<Y> factory(int n)
|
||||
{
|
||||
return shared_ptr<Y>(n < 42 ? new Y(n) : new YY(n));
|
||||
}
|
||||
|
||||
static int stored_v() { return functions<Z>::get()->v(); }
|
||||
static shared_ptr<Z> stored_z() { return functions<Z>::get(); }
|
||||
|
||||
BOOST_PYTHON_MODULE(shared_ptr_ext)
|
||||
{
|
||||
class_<X, boost::noncopyable>("X", init<int>())
|
||||
.def("value", &X::value)
|
||||
;
|
||||
|
||||
def("factory", factory);
|
||||
|
||||
functions<X>::expose();
|
||||
def("x_count", &X::count);
|
||||
def("x_release", &functions<X>::release_store);
|
||||
def("x_look_store", &functions<X>::look_store);
|
||||
|
||||
class_<Y, boost::shared_ptr<Y> >("Y", init<int>())
|
||||
.def("value", &Y::value)
|
||||
;
|
||||
|
||||
class_<YY, bases<Y>, boost::noncopyable>("YY", init<int>())
|
||||
;
|
||||
|
||||
functions<Y>::expose();
|
||||
def("y_count", &Y::count);
|
||||
def("y_release", &functions<Y>::release_store);
|
||||
def("y_look_store", &functions<Y>::look_store);
|
||||
|
||||
class_<Z, ZWrap>("Z", init<int>())
|
||||
.def("value", &Z::value)
|
||||
.def("v", &Z::v, &ZWrap::default_v)
|
||||
;
|
||||
|
||||
functions<Z>::expose();
|
||||
def("z_count", &Z::count);
|
||||
def("z_release", &functions<Z>::release_store);
|
||||
def("z_look_store", &functions<Z>::look_store);
|
||||
def("stored_z", &stored_z);
|
||||
def("stored_v", &stored_v);
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
'''
|
||||
>>> from shared_ptr_ext import *
|
||||
|
||||
>>> type(factory(3))
|
||||
<class 'shared_ptr_ext.Y'>
|
||||
>>> type(factory(42))
|
||||
<class 'shared_ptr_ext.YY'>
|
||||
|
||||
>>> class P(Z):
|
||||
... def v(self):
|
||||
... return -Z.v(self);
|
||||
... def __del__(self):
|
||||
... print 'bye'
|
||||
...
|
||||
>>> p = P(12)
|
||||
>>> p.value()
|
||||
12
|
||||
>>> p.v()
|
||||
-12
|
||||
>>> look(p)
|
||||
12
|
||||
>>> try: modify(p)
|
||||
... except TypeError: pass
|
||||
... else: 'print expected a TypeError'
|
||||
>>> look(None)
|
||||
-1
|
||||
>>> store(p)
|
||||
>>> del p
|
||||
>>> stored_v()
|
||||
-12
|
||||
>>> z_count()
|
||||
1
|
||||
>>> z_look_store()
|
||||
12
|
||||
>>> z_release()
|
||||
bye
|
||||
>>> z_count()
|
||||
0
|
||||
|
||||
>>> z = Z(13)
|
||||
>>> z.value()
|
||||
13
|
||||
>>> z.v()
|
||||
13
|
||||
>>> try: modify(z)
|
||||
... except TypeError: pass
|
||||
... else: 'print expected a TypeError'
|
||||
>>> store(z)
|
||||
>>> assert stored_z() is z # show that deleter introspection works
|
||||
>>> del z
|
||||
>>> stored_v()
|
||||
13
|
||||
>>> z_count()
|
||||
1
|
||||
>>> z_look_store()
|
||||
13
|
||||
>>> z_release()
|
||||
>>> z_count()
|
||||
0
|
||||
|
||||
>>> x = X(17)
|
||||
>>> x.value()
|
||||
17
|
||||
>>> look(x)
|
||||
17
|
||||
>>> try: modify(x)
|
||||
... except TypeError: pass
|
||||
... else: 'print expected a TypeError'
|
||||
>>> look(None)
|
||||
-1
|
||||
>>> store(x)
|
||||
>>> del x
|
||||
>>> x_count()
|
||||
1
|
||||
>>> x_look_store()
|
||||
17
|
||||
>>> x_release()
|
||||
>>> x_count()
|
||||
0
|
||||
|
||||
|
||||
>>> y = Y(19)
|
||||
>>> y.value()
|
||||
19
|
||||
>>> modify(y)
|
||||
>>> look(y)
|
||||
-1
|
||||
>>> store(Y(23))
|
||||
>>> y_count()
|
||||
1
|
||||
>>> y_look_store()
|
||||
23
|
||||
>>> y_release()
|
||||
>>> y_count()
|
||||
0
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,14 +0,0 @@
|
||||
// Copyright David Abrahams 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef SIMPLE_TYPE_DWA2001128_HPP
|
||||
# define SIMPLE_TYPE_DWA2001128_HPP
|
||||
|
||||
struct simple
|
||||
{
|
||||
char* s;
|
||||
};
|
||||
|
||||
#endif // SIMPLE_TYPE_DWA2001128_HPP
|
||||
@@ -1,46 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/call_method.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
struct X
|
||||
{
|
||||
explicit X(int x) : x(x), magic(7654321) { ++counter; }
|
||||
X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
|
||||
virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int x) { assert(magic == 7654321); this->x = x; }
|
||||
int value() const { assert(magic == 7654321); return x; }
|
||||
static int count() { return counter; }
|
||||
private:
|
||||
void operator=(X const&);
|
||||
private:
|
||||
int x;
|
||||
long magic;
|
||||
static int counter;
|
||||
};
|
||||
int X::counter;
|
||||
int getXmagic(){return 7654321;}
|
||||
|
||||
BOOST_PYTHON_MODULE(staticmethod_ext)
|
||||
{
|
||||
class_<X>("X", init<int>())
|
||||
.def("value", &X::value)
|
||||
.def("set", &X::set)
|
||||
.def("count", &X::count)
|
||||
.staticmethod("count")
|
||||
.def("magic", &getXmagic)
|
||||
.staticmethod("magic")
|
||||
;
|
||||
}
|
||||
|
||||
#include "module_tail.cpp"
|
||||
@@ -1,52 +0,0 @@
|
||||
'''
|
||||
>>> from staticmethod_ext import *
|
||||
|
||||
>>> class X1(X):
|
||||
... pass
|
||||
|
||||
|
||||
>>> x = X(16)
|
||||
>>> x1 = X1(17)
|
||||
|
||||
|
||||
|
||||
>>> x1.count()
|
||||
2
|
||||
|
||||
>>> x.count()
|
||||
2
|
||||
|
||||
>>> X1.count()
|
||||
2
|
||||
|
||||
>>> X.count()
|
||||
2
|
||||
|
||||
|
||||
>>> x1.magic()
|
||||
7654321
|
||||
|
||||
>>> x.magic()
|
||||
7654321
|
||||
|
||||
>>> X1.magic()
|
||||
7654321
|
||||
|
||||
>>> X.magic()
|
||||
7654321
|
||||
|
||||
|
||||
'''
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
67
test/str.cpp
67
test/str.cpp
@@ -1,67 +0,0 @@
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/str.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
object convert_to_string(object data)
|
||||
{
|
||||
return str(data);
|
||||
}
|
||||
|
||||
void work_with_string(object print)
|
||||
{
|
||||
str data("this is a demo string");
|
||||
print(data.split(" "));
|
||||
print(data.split(" ",3));
|
||||
print(str("<->").join(data.split(" ")));
|
||||
print(data.capitalize());
|
||||
print('[' + data.center(30) + ']');
|
||||
print(data.count("t"));
|
||||
print(data.encode("utf-8"));
|
||||
print(data.decode("utf-8"));
|
||||
print(data.endswith("xx"));
|
||||
print(data.startswith("test"));
|
||||
print(data.splitlines());
|
||||
print(data.strip());
|
||||
print(data.swapcase());
|
||||
print(data.title());
|
||||
|
||||
print("find");
|
||||
print(data.find("demo"));
|
||||
print(data.find("demo"),3,5);
|
||||
print(data.find(std::string("demo")));
|
||||
print(data.find(std::string("demo"),9));
|
||||
|
||||
print("expandtabs");
|
||||
str tabstr("\t\ttab\tdemo\t!");
|
||||
print(tabstr.expandtabs());
|
||||
print(tabstr.expandtabs(4));
|
||||
print(tabstr.expandtabs(7.9));
|
||||
|
||||
print("operators");
|
||||
print( str("part1") + str("part2") );
|
||||
// print( str("a test string").slice(3,_) );
|
||||
// print( str("another test")[5] );
|
||||
|
||||
print(data.replace("demo",std::string("blabla")));
|
||||
print(data.rfind("i",5));
|
||||
print(data.rindex("i",5));
|
||||
print(data.startswith("asdf"));
|
||||
print(data.endswith("asdf"));
|
||||
print(data.translate(str('a')*256));
|
||||
|
||||
|
||||
bool tmp = data.isalnum() || data.isalpha() || data.isdigit() || data.islower() ||
|
||||
data.isspace() || data.istitle() || data.isupper();
|
||||
(void)tmp; // ignored.
|
||||
}
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(str_ext)
|
||||
{
|
||||
def("convert_to_string",convert_to_string);
|
||||
def("work_with_string",work_with_string);
|
||||
}
|
||||
|
||||
52
test/str.py
52
test/str.py
@@ -1,52 +0,0 @@
|
||||
"""
|
||||
>>> from str_ext import *
|
||||
>>> def printer(*args):
|
||||
... for x in args: print x,
|
||||
... print
|
||||
...
|
||||
>>> work_with_string(printer)
|
||||
['this', 'is', 'a', 'demo', 'string']
|
||||
['this', 'is', 'a', 'demo string']
|
||||
this<->is<->a<->demo<->string
|
||||
This is a demo string
|
||||
[ this is a demo string ]
|
||||
2
|
||||
this is a demo string
|
||||
this is a demo string
|
||||
0
|
||||
0
|
||||
['this is a demo string']
|
||||
this is a demo string
|
||||
THIS IS A DEMO STRING
|
||||
This Is A Demo String
|
||||
find
|
||||
10
|
||||
10 3 5
|
||||
10
|
||||
10
|
||||
expandtabs
|
||||
tab demo !
|
||||
tab demo !
|
||||
tab demo !
|
||||
operators
|
||||
part1part2
|
||||
this is a blabla string
|
||||
18
|
||||
18
|
||||
0
|
||||
0
|
||||
aaaaaaaaaaaaaaaaaaaaa
|
||||
"""
|
||||
|
||||
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
|
||||
sys.exit(run()[0])
|
||||
@@ -1,38 +0,0 @@
|
||||
//#include <stdio.h>
|
||||
#include <cassert>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/python/detail/string_literal.hpp>
|
||||
|
||||
using namespace boost::python::detail;
|
||||
|
||||
|
||||
template <class T>
|
||||
void expect_string_literal(T const&)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(is_string_literal<T const>::value);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
expect_string_literal("hello");
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<int*&>::value);
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<int* const&>::value);
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<int*volatile&>::value);
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<int*const volatile&>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<char const*>::value);
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<char*>::value);
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<char*&>::value);
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<char* const&>::value);
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<char*volatile&>::value);
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<char*const volatile&>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<char[20]>::value);
|
||||
BOOST_STATIC_ASSERT(is_string_literal<char const[20]>::value);
|
||||
BOOST_STATIC_ASSERT(is_string_literal<char const[3]>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<int[20]>::value);
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<int const[20]>::value);
|
||||
BOOST_STATIC_ASSERT(!is_string_literal<int const[3]>::value);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
// Copyright David Hawkes 2002.
|
||||
// Permission is hereby granted to copy, use and modify this software
|
||||
// for any purpose, including commercial distribution, provided this
|
||||
// copyright notice is not removed. No warranty WHATSOEVER is provided with this
|
||||
// software. Any user(s) accepts this software "as is" and as such they will not
|
||||
// bind the author(s) to any claim of suitabilty for any purpose.
|
||||
|
||||
// embed_test.cpp : substantial test of embedding python in c++ using boost
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/call_method.hpp>
|
||||
#include <boost/python/call.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/py_interface.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::python;
|
||||
|
||||
|
||||
// The following macros are for our convenience and coding expediency...
|
||||
// There is no particular recomendation that they be used elsewhere
|
||||
// as they are not feature complete and are just sufficient to suport
|
||||
// the code here
|
||||
|
||||
|
||||
#define DEF(fn) def(#fn, fn)
|
||||
#define DEF_C(c, fn) def(#fn, &c::fn)
|
||||
#define DEF_C_CB(c, fn) def(#fn, &c##_callback::base_##fn)
|
||||
|
||||
#define CLASS(c) class_<c, shared_ptr<c> >(#c)
|
||||
#define CLASS_CB(c) class_<c, shared_ptr<c##_callback>, noncopyable >(#c)
|
||||
|
||||
#define START_CALLBACK_CLASS(c) \
|
||||
class c##_callback : public c \
|
||||
{ \
|
||||
typedef c __base__; \
|
||||
public: \
|
||||
c##_callback(PyObject* self) : m_self(self) {} \
|
||||
private: \
|
||||
PyObject* m_self; \
|
||||
public:
|
||||
|
||||
#define END_CALLBACK_CLASS };
|
||||
|
||||
|
||||
#define CALLBACK_MEMBER0(fn, rtn) \
|
||||
rtn fn() { return call_method<rtn>(m_self, #fn); } \
|
||||
rtn base_##fn() { return __base__::fn(); }
|
||||
|
||||
|
||||
#define CALLBACK_MEMBER0C(fn, rtn) \
|
||||
rtn fn() const { return call_method<rtn>(m_self, #fn); } \
|
||||
rtn base_##fn() const { return __base__::fn(); }
|
||||
// End of convenience macros
|
||||
|
||||
// useful support classes
|
||||
template<class T>
|
||||
struct class_object : public object
|
||||
{
|
||||
typedef object base;
|
||||
class_object() : m_class_ptr(NULL) {}
|
||||
class_object(object const& o) : base(o) { init(); }
|
||||
class_object& operator=(object const& o)
|
||||
{
|
||||
base::operator=(o);
|
||||
init();
|
||||
return *this;
|
||||
}
|
||||
T* operator->() const { return m_class_ptr; }
|
||||
T& operator*() const { return *m_class_ptr; }
|
||||
private:
|
||||
void init()
|
||||
{
|
||||
m_class_ptr = arg_from_python<T*>(ptr())(ptr());
|
||||
}
|
||||
T* m_class_ptr;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct item_object : public object
|
||||
{
|
||||
typedef object base;
|
||||
item_object() {}
|
||||
item_object(object const& o) : base(o), m_class(arg_from_python<T>(ptr())(ptr())) {}
|
||||
item_object& operator=(object const& o)
|
||||
{
|
||||
base::operator=(o);
|
||||
init();
|
||||
return *this;
|
||||
}
|
||||
operator T() { return m_class; }
|
||||
private:
|
||||
void init()
|
||||
{
|
||||
m_class = arg_from_python<T>(ptr())(ptr());
|
||||
}
|
||||
T m_class;
|
||||
};
|
||||
// end of useful support classes
|
||||
|
||||
// pass our args in this struct
|
||||
struct main_args {
|
||||
main_args(int _argc, char* _argv[]) : argc(_argc), argv(_argv) {}
|
||||
int argc;
|
||||
char** argv;
|
||||
};
|
||||
int python_main(main_args const &ma);
|
||||
|
||||
// python module init
|
||||
BOOST_PYTHON_MODULE(python_main)
|
||||
{
|
||||
DEF(python_main);
|
||||
CLASS(main_args);
|
||||
}
|
||||
|
||||
// sub module tests
|
||||
namespace sm {
|
||||
|
||||
int test_func() { return 7; }
|
||||
|
||||
BOOST_PYTHON_MODULE(sm_test)
|
||||
{
|
||||
// define a submodule
|
||||
boost::python::module(".sm");
|
||||
// define a 2nd submodule
|
||||
boost::python::module(".sm.sm2");
|
||||
// define a test function to appear in 2nd submodule
|
||||
DEF(test_func);
|
||||
}
|
||||
|
||||
// sub-module tests
|
||||
int test()
|
||||
{
|
||||
api::run_simple_string("import sm_test");
|
||||
if(api::call_statement("_0 = bpl_test('sub modules', sm_test.sm.sm2.test_func, _1)", test_func()))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// sub class tests
|
||||
namespace sc {
|
||||
|
||||
class c1 {
|
||||
public:
|
||||
c1() {}
|
||||
class c2 {
|
||||
public:
|
||||
c2() : n(2) {}
|
||||
int n;
|
||||
};
|
||||
c2 t;
|
||||
};
|
||||
|
||||
c1::c2 test_func() {
|
||||
return c1().t;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(sc_test)
|
||||
{
|
||||
class_<c1::c2>("c1.c2")
|
||||
.def_init()
|
||||
.def_readwrite("n", &c1::c2::n);
|
||||
CLASS(c1)
|
||||
.def_init()
|
||||
.def_readwrite("t", &c1::t);
|
||||
DEF(test_func);
|
||||
}
|
||||
|
||||
// sub-class tests
|
||||
int test()
|
||||
{
|
||||
api::run_simple_string("import sc_test");
|
||||
if(api::call_statement("_0 = bpl_test('sub classes', lambda : sc_test.c1.c2().n, _1.n)", test_func()))
|
||||
return 1;
|
||||
if(api::call_statement("_0 = bpl_test('sub classes', lambda : sc_test.c1().t.n, _1.n)", test_func()))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// new main that will have a python execution frame
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// default return value;
|
||||
int rtn = 0;
|
||||
// define all the built-in modules used
|
||||
PyImport_AppendInittab("python_main", initpython_main);
|
||||
PyImport_AppendInittab("sm_test", sm::initsm_test);
|
||||
PyImport_AppendInittab("sc_test", sc::initsc_test);
|
||||
// initialize python
|
||||
Py_Initialize();
|
||||
// start a new block so that any objects are released prior to finalizing
|
||||
{
|
||||
// import our main module - this will also initialise boost
|
||||
api::run_simple_string("import python_main");
|
||||
// We call back here so we have a proper python execution frame to work with
|
||||
item_object<int> o_rtn(api::call_statement("_0 = python_main.python_main(_1)", main_args(argc, argv)));
|
||||
rtn = o_rtn;
|
||||
}
|
||||
// clean up
|
||||
Py_Finalize();
|
||||
return rtn;
|
||||
}
|
||||
|
||||
char *bpl_test =
|
||||
"def bpl_test(name, func, result):\n"
|
||||
" print 'testing %s...' % name\n"
|
||||
" if func() != result:\n"
|
||||
" print 'failed'\n"
|
||||
" return 1\n"
|
||||
" else:\n"
|
||||
" print 'OK'\n"
|
||||
" return 0\n";
|
||||
|
||||
|
||||
int python_main(main_args const &ma)
|
||||
{
|
||||
api::print("running...\n");
|
||||
api::call_statement(bpl_test);
|
||||
if(sm::test())
|
||||
return 1;
|
||||
if(sc::test())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#include <string>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <complex>
|
||||
#include <boost/python/handle.hpp>
|
||||
#include <boost/python/cast.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
template <class T>
|
||||
struct by_value
|
||||
{
|
||||
static T rewrap(T x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct by_const_reference
|
||||
{
|
||||
static T rewrap(T const& x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct by_reference
|
||||
{
|
||||
static T rewrap(T& x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
using boost::python::def;
|
||||
using boost::python::handle;
|
||||
using boost::python::object;
|
||||
using boost::python::borrowed;
|
||||
|
||||
// Used to test that arbitrary handle<>s can be returned
|
||||
handle<PyTypeObject> get_type(handle<> x)
|
||||
{
|
||||
return handle<PyTypeObject>(borrowed(x->ob_type));
|
||||
}
|
||||
|
||||
handle<> return_null_handle()
|
||||
{
|
||||
return handle<>();
|
||||
}
|
||||
|
||||
char const* rewrap_value_mutable_cstring(char* x) { return x; }
|
||||
|
||||
BOOST_PYTHON_MODULE(builtin_converters)
|
||||
{
|
||||
def("get_type", get_type);
|
||||
def("return_null_handle", return_null_handle);
|
||||
|
||||
def("rewrap_value_bool", by_value<bool>::rewrap);
|
||||
def("rewrap_value_char", by_value<char>::rewrap);
|
||||
def("rewrap_value_signed_char", by_value<signed char>::rewrap);
|
||||
def("rewrap_value_unsigned_char", by_value<unsigned char>::rewrap);
|
||||
def("rewrap_value_int", by_value<int>::rewrap);
|
||||
def("rewrap_value_unsigned_int", by_value<unsigned int>::rewrap);
|
||||
def("rewrap_value_short", by_value<short>::rewrap);
|
||||
def("rewrap_value_unsigned_short", by_value<unsigned short>::rewrap);
|
||||
def("rewrap_value_long", by_value<long>::rewrap);
|
||||
def("rewrap_value_unsigned_long", by_value<unsigned long>::rewrap);
|
||||
// using Python's macro instead of Boost's - we don't seem to get the
|
||||
// config right all the time.
|
||||
#ifdef HAVE_LONG_LONG
|
||||
def("rewrap_value_long_long", by_value<LONG_LONG>::rewrap);
|
||||
def("rewrap_value_unsigned_long_long", by_value<unsigned LONG_LONG>::rewrap);
|
||||
# endif
|
||||
def("rewrap_value_float", by_value<float>::rewrap);
|
||||
def("rewrap_value_double", by_value<double>::rewrap);
|
||||
def("rewrap_value_long_double", by_value<long double>::rewrap);
|
||||
def("rewrap_value_complex_float", by_value<std::complex<float> >::rewrap);
|
||||
def("rewrap_value_complex_double", by_value<std::complex<double> >::rewrap);
|
||||
def("rewrap_value_complex_long_double", by_value<std::complex<long double> >::rewrap);
|
||||
def("rewrap_value_string", by_value<std::string>::rewrap);
|
||||
def("rewrap_value_cstring", by_value<char const*>::rewrap);
|
||||
def("rewrap_value_handle", by_value<handle<> >::rewrap);
|
||||
def("rewrap_value_object", by_value<object>::rewrap);
|
||||
|
||||
// Expose this to illustrate our failings ;-). See test_builtin_converters.py
|
||||
def("rewrap_value_mutable_cstring", rewrap_value_mutable_cstring);
|
||||
|
||||
|
||||
def("rewrap_const_reference_bool", by_const_reference<bool>::rewrap);
|
||||
def("rewrap_const_reference_char", by_const_reference<char>::rewrap);
|
||||
def("rewrap_const_reference_signed_char", by_const_reference<signed char>::rewrap);
|
||||
def("rewrap_const_reference_unsigned_char", by_const_reference<unsigned char>::rewrap);
|
||||
def("rewrap_const_reference_int", by_const_reference<int>::rewrap);
|
||||
def("rewrap_const_reference_unsigned_int", by_const_reference<unsigned int>::rewrap);
|
||||
def("rewrap_const_reference_short", by_const_reference<short>::rewrap);
|
||||
def("rewrap_const_reference_unsigned_short", by_const_reference<unsigned short>::rewrap);
|
||||
def("rewrap_const_reference_long", by_const_reference<long>::rewrap);
|
||||
def("rewrap_const_reference_unsigned_long", by_const_reference<unsigned long>::rewrap);
|
||||
// using Python's macro instead of Boost's - we don't seem to get the
|
||||
// config right all the time.
|
||||
# ifdef HAVE_LONG_LONG
|
||||
def("rewrap_const_reference_long_long", by_const_reference<LONG_LONG>::rewrap);
|
||||
def("rewrap_const_reference_unsigned_long_long", by_const_reference<unsigned LONG_LONG>::rewrap);
|
||||
# endif
|
||||
def("rewrap_const_reference_float", by_const_reference<float>::rewrap);
|
||||
def("rewrap_const_reference_double", by_const_reference<double>::rewrap);
|
||||
def("rewrap_const_reference_long_double", by_const_reference<long double>::rewrap);
|
||||
def("rewrap_const_reference_complex_float", by_const_reference<std::complex<float> >::rewrap);
|
||||
def("rewrap_const_reference_complex_double", by_const_reference<std::complex<double> >::rewrap);
|
||||
def("rewrap_const_reference_complex_long_double", by_const_reference<std::complex<long double> >::rewrap);
|
||||
def("rewrap_const_reference_string", by_const_reference<std::string>::rewrap);
|
||||
def("rewrap_const_reference_cstring", by_const_reference<char const*>::rewrap);
|
||||
def("rewrap_const_reference_handle", by_const_reference<handle<> >::rewrap);
|
||||
def("rewrap_const_reference_object", by_const_reference<object>::rewrap);
|
||||
def("rewrap_reference_object", by_reference<object>::rewrap);
|
||||
}
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
r"""
|
||||
>>> from builtin_converters import *
|
||||
|
||||
# Synthesize idendity functions in case long long not supported
|
||||
>>> if not 'rewrap_value_long_long' in dir():
|
||||
... def rewrap_value_long_long(x): return long(x)
|
||||
... def rewrap_value_unsigned_long_long(x): return long(x)
|
||||
... def rewrap_const_reference_long_long(x): return long(x)
|
||||
... def rewrap_const_reference_unsigned_long_long(x): return long(x)
|
||||
|
||||
>>> rewrap_value_bool(None)
|
||||
0
|
||||
>>> rewrap_value_bool(0)
|
||||
0
|
||||
>>> rewrap_value_bool(33)
|
||||
1
|
||||
>>> rewrap_value_char('x')
|
||||
'x'
|
||||
|
||||
Note that there's currently silent truncation of strings passed to
|
||||
char arguments.
|
||||
|
||||
>>> rewrap_value_char('xy')
|
||||
'x'
|
||||
>>> rewrap_value_signed_char(42)
|
||||
42
|
||||
>>> rewrap_value_unsigned_char(42)
|
||||
42
|
||||
>>> rewrap_value_int(42)
|
||||
42
|
||||
>>> rewrap_value_unsigned_int(42)
|
||||
42
|
||||
>>> rewrap_value_short(42)
|
||||
42
|
||||
>>> rewrap_value_unsigned_short(42)
|
||||
42
|
||||
>>> rewrap_value_long(42)
|
||||
42
|
||||
>>> rewrap_value_unsigned_long(42)
|
||||
42
|
||||
|
||||
test unsigned long values which don't fit in a signed long.
|
||||
strip any 'L' characters in case the platform has > 32 bit longs
|
||||
|
||||
>>> hex(rewrap_value_unsigned_long(0x80000001L)).replace('L','')
|
||||
'0x80000001'
|
||||
|
||||
>>> rewrap_value_long_long(42)
|
||||
42L
|
||||
>>> rewrap_value_unsigned_long_long(42)
|
||||
42L
|
||||
|
||||
show that we have range checking.
|
||||
|
||||
>>> try: rewrap_value_unsigned_short(-42)
|
||||
... except OverflowError: pass
|
||||
... else: print 'expected an OverflowError!'
|
||||
|
||||
>>> try: rewrap_value_int(sys.maxint * 2)
|
||||
... except OverflowError: pass
|
||||
... else: print 'expected an OverflowError!'
|
||||
|
||||
|
||||
>>> assert abs(rewrap_value_float(4.2) - 4.2) < .000001
|
||||
>>> rewrap_value_double(4.2) - 4.2
|
||||
0.0
|
||||
>>> rewrap_value_long_double(4.2) - 4.2
|
||||
0.0
|
||||
|
||||
>>> assert abs(rewrap_value_complex_float(4+.2j) - (4+.2j)) < .000001
|
||||
>>> assert abs(rewrap_value_complex_double(4+.2j) - (4+.2j)) < .000001
|
||||
>>> assert abs(rewrap_value_complex_long_double(4+.2j) - (4+.2j)) < .000001
|
||||
|
||||
>>> rewrap_value_cstring('hello, world')
|
||||
'hello, world'
|
||||
>>> rewrap_value_string('yo, wassup?')
|
||||
'yo, wassup?'
|
||||
|
||||
wrap strings with embedded nulls:
|
||||
|
||||
>>> rewrap_value_string('yo,\0wassup?')
|
||||
'yo,\x00wassup?'
|
||||
|
||||
>>> rewrap_value_handle(1)
|
||||
1
|
||||
>>> x = 'hi'
|
||||
>>> assert rewrap_value_handle(x) is x
|
||||
>>> assert rewrap_value_object(x) is x
|
||||
|
||||
Note that we can currently get a mutable pointer into an immutable
|
||||
Python string:
|
||||
|
||||
>>> rewrap_value_mutable_cstring('hello, world')
|
||||
'hello, world'
|
||||
|
||||
>>> rewrap_const_reference_bool(None)
|
||||
0
|
||||
>>> rewrap_const_reference_bool(0)
|
||||
0
|
||||
|
||||
>>> try: rewrap_const_reference_bool('yes')
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError exception'
|
||||
|
||||
>>> rewrap_const_reference_char('x')
|
||||
'x'
|
||||
|
||||
Note that there's currently silent truncation of strings passed to
|
||||
char arguments.
|
||||
|
||||
>>> rewrap_const_reference_char('xy')
|
||||
'x'
|
||||
>>> rewrap_const_reference_signed_char(42)
|
||||
42
|
||||
>>> rewrap_const_reference_unsigned_char(42)
|
||||
42
|
||||
>>> rewrap_const_reference_int(42)
|
||||
42
|
||||
>>> rewrap_const_reference_unsigned_int(42)
|
||||
42
|
||||
>>> rewrap_const_reference_short(42)
|
||||
42
|
||||
>>> rewrap_const_reference_unsigned_short(42)
|
||||
42
|
||||
>>> rewrap_const_reference_long(42)
|
||||
42
|
||||
>>> rewrap_const_reference_unsigned_long(42)
|
||||
42
|
||||
>>> rewrap_const_reference_long_long(42)
|
||||
42L
|
||||
>>> rewrap_const_reference_unsigned_long_long(42)
|
||||
42L
|
||||
|
||||
|
||||
>>> assert abs(rewrap_const_reference_float(4.2) - 4.2) < .000001
|
||||
>>> rewrap_const_reference_double(4.2) - 4.2
|
||||
0.0
|
||||
>>> rewrap_const_reference_long_double(4.2) - 4.2
|
||||
0.0
|
||||
|
||||
>>> assert abs(rewrap_const_reference_complex_float(4+.2j) - (4+.2j)) < .000001
|
||||
>>> assert abs(rewrap_const_reference_complex_double(4+.2j) - (4+.2j)) < .000001
|
||||
>>> assert abs(rewrap_const_reference_complex_long_double(4+.2j) - (4+.2j)) < .000001
|
||||
|
||||
>>> rewrap_const_reference_cstring('hello, world')
|
||||
'hello, world'
|
||||
>>> rewrap_const_reference_string('yo, wassup?')
|
||||
'yo, wassup?'
|
||||
|
||||
>>> rewrap_const_reference_handle(1)
|
||||
1
|
||||
>>> x = 'hi'
|
||||
>>> assert rewrap_const_reference_handle(x) is x
|
||||
>>> assert rewrap_const_reference_object(x) is x
|
||||
>>> assert rewrap_reference_object(x) is x
|
||||
|
||||
|
||||
Check that None <==> NULL
|
||||
|
||||
>>> rewrap_const_reference_cstring(None)
|
||||
|
||||
But None cannot be converted to a string object:
|
||||
|
||||
>>> try: rewrap_const_reference_string(None)
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError exception'
|
||||
|
||||
Now check implicit conversions between floating/integer types
|
||||
|
||||
>>> rewrap_const_reference_float(42)
|
||||
42.0
|
||||
|
||||
>>> rewrap_const_reference_float(42L)
|
||||
42.0
|
||||
|
||||
>>> try: rewrap_const_reference_int(42.0)
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError exception'
|
||||
|
||||
>>> rewrap_value_float(42)
|
||||
42.0
|
||||
|
||||
>>> try: rewrap_value_int(42.0)
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError exception'
|
||||
|
||||
Check that classic classes also work
|
||||
|
||||
>>> class FortyTwo:
|
||||
... def __int__(self):
|
||||
... return 42
|
||||
... def __float__(self):
|
||||
... return 42.0
|
||||
... def __complex__(self):
|
||||
... return complex(4+.2j)
|
||||
... def __str__(self):
|
||||
... return '42'
|
||||
|
||||
>>> try: rewrap_const_reference_float(FortyTwo())
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError exception'
|
||||
|
||||
>>> try: rewrap_value_int(FortyTwo())
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError exception'
|
||||
|
||||
>>> try: rewrap_const_reference_string(FortyTwo())
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError exception'
|
||||
|
||||
>>> try: rewrap_value_complex_double(FortyTwo())
|
||||
... except TypeError: pass
|
||||
... else: print 'expected a TypeError exception'
|
||||
|
||||
# show that arbitrary handle<T> instantiations can be returned
|
||||
>>> assert get_type(1) is type(1)
|
||||
|
||||
>>> assert return_null_handle() is None
|
||||
"""
|
||||
|
||||
def run(args = None):
|
||||
import sys
|
||||
import doctest
|
||||
import builtin_converters
|
||||
|
||||
if 'rewrap_value_long_long' in dir(builtin_converters):
|
||||
print 'LONG_LONG supported, testing...'
|
||||
else:
|
||||
print 'LONG_LONG not supported, skipping those tests...'
|
||||
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
return doctest.testmod(sys.modules.get(__name__))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "running..."
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright David Abrahams 2002. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
#ifndef TEST_CLASS_DWA2002326_HPP
|
||||
# define TEST_CLASS_DWA2002326_HPP
|
||||
# include <cassert>
|
||||
|
||||
template <int n = 0>
|
||||
struct test_class
|
||||
{
|
||||
explicit test_class(int x) : x(x), magic(7654321 + n) { ++counter; }
|
||||
test_class(test_class const& rhs) : x(rhs.x), magic(7654321 + n) { ++counter; }
|
||||
virtual ~test_class() { assert(magic == 7654321 + n); magic = 6666666; x = 9999; --counter; }
|
||||
|
||||
void set(int x) { assert(magic == 7654321 + n); this->x = x; }
|
||||
int value() const { assert(magic == 7654321 + n); return x; }
|
||||
operator int() const { return x; }
|
||||
static int count() { return counter; }
|
||||
|
||||
int x;
|
||||
long magic;
|
||||
static int counter;
|
||||
|
||||
private:
|
||||
void operator=(test_class const&);
|
||||
};
|
||||
|
||||
template <int n>
|
||||
int test_class<n>::counter;
|
||||
|
||||
#endif // TEST_CLASS_DWA2002326_HPP
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user