27 static constexpr
auto name = _<value_and_holder>();
36 if (!ptr)
throw type_error(
"pybind11::init(): factory function returned nullptr");
41 template <
typename Class>
using Alias =
typename Class::type_alias;
42 template <
typename Class>
using Holder =
typename Class::holder_type;
47 template <
typename Class, enable_if_t<Class::has_alias,
int> = 0>
53 constexpr
bool is_alias(
void *) {
return false; }
70 template <
typename Class>
75 template <
typename Class>
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>
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)) {
123 template <
typename Class, enable_if_t<Class::has_alias,
int> = 0>
132 template <
typename Class>
136 if (Class::has_alias && need_alias && !is_alias<Class>(ptr))
137 throw type_error(
"pybind11::init(): construction failed: returned holder-wrapped instance " 138 "is not an alias instance");
148 template <
typename Class>
151 "pybind11::init() return-by-value factory function requires a movable class");
152 if (Class::has_alias && need_alias)
161 template <
typename Class>
164 "pybind11::init() return-by-alias-value factory function requires a movable alias class");
169 template <
typename... Args>
172 static void execute(Class &cl,
const Extra&... extra) {
174 v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
178 template <
typename Class,
typename... Extra,
180 std::is_constructible<Cpp<Class>, Args...>
::value,
int> = 0>
181 static void execute(Class &cl,
const Extra&... extra) {
183 if (Py_TYPE(v_h.inst) == v_h.type->type)
184 v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
186 v_h.value_ptr() = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
190 template <
typename Class,
typename... Extra,
192 !std::is_constructible<Cpp<Class>, Args...>
::value,
int> = 0>
193 static void execute(Class &cl,
const Extra&... extra) {
195 v_h.value_ptr() = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
202 template <
typename Class,
typename... Extra,
204 static void execute(Class &cl,
const Extra&... extra) {
206 v_h.value_ptr() = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
212 template <
typename CFunc,
typename AFunc =
void_type (*)(),
217 template <
typename Func,
typename Return,
typename... Args>
228 template <
typename Class,
typename... Extra>
229 void execute(Class &cl,
const Extra &...extra) && {
230 #if defined(PYBIND11_CPP14) 231 cl.def(
"__init__", [func =
std::move(class_factory)]
233 auto &func = class_factory;
234 cl.def(
"__init__", [func]
237 construct<Class>(v_h, func(std::forward<Args>(args)...),
238 Py_TYPE(v_h.inst) != v_h.type->type);
244 template <
typename CFunc,
typename AFunc,
245 typename CReturn,
typename... CArgs,
typename AReturn,
typename... AArgs>
246 struct factory<CFunc, AFunc, CReturn(CArgs...), AReturn(AArgs...)> {
247 static_assert(
sizeof...(CArgs) ==
sizeof...(AArgs),
248 "pybind11::init(class_factory, alias_factory): class and alias factories " 249 "must have identical argument signatures");
250 static_assert(
all_of<std::is_same<CArgs, AArgs>...>::
value,
251 "pybind11::init(class_factory, alias_factory): class and alias factories " 252 "must have identical argument signatures");
258 : class_factory(
std::forward<CFunc>(c)), alias_factory(
std::forward<AFunc>(a)) { }
262 template <
typename Class,
typename... Extra>
263 void execute(Class &cl,
const Extra&... extra) && {
264 static_assert(Class::has_alias,
"The two-argument version of `py::init()` can " 265 "only be used if the class has an alias");
266 #if defined(PYBIND11_CPP14) 267 cl.def(
"__init__", [class_func =
std::move(class_factory), alias_func =
std::move(alias_factory)]
269 auto &class_func = class_factory;
270 auto &alias_func = alias_factory;
271 cl.def(
"__init__", [class_func, alias_func]
274 if (Py_TYPE(v_h.inst) == v_h.type->type)
277 construct<Class>(v_h, class_func(std::forward<CArgs>(args)...), false);
279 construct<Class>(v_h, alias_func(std::forward<CArgs>(args)...), true);
285 template <
typename Class,
typename T>
287 construct<Class>(v_h, std::forward<T>(result), need_alias);
291 template <
typename Class,
typename T,
typename O,
294 construct<Class>(v_h,
std::move(result.first), need_alias);
295 setattr((PyObject *) v_h.inst,
"__dict__", result.second);
299 template <
typename Get,
typename Set,
303 template <
typename Get,
typename Set,
304 typename RetState,
typename Self,
typename NewInstance,
typename ArgState>
307 "The type returned by `__getstate__` must be the same " 308 "as the argument accepted by `__setstate__`");
314 : get(
std::forward<Get>(get)),
set(
std::forward<Set>(
set)) { }
316 template <
typename Class,
typename... Extra>
317 void execute(Class &cl,
const Extra &...extra) && {
320 #if defined(PYBIND11_CPP14) 321 cl.def(
"__setstate__", [func =
std::move(
set)]
324 cl.def(
"__setstate__", [func]
327 setstate<Class>(v_h, func(std::forward<ArgState>(state)),
328 Py_TYPE(v_h.inst) != v_h.
type->
type);
Implementation for py::pickle(GetState, SetState)
Class * construct_or_initialize(Args &&...args)
bool load(handle h, bool)
#define PYBIND11_NAMESPACE
PyObject * ptr() const
Return the underlying PyObject * pointer.
Tag for a new-style __init__ defined in detail/init.h
glibc defines I as a macro which breaks things, e.g., boost template names
void execute(Class &cl, const Extra &... extra) &&
static void execute(Class &cl, const Extra &... extra)
std::is_same< bools< Ts::value..., true >, bools< true, Ts::value... > > all_of
void execute(Class &cl, const Extra &...extra) &&
factory(CFunc &&c, AFunc &&a)
void(* init_instance)(instance *, const void *)
remove_reference_t< AFunc > alias_factory
pickle_factory(Get get, Set set)
constexpr bool is_alias(void *)
#define NAMESPACE_END(name)
const detail::type_info * type
typename intrinsic_type< T >::type intrinsic_t
typename Class::type_alias Alias
void execute(Class &cl, const Extra &...extra) &&
typename std::remove_reference< T >::type remove_reference_t
static void execute(Class &cl, const Extra &... extra)
Annotation indicating that a class derives from another given type.
const detail::type_info * type
remove_reference_t< CFunc > class_factory
Annotation for function names.
void set_instance_registered(bool v=true)
void construct_alias_from_cpp(std::false_type, value_and_holder &, Cpp< Class > &&)
detail::enable_if_t<!detail::move_never< T >::value, T > move(object &&obj)
Helper type to replace 'void' in some expressions.
void setstate(value_and_holder &v_h, std::pair< T, O > &&result, bool need_alias)
Set both the C++ and Python states.
typename Class::holder_type Holder
void no_nullptr(void *ptr)
void(* dealloc)(value_and_holder &v_h)
#define NAMESPACE_BEGIN(name)
conditional_t< std::is_function< F >::value, F, typename conditional_t< std::is_pointer< F >::value||std::is_member_pointer< F >::value, std::remove_pointer< F >, strip_function_object< F > >::type > function_signature_t
void setattr(handle obj, handle name, handle value)
std::is_constructible< Alias< Class >, Cpp< Class > && > is_alias_constructible
remove_reference_t< Func > class_factory
typename std::enable_if< B, T >::type enable_if_t
from cpp_future import (convenient aliases from C++14/17)
void construct(value_and_holder &v_h, Alias< Class > &&result, bool)