Skip to content

Commit c8e8ccf

Browse files
committed
New-style polymorphism
[SVN r24083]
1 parent 597342b commit c8e8ccf

24 files changed

+954
-291
lines changed

build/Jamfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ if [ check-python-config ]
5353
object/iterator.cpp
5454
object_protocol.cpp
5555
object_operators.cpp
56+
wrapper.cpp
5657
;
5758

5859
dll boost_python

include/boost/python/base_type_traits.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ struct base_type_traits<PyTypeObject>
3232
typedef PyObject type;
3333
};
3434

35+
template <>
36+
struct base_type_traits<PyMethodObject>
37+
{
38+
typedef PyObject type;
39+
};
40+
3541
}} // namespace boost::python
3642

3743
#endif // BASE_TYPE_TRAITS_DWA2002614_HPP

include/boost/python/class.hpp

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
# include <boost/python/detail/operator_id.hpp>
3030
# include <boost/python/detail/def_helper.hpp>
3131
# include <boost/python/detail/force_instantiate.hpp>
32+
# include <boost/python/detail/unwrap_type_id.hpp>
33+
# include <boost/python/detail/unwrap_wrapper.hpp>
3234

3335
# include <boost/type_traits/is_same.hpp>
3436
# include <boost/type_traits/is_member_function_pointer.hpp>
@@ -151,7 +153,7 @@ namespace detail
151153
// This is the primary mechanism through which users will expose
152154
// C++ classes to Python.
153155
template <
154-
class T // class being wrapped
156+
class W // class being wrapped
155157
, class X1 // = detail::not_specified
156158
, class X2 // = detail::not_specified
157159
, class X3 // = detail::not_specified
@@ -160,9 +162,9 @@ class class_ : public objects::class_base
160162
{
161163
public: // types
162164
typedef objects::class_base base;
163-
typedef class_<T,X1,X2,X3> self;
164-
typedef typename objects::class_metadata<T,X1,X2,X3> metadata;
165-
typedef T wrapped_type;
165+
typedef class_<W,X1,X2,X3> self;
166+
typedef typename objects::class_metadata<W,X1,X2,X3> metadata;
167+
typedef W wrapped_type;
166168

167169
private: // types
168170

@@ -175,7 +177,7 @@ class class_ : public objects::class_base
175177
id_vector()
176178
{
177179
// Stick the derived class id into the first element of the array
178-
ids[0] = type_id<T>();
180+
ids[0] = detail::unwrap_type_id((W*)0, (W*)0);
179181

180182
// Write the rest of the elements into succeeding positions.
181183
type_info* p = ids + 1;
@@ -231,7 +233,9 @@ class class_ : public objects::class_base
231233
template <class F>
232234
self& def(char const* name, F f)
233235
{
234-
this->def_impl(name, f, detail::def_helper<char const*>(0), &f);
236+
this->def_impl(
237+
detail::unwrap_wrapper((W*)0)
238+
, name, f, detail::def_helper<char const*>(0), &f);
235239
return *this;
236240
}
237241

@@ -250,9 +254,10 @@ class class_ : public objects::class_base
250254
// def(name, function, doc_string, policy)
251255

252256
this->def_impl(
253-
name, fn
254-
, detail::def_helper<A1,A2>(a1,a2)
255-
, &fn);
257+
detail::unwrap_wrapper((W*)0)
258+
, name, fn
259+
, detail::def_helper<A1,A2>(a1,a2)
260+
, &fn);
256261

257262
return *this;
258263
}
@@ -261,9 +266,10 @@ class class_ : public objects::class_base
261266
self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3)
262267
{
263268
this->def_impl(
264-
name, fn
265-
, detail::def_helper<A1,A2,A3>(a1,a2,a3)
266-
, &fn);
269+
detail::unwrap_wrapper((W*)0)
270+
, name, fn
271+
, detail::def_helper<A1,A2,A3>(a1,a2,a3)
272+
, &fn);
267273

268274
return *this;
269275
}
@@ -371,7 +377,8 @@ class class_ : public objects::class_base
371377
typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
372378

373379
return this->make_fn_impl(
374-
f, is_obj_or_proxy(), (char*)0, detail::is_data_member_pointer<F>()
380+
detail::unwrap_wrapper((W*)0)
381+
, f, is_obj_or_proxy(), (char*)0, detail::is_data_member_pointer<F>()
375382
);
376383
}
377384

@@ -381,32 +388,33 @@ class class_ : public objects::class_base
381388
typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
382389

