Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-01 08:27:28

0001 /*
0002     pybind11/detail/init.h: init factory function implementation and support code.
0003 
0004     Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>
0005 
0006     All rights reserved. Use of this source code is governed by a
0007     BSD-style license that can be found in the LICENSE file.
0008 */
0009 
0010 #pragma once
0011 
0012 #include "class.h"
0013 #include "using_smart_holder.h"
0014 
0015 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0016 
0017 PYBIND11_WARNING_DISABLE_MSVC(4127)
0018 
0019 PYBIND11_NAMESPACE_BEGIN(detail)
0020 
0021 template <>
0022 class type_caster<value_and_holder> {
0023 public:
0024     bool load(handle h, bool) {
0025         value = reinterpret_cast<value_and_holder *>(h.ptr());
0026         return true;
0027     }
0028 
0029     template <typename>
0030     using cast_op_type = value_and_holder &;
0031     explicit operator value_and_holder &() { return *value; }
0032     static constexpr auto name = const_name<value_and_holder>();
0033 
0034 private:
0035     value_and_holder *value = nullptr;
0036 };
0037 
0038 PYBIND11_NAMESPACE_BEGIN(initimpl)
0039 
0040 inline void no_nullptr(const void *ptr) {
0041     if (!ptr) {
0042         throw type_error("pybind11::init(): factory function returned nullptr");
0043     }
0044 }
0045 
0046 // Implementing functions for all forms of py::init<...> and py::init(...)
0047 template <typename Class>
0048 using Cpp = typename Class::type;
0049 template <typename Class>
0050 using Alias = typename Class::type_alias;
0051 template <typename Class>
0052 using Holder = typename Class::holder_type;
0053 
0054 template <typename Class>
0055 using is_alias_constructible = std::is_constructible<Alias<Class>, Cpp<Class> &&>;
0056 
0057 // Takes a Cpp pointer and returns true if it actually is a polymorphic Alias instance.
0058 template <typename Class, enable_if_t<Class::has_alias, int> = 0>
0059 bool is_alias(Cpp<Class> *ptr) {
0060     return dynamic_cast<Alias<Class> *>(ptr) != nullptr;
0061 }
0062 // Failing fallback version of the above for a no-alias class (always returns false)
0063 template <typename /*Class*/>
0064 constexpr bool is_alias(const void *) {
0065     return false;
0066 }
0067 
0068 // Constructs and returns a new object; if the given arguments don't map to a constructor, we fall
0069 // back to brace aggregate initialization so that for aggregate initialization can be used with
0070 // py::init, e.g.  `py::init<int, int>` to initialize a `struct T { int a; int b; }`.  For
0071 // non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually
0072 // works, but will not do the expected thing when `T` has an `initializer_list<T>` constructor).
0073 template <typename Class,
0074           typename... Args,
0075           detail::enable_if_t<std::is_constructible<Class, Args...>::value, int> = 0>
0076 inline Class *construct_or_initialize(Args &&...args) {
0077     return new Class(std::forward<Args>(args)...);
0078 }
0079 template <typename Class,
0080           typename... Args,
0081           detail::enable_if_t<!std::is_constructible<Class, Args...>::value, int> = 0>
0082 inline Class *construct_or_initialize(Args &&...args) {
0083     return new Class{std::forward<Args>(args)...};
0084 }
0085 
0086 // Attempts to constructs an alias using a `Alias(Cpp &&)` constructor.  This allows types with
0087 // an alias to provide only a single Cpp factory function as long as the Alias can be
0088 // constructed from an rvalue reference of the base Cpp type.  This means that Alias classes
0089 // can, when appropriate, simply define a `Alias(Cpp &&)` constructor rather than needing to
0090 // inherit all the base class constructors.
0091 template <typename Class>
0092 void construct_alias_from_cpp(std::true_type /*is_alias_constructible*/,
0093                               value_and_holder &v_h,
0094                               Cpp<Class> &&base) {
0095     v_h.value_ptr() = new Alias<Class>(std::move(base));
0096 }
0097 template <typename Class>
0098 [[noreturn]] void construct_alias_from_cpp(std::false_type /*!is_alias_constructible*/,
0099                                            value_and_holder &,
0100                                            Cpp<Class> &&) {
0101     throw type_error("pybind11::init(): unable to convert returned instance to required "
0102                      "alias class: no `Alias<Class>(Class &&)` constructor available");
0103 }
0104 
0105 // Error-generating fallback for factories that don't match one of the below construction
0106 // mechanisms.
0107 template <typename Class>
0108 void construct(...) {
0109     static_assert(!std::is_same<Class, Class>::value /* always false */,
0110                   "pybind11::init(): init function must return a compatible pointer, "
0111                   "holder, or value");
0112 }
0113 
0114 // Pointer return v1: the factory function returns a class pointer for a registered class.
0115 // If we don't need an alias (because this class doesn't have one, or because the final type is
0116 // inherited on the Python side) we can simply take over ownership.  Otherwise we need to try to
0117 // construct an Alias from the returned base instance.
0118 template <typename Class>
0119 void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
0120     PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
0121     no_nullptr(ptr);
0122     if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
0123         // We're going to try to construct an alias by moving the cpp type.  Whether or not
0124         // that succeeds, we still need to destroy the original cpp pointer (either the
0125         // moved away leftover, if the alias construction works, or the value itself if we
0126         // throw an error), but we can't just call `delete ptr`: it might have a special
0127         // deleter, or might be shared_from_this.  So we construct a holder around it as if
0128         // it was a normal instance, then steal the holder away into a local variable; thus
0129         // the holder and destruction happens when we leave the C++ scope, and the holder
0130         // class gets to handle the destruction however it likes.
0131         v_h.value_ptr() = ptr;
0132         v_h.set_instance_registered(true); // Trick to prevent init_instance from registering it
0133         // DANGER ZONE BEGIN: exceptions will leave v_h in an invalid state.
0134         v_h.type->init_instance(v_h.inst, nullptr);                        // Set up the holder
0135         Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>())); // Steal the holder
0136         v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null
0137         v_h.set_instance_registered(false);
0138         // DANGER ZONE END.
0139 
0140         construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(*ptr));
0141     } else {
0142         // Otherwise the type isn't inherited, so we don't need an Alias
0143         v_h.value_ptr() = ptr;
0144     }
0145 }
0146 
0147 // Pointer return v2: a factory that always returns an alias instance ptr.  We simply take over
0148 // ownership of the pointer.
0149 template <typename Class, enable_if_t<Class::has_alias, int> = 0>
0150 void construct(value_and_holder &v_h, Alias<Class> *alias_ptr, bool) {
0151     no_nullptr(alias_ptr);
0152     v_h.value_ptr() = static_cast<Cpp<Class> *>(alias_ptr);
0153 }
0154 
0155 // Holder return: copy its pointer, and move or copy the returned holder into the new instance's
0156 // holder.  This also handles types like std::shared_ptr<T> and std::unique_ptr<T> where T is a
0157 // derived type (through those holder's implicit conversion from derived class holder
0158 // constructors).
0159 template <typename Class, detail::enable_if_t<!is_smart_holder<Holder<Class>>::value, int> = 0>
0160 void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
0161     PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
0162     auto *ptr = holder_helper<Holder<Class>>::get(holder);
0163     no_nullptr(ptr);
0164     // If we need an alias, check that the held pointer is actually an alias instance
0165     if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
0166         throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance "
0167                          "is not an alias instance");
0168     }
0169 
0170     // Cast away constness to store in void* storage.
0171     // The value_and_holder storage is fundamentally untyped (void**), so we lose
0172     // const-correctness here by design. The const qualifier will be restored
0173     // when the pointer is later retrieved and cast back to the original type.
0174     // This explicit const_cast makes the const-removal clearly visible.
0175     v_h.value_ptr() = const_cast<void *>(static_cast<const void *>(ptr));
0176     v_h.type->init_instance(v_h.inst, &holder);
0177 }
0178 
0179 // return-by-value version 1: returning a cpp class by value.  If the class has an alias and an
0180 // alias is required the alias must have an `Alias(Cpp &&)` constructor so that we can construct
0181 // the alias from the base when needed (i.e. because of Python-side inheritance).  When we don't
0182 // need it, we simply move-construct the cpp value into a new instance.
0183 template <typename Class>
0184 void construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {
0185     PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
0186     static_assert(is_move_constructible<Cpp<Class>>::value,
0187                   "pybind11::init() return-by-value factory function requires a movable class");
0188     if (Class::has_alias && need_alias) {
0189         construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
0190     } else {
0191         v_h.value_ptr() = new Cpp<Class>(std::move(result));
0192     }
0193 }
0194 
0195 // return-by-value version 2: returning a value of the alias type itself.  We move-construct an
0196 // Alias instance (even if no the python-side inheritance is involved).  The is intended for
0197 // cases where Alias initialization is always desired.
0198 template <typename Class>
0199 void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
0200     static_assert(
0201         is_move_constructible<Alias<Class>>::value,
0202         "pybind11::init() return-by-alias-value factory function requires a movable alias class");
0203     v_h.value_ptr() = new Alias<Class>(std::move(result));
0204 }
0205 
0206 template <typename T, typename D>
0207 smart_holder init_smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
0208                                                bool void_cast_raw_ptr) {
0209     void *void_ptr = void_cast_raw_ptr ? static_cast<void *>(unq_ptr.get()) : nullptr;
0210     return smart_holder::from_unique_ptr(std::move(unq_ptr), void_ptr);
0211 }
0212 
0213 template <typename Class,
0214           typename D = std::default_delete<Cpp<Class>>,
0215           detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
0216 void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_ptr, bool need_alias) {
0217     PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
0218     auto *ptr = unq_ptr.get();
0219     no_nullptr(ptr);
0220     if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
0221         throw type_error("pybind11::init(): construction failed: returned std::unique_ptr pointee "
0222                          "is not an alias instance");
0223     }
0224     // Here and below: if the new object is a trampoline, the shared_from_this mechanism needs
0225     // to be prevented from accessing the smart_holder vptr, because it does not keep the
0226     // trampoline Python object alive. For types that don't inherit from enable_shared_from_this
0227     // it does not matter if void_cast_raw_ptr is true or false, therefore it's not necessary
0228     // to also inspect the type.
0229     auto smhldr = init_smart_holder_from_unique_ptr(
0230         std::move(unq_ptr), /*void_cast_raw_ptr*/ Class::has_alias && is_alias<Class>(ptr));
0231     v_h.value_ptr() = ptr;
0232     v_h.type->init_instance(v_h.inst, &smhldr);
0233 }
0234 
0235 template <typename Class,
0236           typename D = std::default_delete<Alias<Class>>,
0237           detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
0238 void construct(value_and_holder &v_h,
0239                std::unique_ptr<Alias<Class>, D> &&unq_ptr,
0240                bool /*need_alias*/) {
0241     auto *ptr = unq_ptr.get();
0242     no_nullptr(ptr);
0243     auto smhldr
0244         = init_smart_holder_from_unique_ptr(std::move(unq_ptr), /*void_cast_raw_ptr*/ true);
0245     v_h.value_ptr() = ptr;
0246     v_h.type->init_instance(v_h.inst, &smhldr);
0247 }
0248 
0249 template <typename PtrType, typename Class>
0250 void construct_from_shared_ptr(value_and_holder &v_h,
0251                                std::shared_ptr<PtrType> &&shd_ptr,
0252                                bool need_alias) {
0253     static_assert(std::is_same<PtrType, Cpp<Class>>::value
0254                       || std::is_same<PtrType, const Cpp<Class>>::value,
0255                   "Expected (const) Cpp<Class> as shared_ptr pointee");
0256     auto *ptr = shd_ptr.get();
0257     no_nullptr(ptr);
0258     if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
0259         throw type_error("pybind11::init(): construction failed: returned std::shared_ptr pointee "
0260                          "is not an alias instance");
0261     }
0262     // Cast to non-const if needed, consistent with internal design
0263     auto smhldr
0264         = smart_holder::from_shared_ptr(std::const_pointer_cast<Cpp<Class>>(std::move(shd_ptr)));
0265     v_h.value_ptr() = const_cast<Cpp<Class> *>(ptr);
0266     v_h.type->init_instance(v_h.inst, &smhldr);
0267 }
0268 
0269 template <typename Class, detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
0270 void construct(value_and_holder &v_h, std::shared_ptr<Cpp<Class>> &&shd_ptr, bool need_alias) {
0271     construct_from_shared_ptr<Cpp<Class>, Class>(v_h, std::move(shd_ptr), need_alias);
0272 }
0273 
0274 template <typename Class, detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
0275 void construct(value_and_holder &v_h,
0276                std::shared_ptr<const Cpp<Class>> &&shd_ptr,
0277                bool need_alias) {
0278     construct_from_shared_ptr<const Cpp<Class>, Class>(v_h, std::move(shd_ptr), need_alias);
0279 }
0280 
0281 template <typename Class, detail::enable_if_t<is_smart_holder<Holder<Class>>::value, int> = 0>
0282 void construct(value_and_holder &v_h,
0283                std::shared_ptr<Alias<Class>> &&shd_ptr,
0284                bool /*need_alias*/) {
0285     auto *ptr = shd_ptr.get();
0286     no_nullptr(ptr);
0287     auto smhldr = smart_holder::from_shared_ptr(shd_ptr);
0288     v_h.value_ptr() = ptr;
0289     v_h.type->init_instance(v_h.inst, &smhldr);
0290 }
0291 
0292 // Implementing class for py::init<...>()
0293 template <typename... Args>
0294 struct constructor {
0295     template <typename Class, typename... Extra, enable_if_t<!Class::has_alias, int> = 0>
0296     static void execute(Class &cl, const Extra &...extra) {
0297         cl.def(
0298             "__init__",
0299             [](value_and_holder &v_h,
0300                Args... args) { // NOLINT(performance-unnecessary-value-param)
0301                 v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
0302             },
0303             is_new_style_constructor(),
0304             extra...);
0305     }
0306 
0307     template <
0308         typename Class,
0309         typename... Extra,
0310         enable_if_t<Class::has_alias && std::is_constructible<Cpp<Class>, Args...>::value, int>
0311         = 0>
0312     static void execute(Class &cl, const Extra &...extra) {
0313         cl.def(
0314             "__init__",
0315             [](value_and_holder &v_h, Args... args) {
0316                 if (Py_TYPE(v_h.inst) == v_h.type->type) {
0317                     v_h.value_ptr()
0318                         = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
0319                 } else {
0320                     v_h.value_ptr()
0321                         = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
0322                 }
0323             },
0324             is_new_style_constructor(),
0325             extra...);
0326     }
0327 
0328     template <
0329         typename Class,
0330         typename... Extra,
0331         enable_if_t<Class::has_alias && !std::is_constructible<Cpp<Class>, Args...>::value, int>
0332         = 0>
0333     static void execute(Class &cl, const Extra &...extra) {
0334         cl.def(
0335             "__init__",
0336             [](value_and_holder &v_h, Args... args) {
0337                 v_h.value_ptr()
0338                     = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
0339             },
0340             is_new_style_constructor(),
0341             extra...);
0342     }
0343 };
0344 
0345 // Implementing class for py::init_alias<...>()
0346 template <typename... Args>
0347 struct alias_constructor {
0348     template <
0349         typename Class,
0350         typename... Extra,
0351         enable_if_t<Class::has_alias && std::is_constructible<Alias<Class>, Args...>::value, int>
0352         = 0>
0353     static void execute(Class &cl, const Extra &...extra) {
0354         cl.def(
0355             "__init__",
0356             [](value_and_holder &v_h, Args... args) {
0357                 v_h.value_ptr()
0358                     = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
0359             },
0360             is_new_style_constructor(),
0361             extra...);
0362     }
0363 };
0364 
0365 // Implementation class for py::init(Func) and py::init(Func, AliasFunc)
0366 template <typename CFunc,
0367           typename AFunc = void_type (*)(),
0368           typename = function_signature_t<CFunc>,
0369           typename = function_signature_t<AFunc>>
0370 struct factory;
0371 
0372 // Specialization for py::init(Func)
0373 template <typename Func, typename Return, typename... Args>
0374 struct factory<Func, void_type (*)(), Return(Args...)> {
0375     remove_reference_t<Func> class_factory;
0376 
0377     // NOLINTNEXTLINE(google-explicit-constructor)
0378     factory(Func &&f) : class_factory(std::forward<Func>(f)) {}
0379 
0380     // The given class either has no alias or has no separate alias factory;
0381     // this always constructs the class itself.  If the class is registered with an alias
0382     // type and an alias instance is needed (i.e. because the final type is a Python class
0383     // inheriting from the C++ type) the returned value needs to either already be an alias
0384     // instance, or the alias needs to be constructible from a `Class &&` argument.
0385     template <typename Class, typename... Extra>
0386     void execute(Class &cl, const Extra &...extra) && {
0387 #if defined(PYBIND11_CPP14)
0388         cl.def(
0389             "__init__",
0390             [func = std::move(class_factory)]
0391 #else
0392         auto &func = class_factory;
0393         cl.def(
0394             "__init__",
0395             [func]
0396 #endif
0397             (value_and_holder &v_h, Args... args) {
0398                 construct<Class>(
0399                     v_h, func(std::forward<Args>(args)...), Py_TYPE(v_h.inst) != v_h.type->type);
0400             },
0401             is_new_style_constructor(),
0402             extra...);
0403     }
0404 };
0405 
0406 // Specialization for py::init(Func, AliasFunc)
0407 template <typename CFunc,
0408           typename AFunc,
0409           typename CReturn,
0410           typename... CArgs,
0411           typename AReturn,
0412           typename... AArgs>
0413 struct factory<CFunc, AFunc, CReturn(CArgs...), AReturn(AArgs...)> {
0414     static_assert(sizeof...(CArgs) == sizeof...(AArgs),
0415                   "pybind11::init(class_factory, alias_factory): class and alias factories "
0416                   "must have identical argument signatures");
0417     static_assert(all_of<std::is_same<CArgs, AArgs>...>::value,
0418                   "pybind11::init(class_factory, alias_factory): class and alias factories "
0419                   "must have identical argument signatures");
0420 
0421     remove_reference_t<CFunc> class_factory;
0422     remove_reference_t<AFunc> alias_factory;
0423 
0424     factory(CFunc &&c, AFunc &&a)
0425         : class_factory(std::forward<CFunc>(c)), alias_factory(std::forward<AFunc>(a)) {}
0426 
0427     // The class factory is called when the `self` type passed to `__init__` is the direct
0428     // class (i.e. not inherited), the alias factory when `self` is a Python-side subtype.
0429     template <typename Class, typename... Extra>
0430     void execute(Class &cl, const Extra &...extra) && {
0431         static_assert(Class::has_alias,
0432                       "The two-argument version of `py::init()` can "
0433                       "only be used if the class has an alias");
0434 #if defined(PYBIND11_CPP14)
0435         cl.def(
0436             "__init__",
0437             [class_func = std::move(class_factory), alias_func = std::move(alias_factory)]
0438 #else
0439         auto &class_func = class_factory;
0440         auto &alias_func = alias_factory;
0441         cl.def(
0442             "__init__",
0443             [class_func, alias_func]
0444 #endif
0445             (value_and_holder &v_h, CArgs... args) {
0446                 if (Py_TYPE(v_h.inst) == v_h.type->type) {
0447                     // If the instance type equals the registered type we don't have inheritance,
0448                     // so don't need the alias and can construct using the class function:
0449                     construct<Class>(v_h, class_func(std::forward<CArgs>(args)...), false);
0450                 } else {
0451                     construct<Class>(v_h, alias_func(std::forward<CArgs>(args)...), true);
0452                 }
0453             },
0454             is_new_style_constructor(),
0455             extra...);
0456     }
0457 };
0458 
0459 /// Set just the C++ state. Same as `__init__`.
0460 template <typename Class, typename T>
0461 void setstate(value_and_holder &v_h, T &&result, bool need_alias) {
0462     construct<Class>(v_h, std::forward<T>(result), need_alias);
0463 }
0464 
0465 /// Set both the C++ and Python states
0466 template <typename Class,
0467           typename T,
0468           typename O,
0469           enable_if_t<std::is_convertible<O, handle>::value, int> = 0>
0470 void setstate(value_and_holder &v_h, std::pair<T, O> &&result, bool need_alias) {
0471     construct<Class>(v_h, std::move(result.first), need_alias);
0472     auto d = handle(result.second);
0473     if (PyDict_Check(d.ptr()) && PyDict_Size(d.ptr()) == 0) {
0474         // Skipping setattr below, to not force use of py::dynamic_attr() for Class unnecessarily.
0475         // See PR #2972 for details.
0476         return;
0477     }
0478     // Our tests never run into an unset dict, but being careful here for now (see #5658)
0479     auto dict = getattr((PyObject *) v_h.inst, "__dict__", none());
0480     if (dict.is_none()) {
0481         setattr((PyObject *) v_h.inst, "__dict__", d);
0482     } else {
0483         // Keep the original object dict and just update it
0484         if (PyDict_Update(dict.ptr(), d.ptr()) < 0) {
0485             throw error_already_set();
0486         }
0487     }
0488 }
0489 
0490 /// Implementation for py::pickle(GetState, SetState)
0491 template <typename Get,
0492           typename Set,
0493           typename = function_signature_t<Get>,
0494           typename = function_signature_t<Set>>
0495 struct pickle_factory;
0496 
0497 template <typename Get,
0498           typename Set,
0499           typename RetState,
0500           typename Self,
0501           typename NewInstance,
0502           typename ArgState>
0503 struct pickle_factory<Get, Set, RetState(Self), NewInstance(ArgState)> {
0504     static_assert(std::is_same<intrinsic_t<RetState>, intrinsic_t<ArgState>>::value,
0505                   "The type returned by `__getstate__` must be the same "
0506                   "as the argument accepted by `__setstate__`");
0507 
0508     remove_reference_t<Get> get;
0509     remove_reference_t<Set> set;
0510 
0511     pickle_factory(Get get, Set set) : get(std::forward<Get>(get)), set(std::forward<Set>(set)) {}
0512 
0513     template <typename Class, typename... Extra>
0514     void execute(Class &cl, const Extra &...extra) && {
0515         cl.def("__getstate__", std::move(get), pos_only());
0516 
0517 #if defined(PYBIND11_CPP14)
0518         cl.def(
0519             "__setstate__",
0520             [func = std::move(set)]
0521 #else
0522         auto &func = set;
0523         cl.def(
0524             "__setstate__",
0525             [func]
0526 #endif
0527             (value_and_holder &v_h, ArgState state) {
0528                 setstate<Class>(
0529                     v_h, func(std::forward<ArgState>(state)), Py_TYPE(v_h.inst) != v_h.type->type);
0530             },
0531             is_new_style_constructor(),
0532             extra...);
0533     }
0534 };
0535 
0536 PYBIND11_NAMESPACE_END(initimpl)
0537 PYBIND11_NAMESPACE_END(detail)
0538 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)