14 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
15 PYBIND11_NAMESPACE_BEGIN(detail)
20 bool load(
handle h,
bool) {
21 value =
reinterpret_cast<value_and_holder *
>(h.
ptr());
25 template <
typename>
using cast_op_type = value_and_holder &;
26 operator value_and_holder &() {
return *value; }
27 static constexpr
auto name = _<value_and_holder>();
30 value_and_holder *value =
nullptr;
33 PYBIND11_NAMESPACE_BEGIN(initimpl)
35 inline
void no_nullptr(
void *ptr) {
36 if (!ptr)
throw type_error(
"pybind11::init(): factory function returned nullptr");
40 template <
typename Class>
using Cpp =
typename Class::type;
41 template <
typename Class>
using Alias =
typename Class::type_alias;
42 template <
typename Class>
using Holder =
typename Class::holder_type;
44 template <
typename Class>
using is_alias_constructible = std::is_constructible<Alias<Class>, Cpp<Class> &&>;
47 template <
typename Class, enable_if_t<Class::has_alias,
int> = 0>
48 bool is_alias(Cpp<Class> *ptr) {
49 return dynamic_cast<Alias<Class> *
>(ptr) !=
nullptr;
53 constexpr
bool is_alias(
void *) {
return false; }
60 template <
typename Class,
typename... Args, detail::enable_if_t<std::is_constructible<Class, Args...>::value,
int> = 0>
61 inline Class *construct_or_initialize(Args &&...
args) {
return new Class(std::forward<Args>(
args)...); }
62 template <
typename Class,
typename... Args, detail::enable_if_t<!std::is_constructible<Class, Args...>::value,
int> = 0>
63 inline Class *construct_or_initialize(Args &&...
args) {
return new Class{std::forward<Args>(
args)...}; }
70 template <
typename Class>
71 void construct_alias_from_cpp(std::true_type ,
73 v_h.value_ptr() =
new Alias<Class>(std::move(
base));
75 template <
typename Class>
76 [[noreturn]]
void construct_alias_from_cpp(std::false_type ,
78 throw type_error(
"pybind11::init(): unable to convert returned instance to required "
79 "alias class: no `Alias<Class>(Class &&)` constructor available");
84 template <
typename Class>
86 static_assert(!std::is_same<Class, Class>::value ,
87 "pybind11::init(): init function must return a compatible pointer, "
95 template <
typename Class>
98 if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
107 v_h.value_ptr() = ptr;
108 v_h.set_instance_registered(
true);
109 v_h.type->init_instance(v_h.inst,
nullptr);
110 Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>()));
111 v_h.type->dealloc(v_h);
112 v_h.set_instance_registered(
false);
114 construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(*ptr));
117 v_h.value_ptr() = ptr;
123 template <
typename Class, enable_if_t<Class::has_alias,
int> = 0>
125 no_nullptr(alias_ptr);
126 v_h.value_ptr() =
static_cast<Cpp<Class> *
>(alias_ptr);
132 template <
typename Class>
133 void construct(
value_and_holder &v_h, Holder<Class> holder,
bool need_alias) {
137 if (Class::has_alias && need_alias && !is_alias<Class>(ptr))
138 throw type_error(
"pybind11::init(): construction failed: returned holder-wrapped instance "
139 "is not an alias instance");
141 v_h.value_ptr() = ptr;
142 v_h.type->init_instance(v_h.inst, &holder);
149 template <
typename Class>
150 void construct(
value_and_holder &v_h, Cpp<Class> &&result,
bool need_alias) {
151 static_assert(std::is_move_constructible<Cpp<Class>>::value,
152 "pybind11::init() return-by-value factory function requires a movable class");
153 if (Class::has_alias && need_alias)
154 construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
156 v_h.value_ptr() =
new Cpp<Class>(std::move(result));
162 template <
typename Class>
164 static_assert(std::is_move_constructible<Alias<Class>>::value,
165 "pybind11::init() return-by-alias-value factory function requires a movable alias class");
166 v_h.value_ptr() =
new Alias<Class>(std::move(result));
170 template <
typename... Args>
172 template <
typename Class,
typename... Extra, enable_if_t<!Class::has_alias, int> = 0>
173 static void execute(Class &cl,
const Extra&... extra) {
175 v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(
args)...);
179 template <
typename Class,
typename... Extra,
180 enable_if_t<Class::has_alias &&
181 std::is_constructible<Cpp<Class>, Args...>::value,
int> = 0>
182 static void execute(Class &cl,
const Extra&... extra) {
184 if (Py_TYPE(v_h.inst) == v_h.type->type)
185 v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(
args)...);
187 v_h.value_ptr() = construct_or_initialize<Alias<Class>>(std::forward<Args>(
args)...);
191 template <
typename Class,
typename... Extra,
192 enable_if_t<Class::has_alias &&
193 !std::is_constructible<Cpp<Class>, Args...>::value,
int> = 0>
194 static void execute(Class &cl,
const Extra&... extra) {
196 v_h.value_ptr() = construct_or_initialize<Alias<Class>>(std::forward<Args>(
args)...);
203 template <
typename Class,
typename... Extra,
204 enable_if_t<Class::has_alias && std::is_constructible<Alias<Class>, Args...>::value,
int> = 0>
205 static void execute(Class &cl,
const Extra&... extra) {
207 v_h.value_ptr() = construct_or_initialize<Alias<Class>>(std::forward<Args>(
args)...);
213 template <
typename CFunc,
typename AFunc =
void_type (*)(),
214 typename = function_signature_t<CFunc>,
typename = function_signature_t<AFunc>>
218 template <
typename Func,
typename Return,
typename... Args>
220 remove_reference_t<Func> class_factory;
222 factory(Func &&f) : class_factory(std::forward<Func>(f)) { }
229 template <
typename Class,
typename... Extra>
230 void execute(Class &cl,
const Extra &...extra) && {
231 #if defined(PYBIND11_CPP14)
232 cl.def(
"__init__", [func = std::move(class_factory)]
234 auto &func = class_factory;
235 cl.def(
"__init__", [func]
238 construct<Class>(v_h, func(std::forward<Args>(
args)...),
239 Py_TYPE(v_h.inst) != v_h.type->type);
245 template <
typename CFunc,
typename AFunc,
246 typename CReturn,
typename... CArgs,
typename AReturn,
typename... AArgs>
247 struct factory<CFunc, AFunc, CReturn(CArgs...), AReturn(AArgs...)> {
248 static_assert(
sizeof...(CArgs) ==
sizeof...(AArgs),
249 "pybind11::init(class_factory, alias_factory): class and alias factories "
250 "must have identical argument signatures");
251 static_assert(all_of<std::is_same<CArgs, AArgs>...>::value,
252 "pybind11::init(class_factory, alias_factory): class and alias factories "
253 "must have identical argument signatures");
255 remove_reference_t<CFunc> class_factory;
256 remove_reference_t<AFunc> alias_factory;
259 : class_factory(std::forward<CFunc>(c)), alias_factory(std::forward<AFunc>(a)) { }
263 template <
typename Class,
typename... Extra>
264 void execute(Class &cl,
const Extra&... extra) && {
265 static_assert(Class::has_alias,
"The two-argument version of `py::init()` can "
266 "only be used if the class has an alias");
267 #if defined(PYBIND11_CPP14)
268 cl.def(
"__init__", [class_func = std::move(class_factory), alias_func = std::move(alias_factory)]
270 auto &class_func = class_factory;
271 auto &alias_func = alias_factory;
272 cl.def(
"__init__", [class_func, alias_func]
275 if (Py_TYPE(v_h.inst) == v_h.type->type)
278 construct<Class>(v_h, class_func(std::forward<CArgs>(
args)...),
false);
280 construct<Class>(v_h, alias_func(std::forward<CArgs>(
args)...),
true);
286 template <
typename Class,
typename T>
288 construct<Class>(v_h, std::forward<T>(result), need_alias);
292 template <
typename Class,
typename T,
typename O,
293 enable_if_t<std::is_convertible<O, handle>::value,
int> = 0>
294 void setstate(
value_and_holder &v_h, std::pair<T, O> &&result,
bool need_alias) {
295 construct<Class>(v_h, std::move(result.first), need_alias);
296 setattr((PyObject *) v_h.inst,
"__dict__", result.second);
300 template <
typename Get,
typename Set,
301 typename = function_signature_t<Get>,
typename = function_signature_t<Set>>
304 template <
typename Get,
typename Set,
305 typename RetState,
typename Self,
typename NewInstance,
typename ArgState>
307 static_assert(std::is_same<intrinsic_t<RetState>, intrinsic_t<ArgState>>::value,
308 "The type returned by `__getstate__` must be the same "
309 "as the argument accepted by `__setstate__`");
311 remove_reference_t<Get>
get;
312 remove_reference_t<Set>
set;
315 :
get(std::forward<Get>(
get)), set(std::forward<Set>(set)) { }
317 template <
typename Class,
typename... Extra>
318 void execute(Class &cl,
const Extra &...extra) && {
319 cl.def(
"__getstate__", std::move(
get));
321 #if defined(PYBIND11_CPP14)
322 cl.def(
"__setstate__", [func = std::move(set)]
325 cl.def(
"__setstate__", [func]
328 setstate<Class>(v_h, func(std::forward<ArgState>(state)),
329 Py_TYPE(v_h.inst) != v_h.type->type);
334 PYBIND11_NAMESPACE_END(initimpl)
335 PYBIND11_NAMESPACE_END(detail)
336 PYBIND11_NAMESPACE_END(pybind11)
Tag for a new-style __init__ defined in detail/init.h
PyObject * ptr() const
Return the underlying PyObject * pointer.
Helper type to replace 'void' in some expressions.
Annotation for function names.
Annotation indicating that a class derives from another given type.
Implementation for py::pickle(GetState, SetState)