383390
return this->make_fn_impl(
384-
f, is_obj_or_proxy(), (int*)0, detail::is_data_member_pointer<F>()
391+
detail::unwrap_wrapper((W*)0)
392+
, f, is_obj_or_proxy(), (int*)0, detail::is_data_member_pointer<F>()
385393
);
386394
}
387395

388-
template <class F>
389-
object make_fn_impl(F const& f, mpl::false_, void*, mpl::false_)
396+
template <class T, class F>
397+
object make_fn_impl(T*, F const& f, mpl::false_, void*, mpl::false_)
390398
{
391399
return python::make_function(f, default_call_policies(), detail::get_signature(f, (T*)0));
392400
}
393401

394-
template <class D, class B>
395-
object make_fn_impl(D B::*pm_, mpl::false_, char*, mpl::true_)
402+
template <class T, class D, class B>
403+
object make_fn_impl(T*, D B::*pm_, mpl::false_, char*, mpl::true_)
396404
{
397405
D T::*pm = pm_;
398406
return python::make_getter(pm);
399407
}
400408

401-
template <class D, class B>
402-
object make_fn_impl(D B::*pm_, mpl::false_, int*, mpl::true_)
409+
template <class T, class D, class B>
410+
object make_fn_impl(T*, D B::*pm_, mpl::false_, int*, mpl::true_)
403411
{
404412
D T::*pm = pm_;
405413
return python::make_setter(pm);
406414
}
407415

408-
template <class F>
409-
object make_fn_impl(F const& x, mpl::true_, void*, mpl::false_)
416+
template <class T, class F>
417+
object make_fn_impl(T*, F const& x, mpl::true_, void*, mpl::false_)
410418
{
411419
return x;
412420
}
@@ -462,9 +470,10 @@ class class_ : public objects::class_base
462470
// generic visitor and everything else.
463471
//
464472
// @group def_impl {
465-
template <class Helper, class LeafVisitor, class Visitor>
473+
template <class T, class Helper, class LeafVisitor, class Visitor>
466474
inline void def_impl(
467-
char const* name
475+
T*
476+
, char const* name
468477
, LeafVisitor
469478
, Helper const& helper
470479
, def_visitor<Visitor> const* v
@@ -473,9 +482,10 @@ class class_ : public objects::class_base
473482
v->visit(*this, name, helper);
474483
}
475484

