Skip to content

Commit 7d35ed4

Browse files
committed
Move converter registration from body of individual Holder classes to
select_holder implementation, which prevents Holder instantiation in case the class being wrapped is abstract. [SVN r15138]
1 parent ec3cc6a commit 7d35ed4

File tree

5 files changed

+69
-51
lines changed

5 files changed

+69
-51
lines changed

include/boost/python/class.hpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,19 @@ namespace detail
5252
// type of the first (tag) argument. The 2nd argument is a pointer
5353
// to the type of holder that must be created. The 3rd argument is a
5454
// reference to the Python type object to be created.
55-
template <class T, class Holder>
56-
static inline void register_copy_constructor(mpl::bool_t<true> const&, Holder*, T* = 0)
55+
template <class T, class SelectHolder>
56+
static inline void register_copy_constructor(mpl::bool_t<true> const&, SelectHolder const& , T* = 0)
5757
{
58-
force_instantiate(objects::class_wrapper<T,Holder>());
59-
Holder::register_();
58+
typedef typename SelectHolder::type holder;
59+
force_instantiate(objects::class_wrapper<T,holder>());
60+
SelectHolder::register_();
6061
}
6162

6263
// Tag dispatched to have no effect.
63-
template <class T, class Holder>
64-
static inline void register_copy_constructor(mpl::bool_t<false> const&, Holder*, T* = 0)
64+
template <class T, class SelectHolder>
65+
static inline void register_copy_constructor(mpl::bool_t<false> const&, SelectHolder const&, T* = 0)
6566
{
66-
Holder::register_();
67+
SelectHolder::register_();
6768
}
6869

6970
template <class T> int assert_default_constructible(T const&);
@@ -340,7 +341,7 @@ inline void class_<T,X1,X2,X3>::register_() const
340341

341342
detail::register_copy_constructor<T>(
342343
mpl::bool_t<is_copyable>()
343-
, objects::select_holder<T,held_type>((held_type*)0).get()
344+
, objects::select_holder<T,held_type>((held_type*)0)
344345
);
345346
}
346347

include/boost/python/instance_holder.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,10 @@ struct BOOST_PYTHON_DECL instance_holder : private noncopyable
2525

2626
void install(PyObject* inst) throw();
2727

28-
// Register any converters associated with this Holder
29-
static inline void register_() {}
30-
3128
private:
3229
instance_holder* m_next;
3330
};
31+
3432
// This macro is needed for implementation of derived holders
3533
# define BOOST_PYTHON_UNFORWARD(N,ignored) (typename unforward<A##N>::type)(a##N)
3634

include/boost/python/object/pointer_holder.hpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,12 @@ struct pointer_holder : instance_holder
3939

4040
pointer_holder(Pointer);
4141

42-
static void register_();
43-
4442
// Forward construction to the held object
4543

4644
# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/object/pointer_holder.hpp>, 1))
4745
# include BOOST_PP_ITERATE()
4846

4947
private: // types
50-
struct construct_from_pointer
51-
{
52-
static pointer_holder* execute(PyObject*, Pointer x)
53-
{
54-
return new pointer_holder(x);
55-
}
56-
};
5748

5849
private: // required holder implementation
5950
void* holds(type_info);
@@ -74,8 +65,6 @@ struct pointer_holder_back_reference : instance_holder
7465
// undoubtedly does not carry the correct back reference pointer.
7566
pointer_holder_back_reference(Pointer);
7667

77-
static void register_();
78-
7968
// Forward construction to the held object
8069
# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/object/pointer_holder.hpp>, 2))
8170
# include BOOST_PP_ITERATE()
@@ -95,29 +84,12 @@ inline pointer_holder<Pointer,Value>::pointer_holder(Pointer p)
9584
{
9685
}
9786

98-
template <class Pointer, class Value>
99-
inline void pointer_holder<Pointer,Value>::register_()
100-
{
101-
python::detail::force_instantiate(class_wrapper<Pointer,pointer_holder,construct_from_pointer>());
102-
python::detail::force_instantiate(instance_finder<Pointer>::registration);
103-
}
104-
105-
10687
template <class Pointer, class Value>
10788
inline pointer_holder_back_reference<Pointer,Value>::pointer_holder_back_reference(Pointer p)
10889
: m_p(p)
10990
{
11091
}
11192

