18
18
NAMESPACE_BEGIN (pybind11)
19
19
NAMESPACE_BEGIN(detail)
20
20
21
- #if defined(_MSC_VER)
22
- #define NOINLINE __declspec (noinline)
23
- #else
24
- #define NOINLINE __attribute__ ((noinline))
25
- #endif
26
-
27
21
#if PY_MAJOR_VERSION >= 3
28
22
#define PYBIND11_AS_STRING PyBytes_AsString
29
23
#else
@@ -44,35 +38,35 @@ class descr {
44
38
45
39
descr () { }
46
40
descr (descr &&d) : first(d.first), last(d.last) { d.first = d.last = nullptr ; }
47
- NOINLINE descr (const char *str) { first = last = new entry { str }; }
48
- NOINLINE descr (const std::type_info &type) { first = last = new entry { &type }; }
41
+ PYBIND11_NOINLINE descr (const char *str) { first = last = new entry { str }; }
42
+ PYBIND11_NOINLINE descr (const std::type_info &type) { first = last = new entry { &type }; }
49
43
50
- NOINLINE void operator +(const char *str) {
44
+ PYBIND11_NOINLINE void operator +(const char *str) {
51
45
entry *next = new entry { str };
52
46
last->next = next;
53
47
last = next;
54
48
}
55
49
56
- NOINLINE void operator +(const std::type_info *type) {
50
+ PYBIND11_NOINLINE void operator +(const std::type_info *type) {
57
51
entry *next = new entry { type };
58
52
last->next = next;
59
53
last = next;
60
54
}
61
55
62
- NOINLINE void operator +=(descr &&other) {
56
+ PYBIND11_NOINLINE void operator +=(descr &&other) {
63
57
last->next = other.first ;
64
58
while (last->next )
65
59
last = last->next ;
66
60
other.first = other.last = nullptr ;
67
61
}
68
62
69
- NOINLINE friend descr operator +(descr &&l, descr &&r) {
63
+ PYBIND11_NOINLINE friend descr operator +(descr &&l, descr &&r) {
70
64
descr result (std::move (l));
71
65
result += std::move (r);
72
66
return result;
73
67
}
74
68
75
- NOINLINE std::string str () const {
69
+ PYBIND11_NOINLINE std::string str () const {
76
70
std::string result;
77
71
auto const & registered_types = get_internals ().registered_types ;
78
72
for (entry *it = first; it != nullptr ; it = it->next ) {
@@ -92,7 +86,7 @@ class descr {
92
86
return result;
93
87
}
94
88
95
- NOINLINE ~descr () {
89
+ PYBIND11_NOINLINE ~descr () {
96
90
while (first) {
97
91
entry *tmp = first->next ;
98
92
delete first;
@@ -104,27 +98,20 @@ class descr {
104
98
entry *last = nullptr ;
105
99
};
106
100
107
- #undef NOINLINE
108
-
109
- // / Generic type caster for objects stored on the heap
110
- template <typename type> class type_caster {
101
+ class type_caster_custom {
111
102
public:
112
- typedef instance<type> instance_type;
113
-
114
- static descr name () { return typeid (type); }
115
-
116
- type_caster () {
103
+ PYBIND11_NOINLINE type_caster_custom (const std::type_info *type_info) {
117
104
auto const & registered_types = get_internals ().registered_types ;
118
- auto it = registered_types.find (& typeid (type) );
105
+ auto it = registered_types.find (type_info );
119
106
if (it != registered_types.end ())
120
107
typeinfo = &it->second ;
121
108
}
122
109
123
- bool load (PyObject *src, bool convert) {
110
+ PYBIND11_NOINLINE bool load (PyObject *src, bool convert) {
124
111
if (src == nullptr || typeinfo == nullptr )
125
112
return false ;
126
113
if (PyType_IsSubtype (Py_TYPE (src), typeinfo->type )) {
127
- value = ((instance_type *) src)->value ;
114
+ value = ((instance< void > *) src)->value ;
128
115
return true ;
129
116
}
130
117
if (convert) {
@@ -137,14 +124,9 @@ template <typename type> class type_caster {
137
124
return false ;
138
125
}
139
126
140
- static PyObject *cast (const type &src, return_value_policy policy, PyObject *parent) {
141
- if (policy == return_value_policy::automatic)
142
- policy = return_value_policy::copy;
143
- return cast (&src, policy, parent);
144
- }
145
-
146
- static PyObject *cast (const type *_src, return_value_policy policy, PyObject *parent) {
147
- type *src = const_cast <type *>(_src);
127
+ PYBIND11_NOINLINE static PyObject *cast (const void *_src, return_value_policy policy, PyObject *parent,
128
+ const std::type_info *type_info, void *(*copy_constructor)(const void *)) {
129
+ void *src = const_cast <void *>(_src);
148
130
if (src == nullptr ) {
149
131
Py_INCREF (Py_None);
150
132
return Py_None;
@@ -159,61 +141,72 @@ template <typename type> class type_caster {
159
141
Py_INCREF (inst);
160
142
return inst;
161
143
}
162
- auto it = internals.registered_types .find (& typeid (type) );
144
+ auto it = internals.registered_types .find (type_info );
163
145
if (it == internals.registered_types .end ()) {
164
- std::string msg = std::string (" Unregistered type : " ) + type_id<type>();
146
+ std::string msg = std::string (" Unregistered type : " ) + type_info->name ();
147
+ detail::clean_type_id (msg);
165
148
PyErr_SetString (PyExc_TypeError, msg.c_str ());
166
149
return nullptr ;
167
150
}
168
- auto &type_info = it->second ;
169
- instance_type *inst = (instance_type *) PyType_GenericAlloc (type_info .type , 0 );
151
+ auto ®_type = it->second ;
152
+ instance< void > *inst = (instance< void > *) PyType_GenericAlloc (reg_type .type , 0 );
170
153
inst->value = src;
171
154
inst->owned = true ;
172
155
inst->parent = nullptr ;
173
156
if (policy == return_value_policy::automatic)
174
157
policy = return_value_policy::take_ownership;
175
- handle_return_value_policy<type>(inst, policy, parent);
176
- PyObject *inst_pyobj = (PyObject *) inst;
177
- type_info.init_holder (inst_pyobj);
178
- if (!dont_cache)
179
- internals.registered_instances [inst->value ] = inst_pyobj;
180
- return inst_pyobj;
181
- }
182
-
183
- template <class T , typename std::enable_if<std::is_copy_constructible<T>::value, int >::type = 0 >
184
- static void handle_return_value_policy (instance<T> *inst, return_value_policy policy, PyObject *parent) {
185
- if (policy == return_value_policy::copy) {
186
- inst->value = new T (*(inst->value ));
187
- } else if (policy == return_value_policy::reference) {
188
- inst->owned = false ;
189
- } else if (policy == return_value_policy::reference_internal) {
190
- inst->owned = false ;
191
- inst->parent = parent;
192
- Py_XINCREF (parent);
193
- }
194
- }
195
-
196
- template <class T , typename std::enable_if<!std::is_copy_constructible<T>::value, int >::type = 0 >
197
- static void handle_return_value_policy (instance<T> *inst, return_value_policy policy, PyObject *parent) {
198
158
if (policy == return_value_policy::copy) {
199
- throw cast_error (" return_value_policy = copy, but the object is non-copyable!" );
159
+ inst->value = copy_constructor (inst->value );
160
+ if (inst->value == nullptr )
161
+ throw cast_error (" return_value_policy = copy, but the object is non-copyable!" );
200
162
} else if (policy == return_value_policy::reference) {
201
163
inst->owned = false ;
202
164
} else if (policy == return_value_policy::reference_internal) {
203
165
inst->owned = false ;
204
166
inst->parent = parent;
205
167
Py_XINCREF (parent);
206
168
}
169
+ PyObject *inst_pyobj = (PyObject *) inst;
170
+ reg_type.init_holder (inst_pyobj);
171
+ if (!dont_cache)
172
+ internals.registered_instances [inst->value ] = inst_pyobj;
173
+ return inst_pyobj;
207
174
}
208
175
209
- operator type*() { return value; }
210
- operator type&() { return *value; }
211
176
protected:
212
- type *value = nullptr ;
213
177
const type_info *typeinfo = nullptr ;
178
+ void *value = nullptr ;
214
179
object temp;
215
180
};
216
181
182
+ // / Generic type caster for objects stored on the heap
183
+ template <typename type> class type_caster : public type_caster_custom {
184
+ public:
185
+ static descr name () { return typeid (type); }
186
+
187
+ type_caster () : type_caster_custom(&typeid (type)) { }
188
+
189
+ static PyObject *cast (const type &src, return_value_policy policy, PyObject *parent) {
190
+ if (policy == return_value_policy::automatic)
191
+ policy = return_value_policy::copy;
192
+ return type_caster_custom::cast (&src, policy, parent, &typeid (type), ©_constructor);
193
+ }
194
+
195
+ static PyObject *cast (const type *src, return_value_policy policy, PyObject *parent) {
196
+ return type_caster_custom::cast (src, policy, parent, &typeid (type), ©_constructor);
197
+ }
198
+
199
+ operator type*() { return (type *) value; }
200
+ operator type&() { return (type &) *value; }
201
+ protected:
202
+ template <typename T = type, typename std::enable_if<std::is_copy_constructible<T>::value, int >::type = 0 >
203
+ static void *copy_constructor (const void *arg) {
204
+ return new type ((const type &)*arg);
205
+ }
206
+ template <typename T = type, typename std::enable_if<!std::is_copy_constructible<T>::value, int >::type = 0 >
207
+ static void *copy_constructor (const void *) { return nullptr ; }
208
+ };
209
+
217
210
#define PYBIND11_TYPE_CASTER (type, py_name ) \
218
211
protected: \
219
212
type value; \
@@ -516,7 +509,7 @@ template <typename type, typename holder_type> class type_caster_holder : public
516
509
bool load (PyObject *src, bool convert) {
517
510
if (!parent::load (src, convert))
518
511
return false ;
519
- holder = holder_type (parent::value);
512
+ holder = holder_type ((type *) parent::value);
520
513
return true ;
521
514
}
522
515
explicit operator type*() { return this ->value ; }
0 commit comments