476-
template <class Fn, class Helper>
485+
template <class T, class Fn, class Helper>
477486
inline void def_impl(
478-
char const* name
487+
T*
488+
, char const* name
479489
, Fn fn
480490
, Helper const& helper
481491
, ...
@@ -510,7 +520,7 @@ class class_ : public objects::class_base
510520
, Helper const& helper
511521
, mpl::bool_<true>)
512522
{
513-
detail::error::virtual_function_default<T,Fn>::must_be_derived_class_member(
523+
detail::error::virtual_function_default<W,Fn>::must_be_derived_class_member(
514524
helper.default_implementation());
515525

516526
objects::add_to_namespace(
@@ -554,7 +564,8 @@ class class_ : public objects::class_base
554564
, ...)
555565
{
556566
this->def_impl(
557-
name
567+
detail::unwrap_wrapper((W*)0)
568+
, name
558569
, fn
559570
, detail::def_helper<A1>(a1)
560571
, &fn
@@ -569,23 +580,23 @@ class class_ : public objects::class_base
569580
// implementations
570581
//
571582

572-
template <class T, class X1, class X2, class X3>
573-
inline class_<T,X1,X2,X3>::class_(char const* name, char const* doc)
583+
template <class W, class X1, class X2, class X3>
584+
inline class_<W,X1,X2,X3>::class_(char const* name, char const* doc)
574585
: base(name, id_vector::size, id_vector().ids, doc)
575586
{
576587
this->initialize(init<>());
577588
// select_holder::assert_default_constructible();
578589
}
579590

580-
template <class T, class X1, class X2, class X3>
581-
inline class_<T,X1,X2,X3>::class_(char const* name, no_init_t)
591+
template <class W, class X1, class X2, class X3>
592+
inline class_<W,X1,X2,X3>::class_(char const* name, no_init_t)
582593
: base(name, id_vector::size, id_vector().ids)
583594
{
584595
this->initialize(no_init);
585596
}
586597

587-
template <class T, class X1, class X2, class X3>
588-
inline class_<T,X1,X2,X3>::class_(char const* name, char const* doc, no_init_t)
598+
template <class W, class X1, class X2, class X3>
599+
inline class_<W,X1,X2,X3>::class_(char const* name, char const* doc, no_init_t)
589600
: base(name, id_vector::size, id_vector().ids, doc)
590601
{
591602
this->initialize(no_init);

include/boost/python/converter/return_from_python.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
# include <boost/python/converter/rvalue_from_python_data.hpp>
1010
# include <boost/python/converter/registered.hpp>
1111
# include <boost/python/converter/registered_pointee.hpp>
12+
# include <boost/python/converter/object_manager.hpp>
1213
# include <boost/python/detail/void_ptr.hpp>
1314
# include <boost/python/detail/void_return.hpp>
1415
# include <boost/python/errors.hpp>
16+
# include <boost/python/handle.hpp>
1517
# include <boost/type_traits/has_trivial_copy.hpp>
1618
# include <boost/mpl/and.hpp>
1719
# include <boost/mpl/bool.hpp>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright David Abrahams 2004. Distributed under the Boost
2+
// Software License, Version 1.0. (See accompanying
3+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4+
#ifndef ENABLE_IF_DWA2004722_HPP
5+
# define ENABLE_IF_DWA2004722_HPP
6+
7+
# include <boost/python/detail/sfinae.hpp>
8+
# include <boost/detail/workaround.hpp>
9+
10+
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
11+
# include <boost/mpl/if.hpp>
12+
13+
namespace boost { namespace python { namespace detail {
14+
15+
template <class C, class T = int>
16+
struct enable_if_arg
17+
{
18+
typedef typename mpl::if_<C,T,int&>::type type;
19+
};
20+
21+
template <class C, class T = int>
22+
struct disable_if_arg
23+
{
24+
typedef typename mpl::if_<C,int&,T>::type type;
25+
};
26+
27+
template <class C, class T>
28+
struct enable_if_ret
29+
{
30+
typedef typename mpl::if_<C,T,int[2]>::type type;
31+
};
32+
33+
template <class C, class T>
34+
struct disable_if_ret
35+
{
36+
typedef typename mpl::if_<C,int[2],T>::type type;
37+
};
38+
39+
}}} // namespace boost::python::detail
40+
41+
# elif !defined(BOOST_NO_SFINAE)
42+
# include <boost/utility/enable_if.hpp>
43+
44+
namespace boost { namespace python { namespace detail {
45+
46+
template <class C, class T>
47+
struct enable_if_arg
48+
: enable_if<C,T>
49+
{};
50+
51+
template <class C, class T>
52+
struct disable_if_arg
53+
: disable_if<C,T>
54+
{};
55+
56+
template <class C, class T>
57+
struct enable_if_ret
58+
: enable_if<C,T>
59+
{};
60+
61+
template <class C, class T>
62+
struct disable_if_ret
63+
: disable_if<C,T>
64+
{};
65+
66+
}}} // namespace boost::python::detail
67+
68+
# endif
69+
70+
#endif // ENABLE_IF_DWA2004722_HPP
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright David Abrahams 2004. Distributed under the Boost
2+
// Software License, Version 1.0. (See accompanying
3+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4+
#ifndef IS_WRAPPER_DWA2004723_HPP
5+
# define IS_WRAPPER_DWA2004723_HPP
6+
7+
# include <boost/python/detail/prefix.hpp>
8+
# include <boost/mpl/bool.hpp>
9+
10+
namespace boost { namespace python {
11+
12+
template <class T> class wrapper;
13+
14+
namespace detail
15+
{
16+
typedef char (&is_not_wrapper)[2];
17+
is_not_wrapper is_wrapper_helper(...);
18+
template <class T>
19+
char is_wrapper_helper(wrapper<T> const volatile*);
20+
21+
// A metafunction returning true iff T is [derived from] wrapper<U>
22+
template <class T>
23+
struct is_wrapper
24+
: mpl::bool_<(sizeof(detail::is_wrapper_helper((T*)0)) == 1)>
25+
{};
26+
27+
}}} // namespace boost::python::detail
28+
29+
#endif // IS_WRAPPER_DWA2004723_HPP
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright David Abrahams 2004. Distributed under the Boost
2+
// Software License, Version 1.0. (See accompanying
3+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4+
#ifndef SFINAE_DWA2004723_HPP
5+
# define SFINAE_DWA2004723_HPP
6+
7+
# include <boost/python/detail/prefix.hpp>
8+
9+
# if defined(BOOST_NO_SFINAE) && !defined(BOOST_MSVC)
10+
# define BOOST_PYTHON_NO_SFINAE
11+
# endif
12+
13+
#endif // SFINAE_DWA2004723_HPP

0 commit comments

Comments
 (0)