112-
template <class Pointer, class Value>
113-
inline void pointer_holder_back_reference<Pointer,Value>::register_()
114-
{
115-
// not implemented at least until we solve the back reference issue mentioned above.
116-
// python::detail::force_instantiate(class_wrapper<Pointer,pointer_holder_back_reference>());
117-
python::detail::force_instantiate(instance_finder<Pointer>::registration);
118-
python::detail::force_instantiate(instance_finder<held_type>::registration);
119-
}
120-
12193
template <class Pointer, class Value>
12294
void* pointer_holder<Pointer, Value>::holds(type_info dst_t)
12395
{

include/boost/python/object/select_holder.hpp

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
# include <boost/python/pointee.hpp>
1212
# include <boost/python/object/value_holder.hpp>
1313
# include <boost/python/object/pointer_holder.hpp>
14+
# include <boost/python/object/find_instance.hpp>
1415
# include <boost/type.hpp>
1516
# include <boost/mpl/select_type.hpp>
1617
# include <boost/type_traits/same_traits.hpp>
18+
# include <boost/mpl/bool_t.hpp>
1719

1820
namespace boost { namespace python { namespace objects {
1921

@@ -28,9 +30,24 @@ namespace detail
2830
selector
2931
, value_holder_back_reference<T,Held>
3032
, value_holder<T>
31-
>::type holder;
33+
>::type type;
3234

33-
static holder* get() { return 0; }
35+
static inline void register_()
36+
{
37+
select_value_holder::register_(mpl::bool_t<selector>());
38+
}
39+
40+
static type* get() { return 0; }
41+
42+
private:
43+
static inline void register_(mpl::bool_t<true>)
44+
{
45+
python::detail::force_instantiate(instance_finder<Held>::registration);
46+
}
47+
48+
static inline void register_(mpl::bool_t<false>)
49+
{
50+
}
3451
};
3552

3653
template <class T,class Ptr>
@@ -43,9 +60,47 @@ namespace detail
4360
selector
4461
, pointer_holder_back_reference<Ptr,T>
4562
, pointer_holder<Ptr,T>
46-
>::type holder;
63+
>::type type;
64+
65+
static inline void register_()
66+
{
67+
select_pointer_holder::register_(mpl::bool_t<selector>());
68+
}
69+
70+
static type* get() { return 0; }
71+
72+
private:
73+
static inline void register_(mpl::bool_t<true>)
74+
{
75+
// not implemented at least until we solve the back
76+
// reference issue mentioned in pointer_holder.hpp.
77+
//
78+
// python::detail::force_instantiate(
79+
// class_wrapper<Pointer,pointer_holder_back_reference<Pointer,Value> >());
80+
81+
python::detail::force_instantiate(instance_finder<Ptr>::registration);
82+
python::detail::force_instantiate(instance_finder<pointee>::registration);
83+
}
84+
85+
struct construct_from_pointer
86+
{
87+
static type* execute(PyObject*, Ptr x)
88+
{
89+
return new type(x);
90+
}
91+
};
4792

48-
static holder* get() { return 0; }
93+
static inline void register_(mpl::bool_t<false>)
94+
{
95+
python::detail::force_instantiate(
96+
objects::class_wrapper<
97+
Ptr
98+
, type
99+
, construct_from_pointer>());
100+
101+
python::detail::force_instantiate(
102+
instance_finder<Ptr>::registration);
103+
}
49104
};
50105
}
51106

include/boost/python/object/value_holder.hpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ struct value_holder_back_reference : instance_holder
4747
{
4848
typedef Held value_type;
4949

50-
static void register_();
51-
5250
// Forward construction to the held object
5351
# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/object/value_holder.hpp>, 2))
5452
# include BOOST_PP_ITERATE()
@@ -85,12 +83,6 @@ void* value_holder_back_reference<Held,BackReferenceType>::holds(
8583
return find_static_type(x, src_t, dst_t);
8684
}
8785

88-
template <class Held, class BackReferenceType>
89-
void value_holder_back_reference<Held,BackReferenceType>::register_()
90-
{
91-
python::detail::force_instantiate(instance_finder<BackReferenceType>::registration);
92-
}
93-
9486
}}} // namespace boost::python::objects
9587

9688
# endif // VALUE_HOLDER_DWA20011215_HPP

0 commit comments

Comments
 (0)