support-noexcept-ctors.patch 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. --- a/include/pybind11/detail/init.h (index)
  2. +++ b/include/pybind11/detail/init.h (working tree)
  3. @@ -302,6 +302,40 @@ struct factory<Func, void_type (*)(), Return(Args...)> {
  4. }
  5. };
  6. +// Specialization for py::init(Func) if Func is marked as noexcept and we are compiling -std=c++17-or-above mode
  7. +template <typename Func, typename Return, typename... Args>
  8. +struct factory<Func, void_type (*)(), Return(Args...) noexcept> {
  9. + remove_reference_t<Func> class_factory;
  10. +
  11. + // NOLINTNEXTLINE(google-explicit-constructor)
  12. + factory(Func &&f) : class_factory(std::forward<Func>(f)) {}
  13. +
  14. + // The given class either has no alias or has no separate alias factory;
  15. + // this always constructs the class itself. If the class is registered with an alias
  16. + // type and an alias instance is needed (i.e. because the final type is a Python class
  17. + // inheriting from the C++ type) the returned value needs to either already be an alias
  18. + // instance, or the alias needs to be constructible from a `Class &&` argument.
  19. + template <typename Class, typename... Extra>
  20. + void execute(Class &cl, const Extra &...extra) && {
  21. +#if defined(PYBIND11_CPP14)
  22. + cl.def(
  23. + "__init__",
  24. + [func = std::move(class_factory)]
  25. +#else
  26. + auto &func = class_factory;
  27. + cl.def(
  28. + "__init__",
  29. + [func]
  30. +#endif
  31. + (value_and_holder &v_h, Args... args) {
  32. + construct<Class>(
  33. + v_h, func(std::forward<Args>(args)...), Py_TYPE(v_h.inst) != v_h.type->type);
  34. + },
  35. + is_new_style_constructor(),
  36. + extra...);
  37. + }
  38. +};
  39. +
  40. // Specialization for py::init(Func, AliasFunc)
  41. template <typename CFunc,
  42. typename AFunc,