in pybind11

we need virtual tables to work from python
this does not work in release mode
i have literally no idea why
there are many pybind github issues with people complaining about things breaking in release mode

pybind11.h
/*
    pybind11/pybind11.h: Main header file of the C++11 python
    binding generator library

    Copyright (c) 2016 Wenzel Jakob <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#pragma once

#include "detail/class.h"
#include "detail/init.h"
#include "attr.h"
#include "gil.h"
#include "gil_safe_call_once.h"
#include "options.h"
#include "typing.h"

#include <cstdlib>
#include <cstring>
#include <memory>
#include <new>
#include <string>
#include <utility>
#include <vector>

#if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914))
#    define PYBIND11_STD_LAUNDER std::launder
#    define PYBIND11_HAS_STD_LAUNDER 1
#else
#    define PYBIND11_STD_LAUNDER
#    define PYBIND11_HAS_STD_LAUNDER 0
#endif
#if defined(__GNUG__) && !defined(__clang__)
#    include <cxxabi.h>
#endif

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

/* https://stackoverflow.com/questions/46798456/handling-gccs-noexcept-type-warning
   This warning is about ABI compatibility, not code health.
   It is only actually needed in a couple places, but apparently GCC 7 "generates this warning if
   and only if the first template instantiation ... involves noexcept" [stackoverflow], therefore
   it could get triggered from seemingly random places, depending on user code.
   No other GCC version generates this warning.
 */
#if defined(__GNUC__) && __GNUC__ == 7
PYBIND11_WARNING_DISABLE_GCC("-Wnoexcept-type")
#endif

PYBIND11_WARNING_DISABLE_MSVC(4127)

PYBIND11_NAMESPACE_BEGIN(detail)

inline std::string replace_newlines_and_squash(const char *text) {
    const char *whitespaces = " \t\n\r\f\v";
    std::string result(text);
    bool previous_is_whitespace = false;

    if (result.size() >= 2) {
        // Do not modify string representations
        char first_char = result[0];
        char last_char = result[result.size() - 1];
        if (first_char == last_char && first_char == '\'') {
            return result;
        }
    }
    result.clear();

    // Replace characters in whitespaces array with spaces and squash consecutive spaces
    while (*text != '\0') {
        if (std::strchr(whitespaces, *text)) {
            if (!previous_is_whitespace) {
                result += ' ';
                previous_is_whitespace = true;
            }
        } else {
            result += *text;
            previous_is_whitespace = false;
        }
        ++text;
    }

    // Strip leading and trailing whitespaces
    const size_t str_begin = result.find_first_not_of(whitespaces);
    if (str_begin == std::string::npos) {
        return "";
    }

    const size_t str_end = result.find_last_not_of(whitespaces);
    const size_t str_range = str_end - str_begin + 1;

    return result.substr(str_begin, str_range);
}

// Apply all the extensions translators from a list
// Return true if one of the translators completed without raising an exception
// itself. Return of false indicates that if there are other translators
// available, they should be tried.
inline bool apply_exception_translators(std::forward_list<ExceptionTranslator> &translators) {
    auto last_exception = std::current_exception();

    for (auto &translator : translators) {
        try {
            translator(last_exception);
            return true;
        } catch (...) {
            last_exception = std::current_exception();
        }
    }
    return false;
}

#if defined(_MSC_VER)
#    define PYBIND11_COMPAT_STRDUP _strdup
#else
#    define PYBIND11_COMPAT_STRDUP strdup
#endif

PYBIND11_NAMESPACE_END(detail)

/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object
class cpp_function : public function {
public:
    cpp_function() = default;
    // NOLINTNEXTLINE(google-explicit-constructor)
    cpp_function(std::nullptr_t) {}
    cpp_function(std::nullptr_t, const is_setter &) {}

    /// Construct a cpp_function from a vanilla function pointer
    template <typename Return, typename... Args, typename... Extra>
    // NOLINTNEXTLINE(google-explicit-constructor)
    cpp_function(Return (*f)(Args...), const Extra &...extra) {
        initialize(f, f, extra...);
    }

    /// Construct a cpp_function from a lambda function (possibly with internal state)
    template <typename Func,
              typename... Extra,
              typename = detail::enable_if_t<detail::is_lambda<Func>::value>>
    // NOLINTNEXTLINE(google-explicit-constructor)
    cpp_function(Func &&f, const Extra &...extra) {
        initialize(
            std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr, extra...);
    }

    /// Construct a cpp_function from a class method (non-const, no ref-qualifier)
    template <typename Return, typename Class, typename... Arg, typename... Extra>
    // NOLINTNEXTLINE(google-explicit-constructor)
    cpp_function(Return (Class::*f)(Arg...), const Extra &...extra) {
        initialize(
            [f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
            (Return(*)(Class *, Arg...)) nullptr,
            extra...);
    }

    /// Construct a cpp_function from a class method (non-const, lvalue ref-qualifier)
    /// A copy of the overload for non-const functions without explicit ref-qualifier
    /// but with an added `&`.
    template <typename Return, typename Class, typename... Arg, typename... Extra>
    // NOLINTNEXTLINE(google-explicit-constructor)
    cpp_function(Return (Class::*f)(Arg...) &, const Extra &...extra) {
        initialize(
            [f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
            (Return(*)(Class *, Arg...)) nullptr,
            extra...);
    }

    /// Construct a cpp_function from a class method (const, no ref-qualifier)
    template <typename Return, typename Class, typename... Arg, typename... Extra>
    // NOLINTNEXTLINE(google-explicit-constructor)
    cpp_function(Return (Class::*f)(Arg...) const, const Extra &...extra) {
        initialize([f](const Class *c,
                       Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
                   (Return(*)(const Class *, Arg...)) nullptr,
                   extra...);
    }

    /// Construct a cpp_function from a class method (const, lvalue ref-qualifier)
    /// A copy of the overload for const functions without explicit ref-qualifier
    /// but with an added `&`.
    template <typename Return, typename Class, typename... Arg, typename... Extra>
    // NOLINTNEXTLINE(google-explicit-constructor)
    cpp_function(Return (Class::*f)(Arg...) const &, const Extra &...extra) {
        initialize([f](const Class *c,
                       Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
                   (Return(*)(const Class *, Arg...)) nullptr,
                   extra...);
    }

    /// Return the function name
    object name() const { return attr("__name__"); }

protected:
    struct InitializingFunctionRecordDeleter {
        // `destruct(function_record, false)`: `initialize_generic` copies strings and
        // takes care of cleaning up in case of exceptions. So pass `false` to `free_strings`.
        void operator()(detail::function_record *rec) { destruct(rec, false); }
    };
    using unique_function_record
        = std::unique_ptr<detail::function_record, InitializingFunctionRecordDeleter>;

    /// Space optimization: don't inline this frequently instantiated fragment
    PYBIND11_NOINLINE unique_function_record make_function_record() {
        return unique_function_record(new detail::function_record());
    }

    /// Special internal constructor for functors, lambda functions, etc.
    template <typename Func, typename Return, typename... Args, typename... Extra>
    void initialize(Func &&f, Return (*)(Args...), const Extra &...extra) {
        using namespace detail;
        struct capture {
            remove_reference_t<Func> f;
        };

        /* Store the function including any extra state it might have (e.g. a lambda capture
         * object) */
        // The unique_ptr makes sure nothing is leaked in case of an exception.
        auto unique_rec = make_function_record();
        auto *rec = unique_rec.get();

        /* Store the capture object directly in the function record if there is enough space */
        if (sizeof(capture) <= sizeof(rec->data)) {
            /* Without these pragmas, GCC warns that there might not be
               enough space to use the placement new operator. However, the
               'if' statement above ensures that this is the case. */
            PYBIND11_WARNING_PUSH

#if defined(__GNUG__) && __GNUC__ >= 6
            PYBIND11_WARNING_DISABLE_GCC("-Wplacement-new")
#endif

            new ((capture *) &rec->data) capture{std::forward<Func>(f)};

#if !PYBIND11_HAS_STD_LAUNDER
            PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing")
#endif

            // UB without std::launder, but without breaking ABI and/or
            // a significant refactoring it's "impossible" to solve.
            if (!std::is_trivially_destructible<capture>::value) {
                rec->free_data = [](function_record *r) {
                    auto data = PYBIND11_STD_LAUNDER((capture *) &r->data);
                    (void) data;
                    data->~capture();
                };
            }
            PYBIND11_WARNING_POP
        } else {
            rec->data[0] = new capture{std::forward<Func>(f)};
            rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); };
        }

        /* Type casters for the function arguments and return value */
        using cast_in = argument_loader<Args...>;
        using cast_out
            = make_caster<conditional_t<std::is_void<Return>::value, void_type, Return>>;

        static_assert(
            expected_num_args<Extra...>(
                sizeof...(Args), cast_in::args_pos >= 0, cast_in::has_kwargs),
            "The number of argument annotations does not match the number of function arguments");

        /* Dispatch code which converts function arguments and performs the actual function call */
        rec->impl = [](function_call &call) -> handle {
            cast_in args_converter;

            /* Try to cast the function arguments into the C++ domain */
            if (!args_converter.load_args(call)) {
                return PYBIND11_TRY_NEXT_OVERLOAD;
            }

            /* Invoke call policy pre-call hook */
            process_attributes<Extra...>::precall(call);

            /* Get a pointer to the capture object */
            const auto *data = (sizeof(capture) <= sizeof(call.func.data) ? &call.func.data
                                                                          : call.func.data[0]);
            auto *cap = const_cast<capture *>(reinterpret_cast<const capture *>(data));

            /* Override policy for rvalues -- usually to enforce rvp::move on an rvalue */
            return_value_policy policy
                = return_value_policy_override<Return>::policy(call.func.policy);

            /* Function scope guard -- defaults to the compile-to-nothing `void_type` */
            using Guard = extract_guard_t<Extra...>;

            /* Perform the function call */
            handle result;
            if (call.func.is_setter) {
                (void) std::move(args_converter).template call<Return, Guard>(cap->f);
                result = none().release();
            } else {
                result = cast_out::cast(
                    std::move(args_converter).template call<Return, Guard>(cap->f),
                    policy,
                    call.parent);
            }

            /* Invoke call policy post-call hook */
            process_attributes<Extra...>::postcall(call, result);

            return result;
        };

        rec->nargs_pos = cast_in::args_pos >= 0
                             ? static_cast<std::uint16_t>(cast_in::args_pos)
                             : sizeof...(Args) - cast_in::has_kwargs; // Will get reduced more if
                                                                      // we have a kw_only
        rec->has_args = cast_in::args_pos >= 0;
        rec->has_kwargs = cast_in::has_kwargs;

        /* Process any user-provided function attributes */
        process_attributes<Extra...>::init(extra..., rec);

        {
            constexpr bool has_kw_only_args = any_of<std::is_same<kw_only, Extra>...>::value,
                           has_pos_only_args = any_of<std::is_same<pos_only, Extra>...>::value,
                           has_arg_annotations = any_of<is_keyword<Extra>...>::value;
            static_assert(has_arg_annotations || !has_kw_only_args,
                          "py::kw_only requires the use of argument annotations");
            static_assert(has_arg_annotations || !has_pos_only_args,
                          "py::pos_only requires the use of argument annotations (for docstrings "
                          "and aligning the annotations to the argument)");

            static_assert(constexpr_sum(is_kw_only<Extra>::value...) <= 1,
                          "py::kw_only may be specified only once");
            static_assert(constexpr_sum(is_pos_only<Extra>::value...) <= 1,
                          "py::pos_only may be specified only once");
            constexpr auto kw_only_pos = constexpr_first<is_kw_only, Extra...>();
            constexpr auto pos_only_pos = constexpr_first<is_pos_only, Extra...>();
            static_assert(!(has_kw_only_args && has_pos_only_args) || pos_only_pos < kw_only_pos,
                          "py::pos_only must come before py::kw_only");
        }

        /* Generate a readable signature describing the function's arguments and return
           value types */
        static constexpr auto signature
            = const_name("(") + cast_in::arg_names + const_name(") -> ") + cast_out::name;
        PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types();

        /* Register the function with Python from generic (non-templated) code */
        // Pass on the ownership over the `unique_rec` to `initialize_generic`. `rec` stays valid.
        initialize_generic(std::move(unique_rec), signature.text, types.data(), sizeof...(Args));

        /* Stash some additional information used by an important optimization in 'functional.h' */
        using FunctionType = Return (*)(Args...);
        constexpr bool is_function_ptr
            = std::is_convertible<Func, FunctionType>::value && sizeof(capture) == sizeof(void *);
        if (is_function_ptr) {
            rec->is_stateless = true;
            rec->data[1]
                = const_cast<void *>(reinterpret_cast<const void *>(&typeid(FunctionType)));
        }
    }

    // Utility class that keeps track of all duplicated strings, and cleans them up in its
    // destructor, unless they are released. Basically a RAII-solution to deal with exceptions
    // along the way.
    class strdup_guard {
    public:
        strdup_guard() = default;
        strdup_guard(const strdup_guard &) = delete;
        strdup_guard &operator=(const strdup_guard &) = delete;

        ~strdup_guard() {
            for (auto *s : strings) {
                std::free(s);
            }
        }
        char *operator()(const char *s) {
            auto *t = PYBIND11_COMPAT_STRDUP(s);
            strings.push_back(t);
            return t;
        }
        void release() { strings.clear(); }

    private:
        std::vector<char *> strings;
    };

    /// Register a function call with Python (generic non-templated code goes here)
    void initialize_generic(unique_function_record &&unique_rec,
                            const char *text,
                            const std::type_info *const *types,
                            size_t args) {
        // Do NOT receive `unique_rec` by value. If this function fails to move out the unique_ptr,
        // we do not want this to destruct the pointer. `initialize` (the caller) still relies on
        // the pointee being alive after this call. Only move out if a `capsule` is going to keep
        // it alive.
        auto *rec = unique_rec.get();

        // Keep track of strdup'ed strings, and clean them up as long as the function's capsule
        // has not taken ownership yet (when `unique_rec.release()` is called).
        // Note: This cannot easily be fixed by a `unique_ptr` with custom deleter, because the
        // strings are only referenced before strdup'ing. So only *after* the following block could
        // `destruct` safely be called, but even then, `repr` could still throw in the middle of
        // copying all strings.
        strdup_guard guarded_strdup;

        /* Create copies of all referenced C-style strings */
        rec->name = guarded_strdup(rec->name ? rec->name : "");
        if (rec->doc) {
            rec->doc = guarded_strdup(rec->doc);
        }
        for (auto &a : rec->args) {
            if (a.name) {
                a.name = guarded_strdup(a.name);
            }
            if (a.descr) {
                a.descr = guarded_strdup(a.descr);
            } else if (a.value) {
                a.descr = guarded_strdup(repr(a.value).cast<std::string>().c_str());
            }
        }

        rec->is_constructor = (std::strcmp(rec->name, "__init__") == 0)
                              || (std::strcmp(rec->name, "__setstate__") == 0);

#if defined(PYBIND11_DETAILED_ERROR_MESSAGES) && !defined(PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING)
        if (rec->is_constructor && !rec->is_new_style_constructor) {
            const auto class_name
                = detail::get_fully_qualified_tp_name((PyTypeObject *) rec->scope.ptr());
            const auto func_name = std::string(rec->name);
            PyErr_WarnEx(PyExc_FutureWarning,
                         ("pybind11-bound class '" + class_name
                          + "' is using an old-style "
                            "placement-new '"
                          + func_name
                          + "' which has been deprecated. See "
                            "the upgrade guide in pybind11's docs. This message is only visible "
                            "when compiled in debug mode.")
                             .c_str(),
                         0);
        }
#endif

        /* Generate a proper function signature */
        std::string signature;
        size_t type_index = 0, arg_index = 0;
        bool is_starred = false;
        for (const auto *pc = text; *pc != '\0'; ++pc) {
            const auto c = *pc;

            if (c == '{') {
                // Write arg name for everything except *args and **kwargs.
                is_starred = *(pc + 1) == '*';
                if (is_starred) {
                    continue;
                }
                // Separator for keyword-only arguments, placed before the kw
                // arguments start (unless we are already putting an *args)
                if (!rec->has_args && arg_index == rec->nargs_pos) {
                    signature += "*, ";
                }
                if (arg_index < rec->args.size() && rec->args[arg_index].name) {
                    signature += rec->args[arg_index].name;
                } else if (arg_index == 0 && rec->is_method) {
                    signature += "self";
                } else {
                    signature += "arg" + std::to_string(arg_index - (rec->is_method ? 1 : 0));
                }
                signature += ": ";
            } else if (c == '}') {
                // Write default value if available.
                if (!is_starred && arg_index < rec->args.size() && rec->args[arg_index].descr) {
                    signature += " = ";
                    signature += detail::replace_newlines_and_squash(rec->args[arg_index].descr);
                }
                // Separator for positional-only arguments (placed after the
                // argument, rather than before like *
                if (rec->nargs_pos_only > 0 && (arg_index + 1) == rec->nargs_pos_only) {
                    signature += ", /";
                }
                if (!is_starred) {
                    arg_index++;
                }
            } else if (c == '%') {
                const std::type_info *t = types[type_index++];
                if (!t) {
                    pybind11_fail("Internal error while parsing type signature (1)");
                }
                if (auto *tinfo = detail::get_type_info(*t)) {
                    handle th((PyObject *) tinfo->type);
                    signature += th.attr("__module__").cast<std::string>() + "."
                                 + th.attr("__qualname__").cast<std::string>();
                } else if (rec->is_new_style_constructor && arg_index == 0) {
                    // A new-style `__init__` takes `self` as `value_and_holder`.
                    // Rewrite it to the proper class type.
                    signature += rec->scope.attr("__module__").cast<std::string>() + "."
                                 + rec->scope.attr("__qualname__").cast<std::string>();
                } else {
                    signature += detail::quote_cpp_type_name(detail::clean_type_id(t->name()));
                }
            } else {
                signature += c;
            }
        }

        if (arg_index != args - rec->has_args - rec->has_kwargs || types[type_index] != nullptr) {
            pybind11_fail("Internal error while parsing type signature (2)");
        }

        rec->signature = guarded_strdup(signature.c_str());
        rec->args.shrink_to_fit();
        rec->nargs = (std::uint16_t) args;

        if (rec->sibling && PYBIND11_INSTANCE_METHOD_CHECK(rec->sibling.ptr())) {
            rec->sibling = PYBIND11_INSTANCE_METHOD_GET_FUNCTION(rec->sibling.ptr());
        }

        detail::function_record *chain = nullptr, *chain_start = rec;
        if (rec->sibling) {
            if (PyCFunction_Check(rec->sibling.ptr())) {
                auto *self = PyCFunction_GET_SELF(rec->sibling.ptr());
                if (!isinstance<capsule>(self)) {
                    chain = nullptr;
                } else {
                    auto rec_capsule = reinterpret_borrow<capsule>(self);
                    if (detail::is_function_record_capsule(rec_capsule)) {
                        chain = rec_capsule.get_pointer<detail::function_record>();
                        /* Never append a method to an overload chain of a parent class;
                           instead, hide the parent's overloads in this case */
                        if (!chain->scope.is(rec->scope)) {
                            chain = nullptr;
                        }
                    } else {
                        chain = nullptr;
                    }
                }
            }
            // Don't trigger for things like the default __init__, which are wrapper_descriptors
            // that we are intentionally replacing
            else if (!rec->sibling.is_none() && rec->name[0] != '_') {
                pybind11_fail("Cannot overload existing non-function object \""
                              + std::string(rec->name) + "\" with a function of the same name");
            }
        }

        if (!chain) {
            /* No existing overload was found, create a new function object */
            rec->def = new PyMethodDef();
            std::memset(rec->def, 0, sizeof(PyMethodDef));
            rec->def->ml_name = rec->name;
            rec->def->ml_meth
                = reinterpret_cast<PyCFunction>(reinterpret_cast<void (*)()>(dispatcher));
            rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS;

            capsule rec_capsule(unique_rec.release(),
                                detail::get_function_record_capsule_name(),
                                [](void *ptr) { destruct((detail::function_record *) ptr); });
            guarded_strdup.release();

            object scope_module;
            if (rec->scope) {
                if (hasattr(rec->scope, "__module__")) {
                    scope_module = rec->scope.attr("__module__");
                } else if (hasattr(rec->scope, "__name__")) {
                    scope_module = rec->scope.attr("__name__");
                }
            }

            m_ptr = PyCFunction_NewEx(rec->def, rec_capsule.ptr(), scope_module.ptr());
            if (!m_ptr) {
                pybind11_fail("cpp_function::cpp_function(): Could not allocate function object");
            }
        } else {
            /* Append at the beginning or end of the overload chain */
            m_ptr = rec->sibling.ptr();
            inc_ref();
            if (chain->is_method != rec->is_method) {
                pybind11_fail(
                    "overloading a method with both static and instance methods is not supported; "
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
                    "#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more "
                    "details"
#else
                    "error while attempting to bind "
                    + std::string(rec->is_method ? "instance" : "static") + " method "
                    + std::string(pybind11::str(rec->scope.attr("__name__"))) + "."
                    + std::string(rec->name) + signature
#endif
                );
            }

            if (rec->prepend) {
                // Beginning of chain; we need to replace the capsule's current head-of-the-chain
                // pointer with this one, then make this one point to the previous head of the
                // chain.
                chain_start = rec;
                rec->next = chain;
                auto rec_capsule
                    = reinterpret_borrow<capsule>(((PyCFunctionObject *) m_ptr)->m_self);
                rec_capsule.set_pointer(unique_rec.release());
                guarded_strdup.release();
            } else {
                // Or end of chain (normal behavior)
                chain_start = chain;
                while (chain->next) {
                    chain = chain->next;
                }
                chain->next = unique_rec.release();
                guarded_strdup.release();
            }
        }

        std::string signatures;
        int index = 0;
        /* Create a nice pydoc rec including all signatures and
           docstrings of the functions in the overload chain */
        if (chain && options::show_function_signatures()) {
            // First a generic signature
            signatures += rec->name;
            signatures += "(*args, **kwargs)\n";
            signatures += "Overloaded function.\n\n";
        }
        // Then specific overload signatures
        bool first_user_def = true;
        for (auto *it = chain_start; it != nullptr; it = it->next) {
            if (options::show_function_signatures()) {
                if (index > 0) {
                    signatures += '\n';
                }
                if (chain) {
                    signatures += std::to_string(++index) + ". ";
                }
                signatures += rec->name;
                signatures += it->signature;
                signatures += '\n';
            }
            if (it->doc && it->doc[0] != '\0' && options::show_user_defined_docstrings()) {
                // If we're appending another docstring, and aren't printing function signatures,
                // we need to append a newline first:
                if (!options::show_function_signatures()) {
                    if (first_user_def) {
                        first_user_def = false;
                    } else {
                        signatures += '\n';
                    }
                }
                if (options::show_function_signatures()) {
                    signatures += '\n';
                }
                signatures += it->doc;
                if (options::show_function_signatures()) {
                    signatures += '\n';
                }
            }
        }

        /* Install docstring */
        auto *func = (PyCFunctionObject *) m_ptr;
        std::free(const_cast<char *>(func->m_ml->ml_doc));
        // Install docstring if it's non-empty (when at least one option is enabled)
        func->m_ml->ml_doc
            = signatures.empty() ? nullptr : PYBIND11_COMPAT_STRDUP(signatures.c_str());

        if (rec->is_method) {
            m_ptr = PYBIND11_INSTANCE_METHOD_NEW(m_ptr, rec->scope.ptr());
            if (!m_ptr) {
                pybind11_fail(
                    "cpp_function::cpp_function(): Could not allocate instance method object");
            }
            Py_DECREF(func);
        }
    }

    /// When a cpp_function is GCed, release any memory allocated by pybind11
    static void destruct(detail::function_record *rec, bool free_strings = true) {
// If on Python 3.9, check the interpreter "MICRO" (patch) version.
// If this is running on 3.9.0, we have to work around a bug.
#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9
        static bool is_zero = Py_GetVersion()[4] == '0';
#endif

        while (rec) {
            detail::function_record *next = rec->next;
            if (rec->free_data) {
                rec->free_data(rec);
            }
            // During initialization, these strings might not have been copied yet,
            // so they cannot be freed. Once the function has been created, they can.
            // Check `make_function_record` for more details.
            if (free_strings) {
                std::free((char *) rec->name);
                std::free((char *) rec->doc);
                std::free((char *) rec->signature);
                for (auto &arg : rec->args) {
                    std::free(const_cast<char *>(arg.name));
                    std::free(const_cast<char *>(arg.descr));
                }
            }
            for (auto &arg : rec->args) {
                arg.value.dec_ref();
            }
            if (rec->def) {
                std::free(const_cast<char *>(rec->def->ml_doc));
// Python 3.9.0 decref's these in the wrong order; rec->def
// If loaded on 3.9.0, let these leak (use Python 3.9.1 at runtime to fix)
// See https://github.com/python/cpython/pull/22670
#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9
                if (!is_zero) {
                    delete rec->def;
                }
#else
                delete rec->def;
#endif
            }
            delete rec;
            rec = next;
        }
    }

    /// Main dispatch logic for calls to functions bound using pybind11
    static PyObject *dispatcher(PyObject *self, PyObject *args_in, PyObject *kwargs_in) {
        using namespace detail;
        assert(isinstance<capsule>(self));

        /* Iterator over the list of potentially admissible overloads */
        const function_record *overloads = reinterpret_cast<function_record *>(
                                  PyCapsule_GetPointer(self, get_function_record_capsule_name())),
                              *current_overload = overloads;
        assert(overloads != nullptr);

        /* Need to know how many arguments + keyword arguments there are to pick the right
           overload */
        const auto n_args_in = (size_t) PyTuple_GET_SIZE(args_in);

        handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr,
               result = PYBIND11_TRY_NEXT_OVERLOAD;

        auto self_value_and_holder = value_and_holder();
        if (overloads->is_constructor) {
            if (!parent
                || !PyObject_TypeCheck(parent.ptr(), (PyTypeObject *) overloads->scope.ptr())) {
                set_error(PyExc_TypeError,
                          "__init__(self, ...) called with invalid or missing `self` argument");
                return nullptr;
            }

            auto *const tinfo = get_type_info((PyTypeObject *) overloads->scope.ptr());
            auto *const pi = reinterpret_cast<instance *>(parent.ptr());
            self_value_and_holder = pi->get_value_and_holder(tinfo, true);

            // If this value is already registered it must mean __init__ is invoked multiple times;
            // we really can't support that in C++, so just ignore the second __init__.
            if (self_value_and_holder.instance_registered()) {
                return none().release().ptr();
            }
        }

        try {
            // We do this in two passes: in the first pass, we load arguments with `convert=false`;
            // in the second, we allow conversion (except for arguments with an explicit
            // py::arg().noconvert()).  This lets us prefer calls without conversion, with
            // conversion as a fallback.
            std::vector<function_call> second_pass;

            // However, if there are no overloads, we can just skip the no-convert pass entirely
            const bool overloaded
                = current_overload != nullptr && current_overload->next != nullptr;

            for (; current_overload != nullptr; current_overload = current_overload->next) {

                /* For each overload:
                   1. Copy all positional arguments we were given, also checking to make sure that
                      named positional arguments weren't *also* specified via kwarg.
                   2. If we weren't given enough, try to make up the omitted ones by checking
                      whether they were provided by a kwarg matching the `py::arg("name")` name. If
                      so, use it (and remove it from kwargs); if not, see if the function binding
                      provided a default that we can use.
                   3. Ensure that either all keyword arguments were "consumed", or that the
                   function takes a kwargs argument to accept unconsumed kwargs.
                   4. Any positional arguments still left get put into a tuple (for args), and any
                      leftover kwargs get put into a dict.
                   5. Pack everything into a vector; if we have py::args or py::kwargs, they are an
                      extra tuple or dict at the end of the positional arguments.
                   6. Call the function call dispatcher (function_record::impl)

                   If one of these fail, move on to the next overload and keep trying until we get
                   a result other than PYBIND11_TRY_NEXT_OVERLOAD.
                 */

                const function_record &func = *current_overload;
                size_t num_args = func.nargs; // Number of positional arguments that we need
                if (func.has_args) {
                    --num_args; // (but don't count py::args
                }
                if (func.has_kwargs) {
                    --num_args; //  or py::kwargs)
                }
                size_t pos_args = func.nargs_pos;

                if (!func.has_args && n_args_in > pos_args) {
                    continue; // Too many positional arguments for this overload
                }

                if (n_args_in < pos_args && func.args.size() < pos_args) {
                    continue; // Not enough positional arguments given, and not enough defaults to
                              // fill in the blanks
                }

                function_call call(func, parent);

                // Protect std::min with parentheses
                size_t args_to_copy = (std::min)(pos_args, n_args_in);
                size_t args_copied = 0;

                // 0. Inject new-style `self` argument
                if (func.is_new_style_constructor) {
                    // The `value` may have been preallocated by an old-style `__init__`
                    // if it was a preceding candidate for overload resolution.
                    if (self_value_and_holder) {
                        self_value_and_holder.type->dealloc(self_value_and_holder);
                    }

                    call.init_self = PyTuple_GET_ITEM(args_in, 0);
                    call.args.emplace_back(reinterpret_cast<PyObject *>(&self_value_and_holder));
                    call.args_convert.push_back(false);
                    ++args_copied;
                }

                // 1. Copy any position arguments given.
                bool bad_arg = false;
                for (; args_copied < args_to_copy; ++args_copied) {
                    const argument_record *arg_rec
                        = args_copied < func.args.size() ? &func.args[args_copied] : nullptr;
                    if (kwargs_in && arg_rec && arg_rec->name
                        && dict_getitemstring(kwargs_in, arg_rec->name)) {
                        bad_arg = true;
                        break;
                    }

                    handle arg(PyTuple_GET_ITEM(args_in, args_copied));
                    if (arg_rec && !arg_rec->none && arg.is_none()) {
                        bad_arg = true;
                        break;
                    }
                    call.args.push_back(arg);
                    call.args_convert.push_back(arg_rec ? arg_rec->convert : true);
                }
                if (bad_arg) {
                    continue; // Maybe it was meant for another overload (issue #688)
                }

                // Keep track of how many position args we copied out in case we need to come back
                // to copy the rest into a py::args argument.
                size_t positional_args_copied = args_copied;

                // We'll need to copy this if we steal some kwargs for defaults
                dict kwargs = reinterpret_borrow<dict>(kwargs_in);

                // 1.5. Fill in any missing pos_only args from defaults if they exist
                if (args_copied < func.nargs_pos_only) {
                    for (; args_copied < func.nargs_pos_only; ++args_copied) {
                        const auto &arg_rec = func.args[args_copied];
                        handle value;

                        if (arg_rec.value) {
                            value = arg_rec.value;
                        }
                        if (value) {
                            call.args.push_back(value);
                            call.args_convert.push_back(arg_rec.convert);
                        } else {
                            break;
                        }
                    }

                    if (args_copied < func.nargs_pos_only) {
                        continue; // Not enough defaults to fill the positional arguments
                    }
                }

                // 2. Check kwargs and, failing that, defaults that may help complete the list
                if (args_copied < num_args) {
                    bool copied_kwargs = false;

                    for (; args_copied < num_args; ++args_copied) {
                        const auto &arg_rec = func.args[args_copied];

                        handle value;
                        if (kwargs_in && arg_rec.name) {
                            value = dict_getitemstring(kwargs.ptr(), arg_rec.name);
                        }

                        if (value) {
                            // Consume a kwargs value
                            if (!copied_kwargs) {
                                kwargs = reinterpret_steal<dict>(PyDict_Copy(kwargs.ptr()));
                                copied_kwargs = true;
                            }
                            if (PyDict_DelItemString(kwargs.ptr(), arg_rec.name) == -1) {
                                throw error_already_set();
                            }
                        } else if (arg_rec.value) {
                            value = arg_rec.value;
                        }

                        if (!arg_rec.none && value.is_none()) {
                            break;
                        }

                        if (value) {
                            // If we're at the py::args index then first insert a stub for it to be
                            // replaced later
                            if (func.has_args && call.args.size() == func.nargs_pos) {
                                call.args.push_back(none());
                            }

                            call.args.push_back(value);
                            call.args_convert.push_back(arg_rec.convert);
                        } else {
                            break;
                        }
                    }

                    if (args_copied < num_args) {
                        continue; // Not enough arguments, defaults, or kwargs to fill the
                                  // positional arguments
                    }
                }

                // 3. Check everything was consumed (unless we have a kwargs arg)
                if (kwargs && !kwargs.empty() && !func.has_kwargs) {
                    continue; // Unconsumed kwargs, but no py::kwargs argument to accept them
                }

                // 4a. If we have a py::args argument, create a new tuple with leftovers
                if (func.has_args) {
                    tuple extra_args;
                    if (args_to_copy == 0) {
                        // We didn't copy out any position arguments from the args_in tuple, so we
                        // can reuse it directly without copying:
                        extra_args = reinterpret_borrow<tuple>(args_in);
                    } else if (positional_args_copied >= n_args_in) {
                        extra_args = tuple(0);
                    } else {
                        size_t args_size = n_args_in - positional_args_copied;
                        extra_args = tuple(args_size);
                        for (size_t i = 0; i < args_size; ++i) {
                            extra_args[i] = PyTuple_GET_ITEM(args_in, positional_args_copied + i);
                        }
                    }
                    if (call.args.size() <= func.nargs_pos) {
                        call.args.push_back(extra_args);
                    } else {
                        call.args[func.nargs_pos] = extra_args;
                    }
                    call.args_convert.push_back(false);
                    call.args_ref = std::move(extra_args);
                }

                // 4b. If we have a py::kwargs, pass on any remaining kwargs
                if (func.has_kwargs) {
                    if (!kwargs.ptr()) {
                        kwargs = dict(); // If we didn't get one, send an empty one
                    }
                    call.args.push_back(kwargs);
                    call.args_convert.push_back(false);
                    call.kwargs_ref = std::move(kwargs);
                }

// 5. Put everything in a vector.  Not technically step 5, we've been building it
// in `call.args` all along.
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
                if (call.args.size() != func.nargs || call.args_convert.size() != func.nargs) {
                    pybind11_fail("Internal error: function call dispatcher inserted wrong number "
                                  "of arguments!");
                }
#endif

                std::vector<bool> second_pass_convert;
                if (overloaded) {
                    // We're in the first no-convert pass, so swap out the conversion flags for a
                    // set of all-false flags.  If the call fails, we'll swap the flags back in for
                    // the conversion-allowed call below.
                    second_pass_convert.resize(func.nargs, false);
                    call.args_convert.swap(second_pass_convert);
                }

                // 6. Call the function.
                try {
                    loader_life_support guard{};
                    result = func.impl(call);
                } catch (reference_cast_error &) {
                    result = PYBIND11_TRY_NEXT_OVERLOAD;
                }

                if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) {
                    break;
                }

                if (overloaded) {
                    // The (overloaded) call failed; if the call has at least one argument that
                    // permits conversion (i.e. it hasn't been explicitly specified `.noconvert()`)
                    // then add this call to the list of second pass overloads to try.
                    for (size_t i = func.is_method ? 1 : 0; i < pos_args; i++) {
                        if (second_pass_convert[i]) {
                            // Found one: swap the converting flags back in and store the call for
                            // the second pass.
                            call.args_convert.swap(second_pass_convert);
                            second_pass.push_back(std::move(call));
                            break;
                        }
                    }
                }
            }

            if (overloaded && !second_pass.empty() && result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) {
                // The no-conversion pass finished without success, try again with conversion
                // allowed
                for (auto &call : second_pass) {
                    try {
                        loader_life_support guard{};
                        result = call.func.impl(call);
                    } catch (reference_cast_error &) {
                        result = PYBIND11_TRY_NEXT_OVERLOAD;
                    }

                    if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) {
                        // The error reporting logic below expects 'current_overload' to be valid,
                        // as it would be if we'd encountered this failure in the first-pass loop.
                        if (!result) {
                            current_overload = &call.func;
                        }
                        break;
                    }
                }
            }
        } catch (error_already_set &e) {
            e.restore();
            return nullptr;
#ifdef __GLIBCXX__
        } catch (abi::__forced_unwind &) {
            throw;
#endif
        } catch (...) {
            /* When an exception is caught, give each registered exception
               translator a chance to translate it to a Python exception. First
               all module-local translators will be tried in reverse order of
               registration. If none of the module-locale translators handle
               the exception (or there are no module-locale translators) then
               the global translators will be tried, also in reverse order of
               registration.

               A translator may choose to do one of the following:

                - catch the exception and call py::set_error()
                  to set a standard (or custom) Python exception, or
                - do nothing and let the exception fall through to the next translator, or
                - delegate translation to the next translator by throwing a new type of exception.
             */

            bool handled = with_internals([&](internals &internals) {
                auto &local_exception_translators
                    = get_local_internals().registered_exception_translators;
                if (detail::apply_exception_translators(local_exception_translators)) {
                    return true;
                }
                auto &exception_translators = internals.registered_exception_translators;
                if (detail::apply_exception_translators(exception_translators)) {
                    return true;
                }
                return false;
            });

            if (handled) {
                return nullptr;
            }

            set_error(PyExc_SystemError, "Exception escaped from default exception translator!");
            return nullptr;
        }

        auto append_note_if_missing_header_is_suspected = [](std::string &msg) {
            if (msg.find("std::") != std::string::npos) {
                msg += "\n\n"
                       "Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,\n"
                       "<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic\n"
                       "conversions are optional and require extra headers to be included\n"
                       "when compiling your pybind11 module.";
            }
        };

        if (result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) {
            if (overloads->is_operator) {
                return handle(Py_NotImplemented).inc_ref().ptr();
            }

            std::string msg = std::string(overloads->name) + "(): incompatible "
                              + std::string(overloads->is_constructor ? "constructor" : "function")
                              + " arguments. The following argument types are supported:\n";

            int ctr = 0;
            for (const function_record *it2 = overloads; it2 != nullptr; it2 = it2->next) {
                msg += "    " + std::to_string(++ctr) + ". ";

                bool wrote_sig = false;
                if (overloads->is_constructor) {
                    // For a constructor, rewrite `(self: Object, arg0, ...) -> NoneType` as
                    // `Object(arg0, ...)`
                    std::string sig = it2->signature;
                    size_t start = sig.find('(') + 7; // skip "(self: "
                    if (start < sig.size()) {
                        // End at the , for the next argument
                        size_t end = sig.find(", "), next = end + 2;
                        size_t ret = sig.rfind(" -> ");
                        // Or the ), if there is no comma:
                        if (end >= sig.size()) {
                            next = end = sig.find(')');
                        }
                        if (start < end && next < sig.size()) {
                            msg.append(sig, start, end - start);
                            msg += '(';
                            msg.append(sig, next, ret - next);
                            wrote_sig = true;
                        }
                    }
                }
                if (!wrote_sig) {
                    msg += it2->signature;
                }

                msg += '\n';
            }
            msg += "\nInvoked with: ";
            auto args_ = reinterpret_borrow<tuple>(args_in);
            bool some_args = false;
            for (size_t ti = overloads->is_constructor ? 1 : 0; ti < args_.size(); ++ti) {
                if (!some_args) {
                    some_args = true;
                } else {
                    msg += ", ";
                }
                try {
                    msg += pybind11::repr(args_[ti]);
                } catch (const error_already_set &) {
                    msg += "<repr raised Error>";
                }
            }
            if (kwargs_in) {
                auto kwargs = reinterpret_borrow<dict>(kwargs_in);
                if (!kwargs.empty()) {
                    if (some_args) {
                        msg += "; ";
                    }
                    msg += "kwargs: ";
                    bool first = true;
                    for (const auto &kwarg : kwargs) {
                        if (first) {
                            first = false;
                        } else {
                            msg += ", ";
                        }
                        msg += pybind11::str("{}=").format(kwarg.first);
                        try {
                            msg += pybind11::repr(kwarg.second);
                        } catch (const error_already_set &) {
                            msg += "<repr raised Error>";
                        }
                    }
                }
            }

            append_note_if_missing_header_is_suspected(msg);
            // Attach additional error info to the exception if supported
            if (PyErr_Occurred()) {
                // #HelpAppreciated: unit test coverage for this branch.
                raise_from(PyExc_TypeError, msg.c_str());
                return nullptr;
            }
            set_error(PyExc_TypeError, msg.c_str());
            return nullptr;
        }
        if (!result) {
            std::string msg = "Unable to convert function return value to a "
                              "Python type! The signature was\n\t";
            assert(current_overload != nullptr);
            msg += current_overload->signature;
            append_note_if_missing_header_is_suspected(msg);
            // Attach additional error info to the exception if supported
            if (PyErr_Occurred()) {
                raise_from(PyExc_TypeError, msg.c_str());
                return nullptr;
            }
            set_error(PyExc_TypeError, msg.c_str());
            return nullptr;
        }
        if (overloads->is_constructor && !self_value_and_holder.holder_constructed()) {
            auto *pi = reinterpret_cast<instance *>(parent.ptr());
            self_value_and_holder.type->init_instance(pi, nullptr);
        }
        return result.ptr();
    }
};

PYBIND11_NAMESPACE_BEGIN(detail)

template <>
struct handle_type_name<cpp_function> {
    static constexpr auto name = const_name("Callable");
};

PYBIND11_NAMESPACE_END(detail)

// Use to activate Py_MOD_GIL_NOT_USED.
class mod_gil_not_used {
public:
    explicit mod_gil_not_used(bool flag = true) : flag_(flag) {}
    bool flag() const { return flag_; }

private:
    bool flag_;
};

/// Wrapper for Python extension modules
class module_ : public object {
public:
    PYBIND11_OBJECT_DEFAULT(module_, object, PyModule_Check)

    /// Create a new top-level Python module with the given name and docstring
    PYBIND11_DEPRECATED("Use PYBIND11_MODULE or module_::create_extension_module instead")
    explicit module_(const char *name, const char *doc = nullptr) {
        *this = create_extension_module(name, doc, new PyModuleDef());
    }

    /** \rst
        Create Python binding for a new function within the module scope. ``Func``
        can be a plain C++ function, a function pointer, or a lambda function. For
        details on the ``Extra&& ... extra`` argument, see section :ref:`extras`.
    \endrst */
    template <typename Func, typename... Extra>
    module_ &def(const char *name_, Func &&f, const Extra &...extra) {
        cpp_function func(std::forward<Func>(f),
                          name(name_),
                          scope(*this),
                          sibling(getattr(*this, name_, none())),
                          extra...);
        // NB: allow overwriting here because cpp_function sets up a chain with the intention of
        // overwriting (and has already checked internally that it isn't overwriting
        // non-functions).
        add_object(name_, func, true /* overwrite */);
        return *this;
    }

    /** \rst
        Create and return a new Python submodule with the given name and docstring.
        This also works recursively, i.e.

        .. code-block:: cpp

            py::module_ m("example", "pybind11 example plugin");
            py::module_ m2 = m.def_submodule("sub", "A submodule of 'example'");
            py::module_ m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'");
    \endrst */
    module_ def_submodule(const char *name, const char *doc = nullptr) {
        const char *this_name = PyModule_GetName(m_ptr);
        if (this_name == nullptr) {
            throw error_already_set();
        }
        std::string full_name = std::string(this_name) + '.' + name;
        handle submodule = PyImport_AddModule(full_name.c_str());
        if (!submodule) {
            throw error_already_set();
        }
        auto result = reinterpret_borrow<module_>(submodule);
        if (doc && options::show_user_defined_docstrings()) {
            result.attr("__doc__") = pybind11::str(doc);
        }
        attr(name) = result;
        return result;
    }

    /// Import and return a module or throws `error_already_set`.
    static module_ import(const char *name) {
        PyObject *obj = PyImport_ImportModule(name);
        if (!obj) {
            throw error_already_set();
        }
        return reinterpret_steal<module_>(obj);
    }

    /// Reload the module or throws `error_already_set`.
    void reload() {
        PyObject *obj = PyImport_ReloadModule(ptr());
        if (!obj) {
            throw error_already_set();
        }
        *this = reinterpret_steal<module_>(obj);
    }

    /** \rst
        Adds an object to the module using the given name.  Throws if an object with the given name
        already exists.

        ``overwrite`` should almost always be false: attempting to overwrite objects that pybind11
        has established will, in most cases, break things.
    \endrst */
    PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) {
        if (!overwrite && hasattr(*this, name)) {
            pybind11_fail(
                "Error during initialization: multiple incompatible definitions with name \""
                + std::string(name) + "\"");
        }

        PyModule_AddObject(ptr(), name, obj.inc_ref().ptr() /* steals a reference */);
    }

    using module_def = PyModuleDef; // TODO: Can this be removed (it was needed only for Python 2)?

    /** \rst
        Create a new top-level module that can be used as the main module of a C extension.

        ``def`` should point to a statically allocated module_def.
    \endrst */
    static module_ create_extension_module(const char *name,
                                           const char *doc,
                                           module_def *def,
                                           mod_gil_not_used gil_not_used
                                           = mod_gil_not_used(false)) {
        // module_def is PyModuleDef
        // Placement new (not an allocation).
        def = new (def)
            PyModuleDef{/* m_base */ PyModuleDef_HEAD_INIT,
                        /* m_name */ name,
                        /* m_doc */ options::show_user_defined_docstrings() ? doc : nullptr,
                        /* m_size */ -1,
                        /* m_methods */ nullptr,
                        /* m_slots */ nullptr,
                        /* m_traverse */ nullptr,
                        /* m_clear */ nullptr,
                        /* m_free */ nullptr};
        auto *m = PyModule_Create(def);
        if (m == nullptr) {
            if (PyErr_Occurred()) {
                throw error_already_set();
            }
            pybind11_fail("Internal error in module_::create_extension_module()");
        }
        if (gil_not_used.flag()) {
#ifdef Py_GIL_DISABLED
            PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
#endif
        }
        // TODO: Should be reinterpret_steal for Python 3, but Python also steals it again when
        //       returned from PyInit_...
        //       For Python 2, reinterpret_borrow was correct.
        return reinterpret_borrow<module_>(m);
    }
};

PYBIND11_NAMESPACE_BEGIN(detail)

template <>
struct handle_type_name<module_> {
    static constexpr auto name = const_name("module");
};

PYBIND11_NAMESPACE_END(detail)

// When inside a namespace (or anywhere as long as it's not the first item on a line),
// C++20 allows "module" to be used. This is provided for backward compatibility, and for
// simplicity, if someone wants to use py::module for example, that is perfectly safe.
using module = module_;

/// \ingroup python_builtins
/// Return a dictionary representing the global variables in the current execution frame,
/// or ``__main__.__dict__`` if there is no frame (usually when the interpreter is embedded).
inline dict globals() {
#if PY_VERSION_HEX >= 0x030d0000
    PyObject *p = PyEval_GetFrameGlobals();
    return p ? reinterpret_steal<dict>(p)
             : reinterpret_borrow<dict>(module_::import("__main__").attr("__dict__").ptr());
#else
    PyObject *p = PyEval_GetGlobals();
    return reinterpret_borrow<dict>(p ? p : module_::import("__main__").attr("__dict__").ptr());
#endif
}

template <typename... Args, typename = detail::enable_if_t<args_are_all_keyword_or_ds<Args...>()>>
PYBIND11_DEPRECATED("make_simple_namespace should be replaced with "
                    "py::module_::import(\"types\").attr(\"SimpleNamespace\") ")
object make_simple_namespace(Args &&...args_) {
    return module_::import("types").attr("SimpleNamespace")(std::forward<Args>(args_)...);
}

PYBIND11_NAMESPACE_BEGIN(detail)
/// Generic support for creating new Python heap types
class generic_type : public object {
public:
    PYBIND11_OBJECT_DEFAULT(generic_type, object, PyType_Check)
protected:
    void initialize(const type_record &rec) {
        if (rec.scope && hasattr(rec.scope, "__dict__")
            && rec.scope.attr("__dict__").contains(rec.name)) {
            pybind11_fail("generic_type: cannot initialize type \"" + std::string(rec.name)
                          + "\": an object with that name is already defined");
        }

        if ((rec.module_local ? get_local_type_info(*rec.type) : get_global_type_info(*rec.type))
            != nullptr) {
            pybind11_fail("generic_type: type \"" + std::string(rec.name)
                          + "\" is already registered!");
        }

        m_ptr = make_new_python_type(rec);

        /* Register supplemental type information in C++ dict */
        auto *tinfo = new detail::type_info();
        tinfo->type = (PyTypeObject *) m_ptr;
        tinfo->cpptype = rec.type;
        tinfo->type_size = rec.type_size;
        tinfo->type_align = rec.type_align;
        tinfo->operator_new = rec.operator_new;
        tinfo->holder_size_in_ptrs = size_in_ptrs(rec.holder_size);
        tinfo->init_instance = rec.init_instance;
        tinfo->dealloc = rec.dealloc;
        tinfo->simple_type = true;
        tinfo->simple_ancestors = true;
        tinfo->default_holder = rec.default_holder;
        tinfo->module_local = rec.module_local;

        with_internals([&](internals &internals) {
            auto tindex = std::type_index(*rec.type);
            tinfo->direct_conversions = &internals.direct_conversions[tindex];
            if (rec.module_local) {
                get_local_internals().registered_types_cpp[tindex] = tinfo;
            } else {
                internals.registered_types_cpp[tindex] = tinfo;
            }
            internals.registered_types_py[(PyTypeObject *) m_ptr] = {tinfo};
        });

        if (rec.bases.size() > 1 || rec.multiple_inheritance) {
            mark_parents_nonsimple(tinfo->type);
            tinfo->simple_ancestors = false;
        } else if (rec.bases.size() == 1) {
            auto *parent_tinfo = get_type_info((PyTypeObject *) rec.bases[0].ptr());
            assert(parent_tinfo != nullptr);
            bool parent_simple_ancestors = parent_tinfo->simple_ancestors;
            tinfo->simple_ancestors = parent_simple_ancestors;
            // The parent can no longer be a simple type if it has MI and has a child
            parent_tinfo->simple_type = parent_tinfo->simple_type && parent_simple_ancestors;
        }

        if (rec.module_local) {
            // Stash the local typeinfo and loader so that external modules can access it.
            tinfo->module_local_load = &type_caster_generic::local_load;
            setattr(m_ptr, PYBIND11_MODULE_LOCAL_ID, capsule(tinfo));
        }
    }

    /// Helper function which tags all parents of a type using mult. inheritance
    void mark_parents_nonsimple(PyTypeObject *value) {
        auto t = reinterpret_borrow<tuple>(value->tp_bases);
        for (handle h : t) {
            auto *tinfo2 = get_type_info((PyTypeObject *) h.ptr());
            if (tinfo2) {
                tinfo2->simple_type = false;
            }
            mark_parents_nonsimple((PyTypeObject *) h.ptr());
        }
    }

    void install_buffer_funcs(buffer_info *(*get_buffer)(PyObject *, void *),
                              void *get_buffer_data) {
        auto *type = (PyHeapTypeObject *) m_ptr;
        auto *tinfo = detail::get_type_info(&type->ht_type);

        if (!type->ht_type.tp_as_buffer) {
            pybind11_fail("To be able to register buffer protocol support for the type '"
                          + get_fully_qualified_tp_name(tinfo->type)
                          + "' the associated class<>(..) invocation must "
                            "include the pybind11::buffer_protocol() annotation!");
        }

        tinfo->get_buffer = get_buffer;
        tinfo->get_buffer_data = get_buffer_data;
    }

    // rec_func must be set for either fget or fset.
    void def_property_static_impl(const char *name,
                                  handle fget,
                                  handle fset,
                                  detail::function_record *rec_func) {
        const auto is_static = (rec_func != nullptr) && !(rec_func->is_method && rec_func->scope);
        const auto has_doc = (rec_func != nullptr) && (rec_func->doc != nullptr)
                             && pybind11::options::show_user_defined_docstrings();
        auto property = handle(
            (PyObject *) (is_static ? get_internals().static_property_type : &PyProperty_Type));
        attr(name) = property(fget.ptr() ? fget : none(),
                              fset.ptr() ? fset : none(),
                              /*deleter*/ none(),
                              pybind11::str(has_doc ? rec_func->doc : ""));
    }
};

/// Set the pointer to operator new if it exists. The cast is needed because it can be overloaded.
template <typename T,
          typename = void_t<decltype(static_cast<void *(*) (size_t)>(T::operator new))>>
void set_operator_new(type_record *r) {
    r->operator_new = &T::operator new;
}

template <typename>
void set_operator_new(...) {}

template <typename T, typename SFINAE = void>
struct has_operator_delete : std::false_type {};
template <typename T>
struct has_operator_delete<T, void_t<decltype(static_cast<void (*)(void *)>(T::operator delete))>>
    : std::true_type {};
template <typename T, typename SFINAE = void>
struct has_operator_delete_size : std::false_type {};
template <typename T>
struct has_operator_delete_size<
    T,
    void_t<decltype(static_cast<void (*)(void *, size_t)>(T::operator delete))>> : std::true_type {
};
/// Call class-specific delete if it exists or global otherwise. Can also be an overload set.
template <typename T, enable_if_t<has_operator_delete<T>::value, int> = 0>
void call_operator_delete(T *p, size_t, size_t) {
    T::operator delete(p);
}
template <typename T,
          enable_if_t<!has_operator_delete<T>::value && has_operator_delete_size<T>::value, int>
          = 0>
void call_operator_delete(T *p, size_t s, size_t) {
    T::operator delete(p, s);
}

inline void call_operator_delete(void *p, size_t s, size_t a) {
    (void) s;
    (void) a;
#if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912)
    if (a > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
#    ifdef __cpp_sized_deallocation
        ::operator delete(p, s, std::align_val_t(a));
#    else
        ::operator delete(p, std::align_val_t(a));
#    endif
        return;
    }
#endif
#ifdef __cpp_sized_deallocation
    ::operator delete(p, s);
#else
    ::operator delete(p);
#endif
}

inline void add_class_method(object &cls, const char *name_, const cpp_function &cf) {
    cls.attr(cf.name()) = cf;
    if (std::strcmp(name_, "__eq__") == 0 && !cls.attr("__dict__").contains("__hash__")) {
        cls.attr("__hash__") = none();
    }
}

PYBIND11_NAMESPACE_END(detail)

/// Given a pointer to a member function, cast it to its `Derived` version.
/// Forward everything else unchanged.
template <typename /*Derived*/, typename F>
auto method_adaptor(F &&f) -> decltype(std::forward<F>(f)) {
    return std::forward<F>(f);
}

template <typename Derived, typename Return, typename Class, typename... Args>
auto method_adaptor(Return (Class::*pmf)(Args...)) -> Return (Derived::*)(Args...) {
    static_assert(
        detail::is_accessible_base_of<Class, Derived>::value,
        "Cannot bind an inaccessible base class method; use a lambda definition instead");
    return pmf;
}

template <typename Derived, typename Return, typename Class, typename... Args>
auto method_adaptor(Return (Class::*pmf)(Args...) const) -> Return (Derived::*)(Args...) const {
    static_assert(
        detail::is_accessible_base_of<Class, Derived>::value,
        "Cannot bind an inaccessible base class method; use a lambda definition instead");
    return pmf;
}

template <typename type_, typename... options>
class class_ : public detail::generic_type {
    template <typename T>
    using is_holder = detail::is_holder_type<type_, T>;
    template <typename T>
    using is_subtype = detail::is_strict_base_of<type_, T>;
    template <typename T>
    using is_base = detail::is_strict_base_of<T, type_>;
    // struct instead of using here to help MSVC:
    template <typename T>
    struct is_valid_class_option : detail::any_of<is_holder<T>, is_subtype<T>, is_base<T>> {};

public:
    using type = type_;
    using type_alias = detail::exactly_one_t<is_subtype, void, options...>;
    constexpr static bool has_alias = !std::is_void<type_alias>::value;
    using holder_type = detail::exactly_one_t<is_holder, std::unique_ptr<type>, options...>;

    static_assert(detail::all_of<is_valid_class_option<options>...>::value,
                  "Unknown/invalid class_ template parameters provided");

    static_assert(!has_alias || std::is_polymorphic<type>::value,
                  "Cannot use an alias class with a non-polymorphic type");

    PYBIND11_OBJECT(class_, generic_type, PyType_Check)

    template <typename... Extra>
    class_(handle scope, const char *name, const Extra &...extra) {
        using namespace detail;

        // MI can only be specified via class_ template options, not constructor parameters
        static_assert(
            none_of<is_pyobject<Extra>...>::value || // no base class arguments, or:
                (constexpr_sum(is_pyobject<Extra>::value...) == 1 && // Exactly one base
                 constexpr_sum(is_base<options>::value...) == 0 &&   // no template option bases
                 // no multiple_inheritance attr
                 none_of<std::is_same<multiple_inheritance, Extra>...>::value),
            "Error: multiple inheritance bases must be specified via class_ template options");

        type_record record;
        record.scope = scope;
        record.name = name;
        record.type = &typeid(type);
        record.type_size = sizeof(conditional_t<has_alias, type_alias, type>);
        record.type_align = alignof(conditional_t<has_alias, type_alias, type> &);
        record.holder_size = sizeof(holder_type);
        record.init_instance = init_instance;
        record.dealloc = dealloc;
        record.default_holder = detail::is_instantiation<std::unique_ptr, holder_type>::value;

        set_operator_new<type>(&record);

        /* Register base classes specified via template arguments to class_, if any */
        PYBIND11_EXPAND_SIDE_EFFECTS(add_base<options>(record));

        /* Process optional arguments, if any */
        process_attributes<Extra...>::init(extra..., &record);

        generic_type::initialize(record);

        if (has_alias) {
            with_internals([&](internals &internals) {
                auto &instances = record.module_local ? get_local_internals().registered_types_cpp
                                                      : internals.registered_types_cpp;
                instances[std::type_index(typeid(type_alias))]
                    = instances[std::type_index(typeid(type))];
            });
        }
    }

    template <typename Base, detail::enable_if_t<is_base<Base>::value, int> = 0>
    static void add_base(detail::type_record &rec) {
        rec.add_base(typeid(Base), [](void *src) -> void * {
            return static_cast<Base *>(reinterpret_cast<type *>(src));
        });
    }

    template <typename Base, detail::enable_if_t<!is_base<Base>::value, int> = 0>
    static void add_base(detail::type_record &) {}

    template <typename Func, typename... Extra>
    class_ &def(const char *name_, Func &&f, const Extra &...extra) {
        cpp_function cf(method_adaptor<type>(std::forward<Func>(f)),
                        name(name_),
                        is_method(*this),
                        sibling(getattr(*this, name_, none())),
                        extra...);
        add_class_method(*this, name_, cf);
        return *this;
    }

    template <typename Func, typename... Extra>
    class_ &def_static(const char *name_, Func &&f, const Extra &...extra) {
        static_assert(!std::is_member_function_pointer<Func>::value,
                      "def_static(...) called with a non-static member function pointer");
        cpp_function cf(std::forward<Func>(f),
                        name(name_),
                        scope(*this),
                        sibling(getattr(*this, name_, none())),
                        extra...);
        auto cf_name = cf.name();
        attr(std::move(cf_name)) = staticmethod(std::move(cf));
        return *this;
    }

    template <typename T, typename... Extra, detail::enable_if_t<T::op_enable_if_hook, int> = 0>
    class_ &def(const T &op, const Extra &...extra) {
        op.execute(*this, extra...);
        return *this;
    }

    template <typename T, typename... Extra, detail::enable_if_t<T::op_enable_if_hook, int> = 0>
    class_ &def_cast(const T &op, const Extra &...extra) {
        op.execute_cast(*this, extra...);
        return *this;
    }

    template <typename... Args, typename... Extra>
    class_ &def(const detail::initimpl::constructor<Args...> &init, const Extra &...extra) {
        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(init);
        init.execute(*this, extra...);
        return *this;
    }

    template <typename... Args, typename... Extra>
    class_ &def(const detail::initimpl::alias_constructor<Args...> &init, const Extra &...extra) {
        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(init);
        init.execute(*this, extra...);
        return *this;
    }

    template <typename... Args, typename... Extra>
    class_ &def(detail::initimpl::factory<Args...> &&init, const Extra &...extra) {
        std::move(init).execute(*this, extra...);
        return *this;
    }

    template <typename... Args, typename... Extra>
    class_ &def(detail::initimpl::pickle_factory<Args...> &&pf, const Extra &...extra) {
        std::move(pf).execute(*this, extra...);
        return *this;
    }

    template <typename Func>
    class_ &def_buffer(Func &&func) {
        struct capture {
            Func func;
        };
        auto *ptr = new capture{std::forward<Func>(func)};
        install_buffer_funcs(
            [](PyObject *obj, void *ptr) -> buffer_info * {
                detail::make_caster<type> caster;
                if (!caster.load(obj, false)) {
                    return nullptr;
                }
                return new buffer_info(((capture *) ptr)->func(std::move(caster)));
            },
            ptr);
        weakref(m_ptr, cpp_function([ptr](handle wr) {
                    delete ptr;
                    wr.dec_ref();
                }))
            .release();
        return *this;
    }

    template <typename Return, typename Class, typename... Args>
    class_ &def_buffer(Return (Class::*func)(Args...)) {
        return def_buffer([func](type &obj) { return (obj.*func)(); });
    }

    template <typename Return, typename Class, typename... Args>
    class_ &def_buffer(Return (Class::*func)(Args...) const) {
        return def_buffer([func](const type &obj) { return (obj.*func)(); });
    }

    template <typename C, typename D, typename... Extra>
    class_ &def_readwrite(const char *name, D C::*pm, const Extra &...extra) {
        static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value,
                      "def_readwrite() requires a class member (or base class member)");
        cpp_function fget([pm](const type &c) -> const D & { return c.*pm; }, is_method(*this)),
            fset([pm](type &c, const D &value) { c.*pm = value; }, is_method(*this));
        def_property(name, fget, fset, return_value_policy::reference_internal, extra...);
        return *this;
    }

    template <typename C, typename D, typename... Extra>
    class_ &def_readonly(const char *name, const D C::*pm, const Extra &...extra) {
        static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value,
                      "def_readonly() requires a class member (or base class member)");
        cpp_function fget([pm](const type &c) -> const D & { return c.*pm; }, is_method(*this));
        def_property_readonly(name, fget, return_value_policy::reference_internal, extra...);
        return *this;
    }

    template <typename D, typename... Extra>
    class_ &def_readwrite_static(const char *name, D *pm, const Extra &...extra) {
        cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this)),
            fset([pm](const object &, const D &value) { *pm = value; }, scope(*this));
        def_property_static(name, fget, fset, return_value_policy::reference, extra...);
        return *this;
    }

    template <typename D, typename... Extra>
    class_ &def_readonly_static(const char *name, const D *pm, const Extra &...extra) {
        cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this));
        def_property_readonly_static(name, fget, return_value_policy::reference, extra...);
        return *this;
    }

    /// Uses return_value_policy::reference_internal by default
    template <typename Getter, typename... Extra>
    class_ &def_property_readonly(const char *name, const Getter &fget, const Extra &...extra) {
        return def_property_readonly(name,
                                     cpp_function(method_adaptor<type>(fget)),
                                     return_value_policy::reference_internal,
                                     extra...);
    }

    /// Uses cpp_function's return_value_policy by default
    template <typename... Extra>
    class_ &
    def_property_readonly(const char *name, const cpp_function &fget, const Extra &...extra) {
        return def_property(name, fget, nullptr, extra...);
    }

    /// Uses return_value_policy::reference by default
    template <typename Getter, typename... Extra>
    class_ &
    def_property_readonly_static(const char *name, const Getter &fget, const Extra &...extra) {
        return def_property_readonly_static(
            name, cpp_function(fget), return_value_policy::reference, extra...);
    }

    /// Uses cpp_function's return_value_policy by default
    template <typename... Extra>
    class_ &def_property_readonly_static(const char *name,
                                         const cpp_function &fget,
                                         const Extra &...extra) {
        return def_property_static(name, fget, nullptr, extra...);
    }

    /// Uses return_value_policy::reference_internal by default
    template <typename Getter, typename Setter, typename... Extra>
    class_ &
    def_property(const char *name, const Getter &fget, const Setter &fset, const Extra &...extra) {
        return def_property(
            name, fget, cpp_function(method_adaptor<type>(fset), is_setter()), extra...);
    }
    template <typename Getter, typename... Extra>
    class_ &def_property(const char *name,
                         const Getter &fget,
                         const cpp_function &fset,
                         const Extra &...extra) {
        return def_property(name,
                            cpp_function(method_adaptor<type>(fget)),
                            fset,
                            return_value_policy::reference_internal,
                            extra...);
    }

    /// Uses cpp_function's return_value_policy by default
    template <typename... Extra>
    class_ &def_property(const char *name,
                         const cpp_function &fget,
                         const cpp_function &fset,
                         const Extra &...extra) {
        return def_property_static(name, fget, fset, is_method(*this), extra...);
    }

    /// Uses return_value_policy::reference by default
    template <typename Getter, typename... Extra>
    class_ &def_property_static(const char *name,
                                const Getter &fget,
                                const cpp_function &fset,
                                const Extra &...extra) {
        return def_property_static(
            name, cpp_function(fget), fset, return_value_policy::reference, extra...);
    }

    /// Uses cpp_function's return_value_policy by default
    template <typename... Extra>
    class_ &def_property_static(const char *name,
                                const cpp_function &fget,
                                const cpp_function &fset,
                                const Extra &...extra) {
        static_assert(0 == detail::constexpr_sum(std::is_base_of<arg, Extra>::value...),
                      "Argument annotations are not allowed for properties");
        auto rec_fget = get_function_record(fget), rec_fset = get_function_record(fset);
        auto *rec_active = rec_fget;
        if (rec_fget) {
            char *doc_prev = rec_fget->doc; /* 'extra' field may include a property-specific
                                               documentation string */
            detail::process_attributes<Extra...>::init(extra..., rec_fget);
            if (rec_fget->doc && rec_fget->doc != doc_prev) {
                std::free(doc_prev);
                rec_fget->doc = PYBIND11_COMPAT_STRDUP(rec_fget->doc);
            }
        }
        if (rec_fset) {
            char *doc_prev = rec_fset->doc;
            detail::process_attributes<Extra...>::init(extra..., rec_fset);
            if (rec_fset->doc && rec_fset->doc != doc_prev) {
                std::free(doc_prev);
                rec_fset->doc = PYBIND11_COMPAT_STRDUP(rec_fset->doc);
            }
            if (!rec_active) {
                rec_active = rec_fset;
            }
        }
        def_property_static_impl(name, fget, fset, rec_active);
        return *this;
    }

private:
    /// Initialize holder object, variant 1: object derives from enable_shared_from_this
    template <typename T>
    static void init_holder(detail::instance *inst,
                            detail::value_and_holder &v_h,
                            const holder_type * /* unused */,
                            const std::enable_shared_from_this<T> * /* dummy */) {

        auto sh = std::dynamic_pointer_cast<typename holder_type::element_type>(
            detail::try_get_shared_from_this(v_h.value_ptr<type>()));
        if (sh) {
            new (std::addressof(v_h.holder<holder_type>())) holder_type(std::move(sh));
            v_h.set_holder_constructed();
        }

        if (!v_h.holder_constructed() && inst->owned) {
            new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
            v_h.set_holder_constructed();
        }
    }

    static void init_holder_from_existing(const detail::value_and_holder &v_h,
                                          const holder_type *holder_ptr,
                                          std::true_type /*is_copy_constructible*/) {
        new (std::addressof(v_h.holder<holder_type>()))
            holder_type(*reinterpret_cast<const holder_type *>(holder_ptr));
    }

    static void init_holder_from_existing(const detail::value_and_holder &v_h,
                                          const holder_type *holder_ptr,
                                          std::false_type /*is_copy_constructible*/) {
        new (std::addressof(v_h.holder<holder_type>()))
            holder_type(std::move(*const_cast<holder_type *>(holder_ptr)));
    }

    /// Initialize holder object, variant 2: try to construct from existing holder object, if
    /// possible
    static void init_holder(detail::instance *inst,
                            detail::value_and_holder &v_h,
                            const holder_type *holder_ptr,
                            const void * /* dummy -- not enable_shared_from_this<T>) */) {
        if (holder_ptr) {
            init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());
            v_h.set_holder_constructed();
        } else if (detail::always_construct_holder<holder_type>::value || inst->owned) {
            new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
            v_h.set_holder_constructed();
        }
    }

    /// Performs instance initialization including constructing a holder and registering the known
    /// instance.  Should be called as soon as the `type` value_ptr is set for an instance.  Takes
    /// an optional pointer to an existing holder to use; if not specified and the instance is
    /// `.owned`, a new holder will be constructed to manage the value pointer.
    static void init_instance(detail::instance *inst, const void *holder_ptr) {
		inst->has_alias = has_alias;
        auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type)));
        if (!v_h.instance_registered()) {
            register_instance(inst, v_h.value_ptr(), v_h.type);
            v_h.set_instance_registered();
        }
        init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>());
    }

    /// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
    static void dealloc(detail::value_and_holder &v_h) {
        // We could be deallocating because we are cleaning up after a Python exception.
        // If so, the Python error indicator will be set. We need to clear that before
        // running the destructor, in case the destructor code calls more Python.
        // If we don't, the Python API will exit with an exception, and pybind11 will
        // throw error_already_set from the C++ destructor which is forbidden and triggers
        // std::terminate().
        error_scope scope;
        if (v_h.holder_constructed()) {
            v_h.holder<holder_type>().~holder_type();
            v_h.set_holder_constructed(false);
        } else {
            detail::call_operator_delete(
                v_h.value_ptr<type>(), v_h.type->type_size, v_h.type->type_align);
        }
        v_h.value_ptr() = nullptr;
    }

    static detail::function_record *get_function_record(handle h) {
        h = detail::get_function(h);
        if (!h) {
            return nullptr;
        }

        handle func_self = PyCFunction_GET_SELF(h.ptr());
        if (!func_self) {
            throw error_already_set();
        }
        if (!isinstance<capsule>(func_self)) {
            return nullptr;
        }
        auto cap = reinterpret_borrow<capsule>(func_self);
        if (!detail::is_function_record_capsule(cap)) {
            return nullptr;
        }
        return cap.get_pointer<detail::function_record>();
    }
};

/// Binds an existing constructor taking arguments Args...
template <typename... Args>
detail::initimpl::constructor<Args...> init() {
    return {};
}
/// Like `init<Args...>()`, but the instance is always constructed through the alias class (even
/// when not inheriting on the Python side).
template <typename... Args>
detail::initimpl::alias_constructor<Args...> init_alias() {
    return {};
}

/// Binds a factory function as a constructor
template <typename Func, typename Ret = detail::initimpl::factory<Func>>
Ret init(Func &&f) {
    return {std::forward<Func>(f)};
}

/// Dual-argument factory function: the first function is called when no alias is needed, the
/// second when an alias is needed (i.e. due to python-side inheritance).  Arguments must be
/// identical.
template <typename CFunc, typename AFunc, typename Ret = detail::initimpl::factory<CFunc, AFunc>>
Ret init(CFunc &&c, AFunc &&a) {
    return {std::forward<CFunc>(c), std::forward<AFunc>(a)};
}

/// Binds pickling functions `__getstate__` and `__setstate__` and ensures that the type
/// returned by `__getstate__` is the same as the argument accepted by `__setstate__`.
template <typename GetState, typename SetState>
detail::initimpl::pickle_factory<GetState, SetState> pickle(GetState &&g, SetState &&s) {
    return {std::forward<GetState>(g), std::forward<SetState>(s)};
}

PYBIND11_NAMESPACE_BEGIN(detail)

inline str enum_name(handle arg) {
    dict entries = arg.get_type().attr("__entries");
    for (auto kv : entries) {
        if (handle(kv.second[int_(0)]).equal(arg)) {
            return pybind11::str(kv.first);
        }
    }
    return "???";
}

struct enum_base {
    enum_base(const handle &base, const handle &parent) : m_base(base), m_parent(parent) {}

    PYBIND11_NOINLINE void init(bool is_arithmetic, bool is_convertible) {
        m_base.attr("__entries") = dict();
        auto property = handle((PyObject *) &PyProperty_Type);
        auto static_property = handle((PyObject *) get_internals().static_property_type);

        m_base.attr("__repr__") = cpp_function(
            [](const object &arg) -> str {
                handle type = type::handle_of(arg);
                object type_name = type.attr("__name__");
                return pybind11::str("<{}.{}: {}>")
                    .format(std::move(type_name), enum_name(arg), int_(arg));
            },
            name("__repr__"),
            is_method(m_base));

        m_base.attr("name") = property(cpp_function(&enum_name, name("name"), is_method(m_base)));

        m_base.attr("__str__") = cpp_function(
            [](handle arg) -> str {
                object type_name = type::handle_of(arg).attr("__name__");
                return pybind11::str("{}.{}").format(std::move(type_name), enum_name(arg));
            },
            name("__str__"),
            is_method(m_base));

        if (options::show_enum_members_docstring()) {
            m_base.attr("__doc__") = static_property(
                cpp_function(
                    [](handle arg) -> std::string {
                        std::string docstring;
                        dict entries = arg.attr("__entries");
                        if (((PyTypeObject *) arg.ptr())->tp_doc) {
                            docstring += std::string(
                                reinterpret_cast<PyTypeObject *>(arg.ptr())->tp_doc);
                            docstring += "\n\n";
                        }
                        docstring += "Members:";
                        for (auto kv : entries) {
                            auto key = std::string(pybind11::str(kv.first));
                            auto comment = kv.second[int_(1)];
                            docstring += "\n\n  ";
                            docstring += key;
                            if (!comment.is_none()) {
                                docstring += " : ";
                                docstring += pybind11::str(comment).cast<std::string>();
                            }
                        }
                        return docstring;
                    },
                    name("__doc__")),
                none(),
                none(),
                "");
        }

        m_base.attr("__members__") = static_property(cpp_function(
                                                         [](handle arg) -> dict {
                                                             dict entries = arg.attr("__entries"),
                                                                  m;
                                                             for (auto kv : entries) {
                                                                 m[kv.first] = kv.second[int_(0)];
                                                             }
                                                             return m;
                                                         },
                                                         name("__members__")),
                                                     none(),
                                                     none(),
                                                     "");

#define PYBIND11_ENUM_OP_STRICT(op, expr, strict_behavior)                                        \
    m_base.attr(op) = cpp_function(                                                               \
        [](const object &a, const object &b) {                                                    \
            if (!type::handle_of(a).is(type::handle_of(b)))                                       \
                strict_behavior; /* NOLINT(bugprone-macro-parentheses) */                         \
            return expr;                                                                          \
        },                                                                                        \
        name(op),                                                                                 \
        is_method(m_base),                                                                        \
        arg("other"))

#define PYBIND11_ENUM_OP_CONV(op, expr)                                                           \
    m_base.attr(op) = cpp_function(                                                               \
        [](const object &a_, const object &b_) {                                                  \
            int_ a(a_), b(b_);                                                                    \
            return expr;                                                                          \
        },                                                                                        \
        name(op),                                                                                 \
        is_method(m_base),                                                                        \
        arg("other"))

#define PYBIND11_ENUM_OP_CONV_LHS(op, expr)                                                       \
    m_base.attr(op) = cpp_function(                                                               \
        [](const object &a_, const object &b) {                                                   \
            int_ a(a_);                                                                           \
            return expr;                                                                          \
        },                                                                                        \
        name(op),                                                                                 \
        is_method(m_base),                                                                        \
        arg("other"))

        if (is_convertible) {
            PYBIND11_ENUM_OP_CONV_LHS("__eq__", !b.is_none() && a.equal(b));
            PYBIND11_ENUM_OP_CONV_LHS("__ne__", b.is_none() || !a.equal(b));

            if (is_arithmetic) {
                PYBIND11_ENUM_OP_CONV("__lt__", a < b);
                PYBIND11_ENUM_OP_CONV("__gt__", a > b);
                PYBIND11_ENUM_OP_CONV("__le__", a <= b);
                PYBIND11_ENUM_OP_CONV("__ge__", a >= b);
                PYBIND11_ENUM_OP_CONV("__and__", a & b);
                PYBIND11_ENUM_OP_CONV("__rand__", a & b);
                PYBIND11_ENUM_OP_CONV("__or__", a | b);
                PYBIND11_ENUM_OP_CONV("__ror__", a | b);
                PYBIND11_ENUM_OP_CONV("__xor__", a ^ b);
                PYBIND11_ENUM_OP_CONV("__rxor__", a ^ b);
                m_base.attr("__invert__")
                    = cpp_function([](const object &arg) { return ~(int_(arg)); },
                                   name("__invert__"),
                                   is_method(m_base));
            }
        } else {
            PYBIND11_ENUM_OP_STRICT("__eq__", int_(a).equal(int_(b)), return false);
            PYBIND11_ENUM_OP_STRICT("__ne__", !int_(a).equal(int_(b)), return true);

            if (is_arithmetic) {
#define PYBIND11_THROW throw type_error("Expected an enumeration of matching type!");
                PYBIND11_ENUM_OP_STRICT("__lt__", int_(a) < int_(b), PYBIND11_THROW);
                PYBIND11_ENUM_OP_STRICT("__gt__", int_(a) > int_(b), PYBIND11_THROW);
                PYBIND11_ENUM_OP_STRICT("__le__", int_(a) <= int_(b), PYBIND11_THROW);
                PYBIND11_ENUM_OP_STRICT("__ge__", int_(a) >= int_(b), PYBIND11_THROW);
#undef PYBIND11_THROW
            }
        }

#undef PYBIND11_ENUM_OP_CONV_LHS
#undef PYBIND11_ENUM_OP_CONV
#undef PYBIND11_ENUM_OP_STRICT

        m_base.attr("__getstate__") = cpp_function(
            [](const object &arg) { return int_(arg); }, name("__getstate__"), is_method(m_base));

        m_base.attr("__hash__") = cpp_function(
            [](const object &arg) { return int_(arg); }, name("__hash__"), is_method(m_base));
    }

    PYBIND11_NOINLINE void value(char const *name_, object value, const char *doc = nullptr) {
        dict entries = m_base.attr("__entries");
        str name(name_);
        if (entries.contains(name)) {
            std::string type_name = (std::string) str(m_base.attr("__name__"));
            throw value_error(std::move(type_name) + ": element \"" + std::string(name_)
                              + "\" already exists!");
        }

        entries[name] = pybind11::make_tuple(value, doc);
        m_base.attr(std::move(name)) = std::move(value);
    }

    PYBIND11_NOINLINE void export_values() {
        dict entries = m_base.attr("__entries");
        for (auto kv : entries) {
            m_parent.attr(kv.first) = kv.second[int_(0)];
        }
    }

    handle m_base;
    handle m_parent;
};

template <bool is_signed, size_t length>
struct equivalent_integer {};
template <>
struct equivalent_integer<true, 1> {
    using type = int8_t;
};
template <>
struct equivalent_integer<false, 1> {
    using type = uint8_t;
};
template <>
struct equivalent_integer<true, 2> {
    using type = int16_t;
};
template <>
struct equivalent_integer<false, 2> {
    using type = uint16_t;
};
template <>
struct equivalent_integer<true, 4> {
    using type = int32_t;
};
template <>
struct equivalent_integer<false, 4> {
    using type = uint32_t;
};
template <>
struct equivalent_integer<true, 8> {
    using type = int64_t;
};
template <>
struct equivalent_integer<false, 8> {
    using type = uint64_t;
};

template <typename IntLike>
using equivalent_integer_t =
    typename equivalent_integer<std::is_signed<IntLike>::value, sizeof(IntLike)>::type;

PYBIND11_NAMESPACE_END(detail)

/// Binds C++ enumerations and enumeration classes to Python
template <typename Type>
class enum_ : public class_<Type> {
public:
    using Base = class_<Type>;
    using Base::attr;
    using Base::def;
    using Base::def_property_readonly;
    using Base::def_property_readonly_static;
    using Underlying = typename std::underlying_type<Type>::type;
    // Scalar is the integer representation of underlying type
    using Scalar = detail::conditional_t<detail::any_of<detail::is_std_char_type<Underlying>,
                                                        std::is_same<Underlying, bool>>::value,
                                         detail::equivalent_integer_t<Underlying>,
                                         Underlying>;

    template <typename... Extra>
    enum_(const handle &scope, const char *name, const Extra &...extra)
        : class_<Type>(scope, name, extra...), m_base(*this, scope) {
        constexpr bool is_arithmetic = detail::any_of<std::is_same<arithmetic, Extra>...>::value;
        constexpr bool is_convertible = std::is_convertible<Type, Underlying>::value;
        m_base.init(is_arithmetic, is_convertible);

        def(init([](Scalar i) { return static_cast<Type>(i); }), arg("value"));
        def_property_readonly("value", [](Type value) { return (Scalar) value; });
        def("__int__", [](Type value) { return (Scalar) value; });
        def("__index__", [](Type value) { return (Scalar) value; });
        attr("__setstate__") = cpp_function(
            [](detail::value_and_holder &v_h, Scalar arg) {
                detail::initimpl::setstate<Base>(
                    v_h, static_cast<Type>(arg), Py_TYPE(v_h.inst) != v_h.type->type);
            },
            detail::is_new_style_constructor(),
            pybind11::name("__setstate__"),
            is_method(*this),
            arg("state"));
    }

    /// Export enumeration entries into the parent scope
    enum_ &export_values() {
        m_base.export_values();
        return *this;
    }

    /// Add an enumeration entry
    enum_ &value(char const *name, Type value, const char *doc = nullptr) {
        m_base.value(name, pybind11::cast(value, return_value_policy::copy), doc);
        return *this;
    }

private:
    detail::enum_base m_base;
};

PYBIND11_NAMESPACE_BEGIN(detail)

PYBIND11_NOINLINE void keep_alive_impl(handle nurse, handle patient) {
    if (!nurse || !patient) {
        pybind11_fail("Could not activate keep_alive!");
    }

    if (patient.is_none() || nurse.is_none()) {
        return; /* Nothing to keep alive or nothing to be kept alive by */
    }

    auto tinfo = all_type_info(Py_TYPE(nurse.ptr()));
    if (!tinfo.empty()) {
        /* It's a pybind-registered type, so we can store the patient in the
         * internal list. */
        add_patient(nurse.ptr(), patient.ptr());
    } else {
        /* Fall back to clever approach based on weak references taken from
         * Boost.Python. This is not used for pybind-registered types because
         * the objects can be destroyed out-of-order in a GC pass. */
        cpp_function disable_lifesupport([patient](handle weakref) {
            patient.dec_ref();
            weakref.dec_ref();
        });

        weakref wr(nurse, disable_lifesupport);

        patient.inc_ref(); /* reference patient and leak the weak reference */
        (void) wr.release();
    }
}

PYBIND11_NOINLINE void
keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret) {
    auto get_arg = [&](size_t n) {
        if (n == 0) {
            return ret;
        }
        if (n == 1 && call.init_self) {
            return call.init_self;
        }
        if (n <= call.args.size()) {
            return call.args[n - 1];
        }
        return handle();
    };

    keep_alive_impl(get_arg(Nurse), get_arg(Patient));
}

inline std::pair<decltype(internals::registered_types_py)::iterator, bool>
all_type_info_get_cache(PyTypeObject *type) {
    auto res = with_internals([type](internals &internals) {
        return internals
            .registered_types_py
#ifdef __cpp_lib_unordered_map_try_emplace
            .try_emplace(type);
#else
            .emplace(type, std::vector<detail::type_info *>());
#endif
    });
    if (res.second) {
        // New cache entry created; set up a weak reference to automatically remove it if the type
        // gets destroyed:
        weakref((PyObject *) type, cpp_function([type](handle wr) {
                    with_internals([type](internals &internals) {
                        internals.registered_types_py.erase(type);

                        // TODO consolidate the erasure code in pybind11_meta_dealloc() in class.h
                        auto &cache = internals.inactive_override_cache;
                        for (auto it = cache.begin(), last = cache.end(); it != last;) {
                            if (it->first == reinterpret_cast<PyObject *>(type)) {
                                it = cache.erase(it);
                            } else {
                                ++it;
                            }
                        }
                    });

                    wr.dec_ref();
                }))
            .release();
    }

    return res;
}

/* There are a large number of apparently unused template arguments because
 * each combination requires a separate py::class_ registration.
 */
template <typename Access,
          return_value_policy Policy,
          typename Iterator,
          typename Sentinel,
          typename ValueType,
          typename... Extra>
struct iterator_state {
    Iterator it;
    Sentinel end;
    bool first_or_done;
};

// Note: these helpers take the iterator by non-const reference because some
// iterators in the wild can't be dereferenced when const. The & after Iterator
// is required for MSVC < 16.9. SFINAE cannot be reused for result_type due to
// bugs in ICC, NVCC, and PGI compilers. See PR #3293.
template <typename Iterator, typename SFINAE = decltype(*std::declval<Iterator &>())>
struct iterator_access {
    using result_type = decltype(*std::declval<Iterator &>());
    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263
    result_type operator()(Iterator &it) const { return *it; }
};

template <typename Iterator, typename SFINAE = decltype((*std::declval<Iterator &>()).first)>
class iterator_key_access {
private:
    using pair_type = decltype(*std::declval<Iterator &>());

public:
    /* If either the pair itself or the element of the pair is a reference, we
     * want to return a reference, otherwise a value. When the decltype
     * expression is parenthesized it is based on the value category of the
     * expression; otherwise it is the declared type of the pair member.
     * The use of declval<pair_type> in the second branch rather than directly
     * using *std::declval<Iterator &>() is a workaround for nvcc
     * (it's not used in the first branch because going via decltype and back
     * through declval does not perfectly preserve references).
     */
    using result_type
        = conditional_t<std::is_reference<decltype(*std::declval<Iterator &>())>::value,
                        decltype(((*std::declval<Iterator &>()).first)),
                        decltype(std::declval<pair_type>().first)>;
    result_type operator()(Iterator &it) const { return (*it).first; }
};

template <typename Iterator, typename SFINAE = decltype((*std::declval<Iterator &>()).second)>
class iterator_value_access {
private:
    using pair_type = decltype(*std::declval<Iterator &>());

public:
    using result_type
        = conditional_t<std::is_reference<decltype(*std::declval<Iterator &>())>::value,
                        decltype(((*std::declval<Iterator &>()).second)),
                        decltype(std::declval<pair_type>().second)>;
    result_type operator()(Iterator &it) const { return (*it).second; }
};

template <typename Access,
          return_value_policy Policy,
          typename Iterator,
          typename Sentinel,
          typename ValueType,
          typename... Extra>
iterator make_iterator_impl(Iterator first, Sentinel last, Extra &&...extra) {
    using state = detail::iterator_state<Access, Policy, Iterator, Sentinel, ValueType, Extra...>;
    // TODO: state captures only the types of Extra, not the values

    if (!detail::get_type_info(typeid(state), false)) {
        class_<state>(handle(), "iterator", pybind11::module_local())
            .def("__iter__", [](state &s) -> state & { return s; })
            .def(
                "__next__",
                [](state &s) -> ValueType {
                    if (!s.first_or_done) {
                        ++s.it;
                    } else {
                        s.first_or_done = false;
                    }
                    if (s.it == s.end) {
                        s.first_or_done = true;
                        throw stop_iteration();
                    }
                    return Access()(s.it);
                    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263
                },
                std::forward<Extra>(extra)...,
                Policy);
    }

    return cast(state{std::forward<Iterator>(first), std::forward<Sentinel>(last), true});
}

PYBIND11_NAMESPACE_END(detail)

/// Makes a python iterator from a first and past-the-end C++ InputIterator.
template <return_value_policy Policy = return_value_policy::reference_internal,
          typename Iterator,
          typename Sentinel,
          typename ValueType = typename detail::iterator_access<Iterator>::result_type,
          typename... Extra>
typing::Iterator<ValueType> make_iterator(Iterator first, Sentinel last, Extra &&...extra) {
    return detail::make_iterator_impl<detail::iterator_access<Iterator>,
                                      Policy,
                                      Iterator,
                                      Sentinel,
                                      ValueType,
                                      Extra...>(std::forward<Iterator>(first),
                                                std::forward<Sentinel>(last),
                                                std::forward<Extra>(extra)...);
}

/// Makes a python iterator over the keys (`.first`) of a iterator over pairs from a
/// first and past-the-end InputIterator.
template <return_value_policy Policy = return_value_policy::reference_internal,
          typename Iterator,
          typename Sentinel,
          typename KeyType = typename detail::iterator_key_access<Iterator>::result_type,
          typename... Extra>
typing::Iterator<KeyType> make_key_iterator(Iterator first, Sentinel last, Extra &&...extra) {
    return detail::make_iterator_impl<detail::iterator_key_access<Iterator>,
                                      Policy,
                                      Iterator,
                                      Sentinel,
                                      KeyType,
                                      Extra...>(std::forward<Iterator>(first),
                                                std::forward<Sentinel>(last),
                                                std::forward<Extra>(extra)...);
}

/// Makes a python iterator over the values (`.second`) of a iterator over pairs from a
/// first and past-the-end InputIterator.
template <return_value_policy Policy = return_value_policy::reference_internal,
          typename Iterator,
          typename Sentinel,
          typename ValueType = typename detail::iterator_value_access<Iterator>::result_type,
          typename... Extra>
typing::Iterator<ValueType> make_value_iterator(Iterator first, Sentinel last, Extra &&...extra) {
    return detail::make_iterator_impl<detail::iterator_value_access<Iterator>,
                                      Policy,
                                      Iterator,
                                      Sentinel,
                                      ValueType,
                                      Extra...>(std::forward<Iterator>(first),
                                                std::forward<Sentinel>(last),
                                                std::forward<Extra>(extra)...);
}

/// Makes an iterator over values of an stl container or other container supporting
/// `std::begin()`/`std::end()`
template <return_value_policy Policy = return_value_policy::reference_internal,
          typename Type,
          typename ValueType = typename detail::iterator_access<
              decltype(std::begin(std::declval<Type &>()))>::result_type,
          typename... Extra>
typing::Iterator<ValueType> make_iterator(Type &value, Extra &&...extra) {
    return make_iterator<Policy>(
        std::begin(value), std::end(value), std::forward<Extra>(extra)...);
}

/// Makes an iterator over the keys (`.first`) of a stl map-like container supporting
/// `std::begin()`/`std::end()`
template <return_value_policy Policy = return_value_policy::reference_internal,
          typename Type,
          typename KeyType = typename detail::iterator_key_access<
              decltype(std::begin(std::declval<Type &>()))>::result_type,
          typename... Extra>
typing::Iterator<KeyType> make_key_iterator(Type &value, Extra &&...extra) {
    return make_key_iterator<Policy>(
        std::begin(value), std::end(value), std::forward<Extra>(extra)...);
}

/// Makes an iterator over the values (`.second`) of a stl map-like container supporting
/// `std::begin()`/`std::end()`
template <return_value_policy Policy = return_value_policy::reference_internal,
          typename Type,
          typename ValueType = typename detail::iterator_value_access<
              decltype(std::begin(std::declval<Type &>()))>::result_type,
          typename... Extra>
typing::Iterator<ValueType> make_value_iterator(Type &value, Extra &&...extra) {
    return make_value_iterator<Policy>(
        std::begin(value), std::end(value), std::forward<Extra>(extra)...);
}

template <typename InputType, typename OutputType>
void implicitly_convertible() {
    struct set_flag {
        bool &flag;
        explicit set_flag(bool &flag_) : flag(flag_) { flag_ = true; }
        ~set_flag() { flag = false; }
    };
    auto implicit_caster = [](PyObject *obj, PyTypeObject *type) -> PyObject * {
#ifdef Py_GIL_DISABLED
        thread_local bool currently_used = false;
#else
        static bool currently_used = false;
#endif
        if (currently_used) { // implicit conversions are non-reentrant
            return nullptr;
        }
        set_flag flag_helper(currently_used);
        if (!detail::make_caster<InputType>().load(obj, false)) {
            return nullptr;
        }
        tuple args(1);
        args[0] = obj;
        PyObject *result = PyObject_Call((PyObject *) type, args.ptr(), nullptr);
        if (result == nullptr) {
            PyErr_Clear();
        }
        return result;
    };

    if (auto *tinfo = detail::get_type_info(typeid(OutputType))) {
        tinfo->implicit_conversions.emplace_back(std::move(implicit_caster));
    } else {
        pybind11_fail("implicitly_convertible: Unable to find type " + type_id<OutputType>());
    }
}

inline void register_exception_translator(ExceptionTranslator &&translator) {
    detail::with_internals([&](detail::internals &internals) {
        internals.registered_exception_translators.push_front(
            std::forward<ExceptionTranslator>(translator));
    });
}

/**
 * Add a new module-local exception translator. Locally registered functions
 * will be tried before any globally registered exception translators, which
 * will only be invoked if the module-local handlers do not deal with
 * the exception.
 */
inline void register_local_exception_translator(ExceptionTranslator &&translator) {
    detail::with_internals([&](detail::internals &internals) {
        (void) internals;
        detail::get_local_internals().registered_exception_translators.push_front(
            std::forward<ExceptionTranslator>(translator));
    });
}

/**
 * Wrapper to generate a new Python exception type.
 *
 * This should only be used with py::set_error() for now.
 * It is not (yet) possible to use as a py::base.
 * Template type argument is reserved for future use.
 */
template <typename type>
class exception : public object {
public:
    exception() = default;
    exception(handle scope, const char *name, handle base = PyExc_Exception) {
        std::string full_name
            = scope.attr("__name__").cast<std::string>() + std::string(".") + name;
        m_ptr = PyErr_NewException(const_cast<char *>(full_name.c_str()), base.ptr(), nullptr);
        if (hasattr(scope, "__dict__") && scope.attr("__dict__").contains(name)) {
            pybind11_fail("Error during initialization: multiple incompatible "
                          "definitions with name \""
                          + std::string(name) + "\"");
        }
        scope.attr(name) = *this;
    }

    // Sets the current python exception to this exception object with the given message
    PYBIND11_DEPRECATED("Please use py::set_error() instead "
                        "(https://github.com/pybind/pybind11/pull/4772)")
    void operator()(const char *message) const { set_error(*this, message); }
};

PYBIND11_NAMESPACE_BEGIN(detail)

template <>
struct handle_type_name<exception<void>> {
    static constexpr auto name = const_name("Exception");
};

// Helper function for register_exception and register_local_exception
template <typename CppException>
exception<CppException> &
register_exception_impl(handle scope, const char *name, handle base, bool isLocal) {
    PYBIND11_CONSTINIT static gil_safe_call_once_and_store<exception<CppException>> exc_storage;
    exc_storage.call_once_and_store_result(
        [&]() { return exception<CppException>(scope, name, base); });

    auto register_func
        = isLocal ? &register_local_exception_translator : &register_exception_translator;

    register_func([](std::exception_ptr p) {
        if (!p) {
            return;
        }
        try {
            std::rethrow_exception(p);
        } catch (const CppException &e) {
            set_error(exc_storage.get_stored(), e.what());
        }
    });
    return exc_storage.get_stored();
}

PYBIND11_NAMESPACE_END(detail)

/**
 * Registers a Python exception in `m` of the given `name` and installs a translator to
 * translate the C++ exception to the created Python exception using the what() method.
 * This is intended for simple exception translations; for more complex translation, register the
 * exception object and translator directly.
 */
template <typename CppException>
exception<CppException> &
register_exception(handle scope, const char *name, handle base = PyExc_Exception) {
    return detail::register_exception_impl<CppException>(scope, name, base, false /* isLocal */);
}

/**
 * Registers a Python exception in `m` of the given `name` and installs a translator to
 * translate the C++ exception to the created Python exception using the what() method.
 * This translator will only be used for exceptions that are thrown in this module and will be
 * tried before global exception translators, including those registered with register_exception.
 * This is intended for simple exception translations; for more complex translation, register the
 * exception object and translator directly.
 */
template <typename CppException>
exception<CppException> &
register_local_exception(handle scope, const char *name, handle base = PyExc_Exception) {
    return detail::register_exception_impl<CppException>(scope, name, base, true /* isLocal */);
}

PYBIND11_NAMESPACE_BEGIN(detail)
PYBIND11_NOINLINE void print(const tuple &args, const dict &kwargs) {
    auto strings = tuple(args.size());
    for (size_t i = 0; i < args.size(); ++i) {
        strings[i] = str(args[i]);
    }
    auto sep = kwargs.contains("sep") ? kwargs["sep"] : str(" ");
    auto line = sep.attr("join")(std::move(strings));

    object file;
    if (kwargs.contains("file")) {
        file = kwargs["file"].cast<object>();
    } else {
        try {
            file = module_::import("sys").attr("stdout");
        } catch (const error_already_set &) {
            /* If print() is called from code that is executed as
               part of garbage collection during interpreter shutdown,
               importing 'sys' can fail. Give up rather than crashing the
               interpreter in this case. */
            return;
        }
    }

    auto write = file.attr("write");
    write(std::move(line));
    write(kwargs.contains("end") ? kwargs["end"] : str("\n"));

    if (kwargs.contains("flush") && kwargs["flush"].cast<bool>()) {
        file.attr("flush")();
    }
}
PYBIND11_NAMESPACE_END(detail)

template <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>
void print(Args &&...args) {
    auto c = detail::collect_arguments<policy>(std::forward<Args>(args)...);
    detail::print(c.args(), c.kwargs());
}

inline void
error_already_set::m_fetched_error_deleter(detail::error_fetch_and_normalize *raw_ptr) {
    gil_scoped_acquire gil;
    error_scope scope;
    delete raw_ptr;
}

inline const char *error_already_set::what() const noexcept {
    gil_scoped_acquire gil;
    error_scope scope;
    return m_fetched_error->error_string().c_str();
}

PYBIND11_NAMESPACE_BEGIN(detail)

inline function
get_type_override(const void *this_ptr, const type_info *this_type, const char *name) {
    handle self = get_object_handle(this_ptr, this_type);
    if (!self) {
        return function();
    }
    handle type = type::handle_of(self);
    auto key = std::make_pair(type.ptr(), name);

    /* Cache functions that aren't overridden in Python to avoid
       many costly Python dictionary lookups below */
    bool not_overridden = with_internals([&key](internals &internals) {
        auto &cache = internals.inactive_override_cache;
        return cache.find(key) != cache.end();
    });
    if (not_overridden) {
        return function();
    }

    function override = getattr(self, name, function());
    if (override.is_cpp_function()) {
        with_internals([&](internals &internals) {
            internals.inactive_override_cache.insert(std::move(key));
        });
        return function();
    }

    /* Don't call dispatch code if invoked from overridden function.
       Unfortunately this doesn't work on PyPy. */
#if !defined(PYPY_VERSION)
#    if PY_VERSION_HEX >= 0x03090000
    PyFrameObject *frame = PyThreadState_GetFrame(PyThreadState_Get());
    if (frame != nullptr) {
        PyCodeObject *f_code = PyFrame_GetCode(frame);
        // f_code is guaranteed to not be NULL
        if ((std::string) str(f_code->co_name) == name && f_code->co_argcount > 0) {
#        if PY_VERSION_HEX >= 0x030d0000
            PyObject *locals = PyEval_GetFrameLocals();
#        else
            PyObject *locals = PyEval_GetLocals();
            Py_XINCREF(locals);
#        endif
            if (locals != nullptr) {
#        if PY_VERSION_HEX >= 0x030b0000
                PyObject *co_varnames = PyCode_GetVarnames(f_code);
#        else
                PyObject *co_varnames = PyObject_GetAttrString((PyObject *) f_code, "co_varnames");
#        endif
                PyObject *self_arg = PyTuple_GET_ITEM(co_varnames, 0);
                Py_DECREF(co_varnames);
                PyObject *self_caller = dict_getitem(locals, self_arg);
                Py_DECREF(locals);
                if (self_caller == self.ptr()) {
                    Py_DECREF(f_code);
                    Py_DECREF(frame);
                    return function();
                }
            }
        }
        Py_DECREF(f_code);
        Py_DECREF(frame);
    }
#    else
    PyFrameObject *frame = PyThreadState_Get()->frame;
    if (frame != nullptr && (std::string) str(frame->f_code->co_name) == name
        && frame->f_code->co_argcount > 0) {
        PyFrame_FastToLocals(frame);
        PyObject *self_caller
            = dict_getitem(frame->f_locals, PyTuple_GET_ITEM(frame->f_code->co_varnames, 0));
        if (self_caller == self.ptr()) {
            return function();
        }
    }
#    endif

#else
    /* PyPy currently doesn't provide a detailed cpyext emulation of
       frame objects, so we have to emulate this using Python. This
       is going to be slow..*/
    dict d;
    d["self"] = self;
    d["name"] = pybind11::str(name);
    PyObject *result
        = PyRun_String("import inspect\n"
                       "frame = inspect.currentframe()\n"
                       "if frame is not None:\n"
                       "    frame = frame.f_back\n"
                       "    if frame is not None and str(frame.f_code.co_name) == name and "
                       "frame.f_code.co_argcount > 0:\n"
                       "        self_caller = frame.f_locals[frame.f_code.co_varnames[0]]\n"
                       "        if self_caller == self:\n"
                       "            self = None\n",
                       Py_file_input,
                       d.ptr(),
                       d.ptr());
    if (result == nullptr)
        throw error_already_set();
    Py_DECREF(result);
    if (d["self"].is_none())
        return function();
#endif

    return override;
}
PYBIND11_NAMESPACE_END(detail)

/** \rst
  Try to retrieve a python method by the provided name from the instance pointed to by the
  this_ptr.

  :this_ptr: The pointer to the object the overridden method should be retrieved for. This should
             be the first non-trampoline class encountered in the inheritance chain.
  :name: The name of the overridden Python method to retrieve.
  :return: The Python method by this name from the object or an empty function wrapper.
 \endrst */
template <class T>
function get_override(const T *this_ptr, const char *name) {
    auto *tinfo = detail::get_type_info(typeid(T));
    return tinfo ? detail::get_type_override(this_ptr, tinfo, name) : function();
}

#define PYBIND11_OVERRIDE_IMPL(ret_type, cname, name, ...)                                        \
    do {                                                                                          \
        pybind11::gil_scoped_acquire gil;                                                         \
        pybind11::function override                                                               \
            = pybind11::get_override(static_cast<const cname *>(this), name);                     \
        if (override) {                                                                           \
            auto o = override(__VA_ARGS__);                                                       \
            PYBIND11_WARNING_PUSH                                                                 \
            PYBIND11_WARNING_DISABLE_MSVC(4127)                                                   \
            if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value              \
                && !pybind11::detail::is_same_ignoring_cvref<ret_type, PyObject *>::value) {      \
                static pybind11::detail::override_caster_t<ret_type> caster;                      \
                return pybind11::detail::cast_ref<ret_type>(std::move(o), caster);                \
            }                                                                                     \
            PYBIND11_WARNING_POP                                                                  \
            return pybind11::detail::cast_safe<ret_type>(std::move(o));                           \
        }                                                                                         \
    } while (false)

/** \rst
    Macro to populate the virtual method in the trampoline class. This macro tries to look up a
    method named 'fn' from the Python side, deals with the :ref:`gil` and necessary argument
    conversions to call this method and return the appropriate type.
    See :ref:`overriding_virtuals` for more information. This macro should be used when the method
    name in C is not the same as the method name in Python. For example with `__str__`.

    .. code-block:: cpp

      std::string toString() override {
        PYBIND11_OVERRIDE_NAME(
            std::string, // Return type (ret_type)
            Animal,      // Parent class (cname)
            "__str__",   // Name of method in Python (name)
            toString,    // Name of function in C++ (fn)
        );
      }
\endrst */
#define PYBIND11_OVERRIDE_NAME(ret_type, cname, name, fn, ...)                                    \
    do {                                                                                          \
        PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \
        return cname::fn(__VA_ARGS__);                                                            \
    } while (false)

/** \rst
    Macro for pure virtual functions, this function is identical to
    :c:macro:`PYBIND11_OVERRIDE_NAME`, except that it throws if no override can be found.
\endrst */
#define PYBIND11_OVERRIDE_PURE_NAME(ret_type, cname, name, fn, ...)                               \
    do {                                                                                          \
        PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \
        pybind11::pybind11_fail(                                                                  \
            "Tried to call pure virtual function \"" PYBIND11_STRINGIFY(cname) "::" name "\"");   \
    } while (false)

/** \rst
    Macro to populate the virtual method in the trampoline class. This macro tries to look up the
    method from the Python side, deals with the :ref:`gil` and necessary argument conversions to
    call this method and return the appropriate type. This macro should be used if the method name
    in C and in Python are identical.
    See :ref:`overriding_virtuals` for more information.

    .. code-block:: cpp

      class PyAnimal : public Animal {
      public:
          // Inherit the constructors
          using Animal::Animal;

          // Trampoline (need one for each virtual function)
          std::string go(int n_times) override {
              PYBIND11_OVERRIDE_PURE(
                  std::string, // Return type (ret_type)
                  Animal,      // Parent class (cname)
                  go,          // Name of function in C++ (must match Python name) (fn)
                  n_times      // Argument(s) (...)
              );
          }
      };
\endrst */
#define PYBIND11_OVERRIDE(ret_type, cname, fn, ...)                                               \
    PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)

/** \rst
    Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE`,
    except that it throws if no override can be found.
\endrst */
#define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...)                                          \
    PYBIND11_OVERRIDE_PURE_NAME(                                                                  \
        PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)

// Deprecated versions

PYBIND11_DEPRECATED("get_type_overload has been deprecated")
inline function
get_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) {
    return detail::get_type_override(this_ptr, this_type, name);
}

template <class T>
inline function get_overload(const T *this_ptr, const char *name) {
    return get_override(this_ptr, name);
}

#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...)                                         \
    PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__)
#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...)                                    \
    PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__)
#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...)                               \
    PYBIND11_OVERRIDE_PURE_NAME(                                                                  \
        PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__);
#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...)                                               \
    PYBIND11_OVERRIDE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__)
#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...)                                          \
    PYBIND11_OVERRIDE_PURE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__);

PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

/*
    pybind11/cast.h: Partial template specializations to cast between
    C++ and Python types

    Copyright (c) 2016 Wenzel Jakob <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#pragma once

#include "detail/common.h"
#include "detail/descr.h"
#include "detail/type_caster_base.h"
#include "detail/typeid.h"
#include "pytypes.h"
#include "gil.h"

#include <array>
#include <cstring>
#include <functional>
#include <iosfwd>
#include <iterator>
#include <memory>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

PYBIND11_WARNING_DISABLE_MSVC(4127)

PYBIND11_NAMESPACE_BEGIN(detail)

template <typename type, typename SFINAE = void>
class type_caster : public type_caster_base<type> {};
template <typename type>
using make_caster = type_caster<intrinsic_t<type>>;

// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T
template <typename T>
typename make_caster<T>::template cast_op_type<T> cast_op(make_caster<T> &caster) {
    using result_t = typename make_caster<T>::template cast_op_type<T>; // See PR #4893
    return caster.operator result_t();
}
template <typename T>
typename make_caster<T>::template cast_op_type<typename std::add_rvalue_reference<T>::type>
cast_op(make_caster<T> &&caster) {
    using result_t = typename make_caster<T>::template cast_op_type<
        typename std::add_rvalue_reference<T>::type>; // See PR #4893
    return std::move(caster).operator result_t();
}

template <typename type>
class type_caster<std::reference_wrapper<type>> {
private:
    using caster_t = make_caster<type>;
    caster_t subcaster;
    using reference_t = type &;
    using subcaster_cast_op_type = typename caster_t::template cast_op_type<reference_t>;

    static_assert(
        std::is_same<typename std::remove_const<type>::type &, subcaster_cast_op_type>::value
            || std::is_same<reference_t, subcaster_cast_op_type>::value,
        "std::reference_wrapper<T> caster requires T to have a caster with an "
        "`operator T &()` or `operator const T &()`");

public:
    bool load(handle src, bool convert) { return subcaster.load(src, convert); }
    static constexpr auto name = caster_t::name;
    static handle
    cast(const std::reference_wrapper<type> &src, return_value_policy policy, handle parent) {
        // It is definitely wrong to take ownership of this pointer, so mask that rvp
        if (policy == return_value_policy::take_ownership
            || policy == return_value_policy::automatic) {
            policy = return_value_policy::automatic_reference;
        }
        return caster_t::cast(&src.get(), policy, parent);
    }
    template <typename T>
    using cast_op_type = std::reference_wrapper<type>;
    explicit operator std::reference_wrapper<type>() { return cast_op<type &>(subcaster); }
};

#define PYBIND11_TYPE_CASTER(type, py_name)                                                       \
protected:                                                                                        \
    type value;                                                                                   \
                                                                                                  \
public:                                                                                           \
    static constexpr auto name = py_name;                                                         \
    template <typename T_,                                                                        \
              ::pybind11::detail::enable_if_t<                                                    \
                  std::is_same<type, ::pybind11::detail::remove_cv_t<T_>>::value,                 \
                  int>                                                                            \
              = 0>                                                                                \
    static ::pybind11::handle cast(                                                               \
        T_ *src, ::pybind11::return_value_policy policy, ::pybind11::handle parent) {             \
        if (!src)                                                                                 \
            return ::pybind11::none().release();                                                  \
        if (policy == ::pybind11::return_value_policy::take_ownership) {                          \
            auto h = cast(std::move(*src), policy, parent);                                       \
            delete src;                                                                           \
            return h;                                                                             \
        }                                                                                         \
        return cast(*src, policy, parent);                                                        \
    }                                                                                             \
    operator type *() { return &value; }               /* NOLINT(bugprone-macro-parentheses) */   \
    operator type &() { return value; }                /* NOLINT(bugprone-macro-parentheses) */   \
    operator type &&() && { return std::move(value); } /* NOLINT(bugprone-macro-parentheses) */   \
    template <typename T_>                                                                        \
    using cast_op_type = ::pybind11::detail::movable_cast_op_type<T_>

template <typename CharT>
using is_std_char_type = any_of<std::is_same<CharT, char>, /* std::string */
#if defined(PYBIND11_HAS_U8STRING)
                                std::is_same<CharT, char8_t>, /* std::u8string */
#endif
                                std::is_same<CharT, char16_t>, /* std::u16string */
                                std::is_same<CharT, char32_t>, /* std::u32string */
                                std::is_same<CharT, wchar_t>   /* std::wstring */
                                >;

template <typename T>
struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_type<T>::value>> {
    using _py_type_0 = conditional_t<sizeof(T) <= sizeof(long), long, long long>;
    using _py_type_1 = conditional_t<std::is_signed<T>::value,
                                     _py_type_0,
                                     typename std::make_unsigned<_py_type_0>::type>;
    using py_type = conditional_t<std::is_floating_point<T>::value, double, _py_type_1>;

public:
    bool load(handle src, bool convert) {
        py_type py_value;

        if (!src) {
            return false;
        }

#if !defined(PYPY_VERSION)
        auto index_check = [](PyObject *o) { return PyIndex_Check(o); };
#else
        // In PyPy 7.3.3, `PyIndex_Check` is implemented by calling `__index__`,
        // while CPython only considers the existence of `nb_index`/`__index__`.
        auto index_check = [](PyObject *o) { return hasattr(o, "__index__"); };
#endif

        if (std::is_floating_point<T>::value) {
            if (convert || PyFloat_Check(src.ptr())) {
                py_value = (py_type) PyFloat_AsDouble(src.ptr());
            } else {
                return false;
            }
        } else if (PyFloat_Check(src.ptr())
                   || (!convert && !PYBIND11_LONG_CHECK(src.ptr()) && !index_check(src.ptr()))) {
            return false;
        } else {
            handle src_or_index = src;
            // PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls.
#if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
            object index;
            if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr())
                index = reinterpret_steal<object>(PyNumber_Index(src.ptr()));
                if (!index) {
                    PyErr_Clear();
                    if (!convert)
                        return false;
                } else {
                    src_or_index = index;
                }
            }
#endif
            if (std::is_unsigned<py_type>::value) {
                py_value = as_unsigned<py_type>(src_or_index.ptr());
            } else { // signed integer:
                py_value = sizeof(T) <= sizeof(long)
                               ? (py_type) PyLong_AsLong(src_or_index.ptr())
                               : (py_type) PYBIND11_LONG_AS_LONGLONG(src_or_index.ptr());
            }
        }

        // Python API reported an error
        bool py_err = py_value == (py_type) -1 && PyErr_Occurred();

        // Check to see if the conversion is valid (integers should match exactly)
        // Signed/unsigned checks happen elsewhere
        if (py_err
            || (std::is_integral<T>::value && sizeof(py_type) != sizeof(T)
                && py_value != (py_type) (T) py_value)) {
            PyErr_Clear();
            if (py_err && convert && (PyNumber_Check(src.ptr()) != 0)) {
                auto tmp = reinterpret_steal<object>(std::is_floating_point<T>::value
                                                         ? PyNumber_Float(src.ptr())
                                                         : PyNumber_Long(src.ptr()));
                PyErr_Clear();
                return load(tmp, false);
            }
            return false;
        }

        value = (T) py_value;
        return true;
    }

    template <typename U = T>
    static typename std::enable_if<std::is_floating_point<U>::value, handle>::type
    cast(U src, return_value_policy /* policy */, handle /* parent */) {
        return PyFloat_FromDouble((double) src);
    }

    template <typename U = T>
    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_signed<U>::value
                                       && (sizeof(U) <= sizeof(long)),
                                   handle>::type
    cast(U src, return_value_policy /* policy */, handle /* parent */) {
        return PYBIND11_LONG_FROM_SIGNED((long) src);
    }

    template <typename U = T>
    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_unsigned<U>::value
                                       && (sizeof(U) <= sizeof(unsigned long)),
                                   handle>::type
    cast(U src, return_value_policy /* policy */, handle /* parent */) {
        return PYBIND11_LONG_FROM_UNSIGNED((unsigned long) src);
    }

    template <typename U = T>
    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_signed<U>::value
                                       && (sizeof(U) > sizeof(long)),
                                   handle>::type
    cast(U src, return_value_policy /* policy */, handle /* parent */) {
        return PyLong_FromLongLong((long long) src);
    }

    template <typename U = T>
    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_unsigned<U>::value
                                       && (sizeof(U) > sizeof(unsigned long)),
                                   handle>::type
    cast(U src, return_value_policy /* policy */, handle /* parent */) {
        return PyLong_FromUnsignedLongLong((unsigned long long) src);
    }

    PYBIND11_TYPE_CASTER(T, const_name<std::is_integral<T>::value>("int", "float"));
};

template <typename T>
struct void_caster {
public:
    bool load(handle src, bool) {
        if (src && src.is_none()) {
            return true;
        }
        return false;
    }
    static handle cast(T, return_value_policy /* policy */, handle /* parent */) {
        return none().release();
    }
    PYBIND11_TYPE_CASTER(T, const_name("None"));
};

template <>
class type_caster<void_type> : public void_caster<void_type> {};

template <>
class type_caster<void> : public type_caster<void_type> {
public:
    using type_caster<void_type>::cast;

    bool load(handle h, bool) {
        if (!h) {
            return false;
        }
        if (h.is_none()) {
            value = nullptr;
            return true;
        }

        /* Check if this is a capsule */
        if (isinstance<capsule>(h)) {
            value = reinterpret_borrow<capsule>(h);
            return true;
        }

        /* Check if this is a C++ type */
        const auto &bases = all_type_info((PyTypeObject *) type::handle_of(h).ptr());
        if (bases.size() == 1) { // Only allowing loading from a single-value type
            value = values_and_holders(reinterpret_cast<instance *>(h.ptr())).begin()->value_ptr();
            return true;
        }

        /* Fail */
        return false;
    }

    static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) {
        if (ptr) {
            return capsule(ptr).release();
        }
        return none().release();
    }

    template <typename T>
    using cast_op_type = void *&;
    explicit operator void *&() { return value; }
    static constexpr auto name = const_name("capsule");

private:
    void *value = nullptr;
};

template <>
class type_caster<std::nullptr_t> : public void_caster<std::nullptr_t> {};

template <>
class type_caster<bool> {
public:
    bool load(handle src, bool convert) {
        if (!src) {
            return false;
        }
        if (src.ptr() == Py_True) {
            value = true;
            return true;
        }
        if (src.ptr() == Py_False) {
            value = false;
            return true;
        }
        if (convert || is_numpy_bool(src)) {
            // (allow non-implicit conversion for numpy booleans), use strncmp
            // since NumPy 1.x had an additional trailing underscore.

            Py_ssize_t res = -1;
            if (src.is_none()) {
                res = 0; // None is implicitly converted to False
            }
#if defined(PYPY_VERSION)
            // On PyPy, check that "__bool__" attr exists
            else if (hasattr(src, PYBIND11_BOOL_ATTR)) {
                res = PyObject_IsTrue(src.ptr());
            }
#else
            // Alternate approach for CPython: this does the same as the above, but optimized
            // using the CPython API so as to avoid an unneeded attribute lookup.
            else if (auto *tp_as_number = src.ptr()->ob_type->tp_as_number) {
                if (PYBIND11_NB_BOOL(tp_as_number)) {
                    res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr());
                }
            }
#endif
            if (res == 0 || res == 1) {
                value = (res != 0);
                return true;
            }
            PyErr_Clear();
        }
        return false;
    }
    static handle cast(bool src, return_value_policy /* policy */, handle /* parent */) {
        return handle(src ? Py_True : Py_False).inc_ref();
    }
    PYBIND11_TYPE_CASTER(bool, const_name("bool"));

private:
    // Test if an object is a NumPy boolean (without fetching the type).
    static inline bool is_numpy_bool(handle object) {
        const char *type_name = Py_TYPE(object.ptr())->tp_name;
        // Name changed to `numpy.bool` in NumPy 2, `numpy.bool_` is needed for 1.x support
        return std::strcmp("numpy.bool", type_name) == 0
               || std::strcmp("numpy.bool_", type_name) == 0;
    }
};

// Helper class for UTF-{8,16,32} C++ stl strings:
template <typename StringType, bool IsView = false>
struct string_caster {
    using CharT = typename StringType::value_type;

    // Simplify life by being able to assume standard char sizes (the standard only guarantees
    // minimums, but Python requires exact sizes)
    static_assert(!std::is_same<CharT, char>::value || sizeof(CharT) == 1,
                  "Unsupported char size != 1");
#if defined(PYBIND11_HAS_U8STRING)
    static_assert(!std::is_same<CharT, char8_t>::value || sizeof(CharT) == 1,
                  "Unsupported char8_t size != 1");
#endif
    static_assert(!std::is_same<CharT, char16_t>::value || sizeof(CharT) == 2,
                  "Unsupported char16_t size != 2");
    static_assert(!std::is_same<CharT, char32_t>::value || sizeof(CharT) == 4,
                  "Unsupported char32_t size != 4");
    // wchar_t can be either 16 bits (Windows) or 32 (everywhere else)
    static_assert(!std::is_same<CharT, wchar_t>::value || sizeof(CharT) == 2 || sizeof(CharT) == 4,
                  "Unsupported wchar_t size != 2/4");
    static constexpr size_t UTF_N = 8 * sizeof(CharT);

    bool load(handle src, bool) {
        handle load_src = src;
        if (!src) {
            return false;
        }
        if (!PyUnicode_Check(load_src.ptr())) {
            return load_raw(load_src);
        }

        // For UTF-8 we avoid the need for a temporary `bytes` object by using
        // `PyUnicode_AsUTF8AndSize`.
        if (UTF_N == 8) {
            Py_ssize_t size = -1;
            const auto *buffer
                = reinterpret_cast<const CharT *>(PyUnicode_AsUTF8AndSize(load_src.ptr(), &size));
            if (!buffer) {
                PyErr_Clear();
                return false;
            }
            value = StringType(buffer, static_cast<size_t>(size));
            return true;
        }

        auto utfNbytes
            = reinterpret_steal<object>(PyUnicode_AsEncodedString(load_src.ptr(),
                                                                  UTF_N == 8    ? "utf-8"
                                                                  : UTF_N == 16 ? "utf-16"
                                                                                : "utf-32",
                                                                  nullptr));
        if (!utfNbytes) {
            PyErr_Clear();
            return false;
        }

        const auto *buffer
            = reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
        size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
        // Skip BOM for UTF-16/32
        if (UTF_N > 8) {
            buffer++;
            length--;
        }
        value = StringType(buffer, length);

        // If we're loading a string_view we need to keep the encoded Python object alive:
        if (IsView) {
            loader_life_support::add_patient(utfNbytes);
        }

        return true;
    }

    static handle
    cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) {
        const char *buffer = reinterpret_cast<const char *>(src.data());
        auto nbytes = ssize_t(src.size() * sizeof(CharT));
        handle s = decode_utfN(buffer, nbytes);
        if (!s) {
            throw error_already_set();
        }
        return s;
    }

    PYBIND11_TYPE_CASTER(StringType, const_name(PYBIND11_STRING_NAME));

private:
    static handle decode_utfN(const char *buffer, ssize_t nbytes) {
#if !defined(PYPY_VERSION)
        return UTF_N == 8    ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr)
               : UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr)
                             : PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr);
#else
        // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as
        // well), so bypass the whole thing by just passing the encoding as a string value, which
        // works properly:
        return PyUnicode_Decode(buffer,
                                nbytes,
                                UTF_N == 8    ? "utf-8"
                                : UTF_N == 16 ? "utf-16"
                                              : "utf-32",
                                nullptr);
#endif
    }

    // When loading into a std::string or char*, accept a bytes/bytearray object as-is (i.e.
    // without any encoding/decoding attempt).  For other C++ char sizes this is a no-op.
    // which supports loading a unicode from a str, doesn't take this path.
    template <typename C = CharT>
    bool load_raw(enable_if_t<std::is_same<C, char>::value, handle> src) {
        if (PYBIND11_BYTES_CHECK(src.ptr())) {
            // We were passed raw bytes; accept it into a std::string or char*
            // without any encoding attempt.
            const char *bytes = PYBIND11_BYTES_AS_STRING(src.ptr());
            if (!bytes) {
                pybind11_fail("Unexpected PYBIND11_BYTES_AS_STRING() failure.");
            }
            value = StringType(bytes, (size_t) PYBIND11_BYTES_SIZE(src.ptr()));
            return true;
        }
        if (PyByteArray_Check(src.ptr())) {
            // We were passed a bytearray; accept it into a std::string or char*
            // without any encoding attempt.
            const char *bytearray = PyByteArray_AsString(src.ptr());
            if (!bytearray) {
                pybind11_fail("Unexpected PyByteArray_AsString() failure.");
            }
            value = StringType(bytearray, (size_t) PyByteArray_Size(src.ptr()));
            return true;
        }

        return false;
    }

    template <typename C = CharT>
    bool load_raw(enable_if_t<!std::is_same<C, char>::value, handle>) {
        return false;
    }
};

template <typename CharT, class Traits, class Allocator>
struct type_caster<std::basic_string<CharT, Traits, Allocator>,
                   enable_if_t<is_std_char_type<CharT>::value>>
    : string_caster<std::basic_string<CharT, Traits, Allocator>> {};

#ifdef PYBIND11_HAS_STRING_VIEW
template <typename CharT, class Traits>
struct type_caster<std::basic_string_view<CharT, Traits>,
                   enable_if_t<is_std_char_type<CharT>::value>>
    : string_caster<std::basic_string_view<CharT, Traits>, true> {};
#endif

// Type caster for C-style strings.  We basically use a std::string type caster, but also add the
// ability to use None as a nullptr char* (which the string caster doesn't allow).
template <typename CharT>
struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {
    using StringType = std::basic_string<CharT>;
    using StringCaster = make_caster<StringType>;
    StringCaster str_caster;
    bool none = false;
    CharT one_char = 0;

public:
    bool load(handle src, bool convert) {
        if (!src) {
            return false;
        }
        if (src.is_none()) {
            // Defer accepting None to other overloads (if we aren't in convert mode):
            if (!convert) {
                return false;
            }
            none = true;
            return true;
        }
        return str_caster.load(src, convert);
    }

    static handle cast(const CharT *src, return_value_policy policy, handle parent) {
        if (src == nullptr) {
            return pybind11::none().release();
        }
        return StringCaster::cast(StringType(src), policy, parent);
    }

    static handle cast(CharT src, return_value_policy policy, handle parent) {
        if (std::is_same<char, CharT>::value) {
            handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr);
            if (!s) {
                throw error_already_set();
            }
            return s;
        }
        return StringCaster::cast(StringType(1, src), policy, parent);
    }

    explicit operator CharT *() {
        return none ? nullptr : const_cast<CharT *>(static_cast<StringType &>(str_caster).c_str());
    }
    explicit operator CharT &() {
        if (none) {
            throw value_error("Cannot convert None to a character");
        }

        auto &value = static_cast<StringType &>(str_caster);
        size_t str_len = value.size();
        if (str_len == 0) {
            throw value_error("Cannot convert empty string to a character");
        }

        // If we're in UTF-8 mode, we have two possible failures: one for a unicode character that
        // is too high, and one for multiple unicode characters (caught later), so we need to
        // figure out how long the first encoded character is in bytes to distinguish between these
        // two errors.  We also allow want to allow unicode characters U+0080 through U+00FF, as
        // those can fit into a single char value.
        if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) {
            auto v0 = static_cast<unsigned char>(value[0]);
            // low bits only: 0-127
            // 0b110xxxxx - start of 2-byte sequence
            // 0b1110xxxx - start of 3-byte sequence
            // 0b11110xxx - start of 4-byte sequence
            size_t char0_bytes = (v0 & 0x80) == 0      ? 1
                                 : (v0 & 0xE0) == 0xC0 ? 2
                                 : (v0 & 0xF0) == 0xE0 ? 3
                                                       : 4;

            if (char0_bytes == str_len) {
                // If we have a 128-255 value, we can decode it into a single char:
                if (char0_bytes == 2 && (v0 & 0xFC) == 0xC0) { // 0x110000xx 0x10xxxxxx
                    one_char = static_cast<CharT>(((v0 & 3) << 6)
                                                  + (static_cast<unsigned char>(value[1]) & 0x3F));
                    return one_char;
                }
                // Otherwise we have a single character, but it's > U+00FF
                throw value_error("Character code point not in range(0x100)");
            }
        }

        // UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a
        // surrogate pair with total length 2 instantly indicates a range error (but not a "your
        // string was too long" error).
        else if (StringCaster::UTF_N == 16 && str_len == 2) {
            one_char = static_cast<CharT>(value[0]);
            if (one_char >= 0xD800 && one_char < 0xE000) {
                throw value_error("Character code point not in range(0x10000)");
            }
        }

        if (str_len != 1) {
            throw value_error("Expected a character, but multi-character string found");
        }

        one_char = value[0];
        return one_char;
    }

    static constexpr auto name = const_name(PYBIND11_STRING_NAME);
    template <typename _T>
    using cast_op_type = pybind11::detail::cast_op_type<_T>;
};

// Base implementation for std::tuple and std::pair
template <template <typename...> class Tuple, typename... Ts>
class tuple_caster {
    using type = Tuple<Ts...>;
    static constexpr auto size = sizeof...(Ts);
    using indices = make_index_sequence<size>;

public:
    bool load(handle src, bool convert) {
        if (!isinstance<sequence>(src)) {
            return false;
        }
        const auto seq = reinterpret_borrow<sequence>(src);
        if (seq.size() != size) {
            return false;
        }
        return load_impl(seq, convert, indices{});
    }

    template <typename T>
    static handle cast(T &&src, return_value_policy policy, handle parent) {
        return cast_impl(std::forward<T>(src), policy, parent, indices{});
    }

    // copied from the PYBIND11_TYPE_CASTER macro
    template <typename T>
    static handle cast(T *src, return_value_policy policy, handle parent) {
        if (!src) {
            return none().release();
        }
        if (policy == return_value_policy::take_ownership) {
            auto h = cast(std::move(*src), policy, parent);
            delete src;
            return h;
        }
        return cast(*src, policy, parent);
    }

    static constexpr auto name = const_name("tuple[")
                                 + ::pybind11::detail::concat(make_caster<Ts>::name...)
                                 + const_name("]");

    template <typename T>
    using cast_op_type = type;

    explicit operator type() & { return implicit_cast(indices{}); }
    explicit operator type() && { return std::move(*this).implicit_cast(indices{}); }

protected:
    template <size_t... Is>
    type implicit_cast(index_sequence<Is...>) & {
        return type(cast_op<Ts>(std::get<Is>(subcasters))...);
    }
    template <size_t... Is>
    type implicit_cast(index_sequence<Is...>) && {
        return type(cast_op<Ts>(std::move(std::get<Is>(subcasters)))...);
    }

    static constexpr bool load_impl(const sequence &, bool, index_sequence<>) { return true; }

    template <size_t... Is>
    bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) {
#ifdef __cpp_fold_expressions
        if ((... || !std::get<Is>(subcasters).load(seq[Is], convert))) {
            return false;
        }
#else
        for (bool r : {std::get<Is>(subcasters).load(seq[Is], convert)...}) {
            if (!r) {
                return false;
            }
        }
#endif
        return true;
    }

    /* Implementation: Convert a C++ tuple into a Python tuple */
    template <typename T, size_t... Is>
    static handle
    cast_impl(T &&src, return_value_policy policy, handle parent, index_sequence<Is...>) {
        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(src, policy, parent);
        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(policy, parent);
        std::array<object, size> entries{{reinterpret_steal<object>(
            make_caster<Ts>::cast(std::get<Is>(std::forward<T>(src)), policy, parent))...}};
        for (const auto &entry : entries) {
            if (!entry) {
                return handle();
            }
        }
        tuple result(size);
        int counter = 0;
        for (auto &entry : entries) {
            PyTuple_SET_ITEM(result.ptr(), counter++, entry.release().ptr());
        }
        return result.release();
    }

    Tuple<make_caster<Ts>...> subcasters;
};

template <typename T1, typename T2>
class type_caster<std::pair<T1, T2>> : public tuple_caster<std::pair, T1, T2> {};

template <typename... Ts>
class type_caster<std::tuple<Ts...>> : public tuple_caster<std::tuple, Ts...> {};

template <>
class type_caster<std::tuple<>> : public tuple_caster<std::tuple> {
public:
    // PEP 484 specifies this syntax for an empty tuple
    static constexpr auto name = const_name("tuple[()]");
};

/// Helper class which abstracts away certain actions. Users can provide specializations for
/// custom holders, but it's only necessary if the type has a non-standard interface.
template <typename T>
struct holder_helper {
    static auto get(const T &p) -> decltype(p.get()) { return p.get(); }
};

/// Another helper class for holders that helps construct derivative holders from
/// the original holder
template <typename T>
struct holder_retriever {
	static auto get_derivative_holder(const value_and_holder& v_h) -> decltype(v_h.template holder<T>()) {
		return v_h.template holder<T>();
	}
};

template <typename T>
struct holder_retriever<std::shared_ptr<T>> {
	struct shared_ptr_deleter {
		// Note: deleter destructor fails on MSVC 2015 and GCC 4.8, so we manually
		// call dec_ref here instead
		handle ref;
		void operator()(T*) {
			gil_scoped_acquire gil;
			ref.dec_ref();
		}
	};

	static auto get_derivative_holder(const value_and_holder& v_h) -> std::shared_ptr<T> {
		// If there's no trampoline class, nothing special needed
		if (!v_h.inst->is_alias) {
			return v_h.template holder<std::shared_ptr<T>>();
		}

		// If there's a trampoline class, ensure the python side of the object doesn't
		// die until the C++ portion also dies
		//
		// The shared_ptr is always given to C++ code, so construct a new shared_ptr
		// that is given a custom deleter. The custom deleter increments the python
		// reference count to bind the python instance lifetime with the lifetime
		// of the shared_ptr.
		//
		// This enables things like passing the last python reference of a subclass to a
		// C++ function without the python reference dying.
		//
		// Reference cycles will cause a leak, but this is a limitation of shared_ptr
		return std::shared_ptr<T>((T*)v_h.value_ptr(),
			shared_ptr_deleter{ handle((PyObject*)v_h.inst).inc_ref() });
	}
};

/// Type caster for holder types like std::shared_ptr, etc.
/// The SFINAE hook is provided to help work around the current lack of support
/// for smart-pointer interoperability. Please consider it an implementation
/// detail that may change in the future, as formal support for smart-pointer
/// interoperability is added into pybind11.
template <typename type, typename holder_type, typename SFINAE = void>
struct copyable_holder_caster : public type_caster_base<type> {
public:
    using base = type_caster_base<type>;
    static_assert(std::is_base_of<base, type_caster<type>>::value,
                  "Holder classes are only supported for custom types");
    using base::base;
    using base::cast;
    using base::typeinfo;
    using base::value;

    bool load(handle src, bool convert) {
        return base::template load_impl<copyable_holder_caster<type, holder_type>>(src, convert);
    }

    explicit operator type *() { return this->value; }
    // static_cast works around compiler error with MSVC 17 and CUDA 10.2
    // see issue #2180
    explicit operator type &() { return *(static_cast<type *>(this->value)); }
    explicit operator holder_type *() { return std::addressof(holder); }
    explicit operator holder_type &() { return holder; }

    static handle cast(const holder_type &src, return_value_policy, handle) {
        const auto *ptr = holder_helper<holder_type>::get(src);
        return type_caster_base<type>::cast_holder(ptr, &src);
    }

protected:
    friend class type_caster_generic;
    void check_holder_compat() {
        if (typeinfo->default_holder) {
            throw cast_error("Unable to load a custom holder type from a default-holder instance");
        }
    }

    void load_value(value_and_holder &&v_h) {
        if (v_h.holder_constructed()) {
            value = v_h.value_ptr();
            holder = holder_retriever<holder_type>::get_derivative_holder(v_h);
            return;
        }
        throw cast_error("Unable to cast from non-held to held instance (T& to Holder<T>) "
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
                         "(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
                         "type information)");
#else
                         "of type '"
                         + type_id<holder_type>() + "''");
#endif
    }

    template <typename T = holder_type,
              detail::enable_if_t<!std::is_constructible<T, const T &, type *>::value, int> = 0>
    bool try_implicit_casts(handle, bool) {
        return false;
    }

    template <typename T = holder_type,
              detail::enable_if_t<std::is_constructible<T, const T &, type *>::value, int> = 0>
    bool try_implicit_casts(handle src, bool convert) {
        for (auto &cast : typeinfo->implicit_casts) {
            copyable_holder_caster sub_caster(*cast.first);
            if (sub_caster.load(src, convert)) {
                value = cast.second(sub_caster.value);
                holder = holder_type(sub_caster.holder, (type *) value);
                return true;
            }
        }
        return false;
    }

    static bool try_direct_conversions(handle) { return false; }

    holder_type holder;
};

/// Specialize for the common std::shared_ptr, so users don't need to
template <typename T>
class type_caster<std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> {};

/// Type caster for holder types like std::unique_ptr.
/// Please consider the SFINAE hook an implementation detail, as explained
/// in the comment for the copyable_holder_caster.
template <typename type, typename holder_type, typename SFINAE = void>
struct move_only_holder_caster {
    static_assert(std::is_base_of<type_caster_base<type>, type_caster<type>>::value,
                  "Holder classes are only supported for custom types");

    static handle cast(holder_type &&src, return_value_policy, handle) {
        auto *ptr = holder_helper<holder_type>::get(src);
        return type_caster_base<type>::cast_holder(ptr, std::addressof(src));
    }
    static constexpr auto name = type_caster_base<type>::name;
};

template <typename type, typename deleter>
class type_caster<std::unique_ptr<type, deleter>>
    : public move_only_holder_caster<type, std::unique_ptr<type, deleter>> {};

template <typename type, typename holder_type>
using type_caster_holder = conditional_t<is_copy_constructible<holder_type>::value,
                                         copyable_holder_caster<type, holder_type>,
                                         move_only_holder_caster<type, holder_type>>;

template <typename T, bool Value = false>
struct always_construct_holder {
    static constexpr bool value = Value;
};

/// Create a specialization for custom holder types (silently ignores std::shared_ptr)
#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type, ...)                                      \
    PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)                                                  \
    namespace detail {                                                                            \
    template <typename type>                                                                      \
    struct always_construct_holder<holder_type> : always_construct_holder<void, ##__VA_ARGS__> {  \
    };                                                                                            \
    template <typename type>                                                                      \
    class type_caster<holder_type, enable_if_t<!is_shared_ptr<holder_type>::value>>               \
        : public type_caster_holder<type, holder_type> {};                                        \
    }                                                                                             \
    PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

// PYBIND11_DECLARE_HOLDER_TYPE holder types:
template <typename base, typename holder>
struct is_holder_type
    : std::is_base_of<detail::type_caster_holder<base, holder>, detail::type_caster<holder>> {};
// Specialization for always-supported unique_ptr holders:
template <typename base, typename deleter>
struct is_holder_type<base, std::unique_ptr<base, deleter>> : std::true_type {};

#ifdef PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION // See PR #4888

// This leads to compilation errors if a specialization is missing.
template <typename T>
struct handle_type_name;

#else

template <typename T>
struct handle_type_name {
    static constexpr auto name = const_name<T>();
};

#endif

template <>
struct handle_type_name<object> {
    static constexpr auto name = const_name("object");
};
template <>
struct handle_type_name<list> {
    static constexpr auto name = const_name("list");
};
template <>
struct handle_type_name<dict> {
    static constexpr auto name = const_name("dict");
};
template <>
struct handle_type_name<anyset> {
    static constexpr auto name = const_name("Union[set, frozenset]");
};
template <>
struct handle_type_name<set> {
    static constexpr auto name = const_name("set");
};
template <>
struct handle_type_name<frozenset> {
    static constexpr auto name = const_name("frozenset");
};
template <>
struct handle_type_name<str> {
    static constexpr auto name = const_name("str");
};
template <>
struct handle_type_name<tuple> {
    static constexpr auto name = const_name("tuple");
};
template <>
struct handle_type_name<bool_> {
    static constexpr auto name = const_name("bool");
};
template <>
struct handle_type_name<bytes> {
    static constexpr auto name = const_name(PYBIND11_BYTES_NAME);
};
template <>
struct handle_type_name<buffer> {
    static constexpr auto name = const_name("Buffer");
};
template <>
struct handle_type_name<int_> {
    static constexpr auto name = const_name("int");
};
template <>
struct handle_type_name<iterable> {
    static constexpr auto name = const_name("Iterable");
};
template <>
struct handle_type_name<iterator> {
    static constexpr auto name = const_name("Iterator");
};
template <>
struct handle_type_name<float_> {
    static constexpr auto name = const_name("float");
};
template <>
struct handle_type_name<function> {
    static constexpr auto name = const_name("Callable");
};
template <>
struct handle_type_name<handle> {
    static constexpr auto name = handle_type_name<object>::name;
};
template <>
struct handle_type_name<none> {
    static constexpr auto name = const_name("None");
};
template <>
struct handle_type_name<sequence> {
    static constexpr auto name = const_name("Sequence");
};
template <>
struct handle_type_name<bytearray> {
    static constexpr auto name = const_name("bytearray");
};
template <>
struct handle_type_name<memoryview> {
    static constexpr auto name = const_name("memoryview");
};
template <>
struct handle_type_name<slice> {
    static constexpr auto name = const_name("slice");
};
template <>
struct handle_type_name<type> {
    static constexpr auto name = const_name("type");
};
template <>
struct handle_type_name<capsule> {
    static constexpr auto name = const_name("capsule");
};
template <>
struct handle_type_name<ellipsis> {
    static constexpr auto name = const_name("ellipsis");
};
template <>
struct handle_type_name<weakref> {
    static constexpr auto name = const_name("weakref");
};
template <>
struct handle_type_name<args> {
    static constexpr auto name = const_name("*args");
};
template <>
struct handle_type_name<kwargs> {
    static constexpr auto name = const_name("**kwargs");
};
template <>
struct handle_type_name<obj_attr_accessor> {
    static constexpr auto name = const_name<obj_attr_accessor>();
};
template <>
struct handle_type_name<str_attr_accessor> {
    static constexpr auto name = const_name<str_attr_accessor>();
};
template <>
struct handle_type_name<item_accessor> {
    static constexpr auto name = const_name<item_accessor>();
};
template <>
struct handle_type_name<sequence_accessor> {
    static constexpr auto name = const_name<sequence_accessor>();
};
template <>
struct handle_type_name<list_accessor> {
    static constexpr auto name = const_name<list_accessor>();
};
template <>
struct handle_type_name<tuple_accessor> {
    static constexpr auto name = const_name<tuple_accessor>();
};

template <typename type>
struct pyobject_caster {
    template <typename T = type, enable_if_t<std::is_same<T, handle>::value, int> = 0>
    pyobject_caster() : value() {}

    // `type` may not be default constructible (e.g. frozenset, anyset).  Initializing `value`
    // to a nil handle is safe since it will only be accessed if `load` succeeds.
    template <typename T = type, enable_if_t<std::is_base_of<object, T>::value, int> = 0>
    pyobject_caster() : value(reinterpret_steal<type>(handle())) {}

    template <typename T = type, enable_if_t<std::is_same<T, handle>::value, int> = 0>
    bool load(handle src, bool /* convert */) {
        value = src;
        return static_cast<bool>(value);
    }

    template <typename T = type, enable_if_t<std::is_base_of<object, T>::value, int> = 0>
    bool load(handle src, bool /* convert */) {
        if (!isinstance<type>(src)) {
            return false;
        }
        value = reinterpret_borrow<type>(src);
        return true;
    }

    static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) {
        return src.inc_ref();
    }
    PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name);
};

template <typename T>
class type_caster<T, enable_if_t<is_pyobject<T>::value>> : public pyobject_caster<T> {};

// Our conditions for enabling moving are quite restrictive:
// At compile time:
// - T needs to be a non-const, non-pointer, non-reference type
// - type_caster<T>::operator T&() must exist
// - the type must be move constructible (obviously)
// At run-time:
// - if the type is non-copy-constructible, the object must be the sole owner of the type (i.e. it
//   must have ref_count() == 1)h
// If any of the above are not satisfied, we fall back to copying.
template <typename T>
using move_is_plain_type
    = satisfies_none_of<T, std::is_void, std::is_pointer, std::is_reference, std::is_const>;
template <typename T, typename SFINAE = void>
struct move_always : std::false_type {};
template <typename T>
struct move_always<
    T,
    enable_if_t<
        all_of<move_is_plain_type<T>,
               negation<is_copy_constructible<T>>,
               is_move_constructible<T>,
               std::is_same<decltype(std::declval<make_caster<T>>().operator T &()), T &>>::value>>
    : std::true_type {};
template <typename T, typename SFINAE = void>
struct move_if_unreferenced : std::false_type {};
template <typename T>
struct move_if_unreferenced<
    T,
    enable_if_t<
        all_of<move_is_plain_type<T>,
               negation<move_always<T>>,
               is_move_constructible<T>,
               std::is_same<decltype(std::declval<make_caster<T>>().operator T &()), T &>>::value>>
    : std::true_type {};
template <typename T>
using move_never = none_of<move_always<T>, move_if_unreferenced<T>>;

// Detect whether returning a `type` from a cast on type's type_caster is going to result in a
// reference or pointer to a local variable of the type_caster.  Basically, only
// non-reference/pointer `type`s and reference/pointers from a type_caster_generic are safe;
// everything else returns a reference/pointer to a local variable.
template <typename type>
using cast_is_temporary_value_reference
    = bool_constant<(std::is_reference<type>::value || std::is_pointer<type>::value)
                    && !std::is_base_of<type_caster_generic, make_caster<type>>::value
                    && !std::is_same<intrinsic_t<type>, void>::value>;

// When a value returned from a C++ function is being cast back to Python, we almost always want to
// force `policy = move`, regardless of the return value policy the function/method was declared
// with.
template <typename Return, typename SFINAE = void>
struct return_value_policy_override {
    static return_value_policy policy(return_value_policy p) { return p; }
};

template <typename Return>
struct return_value_policy_override<
    Return,
    detail::enable_if_t<std::is_base_of<type_caster_generic, make_caster<Return>>::value, void>> {
    static return_value_policy policy(return_value_policy p) {
        return !std::is_lvalue_reference<Return>::value && !std::is_pointer<Return>::value
                   ? return_value_policy::move
                   : p;
    }
};

// Basic python -> C++ casting; throws if casting fails
template <typename T, typename SFINAE>
type_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &handle) {
    static_assert(!detail::is_pyobject<T>::value,
                  "Internal error: type_caster should only be used for C++ types");
    if (!conv.load(handle, true)) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
        throw cast_error(
            "Unable to cast Python instance of type "
            + str(type::handle_of(handle)).cast<std::string>()
            + " to C++ type '?' (#define "
              "PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
#else
        throw cast_error("Unable to cast Python instance of type "
                         + str(type::handle_of(handle)).cast<std::string>() + " to C++ type '"
                         + type_id<T>() + "'");
#endif
    }
    return conv;
}
// Wrapper around the above that also constructs and returns a type_caster
template <typename T>
make_caster<T> load_type(const handle &handle) {
    make_caster<T> conv;
    load_type(conv, handle);
    return conv;
}

PYBIND11_NAMESPACE_END(detail)

// pytype -> C++ type
template <typename T,
          detail::enable_if_t<!detail::is_pyobject<T>::value
                                  && !detail::is_same_ignoring_cvref<T, PyObject *>::value,
                              int>
          = 0>
T cast(const handle &handle) {
    using namespace detail;
    static_assert(!cast_is_temporary_value_reference<T>::value,
                  "Unable to cast type to reference: value is local to type caster");
    return cast_op<T>(load_type<T>(handle));
}

// pytype -> pytype (calls converting constructor)
template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>
T cast(const handle &handle) {
    return T(reinterpret_borrow<object>(handle));
}

// Note that `cast<PyObject *>(obj)` increments the reference count of `obj`.
// This is necessary for the case that `obj` is a temporary, and could
// not possibly be different, given
// 1. the established convention that the passed `handle` is borrowed, and
// 2. we don't want to force all generic code using `cast<T>()` to special-case
//    handling of `T` = `PyObject *` (to increment the reference count there).
// It is the responsibility of the caller to ensure that the reference count
// is decremented.
template <typename T,
          typename Handle,
          detail::enable_if_t<detail::is_same_ignoring_cvref<T, PyObject *>::value
                                  && detail::is_same_ignoring_cvref<Handle, handle>::value,
                              int>
          = 0>
T cast(Handle &&handle) {
    return handle.inc_ref().ptr();
}
// To optimize way an inc_ref/dec_ref cycle:
template <typename T,
          typename Object,
          detail::enable_if_t<detail::is_same_ignoring_cvref<T, PyObject *>::value
                                  && detail::is_same_ignoring_cvref<Object, object>::value,
                              int>
          = 0>
T cast(Object &&obj) {
    return obj.release().ptr();
}

// C++ type -> py::object
template <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>
object cast(T &&value,
            return_value_policy policy = return_value_policy::automatic_reference,
            handle parent = handle()) {
    using no_ref_T = typename std::remove_reference<T>::type;
    if (policy == return_value_policy::automatic) {
        policy = std::is_pointer<no_ref_T>::value     ? return_value_policy::take_ownership
                 : std::is_lvalue_reference<T>::value ? return_value_policy::copy
                                                      : return_value_policy::move;
    } else if (policy == return_value_policy::automatic_reference) {
        policy = std::is_pointer<no_ref_T>::value     ? return_value_policy::reference
                 : std::is_lvalue_reference<T>::value ? return_value_policy::copy
                                                      : return_value_policy::move;
    }
    return reinterpret_steal<object>(
        detail::make_caster<T>::cast(std::forward<T>(value), policy, parent));
}

template <typename T>
T handle::cast() const {
    return pybind11::cast<T>(*this);
}
template <>
inline void handle::cast() const {
    return;
}

template <typename T>
detail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) {
    if (obj.ref_count() > 1) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
        throw cast_error(
            "Unable to cast Python " + str(type::handle_of(obj)).cast<std::string>()
            + " instance to C++ rvalue: instance has multiple references"
              " (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
#else
        throw cast_error("Unable to move from Python "
                         + str(type::handle_of(obj)).cast<std::string>() + " instance to C++ "
                         + type_id<T>() + " instance: instance has multiple references");
#endif
    }

    // Move into a temporary and return that, because the reference may be a local value of `conv`
    T ret = std::move(detail::load_type<T>(obj).operator T &());
    return ret;
}

// Calling cast() on an rvalue calls pybind11::cast with the object rvalue, which does:
// - If we have to move (because T has no copy constructor), do it.  This will fail if the moved
//   object has multiple references, but trying to copy will fail to compile.
// - If both movable and copyable, check ref count: if 1, move; otherwise copy
// - Otherwise (not movable), copy.
template <typename T>
detail::enable_if_t<!detail::is_pyobject<T>::value && detail::move_always<T>::value, T>
cast(object &&object) {
    return move<T>(std::move(object));
}
template <typename T>
detail::enable_if_t<!detail::is_pyobject<T>::value && detail::move_if_unreferenced<T>::value, T>
cast(object &&object) {
    if (object.ref_count() > 1) {
        return cast<T>(object);
    }
    return move<T>(std::move(object));
}
template <typename T>
detail::enable_if_t<!detail::is_pyobject<T>::value && detail::move_never<T>::value, T>
cast(object &&object) {
    return cast<T>(object);
}

// pytype rvalue -> pytype (calls converting constructor)
template <typename T>
detail::enable_if_t<detail::is_pyobject<T>::value, T> cast(object &&object) {
    return T(std::move(object));
}

template <typename T>
T object::cast() const & {
    return pybind11::cast<T>(*this);
}
template <typename T>
T object::cast() && {
    return pybind11::cast<T>(std::move(*this));
}
template <>
inline void object::cast() const & {
    return;
}
template <>
inline void object::cast() && {
    return;
}

PYBIND11_NAMESPACE_BEGIN(detail)

// Declared in pytypes.h:
template <typename T, enable_if_t<!is_pyobject<T>::value, int>>
object object_or_cast(T &&o) {
    return pybind11::cast(std::forward<T>(o));
}

// Placeholder type for the unneeded (and dead code) static variable in the
// PYBIND11_OVERRIDE_OVERRIDE macro
struct override_unused {};
template <typename ret_type>
using override_caster_t = conditional_t<cast_is_temporary_value_reference<ret_type>::value,
                                        make_caster<ret_type>,
                                        override_unused>;

// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then
// store the result in the given variable.  For other types, this is a no-op.
template <typename T>
enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&o,
                                                                     make_caster<T> &caster) {
    return cast_op<T>(load_type(caster, o));
}
template <typename T>
enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&,
                                                                      override_unused &) {
    pybind11_fail("Internal error: cast_ref fallback invoked");
}

// Trampoline use: Having a pybind11::cast with an invalid reference type is going to
// static_assert, even though if it's in dead code, so we provide a "trampoline" to pybind11::cast
// that only does anything in cases where pybind11::cast is valid.
template <typename T>
enable_if_t<cast_is_temporary_value_reference<T>::value
                && !detail::is_same_ignoring_cvref<T, PyObject *>::value,
            T>
cast_safe(object &&) {
    pybind11_fail("Internal error: cast_safe fallback invoked");
}
template <typename T>
enable_if_t<std::is_void<T>::value, void> cast_safe(object &&) {}
template <typename T>
enable_if_t<detail::is_same_ignoring_cvref<T, PyObject *>::value, PyObject *>
cast_safe(object &&o) {
    return o.release().ptr();
}
template <typename T>
enable_if_t<detail::none_of<cast_is_temporary_value_reference<T>,
                            detail::is_same_ignoring_cvref<T, PyObject *>,
                            std::is_void<T>>::value,
            T>
cast_safe(object &&o) {
    return pybind11::cast<T>(std::move(o));
}

PYBIND11_NAMESPACE_END(detail)

// The overloads could coexist, i.e. the #if is not strictly speaking needed,
// but it is an easy minor optimization.
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
inline cast_error cast_error_unable_to_convert_call_arg(const std::string &name) {
    return cast_error("Unable to convert call argument '" + name
                      + "' to Python object (#define "
                        "PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
}
#else
inline cast_error cast_error_unable_to_convert_call_arg(const std::string &name,
                                                        const std::string &type) {
    return cast_error("Unable to convert call argument '" + name + "' of type '" + type
                      + "' to Python object");
}
#endif

template <return_value_policy policy = return_value_policy::automatic_reference>
tuple make_tuple() {
    return tuple(0);
}

template <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>
tuple make_tuple(Args &&...args_) {
    constexpr size_t size = sizeof...(Args);
    std::array<object, size> args{{reinterpret_steal<object>(
        detail::make_caster<Args>::cast(std::forward<Args>(args_), policy, nullptr))...}};
    for (size_t i = 0; i < args.size(); i++) {
        if (!args[i]) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
            throw cast_error_unable_to_convert_call_arg(std::to_string(i));
#else
            std::array<std::string, size> argtypes{{type_id<Args>()...}};
            throw cast_error_unable_to_convert_call_arg(std::to_string(i), argtypes[i]);
#endif
        }
    }
    tuple result(size);
    int counter = 0;
    for (auto &arg_value : args) {
        PyTuple_SET_ITEM(result.ptr(), counter++, arg_value.release().ptr());
    }
    return result;
}

/// \ingroup annotations
/// Annotation for arguments
struct arg {
    /// Constructs an argument with the name of the argument; if null or omitted, this is a
    /// positional argument.
    constexpr explicit arg(const char *name = nullptr)
        : name(name), flag_noconvert(false), flag_none(true) {}
    /// Assign a value to this argument
    template <typename T>
    arg_v operator=(T &&value) const;
    /// Indicate that the type should not be converted in the type caster
    arg &noconvert(bool flag = true) {
        flag_noconvert = flag;
        return *this;
    }
    /// Indicates that the argument should/shouldn't allow None (e.g. for nullable pointer args)
    arg &none(bool flag = true) {
        flag_none = flag;
        return *this;
    }

    const char *name;        ///< If non-null, this is a named kwargs argument
    bool flag_noconvert : 1; ///< If set, do not allow conversion (requires a supporting type
                             ///< caster!)
    bool flag_none : 1;      ///< If set (the default), allow None to be passed to this argument
};

/// \ingroup annotations
/// Annotation for arguments with values
struct arg_v : arg {
private:
    template <typename T>
    arg_v(arg &&base, T &&x, const char *descr = nullptr)
        : arg(base), value(reinterpret_steal<object>(detail::make_caster<T>::cast(
                         std::forward<T>(x), return_value_policy::automatic, {}))),
          descr(descr)
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
          ,
          type(type_id<T>())
#endif
    {
        // Workaround! See:
        // https://github.com/pybind/pybind11/issues/2336
        // https://github.com/pybind/pybind11/pull/2685#issuecomment-731286700
        if (PyErr_Occurred()) {
            PyErr_Clear();
        }
    }

public:
    /// Direct construction with name, default, and description
    template <typename T>
    arg_v(const char *name, T &&x, const char *descr = nullptr)
        : arg_v(arg(name), std::forward<T>(x), descr) {}

    /// Called internally when invoking `py::arg("a") = value`
    template <typename T>
    arg_v(const arg &base, T &&x, const char *descr = nullptr)
        : arg_v(arg(base), std::forward<T>(x), descr) {}

    /// Same as `arg::noconvert()`, but returns *this as arg_v&, not arg&
    arg_v &noconvert(bool flag = true) {
        arg::noconvert(flag);
        return *this;
    }

    /// Same as `arg::nonone()`, but returns *this as arg_v&, not arg&
    arg_v &none(bool flag = true) {
        arg::none(flag);
        return *this;
    }

    /// The default value
    object value;
    /// The (optional) description of the default value
    const char *descr;
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
    /// The C++ type name of the default value (only available when compiled in debug mode)
    std::string type;
#endif
};

/// \ingroup annotations
/// Annotation indicating that all following arguments are keyword-only; the is the equivalent of
/// an unnamed '*' argument
struct kw_only {};

/// \ingroup annotations
/// Annotation indicating that all previous arguments are positional-only; the is the equivalent of
/// an unnamed '/' argument (in Python 3.8)
struct pos_only {};

template <typename T>
arg_v arg::operator=(T &&value) const {
    return {*this, std::forward<T>(value)};
}

/// Alias for backward compatibility -- to be removed in version 2.0
template <typename /*unused*/>
using arg_t = arg_v;

inline namespace literals {
/** \rst
    String literal version of `arg`
 \endrst */
constexpr arg
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 5
operator"" _a // gcc 4.8.5 insists on having a space (hard error).
#else
operator""_a // clang 17 generates a deprecation warning if there is a space.
#endif
    (const char *name, size_t) {
    return arg(name);
}
} // namespace literals

PYBIND11_NAMESPACE_BEGIN(detail)

template <typename T>
using is_kw_only = std::is_same<intrinsic_t<T>, kw_only>;
template <typename T>
using is_pos_only = std::is_same<intrinsic_t<T>, pos_only>;

// forward declaration (definition in attr.h)
struct function_record;

/// Internal data associated with a single function call
struct function_call {
    function_call(const function_record &f, handle p); // Implementation in attr.h

    /// The function data:
    const function_record &func;

    /// Arguments passed to the function:
    std::vector<handle> args;

    /// The `convert` value the arguments should be loaded with
    std::vector<bool> args_convert;

    /// Extra references for the optional `py::args` and/or `py::kwargs` arguments (which, if
    /// present, are also in `args` but without a reference).
    object args_ref, kwargs_ref;

    /// The parent, if any
    handle parent;

    /// If this is a call to an initializer, this argument contains `self`
    handle init_self;
};

/// Helper class which loads arguments for C++ functions called from Python
template <typename... Args>
class argument_loader {
    using indices = make_index_sequence<sizeof...(Args)>;

    template <typename Arg>
    using argument_is_args = std::is_same<intrinsic_t<Arg>, args>;
    template <typename Arg>
    using argument_is_kwargs = std::is_same<intrinsic_t<Arg>, kwargs>;
    // Get kwargs argument position, or -1 if not present:
    static constexpr auto kwargs_pos = constexpr_last<argument_is_kwargs, Args...>();

    static_assert(kwargs_pos == -1 || kwargs_pos == (int) sizeof...(Args) - 1,
                  "py::kwargs is only permitted as the last argument of a function");

public:
    static constexpr bool has_kwargs = kwargs_pos != -1;

    // py::args argument position; -1 if not present.
    static constexpr int args_pos = constexpr_last<argument_is_args, Args...>();

    static_assert(args_pos == -1 || args_pos == constexpr_first<argument_is_args, Args...>(),
                  "py::args cannot be specified more than once");

    static constexpr auto arg_names
        = ::pybind11::detail::concat(type_descr(make_caster<Args>::name)...);

    bool load_args(function_call &call) { return load_impl_sequence(call, indices{}); }

    template <typename Return, typename Guard, typename Func>
    // NOLINTNEXTLINE(readability-const-return-type)
    enable_if_t<!std::is_void<Return>::value, Return> call(Func &&f) && {
        return std::move(*this).template call_impl<remove_cv_t<Return>>(
            std::forward<Func>(f), indices{}, Guard{});
    }

    template <typename Return, typename Guard, typename Func>
    enable_if_t<std::is_void<Return>::value, void_type> call(Func &&f) && {
        std::move(*this).template call_impl<remove_cv_t<Return>>(
            std::forward<Func>(f), indices{}, Guard{});
        return void_type();
    }

private:
    static bool load_impl_sequence(function_call &, index_sequence<>) { return true; }

    template <size_t... Is>
    bool load_impl_sequence(function_call &call, index_sequence<Is...>) {
#ifdef __cpp_fold_expressions
        if ((... || !std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is]))) {
            return false;
        }
#else
        for (bool r : {std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])...}) {
            if (!r) {
                return false;
            }
        }
#endif
        return true;
    }

    template <typename Return, typename Func, size_t... Is, typename Guard>
    Return call_impl(Func &&f, index_sequence<Is...>, Guard &&) && {
        return std::forward<Func>(f)(cast_op<Args>(std::move(std::get<Is>(argcasters)))...);
    }

    std::tuple<make_caster<Args>...> argcasters;
};

/// Helper class which collects only positional arguments for a Python function call.
/// A fancier version below can collect any argument, but this one is optimal for simple calls.
template <return_value_policy policy>
class simple_collector {
public:
    template <typename... Ts>
    explicit simple_collector(Ts &&...values)
        : m_args(pybind11::make_tuple<policy>(std::forward<Ts>(values)...)) {}

    const tuple &args() const & { return m_args; }
    dict kwargs() const { return {}; }

    tuple args() && { return std::move(m_args); }

    /// Call a Python function and pass the collected arguments
    object call(PyObject *ptr) const {
        PyObject *result = PyObject_CallObject(ptr, m_args.ptr());
        if (!result) {
            throw error_already_set();
        }
        return reinterpret_steal<object>(result);
    }

private:
    tuple m_args;
};

/// Helper class which collects positional, keyword, * and ** arguments for a Python function call
template <return_value_policy policy>
class unpacking_collector {
public:
    template <typename... Ts>
    explicit unpacking_collector(Ts &&...values) {
        // Tuples aren't (easily) resizable so a list is needed for collection,
        // but the actual function call strictly requires a tuple.
        auto args_list = list();
        using expander = int[];
        (void) expander{0, (process(args_list, std::forward<Ts>(values)), 0)...};

        m_args = std::move(args_list);
    }

    const tuple &args() const & { return m_args; }
    const dict &kwargs() const & { return m_kwargs; }

    tuple args() && { return std::move(m_args); }
    dict kwargs() && { return std::move(m_kwargs); }

    /// Call a Python function and pass the collected arguments
    object call(PyObject *ptr) const {
        PyObject *result = PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr());
        if (!result) {
            throw error_already_set();
        }
        return reinterpret_steal<object>(result);
    }

private:
    template <typename T>
    void process(list &args_list, T &&x) {
        auto o = reinterpret_steal<object>(
            detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));
        if (!o) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
            throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()));
#else
            throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()),
                                                        type_id<T>());
#endif
        }
        args_list.append(std::move(o));
    }

    void process(list &args_list, detail::args_proxy ap) {
        for (auto a : ap) {
            args_list.append(a);
        }
    }

    void process(list & /*args_list*/, arg_v a) {
        if (!a.name) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
            nameless_argument_error();
#else
            nameless_argument_error(a.type);
#endif
        }
        if (m_kwargs.contains(a.name)) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
            multiple_values_error();
#else
            multiple_values_error(a.name);
#endif
        }
        if (!a.value) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
            throw cast_error_unable_to_convert_call_arg(a.name);
#else
            throw cast_error_unable_to_convert_call_arg(a.name, a.type);
#endif
        }
        m_kwargs[a.name] = std::move(a.value);
    }

    void process(list & /*args_list*/, detail::kwargs_proxy kp) {
        if (!kp) {
            return;
        }
        for (auto k : reinterpret_borrow<dict>(kp)) {
            if (m_kwargs.contains(k.first)) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
                multiple_values_error();
#else
                multiple_values_error(str(k.first));
#endif
            }
            m_kwargs[k.first] = k.second;
        }
    }

    [[noreturn]] static void nameless_argument_error() {
        throw type_error(
            "Got kwargs without a name; only named arguments "
            "may be passed via py::arg() to a python function call. "
            "(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
    }
    [[noreturn]] static void nameless_argument_error(const std::string &type) {
        throw type_error("Got kwargs without a name of type '" + type
                         + "'; only named "
                           "arguments may be passed via py::arg() to a python function call. ");
    }
    [[noreturn]] static void multiple_values_error() {
        throw type_error(
            "Got multiple values for keyword argument "
            "(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
    }

    [[noreturn]] static void multiple_values_error(const std::string &name) {
        throw type_error("Got multiple values for keyword argument '" + name + "'");
    }

private:
    tuple m_args;
    dict m_kwargs;
};

// [workaround(intel)] Separate function required here
// We need to put this into a separate function because the Intel compiler
// fails to compile enable_if_t<!all_of<is_positional<Args>...>::value>
// (tested with ICC 2021.1 Beta 20200827).
template <typename... Args>
constexpr bool args_are_all_positional() {
    return all_of<is_positional<Args>...>::value;
}

/// Collect only positional arguments for a Python function call
template <return_value_policy policy,
          typename... Args,
          typename = enable_if_t<args_are_all_positional<Args...>()>>
simple_collector<policy> collect_arguments(Args &&...args) {
    return simple_collector<policy>(std::forward<Args>(args)...);
}

/// Collect all arguments, including keywords and unpacking (only instantiated when needed)
template <return_value_policy policy,
          typename... Args,
          typename = enable_if_t<!args_are_all_positional<Args...>()>>
unpacking_collector<policy> collect_arguments(Args &&...args) {
    // Following argument order rules for generalized unpacking according to PEP 448
    static_assert(constexpr_last<is_positional, Args...>()
                          < constexpr_first<is_keyword_or_ds, Args...>()
                      && constexpr_last<is_s_unpacking, Args...>()
                             < constexpr_first<is_ds_unpacking, Args...>(),
                  "Invalid function call: positional args must precede keywords and ** unpacking; "
                  "* unpacking must precede ** unpacking");
    return unpacking_collector<policy>(std::forward<Args>(args)...);
}

template <typename Derived>
template <return_value_policy policy, typename... Args>
object object_api<Derived>::operator()(Args &&...args) const {
#ifndef NDEBUG
    if (!PyGILState_Check()) {
        pybind11_fail("pybind11::object_api<>::operator() PyGILState_Check() failure.");
    }
#endif
    return detail::collect_arguments<policy>(std::forward<Args>(args)...).call(derived().ptr());
}

template <typename Derived>
template <return_value_policy policy, typename... Args>
object object_api<Derived>::call(Args &&...args) const {
    return operator()<policy>(std::forward<Args>(args)...);
}

PYBIND11_NAMESPACE_END(detail)

template <typename T>
handle type::handle_of() {
    static_assert(std::is_base_of<detail::type_caster_generic, detail::make_caster<T>>::value,
                  "py::type::of<T> only supports the case where T is a registered C++ types.");

    return detail::get_type_handle(typeid(T), true);
}

#define PYBIND11_MAKE_OPAQUE(...)                                                                 \
    PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)                                                  \
    namespace detail {                                                                            \
    template <>                                                                                   \
    class type_caster<__VA_ARGS__> : public type_caster_base<__VA_ARGS__> {};                     \
    }                                                                                             \
    PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

/// Lets you pass a type containing a `,` through a macro parameter without needing a separate
/// typedef, e.g.:
/// `PYBIND11_OVERRIDE(PYBIND11_TYPE(ReturnType<A, B>), PYBIND11_TYPE(Parent<C, D>), f, arg)`
#define PYBIND11_TYPE(...) __VA_ARGS__

PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

cast.h

/*
    pybind11/cast.h: Partial template specializations to cast between
    C++ and Python types

    Copyright (c) 2016 Wenzel Jakob <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#pragma once

#include "detail/common.h"
#include "detail/descr.h"
#include "detail/type_caster_base.h"
#include "detail/typeid.h"
#include "pytypes.h"
#include "gil.h"

#include <array>
#include <cstring>
#include <functional>
#include <iosfwd>
#include <iterator>
#include <memory>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

PYBIND11_WARNING_DISABLE_MSVC(4127)

PYBIND11_NAMESPACE_BEGIN(detail)

template <typename type, typename SFINAE = void>
class type_caster : public type_caster_base<type> {};
template <typename type>
using make_caster = type_caster<intrinsic_t<type>>;

// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T
template <typename T>
typename make_caster<T>::template cast_op_type<T> cast_op(make_caster<T> &caster) {
    using result_t = typename make_caster<T>::template cast_op_type<T>; // See PR #4893
    return caster.operator result_t();
}
template <typename T>
typename make_caster<T>::template cast_op_type<typename std::add_rvalue_reference<T>::type>
cast_op(make_caster<T> &&caster) {
    using result_t = typename make_caster<T>::template cast_op_type<
        typename std::add_rvalue_reference<T>::type>; // See PR #4893
    return std::move(caster).operator result_t();
}

template <typename type>
class type_caster<std::reference_wrapper<type>> {
private:
    using caster_t = make_caster<type>;
    caster_t subcaster;
    using reference_t = type &;
    using subcaster_cast_op_type = typename caster_t::template cast_op_type<reference_t>;

    static_assert(
        std::is_same<typename std::remove_const<type>::type &, subcaster_cast_op_type>::value
            || std::is_same<reference_t, subcaster_cast_op_type>::value,
        "std::reference_wrapper<T> caster requires T to have a caster with an "
        "`operator T &()` or `operator const T &()`");

public:
    bool load(handle src, bool convert) { return subcaster.load(src, convert); }
    static constexpr auto name = caster_t::name;
    static handle
    cast(const std::reference_wrapper<type> &src, return_value_policy policy, handle parent) {
        // It is definitely wrong to take ownership of this pointer, so mask that rvp
        if (policy == return_value_policy::take_ownership
            || policy == return_value_policy::automatic) {
            policy = return_value_policy::automatic_reference;
        }
        return caster_t::cast(&src.get(), policy, parent);
    }
    template <typename T>
    using cast_op_type = std::reference_wrapper<type>;
    explicit operator std::reference_wrapper<type>() { return cast_op<type &>(subcaster); }
};

#define PYBIND11_TYPE_CASTER(type, py_name)                                                       \
protected:                                                                                        \
    type value;                                                                                   \
                                                                                                  \
public:                                                                                           \
    static constexpr auto name = py_name;                                                         \
    template <typename T_,                                                                        \
              ::pybind11::detail::enable_if_t<                                                    \
                  std::is_same<type, ::pybind11::detail::remove_cv_t<T_>>::value,                 \
                  int>                                                                            \
              = 0>                                                                                \
    static ::pybind11::handle cast(                                                               \
        T_ *src, ::pybind11::return_value_policy policy, ::pybind11::handle parent) {             \
        if (!src)                                                                                 \
            return ::pybind11::none().release();                                                  \
        if (policy == ::pybind11::return_value_policy::take_ownership) {                          \
            auto h = cast(std::move(*src), policy, parent);                                       \
            delete src;                                                                           \
            return h;                                                                             \
        }                                                                                         \
        return cast(*src, policy, parent);                                                        \
    }                                                                                             \
    operator type *() { return &value; }               /* NOLINT(bugprone-macro-parentheses) */   \
    operator type &() { return value; }                /* NOLINT(bugprone-macro-parentheses) */   \
    operator type &&() && { return std::move(value); } /* NOLINT(bugprone-macro-parentheses) */   \
    template <typename T_>                                                                        \
    using cast_op_type = ::pybind11::detail::movable_cast_op_type<T_>

template <typename CharT>
using is_std_char_type = any_of<std::is_same<CharT, char>, /* std::string */
#if defined(PYBIND11_HAS_U8STRING)
                                std::is_same<CharT, char8_t>, /* std::u8string */
#endif
                                std::is_same<CharT, char16_t>, /* std::u16string */
                                std::is_same<CharT, char32_t>, /* std::u32string */
                                std::is_same<CharT, wchar_t>   /* std::wstring */
                                >;

template <typename T>
struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_type<T>::value>> {
    using _py_type_0 = conditional_t<sizeof(T) <= sizeof(long), long, long long>;
    using _py_type_1 = conditional_t<std::is_signed<T>::value,
                                     _py_type_0,
                                     typename std::make_unsigned<_py_type_0>::type>;
    using py_type = conditional_t<std::is_floating_point<T>::value, double, _py_type_1>;

public:
    bool load(handle src, bool convert) {
        py_type py_value;

        if (!src) {
            return false;
        }

#if !defined(PYPY_VERSION)
        auto index_check = [](PyObject *o) { return PyIndex_Check(o); };
#else
        // In PyPy 7.3.3, `PyIndex_Check` is implemented by calling `__index__`,
        // while CPython only considers the existence of `nb_index`/`__index__`.
        auto index_check = [](PyObject *o) { return hasattr(o, "__index__"); };
#endif

        if (std::is_floating_point<T>::value) {
            if (convert || PyFloat_Check(src.ptr())) {
                py_value = (py_type) PyFloat_AsDouble(src.ptr());
            } else {
                return false;
            }
        } else if (PyFloat_Check(src.ptr())
                   || (!convert && !PYBIND11_LONG_CHECK(src.ptr()) && !index_check(src.ptr()))) {
            return false;
        } else {
            handle src_or_index = src;
            // PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls.
#if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
            object index;
            if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr())
                index = reinterpret_steal<object>(PyNumber_Index(src.ptr()));
                if (!index) {
                    PyErr_Clear();
                    if (!convert)
                        return false;
                } else {
                    src_or_index = index;
                }
            }
#endif
            if (std::is_unsigned<py_type>::value) {
                py_value = as_unsigned<py_type>(src_or_index.ptr());
            } else { // signed integer:
                py_value = sizeof(T) <= sizeof(long)
                               ? (py_type) PyLong_AsLong(src_or_index.ptr())
                               : (py_type) PYBIND11_LONG_AS_LONGLONG(src_or_index.ptr());
            }
        }

        // Python API reported an error
        bool py_err = py_value == (py_type) -1 && PyErr_Occurred();

        // Check to see if the conversion is valid (integers should match exactly)
        // Signed/unsigned checks happen elsewhere
        if (py_err
            || (std::is_integral<T>::value && sizeof(py_type) != sizeof(T)
                && py_value != (py_type) (T) py_value)) {
            PyErr_Clear();
            if (py_err && convert && (PyNumber_Check(src.ptr()) != 0)) {
                auto tmp = reinterpret_steal<object>(std::is_floating_point<T>::value
                                                         ? PyNumber_Float(src.ptr())
                                                         : PyNumber_Long(src.ptr()));
                PyErr_Clear();
                return load(tmp, false);
            }
            return false;
        }

        value = (T) py_value;
        return true;
    }

    template <typename U = T>
    static typename std::enable_if<std::is_floating_point<U>::value, handle>::type
    cast(U src, return_value_policy /* policy */, handle /* parent */) {
        return PyFloat_FromDouble((double) src);
    }

    template <typename U = T>
    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_signed<U>::value
                                       && (sizeof(U) <= sizeof(long)),
                                   handle>::type
    cast(U src, return_value_policy /* policy */, handle /* parent */) {
        return PYBIND11_LONG_FROM_SIGNED((long) src);
    }

    template <typename U = T>
    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_unsigned<U>::value
                                       && (sizeof(U) <= sizeof(unsigned long)),
                                   handle>::type
    cast(U src, return_value_policy /* policy */, handle /* parent */) {
        return PYBIND11_LONG_FROM_UNSIGNED((unsigned long) src);
    }

    template <typename U = T>
    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_signed<U>::value
                                       && (sizeof(U) > sizeof(long)),
                                   handle>::type
    cast(U src, return_value_policy /* policy */, handle /* parent */) {
        return PyLong_FromLongLong((long long) src);
    }

    template <typename U = T>
    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_unsigned<U>::value
                                       && (sizeof(U) > sizeof(unsigned long)),
                                   handle>::type
    cast(U src, return_value_policy /* policy */, handle /* parent */) {
        return PyLong_FromUnsignedLongLong((unsigned long long) src);
    }

    PYBIND11_TYPE_CASTER(T, const_name<std::is_integral<T>::value>("int", "float"));
};

template <typename T>
struct void_caster {
public:
    bool load(handle src, bool) {
        if (src && src.is_none()) {
            return true;
        }
        return false;
    }
    static handle cast(T, return_value_policy /* policy */, handle /* parent */) {
        return none().release();
    }
    PYBIND11_TYPE_CASTER(T, const_name("None"));
};

template <>
class type_caster<void_type> : public void_caster<void_type> {};

template <>
class type_caster<void> : public type_caster<void_type> {
public:
    using type_caster<void_type>::cast;

    bool load(handle h, bool) {
        if (!h) {
            return false;
        }
        if (h.is_none()) {
            value = nullptr;
            return true;
        }

        /* Check if this is a capsule */
        if (isinstance<capsule>(h)) {
            value = reinterpret_borrow<capsule>(h);
            return true;
        }

        /* Check if this is a C++ type */
        const auto &bases = all_type_info((PyTypeObject *) type::handle_of(h).ptr());
        if (bases.size() == 1) { // Only allowing loading from a single-value type
            value = values_and_holders(reinterpret_cast<instance *>(h.ptr())).begin()->value_ptr();
            return true;
        }

        /* Fail */
        return false;
    }

    static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) {
        if (ptr) {
            return capsule(ptr).release();
        }
        return none().release();
    }

    template <typename T>
    using cast_op_type = void *&;
    explicit operator void *&() { return value; }
    static constexpr auto name = const_name("capsule");

private:
    void *value = nullptr;
};

template <>
class type_caster<std::nullptr_t> : public void_caster<std::nullptr_t> {};

template <>
class type_caster<bool> {
public:
    bool load(handle src, bool convert) {
        if (!src) {
            return false;
        }
        if (src.ptr() == Py_True) {
            value = true;
            return true;
        }
        if (src.ptr() == Py_False) {
            value = false;
            return true;
        }
        if (convert || is_numpy_bool(src)) {
            // (allow non-implicit conversion for numpy booleans), use strncmp
            // since NumPy 1.x had an additional trailing underscore.

            Py_ssize_t res = -1;
            if (src.is_none()) {
                res = 0; // None is implicitly converted to False
            }
#if defined(PYPY_VERSION)
            // On PyPy, check that "__bool__" attr exists
            else if (hasattr(src, PYBIND11_BOOL_ATTR)) {
                res = PyObject_IsTrue(src.ptr());
            }
#else
            // Alternate approach for CPython: this does the same as the above, but optimized
            // using the CPython API so as to avoid an unneeded attribute lookup.
            else if (auto *tp_as_number = src.ptr()->ob_type->tp_as_number) {
                if (PYBIND11_NB_BOOL(tp_as_number)) {
                    res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr());
                }
            }
#endif
            if (res == 0 || res == 1) {
                value = (res != 0);
                return true;
            }
            PyErr_Clear();
        }
        return false;
    }
    static handle cast(bool src, return_value_policy /* policy */, handle /* parent */) {
        return handle(src ? Py_True : Py_False).inc_ref();
    }
    PYBIND11_TYPE_CASTER(bool, const_name("bool"));

private:
    // Test if an object is a NumPy boolean (without fetching the type).
    static inline bool is_numpy_bool(handle object) {
        const char *type_name = Py_TYPE(object.ptr())->tp_name;
        // Name changed to `numpy.bool` in NumPy 2, `numpy.bool_` is needed for 1.x support
        return std::strcmp("numpy.bool", type_name) == 0
               || std::strcmp("numpy.bool_", type_name) == 0;
    }
};

// Helper class for UTF-{8,16,32} C++ stl strings:
template <typename StringType, bool IsView = false>
struct string_caster {
    using CharT = typename StringType::value_type;

    // Simplify life by being able to assume standard char sizes (the standard only guarantees
    // minimums, but Python requires exact sizes)
    static_assert(!std::is_same<CharT, char>::value || sizeof(CharT) == 1,
                  "Unsupported char size != 1");
#if defined(PYBIND11_HAS_U8STRING)
    static_assert(!std::is_same<CharT, char8_t>::value || sizeof(CharT) == 1,
                  "Unsupported char8_t size != 1");
#endif
    static_assert(!std::is_same<CharT, char16_t>::value || sizeof(CharT) == 2,
                  "Unsupported char16_t size != 2");
    static_assert(!std::is_same<CharT, char32_t>::value || sizeof(CharT) == 4,
                  "Unsupported char32_t size != 4");
    // wchar_t can be either 16 bits (Windows) or 32 (everywhere else)
    static_assert(!std::is_same<CharT, wchar_t>::value || sizeof(CharT) == 2 || sizeof(CharT) == 4,
                  "Unsupported wchar_t size != 2/4");
    static constexpr size_t UTF_N = 8 * sizeof(CharT);

    bool load(handle src, bool) {
        handle load_src = src;
        if (!src) {
            return false;
        }
        if (!PyUnicode_Check(load_src.ptr())) {
            return load_raw(load_src);
        }

        // For UTF-8 we avoid the need for a temporary `bytes` object by using
        // `PyUnicode_AsUTF8AndSize`.
        if (UTF_N == 8) {
            Py_ssize_t size = -1;
            const auto *buffer
                = reinterpret_cast<const CharT *>(PyUnicode_AsUTF8AndSize(load_src.ptr(), &size));
            if (!buffer) {
                PyErr_Clear();
                return false;
            }
            value = StringType(buffer, static_cast<size_t>(size));
            return true;
        }

        auto utfNbytes
            = reinterpret_steal<object>(PyUnicode_AsEncodedString(load_src.ptr(),
                                                                  UTF_N == 8    ? "utf-8"
                                                                  : UTF_N == 16 ? "utf-16"
                                                                                : "utf-32",
                                                                  nullptr));
        if (!utfNbytes) {
            PyErr_Clear();
            return false;
        }

        const auto *buffer
            = reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
        size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
        // Skip BOM for UTF-16/32
        if (UTF_N > 8) {
            buffer++;
            length--;
        }
        value = StringType(buffer, length);

        // If we're loading a string_view we need to keep the encoded Python object alive:
        if (IsView) {
            loader_life_support::add_patient(utfNbytes);
        }

        return true;
    }

    static handle
    cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) {
        const char *buffer = reinterpret_cast<const char *>(src.data());
        auto nbytes = ssize_t(src.size() * sizeof(CharT));
        handle s = decode_utfN(buffer, nbytes);
        if (!s) {
            throw error_already_set();
        }
        return s;
    }

    PYBIND11_TYPE_CASTER(StringType, const_name(PYBIND11_STRING_NAME));

private:
    static handle decode_utfN(const char *buffer, ssize_t nbytes) {
#if !defined(PYPY_VERSION)
        return UTF_N == 8    ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr)
               : UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr)
                             : PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr);
#else
        // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as
        // well), so bypass the whole thing by just passing the encoding as a string value, which
        // works properly:
        return PyUnicode_Decode(buffer,
                                nbytes,
                                UTF_N == 8    ? "utf-8"
                                : UTF_N == 16 ? "utf-16"
                                              : "utf-32",
                                nullptr);
#endif
    }

    // When loading into a std::string or char*, accept a bytes/bytearray object as-is (i.e.
    // without any encoding/decoding attempt).  For other C++ char sizes this is a no-op.
    // which supports loading a unicode from a str, doesn't take this path.
    template <typename C = CharT>
    bool load_raw(enable_if_t<std::is_same<C, char>::value, handle> src) {
        if (PYBIND11_BYTES_CHECK(src.ptr())) {
            // We were passed raw bytes; accept it into a std::string or char*
            // without any encoding attempt.
            const char *bytes = PYBIND11_BYTES_AS_STRING(src.ptr());
            if (!bytes) {
                pybind11_fail("Unexpected PYBIND11_BYTES_AS_STRING() failure.");
            }
            value = StringType(bytes, (size_t) PYBIND11_BYTES_SIZE(src.ptr()));
            return true;
        }
        if (PyByteArray_Check(src.ptr())) {
            // We were passed a bytearray; accept it into a std::string or char*
            // without any encoding attempt.
            const char *bytearray = PyByteArray_AsString(src.ptr());
            if (!bytearray) {
                pybind11_fail("Unexpected PyByteArray_AsString() failure.");
            }
            value = StringType(bytearray, (size_t) PyByteArray_Size(src.ptr()));
            return true;
        }

        return false;
    }

    template <typename C = CharT>
    bool load_raw(enable_if_t<!std::is_same<C, char>::value, handle>) {
        return false;
    }
};

template <typename CharT, class Traits, class Allocator>
struct type_caster<std::basic_string<CharT, Traits, Allocator>,
                   enable_if_t<is_std_char_type<CharT>::value>>
    : string_caster<std::basic_string<CharT, Traits, Allocator>> {};

#ifdef PYBIND11_HAS_STRING_VIEW
template <typename CharT, class Traits>
struct type_caster<std::basic_string_view<CharT, Traits>,
                   enable_if_t<is_std_char_type<CharT>::value>>
    : string_caster<std::basic_string_view<CharT, Traits>, true> {};
#endif

// Type caster for C-style strings.  We basically use a std::string type caster, but also add the
// ability to use None as a nullptr char* (which the string caster doesn't allow).
template <typename CharT>
struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {
    using StringType = std::basic_string<CharT>;
    using StringCaster = make_caster<StringType>;
    StringCaster str_caster;
    bool none = false;
    CharT one_char = 0;

public:
    bool load(handle src, bool convert) {
        if (!src) {
            return false;
        }
        if (src.is_none()) {
            // Defer accepting None to other overloads (if we aren't in convert mode):
            if (!convert) {
                return false;
            }
            none = true;
            return true;
        }
        return str_caster.load(src, convert);
    }

    static handle cast(const CharT *src, return_value_policy policy, handle parent) {
        if (src == nullptr) {
            return pybind11::none().release();
        }
        return StringCaster::cast(StringType(src), policy, parent);
    }

    static handle cast(CharT src, return_value_policy policy, handle parent) {
        if (std::is_same<char, CharT>::value) {
            handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr);
            if (!s) {
                throw error_already_set();
            }
            return s;
        }
        return StringCaster::cast(StringType(1, src), policy, parent);
    }

    explicit operator CharT *() {
        return none ? nullptr : const_cast<CharT *>(static_cast<StringType &>(str_caster).c_str());
    }
    explicit operator CharT &() {
        if (none) {
            throw value_error("Cannot convert None to a character");
        }

        auto &value = static_cast<StringType &>(str_caster);
        size_t str_len = value.size();
        if (str_len == 0) {
            throw value_error("Cannot convert empty string to a character");
        }

        // If we're in UTF-8 mode, we have two possible failures: one for a unicode character that
        // is too high, and one for multiple unicode characters (caught later), so we need to
        // figure out how long the first encoded character is in bytes to distinguish between these
        // two errors.  We also allow want to allow unicode characters U+0080 through U+00FF, as
        // those can fit into a single char value.
        if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) {
            auto v0 = static_cast<unsigned char>(value[0]);
            // low bits only: 0-127
            // 0b110xxxxx - start of 2-byte sequence
            // 0b1110xxxx - start of 3-byte sequence
            // 0b11110xxx - start of 4-byte sequence
            size_t char0_bytes = (v0 & 0x80) == 0      ? 1
                                 : (v0 & 0xE0) == 0xC0 ? 2
                                 : (v0 & 0xF0) == 0xE0 ? 3
                                                       : 4;

            if (char0_bytes == str_len) {
                // If we have a 128-255 value, we can decode it into a single char:
                if (char0_bytes == 2 && (v0 & 0xFC) == 0xC0) { // 0x110000xx 0x10xxxxxx
                    one_char = static_cast<CharT>(((v0 & 3) << 6)
                                                  + (static_cast<unsigned char>(value[1]) & 0x3F));
                    return one_char;
                }
                // Otherwise we have a single character, but it's > U+00FF
                throw value_error("Character code point not in range(0x100)");
            }
        }

        // UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a
        // surrogate pair with total length 2 instantly indicates a range error (but not a "your
        // string was too long" error).
        else if (StringCaster::UTF_N == 16 && str_len == 2) {
            one_char = static_cast<CharT>(value[0]);
            if (one_char >= 0xD800 && one_char < 0xE000) {
                throw value_error("Character code point not in range(0x10000)");
            }
        }

        if (str_len != 1) {
            throw value_error("Expected a character, but multi-character string found");
        }

        one_char = value[0];
        return one_char;
    }

    static constexpr auto name = const_name(PYBIND11_STRING_NAME);
    template <typename _T>
    using cast_op_type = pybind11::detail::cast_op_type<_T>;
};

// Base implementation for std::tuple and std::pair
template <template <typename...> class Tuple, typename... Ts>
class tuple_caster {
    using type = Tuple<Ts...>;
    static constexpr auto size = sizeof...(Ts);
    using indices = make_index_sequence<size>;

public:
    bool load(handle src, bool convert) {
        if (!isinstance<sequence>(src)) {
            return false;
        }
        const auto seq = reinterpret_borrow<sequence>(src);
        if (seq.size() != size) {
            return false;
        }
        return load_impl(seq, convert, indices{});
    }

    template <typename T>
    static handle cast(T &&src, return_value_policy policy, handle parent) {
        return cast_impl(std::forward<T>(src), policy, parent, indices{});
    }

    // copied from the PYBIND11_TYPE_CASTER macro
    template <typename T>
    static handle cast(T *src, return_value_policy policy, handle parent) {
        if (!src) {
            return none().release();
        }
        if (policy == return_value_policy::take_ownership) {
            auto h = cast(std::move(*src), policy, parent);
            delete src;
            return h;
        }
        return cast(*src, policy, parent);
    }

    static constexpr auto name = const_name("tuple[")
                                 + ::pybind11::detail::concat(make_caster<Ts>::name...)
                                 + const_name("]");

    template <typename T>
    using cast_op_type = type;

    explicit operator type() & { return implicit_cast(indices{}); }
    explicit operator type() && { return std::move(*this).implicit_cast(indices{}); }

protected:
    template <size_t... Is>
    type implicit_cast(index_sequence<Is...>) & {
        return type(cast_op<Ts>(std::get<Is>(subcasters))...);
    }
    template <size_t... Is>
    type implicit_cast(index_sequence<Is...>) && {
        return type(cast_op<Ts>(std::move(std::get<Is>(subcasters)))...);
    }

    static constexpr bool load_impl(const sequence &, bool, index_sequence<>) { return true; }

    template <size_t... Is>
    bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) {
#ifdef __cpp_fold_expressions
        if ((... || !std::get<Is>(subcasters).load(seq[Is], convert))) {
            return false;
        }
#else
        for (bool r : {std::get<Is>(subcasters).load(seq[Is], convert)...}) {
            if (!r) {
                return false;
            }
        }
#endif
        return true;
    }

    /* Implementation: Convert a C++ tuple into a Python tuple */
    template <typename T, size_t... Is>
    static handle
    cast_impl(T &&src, return_value_policy policy, handle parent, index_sequence<Is...>) {
        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(src, policy, parent);
        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(policy, parent);
        std::array<object, size> entries{{reinterpret_steal<object>(
            make_caster<Ts>::cast(std::get<Is>(std::forward<T>(src)), policy, parent))...}};
        for (const auto &entry : entries) {
            if (!entry) {
                return handle();
            }
        }
        tuple result(size);
        int counter = 0;
        for (auto &entry : entries) {
            PyTuple_SET_ITEM(result.ptr(), counter++, entry.release().ptr());
        }
        return result.release();
    }

    Tuple<make_caster<Ts>...> subcasters;
};

template <typename T1, typename T2>
class type_caster<std::pair<T1, T2>> : public tuple_caster<std::pair, T1, T2> {};

template <typename... Ts>
class type_caster<std::tuple<Ts...>> : public tuple_caster<std::tuple, Ts...> {};

template <>
class type_caster<std::tuple<>> : public tuple_caster<std::tuple> {
public:
    // PEP 484 specifies this syntax for an empty tuple
    static constexpr auto name = const_name("tuple[()]");
};

/// Helper class which abstracts away certain actions. Users can provide specializations for
/// custom holders, but it's only necessary if the type has a non-standard interface.
template <typename T>
struct holder_helper {
    static auto get(const T &p) -> decltype(p.get()) { return p.get(); }
};

/// Another helper class for holders that helps construct derivative holders from
/// the original holder
template <typename T>
struct holder_retriever {
	static auto get_derivative_holder(const value_and_holder& v_h) -> decltype(v_h.template holder<T>()) {
		return v_h.template holder<T>();
	}
};

template <typename T>
struct holder_retriever<std::shared_ptr<T>> {
	struct shared_ptr_deleter {
		// Note: deleter destructor fails on MSVC 2015 and GCC 4.8, so we manually
		// call dec_ref here instead
		handle ref;
		void operator()(T*) {
			gil_scoped_acquire gil;
			ref.dec_ref();
		}
	};

	static auto get_derivative_holder(const value_and_holder& v_h) -> std::shared_ptr<T> {
		// If there's no trampoline class, nothing special needed
		if (!v_h.inst->is_alias) {
			return v_h.template holder<std::shared_ptr<T>>();
		}

		// If there's a trampoline class, ensure the python side of the object doesn't
		// die until the C++ portion also dies
		//
		// The shared_ptr is always given to C++ code, so construct a new shared_ptr
		// that is given a custom deleter. The custom deleter increments the python
		// reference count to bind the python instance lifetime with the lifetime
		// of the shared_ptr.
		//
		// This enables things like passing the last python reference of a subclass to a
		// C++ function without the python reference dying.
		//
		// Reference cycles will cause a leak, but this is a limitation of shared_ptr
		return std::shared_ptr<T>((T*)v_h.value_ptr(),
			shared_ptr_deleter{ handle((PyObject*)v_h.inst).inc_ref() });
	}
};

/// Type caster for holder types like std::shared_ptr, etc.
/// The SFINAE hook is provided to help work around the current lack of support
/// for smart-pointer interoperability. Please consider it an implementation
/// detail that may change in the future, as formal support for smart-pointer
/// interoperability is added into pybind11.
template <typename type, typename holder_type, typename SFINAE = void>
struct copyable_holder_caster : public type_caster_base<type> {
public:
    using base = type_caster_base<type>;
    static_assert(std::is_base_of<base, type_caster<type>>::value,
                  "Holder classes are only supported for custom types");
    using base::base;
    using base::cast;
    using base::typeinfo;
    using base::value;

    bool load(handle src, bool convert) {
        return base::template load_impl<copyable_holder_caster<type, holder_type>>(src, convert);
    }

    explicit operator type *() { return this->value; }
    // static_cast works around compiler error with MSVC 17 and CUDA 10.2
    // see issue #2180
    explicit operator type &() { return *(static_cast<type *>(this->value)); }
    explicit operator holder_type *() { return std::addressof(holder); }
    explicit operator holder_type &() { return holder; }

    static handle cast(const holder_type &src, return_value_policy, handle) {
        const auto *ptr = holder_helper<holder_type>::get(src);
        return type_caster_base<type>::cast_holder(ptr, &src);
    }

protected:
    friend class type_caster_generic;
    void check_holder_compat() {
        if (typeinfo->default_holder) {
            throw cast_error("Unable to load a custom holder type from a default-holder instance");
        }
    }

    void load_value(value_and_holder &&v_h) {
        if (v_h.holder_constructed()) {
            value = v_h.value_ptr();
            holder = holder_retriever<holder_type>::get_derivative_holder(v_h);
            return;
        }
        throw cast_error("Unable to cast from non-held to held instance (T& to Holder<T>) "
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
                         "(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
                         "type information)");
#else
                         "of type '"
                         + type_id<holder_type>() + "''");
#endif
    }

    template <typename T = holder_type,
              detail::enable_if_t<!std::is_constructible<T, const T &, type *>::value, int> = 0>
    bool try_implicit_casts(handle, bool) {
        return false;
    }

    template <typename T = holder_type,
              detail::enable_if_t<std::is_constructible<T, const T &, type *>::value, int> = 0>
    bool try_implicit_casts(handle src, bool convert) {
        for (auto &cast : typeinfo->implicit_casts) {
            copyable_holder_caster sub_caster(*cast.first);
            if (sub_caster.load(src, convert)) {
                value = cast.second(sub_caster.value);
                holder = holder_type(sub_caster.holder, (type *) value);
                return true;
            }
        }
        return false;
    }

    static bool try_direct_conversions(handle) { return false; }

    holder_type holder;
};

/// Specialize for the common std::shared_ptr, so users don't need to
template <typename T>
class type_caster<std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> {};

/// Type caster for holder types like std::unique_ptr.
/// Please consider the SFINAE hook an implementation detail, as explained
/// in the comment for the copyable_holder_caster.
template <typename type, typename holder_type, typename SFINAE = void>
struct move_only_holder_caster {
    static_assert(std::is_base_of<type_caster_base<type>, type_caster<type>>::value,
                  "Holder classes are only supported for custom types");

    static handle cast(holder_type &&src, return_value_policy, handle) {
        auto *ptr = holder_helper<holder_type>::get(src);
        return type_caster_base<type>::cast_holder(ptr, std::addressof(src));
    }
    static constexpr auto name = type_caster_base<type>::name;
};

template <typename type, typename deleter>
class type_caster<std::unique_ptr<type, deleter>>
    : public move_only_holder_caster<type, std::unique_ptr<type, deleter>> {};

template <typename type, typename holder_type>
using type_caster_holder = conditional_t<is_copy_constructible<holder_type>::value,
                                         copyable_holder_caster<type, holder_type>,
                                         move_only_holder_caster<type, holder_type>>;

template <typename T, bool Value = false>
struct always_construct_holder {
    static constexpr bool value = Value;
};

/// Create a specialization for custom holder types (silently ignores std::shared_ptr)
#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type, ...)                                      \
    PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)                                                  \
    namespace detail {                                                                            \
    template <typename type>                                                                      \
    struct always_construct_holder<holder_type> : always_construct_holder<void, ##__VA_ARGS__> {  \
    };                                                                                            \
    template <typename type>                                                                      \
    class type_caster<holder_type, enable_if_t<!is_shared_ptr<holder_type>::value>>               \
        : public type_caster_holder<type, holder_type> {};                                        \
    }                                                                                             \
    PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

// PYBIND11_DECLARE_HOLDER_TYPE holder types:
template <typename base, typename holder>
struct is_holder_type
    : std::is_base_of<detail::type_caster_holder<base, holder>, detail::type_caster<holder>> {};
// Specialization for always-supported unique_ptr holders:
template <typename base, typename deleter>
struct is_holder_type<base, std::unique_ptr<base, deleter>> : std::true_type {};

#ifdef PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION // See PR #4888

// This leads to compilation errors if a specialization is missing.
template <typename T>
struct handle_type_name;

#else

template <typename T>
struct handle_type_name {
    static constexpr auto name = const_name<T>();
};

#endif

template <>
struct handle_type_name<object> {
    static constexpr auto name = const_name("object");
};
template <>
struct handle_type_name<list> {
    static constexpr auto name = const_name("list");
};
template <>
struct handle_type_name<dict> {
    static constexpr auto name = const_name("dict");
};
template <>
struct handle_type_name<anyset> {
    static constexpr auto name = const_name("Union[set, frozenset]");
};
template <>
struct handle_type_name<set> {
    static constexpr auto name = const_name("set");
};
template <>
struct handle_type_name<frozenset> {
    static constexpr auto name = const_name("frozenset");
};
template <>
struct handle_type_name<str> {
    static constexpr auto name = const_name("str");
};
template <>
struct handle_type_name<tuple> {
    static constexpr auto name = const_name("tuple");
};
template <>
struct handle_type_name<bool_> {
    static constexpr auto name = const_name("bool");
};
template <>
struct handle_type_name<bytes> {
    static constexpr auto name = const_name(PYBIND11_BYTES_NAME);
};
template <>
struct handle_type_name<buffer> {
    static constexpr auto name = const_name("Buffer");
};
template <>
struct handle_type_name<int_> {
    static constexpr auto name = const_name("int");
};
template <>
struct handle_type_name<iterable> {
    static constexpr auto name = const_name("Iterable");
};
template <>
struct handle_type_name<iterator> {
    static constexpr auto name = const_name("Iterator");
};
template <>
struct handle_type_name<float_> {
    static constexpr auto name = const_name("float");
};
template <>
struct handle_type_name<function> {
    static constexpr auto name = const_name("Callable");
};
template <>
struct handle_type_name<handle> {
    static constexpr auto name = handle_type_name<object>::name;
};
template <>
struct handle_type_name<none> {
    static constexpr auto name = const_name("None");
};
template <>
struct handle_type_name<sequence> {
    static constexpr auto name = const_name("Sequence");
};
template <>
struct handle_type_name<bytearray> {
    static constexpr auto name = const_name("bytearray");
};
template <>
struct handle_type_name<memoryview> {
    static constexpr auto name = const_name("memoryview");
};
template <>
struct handle_type_name<slice> {
    static constexpr auto name = const_name("slice");
};
template <>
struct handle_type_name<type> {
    static constexpr auto name = const_name("type");
};
template <>
struct handle_type_name<capsule> {
    static constexpr auto name = const_name("capsule");
};
template <>
struct handle_type_name<ellipsis> {
    static constexpr auto name = const_name("ellipsis");
};
template <>
struct handle_type_name<weakref> {
    static constexpr auto name = const_name("weakref");
};
template <>
struct handle_type_name<args> {
    static constexpr auto name = const_name("*args");
};
template <>
struct handle_type_name<kwargs> {
    static constexpr auto name = const_name("**kwargs");
};
template <>
struct handle_type_name<obj_attr_accessor> {
    static constexpr auto name = const_name<obj_attr_accessor>();
};
template <>
struct handle_type_name<str_attr_accessor> {
    static constexpr auto name = const_name<str_attr_accessor>();
};
template <>
struct handle_type_name<item_accessor> {
    static constexpr auto name = const_name<item_accessor>();
};
template <>
struct handle_type_name<sequence_accessor> {
    static constexpr auto name = const_name<sequence_accessor>();
};
template <>
struct handle_type_name<list_accessor> {
    static constexpr auto name = const_name<list_accessor>();
};
template <>
struct handle_type_name<tuple_accessor> {
    static constexpr auto name = const_name<tuple_accessor>();
};

template <typename type>
struct pyobject_caster {
    template <typename T = type, enable_if_t<std::is_same<T, handle>::value, int> = 0>
    pyobject_caster() : value() {}

    // `type` may not be default constructible (e.g. frozenset, anyset).  Initializing `value`
    // to a nil handle is safe since it will only be accessed if `load` succeeds.
    template <typename T = type, enable_if_t<std::is_base_of<object, T>::value, int> = 0>
    pyobject_caster() : value(reinterpret_steal<type>(handle())) {}

    template <typename T = type, enable_if_t<std::is_same<T, handle>::value, int> = 0>
    bool load(handle src, bool /* convert */) {
        value = src;
        return static_cast<bool>(value);
    }

    template <typename T = type, enable_if_t<std::is_base_of<object, T>::value, int> = 0>
    bool load(handle src, bool /* convert */) {
        if (!isinstance<type>(src)) {
            return false;
        }
        value = reinterpret_borrow<type>(src);
        return true;
    }

    static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) {
        return src.inc_ref();
    }
    PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name);
};

template <typename T>
class type_caster<T, enable_if_t<is_pyobject<T>::value>> : public pyobject_caster<T> {};

// Our conditions for enabling moving are quite restrictive:
// At compile time:
// - T needs to be a non-const, non-pointer, non-reference type
// - type_caster<T>::operator T&() must exist
// - the type must be move constructible (obviously)
// At run-time:
// - if the type is non-copy-constructible, the object must be the sole owner of the type (i.e. it
//   must have ref_count() == 1)h
// If any of the above are not satisfied, we fall back to copying.
template <typename T>
using move_is_plain_type
    = satisfies_none_of<T, std::is_void, std::is_pointer, std::is_reference, std::is_const>;
template <typename T, typename SFINAE = void>
struct move_always : std::false_type {};
template <typename T>
struct move_always<
    T,
    enable_if_t<
        all_of<move_is_plain_type<T>,
               negation<is_copy_constructible<T>>,
               is_move_constructible<T>,
               std::is_same<decltype(std::declval<make_caster<T>>().operator T &()), T &>>::value>>
    : std::true_type {};
template <typename T, typename SFINAE = void>
struct move_if_unreferenced : std::false_type {};
template <typename T>
struct move_if_unreferenced<
    T,
    enable_if_t<
        all_of<move_is_plain_type<T>,
               negation<move_always<T>>,
               is_move_constructible<T>,
               std::is_same<decltype(std::declval<make_caster<T>>().operator T &()), T &>>::value>>
    : std::true_type {};
template <typename T>
using move_never = none_of<move_always<T>, move_if_unreferenced<T>>;

// Detect whether returning a `type` from a cast on type's type_caster is going to result in a
// reference or pointer to a local variable of the type_caster.  Basically, only
// non-reference/pointer `type`s and reference/pointers from a type_caster_generic are safe;
// everything else returns a reference/pointer to a local variable.
template <typename type>
using cast_is_temporary_value_reference
    = bool_constant<(std::is_reference<type>::value || std::is_pointer<type>::value)
                    && !std::is_base_of<type_caster_generic, make_caster<type>>::value
                    && !std::is_same<intrinsic_t<type>, void>::value>;

// When a value returned from a C++ function is being cast back to Python, we almost always want to
// force `policy = move`, regardless of the return value policy the function/method was declared
// with.
template <typename Return, typename SFINAE = void>
struct return_value_policy_override {
    static return_value_policy policy(return_value_policy p) { return p; }
};

template <typename Return>
struct return_value_policy_override<
    Return,
    detail::enable_if_t<std::is_base_of<type_caster_generic, make_caster<Return>>::value, void>> {
    static return_value_policy policy(return_value_policy p) {
        return !std::is_lvalue_reference<Return>::value && !std::is_pointer<Return>::value
                   ? return_value_policy::move
                   : p;
    }
};

// Basic python -> C++ casting; throws if casting fails
template <typename T, typename SFINAE>
type_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &handle) {
    static_assert(!detail::is_pyobject<T>::value,
                  "Internal error: type_caster should only be used for C++ types");
    if (!conv.load(handle, true)) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
        throw cast_error(
            "Unable to cast Python instance of type "
            + str(type::handle_of(handle)).cast<std::string>()
            + " to C++ type '?' (#define "
              "PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
#else
        throw cast_error("Unable to cast Python instance of type "
                         + str(type::handle_of(handle)).cast<std::string>() + " to C++ type '"
                         + type_id<T>() + "'");
#endif
    }
    return conv;
}
// Wrapper around the above that also constructs and returns a type_caster
template <typename T>
make_caster<T> load_type(const handle &handle) {
    make_caster<T> conv;
    load_type(conv, handle);
    return conv;
}

PYBIND11_NAMESPACE_END(detail)

// pytype -> C++ type
template <typename T,
          detail::enable_if_t<!detail::is_pyobject<T>::value
                                  && !detail::is_same_ignoring_cvref<T, PyObject *>::value,
                              int>
          = 0>
T cast(const handle &handle) {
    using namespace detail;
    static_assert(!cast_is_temporary_value_reference<T>::value,
                  "Unable to cast type to reference: value is local to type caster");
    return cast_op<T>(load_type<T>(handle));
}

// pytype -> pytype (calls converting constructor)
template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>
T cast(const handle &handle) {
    return T(reinterpret_borrow<object>(handle));
}

// Note that `cast<PyObject *>(obj)` increments the reference count of `obj`.
// This is necessary for the case that `obj` is a temporary, and could
// not possibly be different, given
// 1. the established convention that the passed `handle` is borrowed, and
// 2. we don't want to force all generic code using `cast<T>()` to special-case
//    handling of `T` = `PyObject *` (to increment the reference count there).
// It is the responsibility of the caller to ensure that the reference count
// is decremented.
template <typename T,
          typename Handle,
          detail::enable_if_t<detail::is_same_ignoring_cvref<T, PyObject *>::value
                                  && detail::is_same_ignoring_cvref<Handle, handle>::value,
                              int>
          = 0>
T cast(Handle &&handle) {
    return handle.inc_ref().ptr();
}
// To optimize way an inc_ref/dec_ref cycle:
template <typename T,
          typename Object,
          detail::enable_if_t<detail::is_same_ignoring_cvref<T, PyObject *>::value
                                  && detail::is_same_ignoring_cvref<Object, object>::value,
                              int>
          = 0>
T cast(Object &&obj) {
    return obj.release().ptr();
}

// C++ type -> py::object
template <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>
object cast(T &&value,
            return_value_policy policy = return_value_policy::automatic_reference,
            handle parent = handle()) {
    using no_ref_T = typename std::remove_reference<T>::type;
    if (policy == return_value_policy::automatic) {
        policy = std::is_pointer<no_ref_T>::value     ? return_value_policy::take_ownership
                 : std::is_lvalue_reference<T>::value ? return_value_policy::copy
                                                      : return_value_policy::move;
    } else if (policy == return_value_policy::automatic_reference) {
        policy = std::is_pointer<no_ref_T>::value     ? return_value_policy::reference
                 : std::is_lvalue_reference<T>::value ? return_value_policy::copy
                                                      : return_value_policy::move;
    }
    return reinterpret_steal<object>(
        detail::make_caster<T>::cast(std::forward<T>(value), policy, parent));
}

template <typename T>
T handle::cast() const {
    return pybind11::cast<T>(*this);
}
template <>
inline void handle::cast() const {
    return;
}

template <typename T>
detail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) {
    if (obj.ref_count() > 1) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
        throw cast_error(
            "Unable to cast Python " + str(type::handle_of(obj)).cast<std::string>()
            + " instance to C++ rvalue: instance has multiple references"
              " (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
#else
        throw cast_error("Unable to move from Python "
                         + str(type::handle_of(obj)).cast<std::string>() + " instance to C++ "
                         + type_id<T>() + " instance: instance has multiple references");
#endif
    }

    // Move into a temporary and return that, because the reference may be a local value of `conv`
    T ret = std::move(detail::load_type<T>(obj).operator T &());
    return ret;
}

// Calling cast() on an rvalue calls pybind11::cast with the object rvalue, which does:
// - If we have to move (because T has no copy constructor), do it.  This will fail if the moved
//   object has multiple references, but trying to copy will fail to compile.
// - If both movable and copyable, check ref count: if 1, move; otherwise copy
// - Otherwise (not movable), copy.
template <typename T>
detail::enable_if_t<!detail::is_pyobject<T>::value && detail::move_always<T>::value, T>
cast(object &&object) {
    return move<T>(std::move(object));
}
template <typename T>
detail::enable_if_t<!detail::is_pyobject<T>::value && detail::move_if_unreferenced<T>::value, T>
cast(object &&object) {
    if (object.ref_count() > 1) {
        return cast<T>(object);
    }
    return move<T>(std::move(object));
}
template <typename T>
detail::enable_if_t<!detail::is_pyobject<T>::value && detail::move_never<T>::value, T>
cast(object &&object) {
    return cast<T>(object);
}

// pytype rvalue -> pytype (calls converting constructor)
template <typename T>
detail::enable_if_t<detail::is_pyobject<T>::value, T> cast(object &&object) {
    return T(std::move(object));
}

template <typename T>
T object::cast() const & {
    return pybind11::cast<T>(*this);
}
template <typename T>
T object::cast() && {
    return pybind11::cast<T>(std::move(*this));
}
template <>
inline void object::cast() const & {
    return;
}
template <>
inline void object::cast() && {
    return;
}

PYBIND11_NAMESPACE_BEGIN(detail)

// Declared in pytypes.h:
template <typename T, enable_if_t<!is_pyobject<T>::value, int>>
object object_or_cast(T &&o) {
    return pybind11::cast(std::forward<T>(o));
}

// Placeholder type for the unneeded (and dead code) static variable in the
// PYBIND11_OVERRIDE_OVERRIDE macro
struct override_unused {};
template <typename ret_type>
using override_caster_t = conditional_t<cast_is_temporary_value_reference<ret_type>::value,
                                        make_caster<ret_type>,
                                        override_unused>;

// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then
// store the result in the given variable.  For other types, this is a no-op.
template <typename T>
enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&o,
                                                                     make_caster<T> &caster) {
    return cast_op<T>(load_type(caster, o));
}
template <typename T>
enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&,
                                                                      override_unused &) {
    pybind11_fail("Internal error: cast_ref fallback invoked");
}

// Trampoline use: Having a pybind11::cast with an invalid reference type is going to
// static_assert, even though if it's in dead code, so we provide a "trampoline" to pybind11::cast
// that only does anything in cases where pybind11::cast is valid.
template <typename T>
enable_if_t<cast_is_temporary_value_reference<T>::value
                && !detail::is_same_ignoring_cvref<T, PyObject *>::value,
            T>
cast_safe(object &&) {
    pybind11_fail("Internal error: cast_safe fallback invoked");
}
template <typename T>
enable_if_t<std::is_void<T>::value, void> cast_safe(object &&) {}
template <typename T>
enable_if_t<detail::is_same_ignoring_cvref<T, PyObject *>::value, PyObject *>
cast_safe(object &&o) {
    return o.release().ptr();
}
template <typename T>
enable_if_t<detail::none_of<cast_is_temporary_value_reference<T>,
                            detail::is_same_ignoring_cvref<T, PyObject *>,
                            std::is_void<T>>::value,
            T>
cast_safe(object &&o) {
    return pybind11::cast<T>(std::move(o));
}

PYBIND11_NAMESPACE_END(detail)

// The overloads could coexist, i.e. the #if is not strictly speaking needed,
// but it is an easy minor optimization.
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
inline cast_error cast_error_unable_to_convert_call_arg(const std::string &name) {
    return cast_error("Unable to convert call argument '" + name
                      + "' to Python object (#define "
                        "PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
}
#else
inline cast_error cast_error_unable_to_convert_call_arg(const std::string &name,
                                                        const std::string &type) {
    return cast_error("Unable to convert call argument '" + name + "' of type '" + type
                      + "' to Python object");
}
#endif

template <return_value_policy policy = return_value_policy::automatic_reference>
tuple make_tuple() {
    return tuple(0);
}

template <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>
tuple make_tuple(Args &&...args_) {
    constexpr size_t size = sizeof...(Args);
    std::array<object, size> args{{reinterpret_steal<object>(
        detail::make_caster<Args>::cast(std::forward<Args>(args_), policy, nullptr))...}};
    for (size_t i = 0; i < args.size(); i++) {
        if (!args[i]) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
            throw cast_error_unable_to_convert_call_arg(std::to_string(i));
#else
            std::array<std::string, size> argtypes{{type_id<Args>()...}};
            throw cast_error_unable_to_convert_call_arg(std::to_string(i), argtypes[i]);
#endif
        }
    }
    tuple result(size);
    int counter = 0;
    for (auto &arg_value : args) {
        PyTuple_SET_ITEM(result.ptr(), counter++, arg_value.release().ptr());
    }
    return result;
}

/// \ingroup annotations
/// Annotation for arguments
struct arg {
    /// Constructs an argument with the name of the argument; if null or omitted, this is a
    /// positional argument.
    constexpr explicit arg(const char *name = nullptr)
        : name(name), flag_noconvert(false), flag_none(true) {}
    /// Assign a value to this argument
    template <typename T>
    arg_v operator=(T &&value) const;
    /// Indicate that the type should not be converted in the type caster
    arg &noconvert(bool flag = true) {
        flag_noconvert = flag;
        return *this;
    }
    /// Indicates that the argument should/shouldn't allow None (e.g. for nullable pointer args)
    arg &none(bool flag = true) {
        flag_none = flag;
        return *this;
    }

    const char *name;        ///< If non-null, this is a named kwargs argument
    bool flag_noconvert : 1; ///< If set, do not allow conversion (requires a supporting type
                             ///< caster!)
    bool flag_none : 1;      ///< If set (the default), allow None to be passed to this argument
};

/// \ingroup annotations
/// Annotation for arguments with values
struct arg_v : arg {
private:
    template <typename T>
    arg_v(arg &&base, T &&x, const char *descr = nullptr)
        : arg(base), value(reinterpret_steal<object>(detail::make_caster<T>::cast(
                         std::forward<T>(x), return_value_policy::automatic, {}))),
          descr(descr)
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
          ,
          type(type_id<T>())
#endif
    {
        // Workaround! See:
        // https://github.com/pybind/pybind11/issues/2336
        // https://github.com/pybind/pybind11/pull/2685#issuecomment-731286700
        if (PyErr_Occurred()) {
            PyErr_Clear();
        }
    }

public:
    /// Direct construction with name, default, and description
    template <typename T>
    arg_v(const char *name, T &&x, const char *descr = nullptr)
        : arg_v(arg(name), std::forward<T>(x), descr) {}

    /// Called internally when invoking `py::arg("a") = value`
    template <typename T>
    arg_v(const arg &base, T &&x, const char *descr = nullptr)
        : arg_v(arg(base), std::forward<T>(x), descr) {}

    /// Same as `arg::noconvert()`, but returns *this as arg_v&, not arg&
    arg_v &noconvert(bool flag = true) {
        arg::noconvert(flag);
        return *this;
    }

    /// Same as `arg::nonone()`, but returns *this as arg_v&, not arg&
    arg_v &none(bool flag = true) {
        arg::none(flag);
        return *this;
    }

    /// The default value
    object value;
    /// The (optional) description of the default value
    const char *descr;
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
    /// The C++ type name of the default value (only available when compiled in debug mode)
    std::string type;
#endif
};

/// \ingroup annotations
/// Annotation indicating that all following arguments are keyword-only; the is the equivalent of
/// an unnamed '*' argument
struct kw_only {};

/// \ingroup annotations
/// Annotation indicating that all previous arguments are positional-only; the is the equivalent of
/// an unnamed '/' argument (in Python 3.8)
struct pos_only {};

template <typename T>
arg_v arg::operator=(T &&value) const {
    return {*this, std::forward<T>(value)};
}

/// Alias for backward compatibility -- to be removed in version 2.0
template <typename /*unused*/>
using arg_t = arg_v;

inline namespace literals {
/** \rst
    String literal version of `arg`
 \endrst */
constexpr arg
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 5
operator"" _a // gcc 4.8.5 insists on having a space (hard error).
#else
operator""_a // clang 17 generates a deprecation warning if there is a space.
#endif
    (const char *name, size_t) {
    return arg(name);
}
} // namespace literals

PYBIND11_NAMESPACE_BEGIN(detail)

template <typename T>
using is_kw_only = std::is_same<intrinsic_t<T>, kw_only>;
template <typename T>
using is_pos_only = std::is_same<intrinsic_t<T>, pos_only>;

// forward declaration (definition in attr.h)
struct function_record;

/// Internal data associated with a single function call
struct function_call {
    function_call(const function_record &f, handle p); // Implementation in attr.h

    /// The function data:
    const function_record &func;

    /// Arguments passed to the function:
    std::vector<handle> args;

    /// The `convert` value the arguments should be loaded with
    std::vector<bool> args_convert;

    /// Extra references for the optional `py::args` and/or `py::kwargs` arguments (which, if
    /// present, are also in `args` but without a reference).
    object args_ref, kwargs_ref;

    /// The parent, if any
    handle parent;

    /// If this is a call to an initializer, this argument contains `self`
    handle init_self;
};

/// Helper class which loads arguments for C++ functions called from Python
template <typename... Args>
class argument_loader {
    using indices = make_index_sequence<sizeof...(Args)>;

    template <typename Arg>
    using argument_is_args = std::is_same<intrinsic_t<Arg>, args>;
    template <typename Arg>
    using argument_is_kwargs = std::is_same<intrinsic_t<Arg>, kwargs>;
    // Get kwargs argument position, or -1 if not present:
    static constexpr auto kwargs_pos = constexpr_last<argument_is_kwargs, Args...>();

    static_assert(kwargs_pos == -1 || kwargs_pos == (int) sizeof...(Args) - 1,
                  "py::kwargs is only permitted as the last argument of a function");

public:
    static constexpr bool has_kwargs = kwargs_pos != -1;

    // py::args argument position; -1 if not present.
    static constexpr int args_pos = constexpr_last<argument_is_args, Args...>();

    static_assert(args_pos == -1 || args_pos == constexpr_first<argument_is_args, Args...>(),
                  "py::args cannot be specified more than once");

    static constexpr auto arg_names
        = ::pybind11::detail::concat(type_descr(make_caster<Args>::name)...);

    bool load_args(function_call &call) { return load_impl_sequence(call, indices{}); }

    template <typename Return, typename Guard, typename Func>
    // NOLINTNEXTLINE(readability-const-return-type)
    enable_if_t<!std::is_void<Return>::value, Return> call(Func &&f) && {
        return std::move(*this).template call_impl<remove_cv_t<Return>>(
            std::forward<Func>(f), indices{}, Guard{});
    }

    template <typename Return, typename Guard, typename Func>
    enable_if_t<std::is_void<Return>::value, void_type> call(Func &&f) && {
        std::move(*this).template call_impl<remove_cv_t<Return>>(
            std::forward<Func>(f), indices{}, Guard{});
        return void_type();
    }

private:
    static bool load_impl_sequence(function_call &, index_sequence<>) { return true; }

    template <size_t... Is>
    bool load_impl_sequence(function_call &call, index_sequence<Is...>) {
#ifdef __cpp_fold_expressions
        if ((... || !std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is]))) {
            return false;
        }
#else
        for (bool r : {std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])...}) {
            if (!r) {
                return false;
            }
        }
#endif
        return true;
    }

    template <typename Return, typename Func, size_t... Is, typename Guard>
    Return call_impl(Func &&f, index_sequence<Is...>, Guard &&) && {
        return std::forward<Func>(f)(cast_op<Args>(std::move(std::get<Is>(argcasters)))...);
    }

    std::tuple<make_caster<Args>...> argcasters;
};

/// Helper class which collects only positional arguments for a Python function call.
/// A fancier version below can collect any argument, but this one is optimal for simple calls.
template <return_value_policy policy>
class simple_collector {
public:
    template <typename... Ts>
    explicit simple_collector(Ts &&...values)
        : m_args(pybind11::make_tuple<policy>(std::forward<Ts>(values)...)) {}

    const tuple &args() const & { return m_args; }
    dict kwargs() const { return {}; }

    tuple args() && { return std::move(m_args); }

    /// Call a Python function and pass the collected arguments
    object call(PyObject *ptr) const {
        PyObject *result = PyObject_CallObject(ptr, m_args.ptr());
        if (!result) {
            throw error_already_set();
        }
        return reinterpret_steal<object>(result);
    }

private:
    tuple m_args;
};

/// Helper class which collects positional, keyword, * and ** arguments for a Python function call
template <return_value_policy policy>
class unpacking_collector {
public:
    template <typename... Ts>
    explicit unpacking_collector(Ts &&...values) {
        // Tuples aren't (easily) resizable so a list is needed for collection,
        // but the actual function call strictly requires a tuple.
        auto args_list = list();
        using expander = int[];
        (void) expander{0, (process(args_list, std::forward<Ts>(values)), 0)...};

        m_args = std::move(args_list);
    }

    const tuple &args() const & { return m_args; }
    const dict &kwargs() const & { return m_kwargs; }

    tuple args() && { return std::move(m_args); }
    dict kwargs() && { return std::move(m_kwargs); }

    /// Call a Python function and pass the collected arguments
    object call(PyObject *ptr) const {
        PyObject *result = PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr());
        if (!result) {
            throw error_already_set();
        }
        return reinterpret_steal<object>(result);
    }

private:
    template <typename T>
    void process(list &args_list, T &&x) {
        auto o = reinterpret_steal<object>(
            detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));
        if (!o) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
            throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()));
#else
            throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()),
                                                        type_id<T>());
#endif
        }
        args_list.append(std::move(o));
    }

    void process(list &args_list, detail::args_proxy ap) {
        for (auto a : ap) {
            args_list.append(a);
        }
    }

    void process(list & /*args_list*/, arg_v a) {
        if (!a.name) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
            nameless_argument_error();
#else
            nameless_argument_error(a.type);
#endif
        }
        if (m_kwargs.contains(a.name)) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
            multiple_values_error();
#else
            multiple_values_error(a.name);
#endif
        }
        if (!a.value) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
            throw cast_error_unable_to_convert_call_arg(a.name);
#else
            throw cast_error_unable_to_convert_call_arg(a.name, a.type);
#endif
        }
        m_kwargs[a.name] = std::move(a.value);
    }

    void process(list & /*args_list*/, detail::kwargs_proxy kp) {
        if (!kp) {
            return;
        }
        for (auto k : reinterpret_borrow<dict>(kp)) {
            if (m_kwargs.contains(k.first)) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
                multiple_values_error();
#else
                multiple_values_error(str(k.first));
#endif
            }
            m_kwargs[k.first] = k.second;
        }
    }

    [[noreturn]] static void nameless_argument_error() {
        throw type_error(
            "Got kwargs without a name; only named arguments "
            "may be passed via py::arg() to a python function call. "
            "(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
    }
    [[noreturn]] static void nameless_argument_error(const std::string &type) {
        throw type_error("Got kwargs without a name of type '" + type
                         + "'; only named "
                           "arguments may be passed via py::arg() to a python function call. ");
    }
    [[noreturn]] static void multiple_values_error() {
        throw type_error(
            "Got multiple values for keyword argument "
            "(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
    }

    [[noreturn]] static void multiple_values_error(const std::string &name) {
        throw type_error("Got multiple values for keyword argument '" + name + "'");
    }

private:
    tuple m_args;
    dict m_kwargs;
};

// [workaround(intel)] Separate function required here
// We need to put this into a separate function because the Intel compiler
// fails to compile enable_if_t<!all_of<is_positional<Args>...>::value>
// (tested with ICC 2021.1 Beta 20200827).
template <typename... Args>
constexpr bool args_are_all_positional() {
    return all_of<is_positional<Args>...>::value;
}

/// Collect only positional arguments for a Python function call
template <return_value_policy policy,
          typename... Args,
          typename = enable_if_t<args_are_all_positional<Args...>()>>
simple_collector<policy> collect_arguments(Args &&...args) {
    return simple_collector<policy>(std::forward<Args>(args)...);
}

/// Collect all arguments, including keywords and unpacking (only instantiated when needed)
template <return_value_policy policy,
          typename... Args,
          typename = enable_if_t<!args_are_all_positional<Args...>()>>
unpacking_collector<policy> collect_arguments(Args &&...args) {
    // Following argument order rules for generalized unpacking according to PEP 448
    static_assert(constexpr_last<is_positional, Args...>()
                          < constexpr_first<is_keyword_or_ds, Args...>()
                      && constexpr_last<is_s_unpacking, Args...>()
                             < constexpr_first<is_ds_unpacking, Args...>(),
                  "Invalid function call: positional args must precede keywords and ** unpacking; "
                  "* unpacking must precede ** unpacking");
    return unpacking_collector<policy>(std::forward<Args>(args)...);
}

template <typename Derived>
template <return_value_policy policy, typename... Args>
object object_api<Derived>::operator()(Args &&...args) const {
#ifndef NDEBUG
    if (!PyGILState_Check()) {
        pybind11_fail("pybind11::object_api<>::operator() PyGILState_Check() failure.");
    }
#endif
    return detail::collect_arguments<policy>(std::forward<Args>(args)...).call(derived().ptr());
}

template <typename Derived>
template <return_value_policy policy, typename... Args>
object object_api<Derived>::call(Args &&...args) const {
    return operator()<policy>(std::forward<Args>(args)...);
}

PYBIND11_NAMESPACE_END(detail)

template <typename T>
handle type::handle_of() {
    static_assert(std::is_base_of<detail::type_caster_generic, detail::make_caster<T>>::value,
                  "py::type::of<T> only supports the case where T is a registered C++ types.");

    return detail::get_type_handle(typeid(T), true);
}

#define PYBIND11_MAKE_OPAQUE(...)                                                                 \
    PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)                                                  \
    namespace detail {                                                                            \
    template <>                                                                                   \
    class type_caster<__VA_ARGS__> : public type_caster_base<__VA_ARGS__> {};                     \
    }                                                                                             \
    PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

/// Lets you pass a type containing a `,` through a macro parameter without needing a separate
/// typedef, e.g.:
/// `PYBIND11_OVERRIDE(PYBIND11_TYPE(ReturnType<A, B>), PYBIND11_TYPE(Parent<C, D>), f, arg)`
#define PYBIND11_TYPE(...) __VA_ARGS__

PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

common.h
/*
    pybind11/detail/common.h -- Basic macros

    Copyright (c) 2016 Wenzel Jakob <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#pragma once

#define PYBIND11_VERSION_MAJOR 2
#define PYBIND11_VERSION_MINOR 13
#define PYBIND11_VERSION_PATCH 5

// Similar to Python's convention: https://docs.python.org/3/c-api/apiabiversion.html
// Additional convention: 0xD = dev
#define PYBIND11_VERSION_HEX 0x020D0500

// Define some generic pybind11 helper macros for warning management.
//
// Note that compiler-specific push/pop pairs are baked into the
// PYBIND11_NAMESPACE_BEGIN/PYBIND11_NAMESPACE_END pair of macros. Therefore manual
// PYBIND11_WARNING_PUSH/PYBIND11_WARNING_POP are usually only needed in `#include` sections.
//
// If you find you need to suppress a warning, please try to make the suppression as local as
// possible using these macros. Please also be sure to push/pop with the pybind11 macros. Please
// only use compiler specifics if you need to check specific versions, e.g. Apple Clang vs. vanilla
// Clang.
#if defined(_MSC_VER)
#    define PYBIND11_COMPILER_MSVC
#    define PYBIND11_PRAGMA(...) __pragma(__VA_ARGS__)
#    define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(warning(push))
#    define PYBIND11_WARNING_POP PYBIND11_PRAGMA(warning(pop))
#elif defined(__INTEL_COMPILER)
#    define PYBIND11_COMPILER_INTEL
#    define PYBIND11_PRAGMA(...) _Pragma(#__VA_ARGS__)
#    define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(warning push)
#    define PYBIND11_WARNING_POP PYBIND11_PRAGMA(warning pop)
#elif defined(__clang__)
#    define PYBIND11_COMPILER_CLANG
#    define PYBIND11_PRAGMA(...) _Pragma(#__VA_ARGS__)
#    define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(clang diagnostic push)
#    define PYBIND11_WARNING_POP PYBIND11_PRAGMA(clang diagnostic push)
#elif defined(__GNUC__)
#    define PYBIND11_COMPILER_GCC
#    define PYBIND11_PRAGMA(...) _Pragma(#__VA_ARGS__)
#    define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(GCC diagnostic push)
#    define PYBIND11_WARNING_POP PYBIND11_PRAGMA(GCC diagnostic pop)
#endif

#ifdef PYBIND11_COMPILER_MSVC
#    define PYBIND11_WARNING_DISABLE_MSVC(name) PYBIND11_PRAGMA(warning(disable : name))
#else
#    define PYBIND11_WARNING_DISABLE_MSVC(name)
#endif

#ifdef PYBIND11_COMPILER_CLANG
#    define PYBIND11_WARNING_DISABLE_CLANG(name) PYBIND11_PRAGMA(clang diagnostic ignored name)
#else
#    define PYBIND11_WARNING_DISABLE_CLANG(name)
#endif

#ifdef PYBIND11_COMPILER_GCC
#    define PYBIND11_WARNING_DISABLE_GCC(name) PYBIND11_PRAGMA(GCC diagnostic ignored name)
#else
#    define PYBIND11_WARNING_DISABLE_GCC(name)
#endif

#ifdef PYBIND11_COMPILER_INTEL
#    define PYBIND11_WARNING_DISABLE_INTEL(name) PYBIND11_PRAGMA(warning disable name)
#else
#    define PYBIND11_WARNING_DISABLE_INTEL(name)
#endif

#define PYBIND11_NAMESPACE_BEGIN(name)                                                            \
    namespace name {                                                                              \
    PYBIND11_WARNING_PUSH

#define PYBIND11_NAMESPACE_END(name)                                                              \
    PYBIND11_WARNING_POP                                                                          \
    }

// Robust support for some features and loading modules compiled against different pybind versions
// requires forcing hidden visibility on pybind code, so we enforce this by setting the attribute
// on the main `pybind11` namespace.
#if !defined(PYBIND11_NAMESPACE)
#    ifdef __GNUG__
#        define PYBIND11_NAMESPACE pybind11 __attribute__((visibility("hidden")))
#    else
#        define PYBIND11_NAMESPACE pybind11
#    endif
#endif

#if !(defined(_MSC_VER) && __cplusplus == 199711L)
#    if __cplusplus >= 201402L
#        define PYBIND11_CPP14
#        if __cplusplus >= 201703L
#            define PYBIND11_CPP17
#            if __cplusplus >= 202002L
#                define PYBIND11_CPP20
// Please update tests/pybind11_tests.cpp `cpp_std()` when adding a macro here.
#            endif
#        endif
#    endif
#elif defined(_MSC_VER) && __cplusplus == 199711L
// MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully
// implemented). Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3
// or newer.
#    if _MSVC_LANG >= 201402L
#        define PYBIND11_CPP14
#        if _MSVC_LANG > 201402L
#            define PYBIND11_CPP17
#            if _MSVC_LANG >= 202002L
#                define PYBIND11_CPP20
#            endif
#        endif
#    endif
#endif

#if defined(PYBIND11_CPP20)
#    define PYBIND11_CONSTINIT constinit
#    define PYBIND11_DTOR_CONSTEXPR constexpr
#else
#    define PYBIND11_CONSTINIT
#    define PYBIND11_DTOR_CONSTEXPR
#endif

// Compiler version assertions
#if defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER < 1800
#        error pybind11 requires Intel C++ compiler v18 or newer
#    elif __INTEL_COMPILER < 1900 && defined(PYBIND11_CPP14)
#        error pybind11 supports only C++11 with Intel C++ compiler v18. Use v19 or newer for C++14.
#    endif
/* The following pragma cannot be pop'ed:
   https://community.intel.com/t5/Intel-C-Compiler/Inline-and-no-inline-warning/td-p/1216764 */
#    pragma warning disable 2196 // warning #2196: routine is both "inline" and "noinline"
#elif defined(__clang__) && !defined(__apple_build_version__)
#    if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3)
#        error pybind11 requires clang 3.3 or newer
#    endif
#elif defined(__clang__)
// Apple changes clang version macros to its Xcode version; the first Xcode release based on
// (upstream) clang 3.3 was Xcode 5:
#    if __clang_major__ < 5
#        error pybind11 requires Xcode/clang 5.0 or newer
#    endif
#elif defined(__GNUG__)
#    if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)
#        error pybind11 requires gcc 4.8 or newer
#    endif
#elif defined(_MSC_VER)
#    if _MSC_VER < 1910
#        error pybind11 2.10+ requires MSVC 2017 or newer
#    endif
#endif

#if !defined(PYBIND11_EXPORT)
#    if defined(WIN32) || defined(_WIN32)
#        define PYBIND11_EXPORT __declspec(dllexport)
#    else
#        define PYBIND11_EXPORT __attribute__((visibility("default")))
#    endif
#endif

#if !defined(PYBIND11_EXPORT_EXCEPTION)
#    if defined(__apple_build_version__)
#        define PYBIND11_EXPORT_EXCEPTION PYBIND11_EXPORT
#    else
#        define PYBIND11_EXPORT_EXCEPTION
#    endif
#endif

// For CUDA, GCC7, GCC8:
// PYBIND11_NOINLINE_FORCED is incompatible with `-Wattributes -Werror`.
// When defining PYBIND11_NOINLINE_FORCED, it is best to also use `-Wno-attributes`.
// However, the measured shared-library size saving when using noinline are only
// 1.7% for CUDA, -0.2% for GCC7, and 0.0% for GCC8 (using -DCMAKE_BUILD_TYPE=MinSizeRel,
// the default under pybind11/tests).
#if !defined(PYBIND11_NOINLINE_FORCED)                                                            \
    && (defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)))
#    define PYBIND11_NOINLINE_DISABLED
#endif

// The PYBIND11_NOINLINE macro is for function DEFINITIONS.
// In contrast, FORWARD DECLARATIONS should never use this macro:
// https://stackoverflow.com/questions/9317473/forward-declaration-of-inline-functions
#if defined(PYBIND11_NOINLINE_DISABLED) // Option for maximum portability and experimentation.
#    define PYBIND11_NOINLINE inline
#elif defined(_MSC_VER)
#    define PYBIND11_NOINLINE __declspec(noinline) inline
#else
#    define PYBIND11_NOINLINE __attribute__((noinline)) inline
#endif

#if defined(__MINGW32__)
// For unknown reasons all PYBIND11_DEPRECATED member trigger a warning when declared
// whether it is used or not
#    define PYBIND11_DEPRECATED(reason)
#elif defined(PYBIND11_CPP14)
#    define PYBIND11_DEPRECATED(reason) [[deprecated(reason)]]
#else
#    define PYBIND11_DEPRECATED(reason) __attribute__((deprecated(reason)))
#endif

#if defined(PYBIND11_CPP17)
#    define PYBIND11_MAYBE_UNUSED [[maybe_unused]]
#elif defined(_MSC_VER) && !defined(__clang__)
#    define PYBIND11_MAYBE_UNUSED
#else
#    define PYBIND11_MAYBE_UNUSED __attribute__((__unused__))
#endif

/* Don't let Python.h #define (v)snprintf as macro because they are implemented
   properly in Visual Studio since 2015. */
#if defined(_MSC_VER)
#    define HAVE_SNPRINTF 1
#endif

/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode
#if defined(_MSC_VER)
PYBIND11_WARNING_PUSH
PYBIND11_WARNING_DISABLE_MSVC(4505)
// C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only)
#    if defined(_DEBUG) && !defined(Py_DEBUG)
// Workaround for a VS 2022 issue.
// NOTE: This workaround knowingly violates the Python.h include order requirement:
// https://docs.python.org/3/c-api/intro.html#include-files
// See https://github.com/pybind/pybind11/pull/3497 for full context.
#        include <yvals.h>
#        if _MSVC_STL_VERSION >= 143
#            include <crtdefs.h>
#        endif
#        define PYBIND11_DEBUG_MARKER
#        undef _DEBUG
#    endif
#endif

// https://en.cppreference.com/w/c/chrono/localtime
#if defined(__STDC_LIB_EXT1__) && !defined(__STDC_WANT_LIB_EXT1__)
#    define __STDC_WANT_LIB_EXT1__
#endif

#ifdef __has_include
// std::optional (but including it in c++14 mode isn't allowed)
#    if defined(PYBIND11_CPP17) && __has_include(<optional>)
#        define PYBIND11_HAS_OPTIONAL 1
#    endif
// std::experimental::optional (but not allowed in c++11 mode)
#    if defined(PYBIND11_CPP14) && (__has_include(<experimental/optional>) && \
                                 !__has_include(<optional>))
#        define PYBIND11_HAS_EXP_OPTIONAL 1
#    endif
// std::variant
#    if defined(PYBIND11_CPP17) && __has_include(<variant>)
#        define PYBIND11_HAS_VARIANT 1
#    endif
#elif defined(_MSC_VER) && defined(PYBIND11_CPP17)
#    define PYBIND11_HAS_OPTIONAL 1
#    define PYBIND11_HAS_VARIANT 1
#endif

#if defined(PYBIND11_CPP17)
#    if defined(__has_include)
#        if __has_include(<string_view>)
#            define PYBIND11_HAS_STRING_VIEW
#        endif
#    elif defined(_MSC_VER)
#        define PYBIND11_HAS_STRING_VIEW
#    endif
#endif

#include <Python.h>
#if PY_VERSION_HEX < 0x03070000
#    error "PYTHON < 3.7 IS UNSUPPORTED. pybind11 v2.12 was the last to support Python 3.6."
#endif
#include <frameobject.h>
#include <pythread.h>

/* Python #defines overrides on all sorts of core functions, which
   tends to weak havok in C++ codebases that expect these to work
   like regular functions (potentially with several overloads) */
#if defined(isalnum)
#    undef isalnum
#    undef isalpha
#    undef islower
#    undef isspace
#    undef isupper
#    undef tolower
#    undef toupper
#endif

#if defined(copysign)
#    undef copysign
#endif

#if defined(PYBIND11_NUMPY_1_ONLY)
#    define PYBIND11_INTERNAL_NUMPY_1_ONLY_DETECTED
#endif

#if defined(PYPY_VERSION) && !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
#    define PYBIND11_SIMPLE_GIL_MANAGEMENT
#endif

#if defined(_MSC_VER)
#    if defined(PYBIND11_DEBUG_MARKER)
#        define _DEBUG
#        undef PYBIND11_DEBUG_MARKER
#    endif
PYBIND11_WARNING_POP
#endif

#include <cstddef>
#include <cstring>
#include <exception>
#include <forward_list>
#include <memory>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <typeindex>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#if defined(__has_include)
#    if __has_include(<version>)
#        include <version>
#    endif
#endif

// Must be after including <version> or one of the other headers specified by the standard
#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
#    define PYBIND11_HAS_U8STRING
#endif

// See description of PR #4246:
#if !defined(PYBIND11_NO_ASSERT_GIL_HELD_INCREF_DECREF) && !defined(NDEBUG)                       \
    && !defined(PYPY_VERSION) && !defined(PYBIND11_ASSERT_GIL_HELD_INCREF_DECREF)
#    define PYBIND11_ASSERT_GIL_HELD_INCREF_DECREF
#endif

// #define PYBIND11_STR_LEGACY_PERMISSIVE
// If DEFINED, pybind11::str can hold PyUnicodeObject or PyBytesObject
//             (probably surprising and never documented, but this was the
//             legacy behavior until and including v2.6.x). As a side-effect,
//             pybind11::isinstance<str>() is true for both pybind11::str and
//             pybind11::bytes.
// If UNDEFINED, pybind11::str can only hold PyUnicodeObject, and
//               pybind11::isinstance<str>() is true only for pybind11::str.
//               However, for Python 2 only (!), the pybind11::str caster
//               implicitly decoded bytes to PyUnicodeObject. This was to ease
//               the transition from the legacy behavior to the non-permissive
//               behavior.

/// Compatibility macros for Python 2 / Python 3 versions TODO: remove
#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr)
#define PYBIND11_INSTANCE_METHOD_CHECK PyInstanceMethod_Check
#define PYBIND11_INSTANCE_METHOD_GET_FUNCTION PyInstanceMethod_GET_FUNCTION
#define PYBIND11_BYTES_CHECK PyBytes_Check
#define PYBIND11_BYTES_FROM_STRING PyBytes_FromString
#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize
#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize
#define PYBIND11_BYTES_AS_STRING PyBytes_AsString
#define PYBIND11_BYTES_SIZE PyBytes_Size
#define PYBIND11_LONG_CHECK(o) PyLong_Check(o)
#define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o)
#define PYBIND11_LONG_FROM_SIGNED(o) PyLong_FromSsize_t((ssize_t) (o))
#define PYBIND11_LONG_FROM_UNSIGNED(o) PyLong_FromSize_t((size_t) (o))
#define PYBIND11_BYTES_NAME "bytes"
#define PYBIND11_STRING_NAME "str"
#define PYBIND11_SLICE_OBJECT PyObject
#define PYBIND11_FROM_STRING PyUnicode_FromString
#define PYBIND11_STR_TYPE ::pybind11::str
#define PYBIND11_BOOL_ATTR "__bool__"
#define PYBIND11_NB_BOOL(ptr) ((ptr)->nb_bool)
#define PYBIND11_BUILTINS_MODULE "builtins"
// Providing a separate declaration to make Clang's -Wmissing-prototypes happy.
// See comment for PYBIND11_MODULE below for why this is marked "maybe unused".
#define PYBIND11_PLUGIN_IMPL(name)                                                                \
    extern "C" PYBIND11_MAYBE_UNUSED PYBIND11_EXPORT PyObject *PyInit_##name();                   \
    extern "C" PYBIND11_EXPORT PyObject *PyInit_##name()

#define PYBIND11_TRY_NEXT_OVERLOAD ((PyObject *) 1) // special failure return code
#define PYBIND11_STRINGIFY(x) #x
#define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x)
#define PYBIND11_CONCAT(first, second) first##second
#define PYBIND11_ENSURE_INTERNALS_READY pybind11::detail::get_internals();

#define PYBIND11_CHECK_PYTHON_VERSION                                                             \
    {                                                                                             \
        const char *compiled_ver                                                                  \
            = PYBIND11_TOSTRING(PY_MAJOR_VERSION) "." PYBIND11_TOSTRING(PY_MINOR_VERSION);        \
        const char *runtime_ver = Py_GetVersion();                                                \
        size_t len = std::strlen(compiled_ver);                                                   \
        if (std::strncmp(runtime_ver, compiled_ver, len) != 0                                     \
            || (runtime_ver[len] >= '0' && runtime_ver[len] <= '9')) {                            \
            PyErr_Format(PyExc_ImportError,                                                       \
                         "Python version mismatch: module was compiled for Python %s, "           \
                         "but the interpreter version is incompatible: %s.",                      \
                         compiled_ver,                                                            \
                         runtime_ver);                                                            \
            return nullptr;                                                                       \
        }                                                                                         \
    }

#define PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \
    catch (pybind11::error_already_set & e) {                                                     \
        pybind11::raise_from(e, PyExc_ImportError, "initialization failed");                      \
        return nullptr;                                                                           \
    }                                                                                             \
    catch (const std::exception &e) {                                                             \
        ::pybind11::set_error(PyExc_ImportError, e.what());                                       \
        return nullptr;                                                                           \
    }

/** \rst
    ***Deprecated in favor of PYBIND11_MODULE***

    This macro creates the entry point that will be invoked when the Python interpreter
    imports a plugin library. Please create a `module_` in the function body and return
    the pointer to its underlying Python object at the end.

    .. code-block:: cpp

        PYBIND11_PLUGIN(example) {
            pybind11::module_ m("example", "pybind11 example plugin");
            /// Set up bindings here
            return m.ptr();
        }
\endrst */
#define PYBIND11_PLUGIN(name)                                                                     \
    PYBIND11_DEPRECATED("PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE")                     \
    static PyObject *pybind11_init();                                                             \
    PYBIND11_PLUGIN_IMPL(name) {                                                                  \
        PYBIND11_CHECK_PYTHON_VERSION                                                             \
        PYBIND11_ENSURE_INTERNALS_READY                                                           \
        try {                                                                                     \
            return pybind11_init();                                                               \
        }                                                                                         \
        PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \
    }                                                                                             \
    PyObject *pybind11_init()

/** \rst
    This macro creates the entry point that will be invoked when the Python interpreter
    imports an extension module. The module name is given as the first argument and it
    should not be in quotes. The second macro argument defines a variable of type
    `py::module_` which can be used to initialize the module.

    The entry point is marked as "maybe unused" to aid dead-code detection analysis:
    since the entry point is typically only looked up at runtime and not referenced
    during translation, it would otherwise appear as unused ("dead") code.

    .. code-block:: cpp

        PYBIND11_MODULE(example, m) {
            m.doc() = "pybind11 example module";

            // Add bindings here
            m.def("foo", []() {
                return "Hello, World!";
            });
        }

    The third macro argument is optional (available since 2.13.0), and can be used to
    mark the extension module as safe to run without the GIL under a free-threaded CPython
    interpreter. Passing this argument has no effect on other interpreters.

    .. code-block:: cpp

        PYBIND11_MODULE(example, m, py::mod_gil_not_used()) {
            m.doc() = "pybind11 example module safe to run without the GIL";

            // Add bindings here
            m.def("foo", []() {
                return "Hello, Free-threaded World!";
            });
        }

\endrst */
PYBIND11_WARNING_PUSH
PYBIND11_WARNING_DISABLE_CLANG("-Wgnu-zero-variadic-macro-arguments")
#define PYBIND11_MODULE(name, variable, ...)                                                      \
    static ::pybind11::module_::module_def PYBIND11_CONCAT(pybind11_module_def_, name)            \
        PYBIND11_MAYBE_UNUSED;                                                                    \
    PYBIND11_MAYBE_UNUSED                                                                         \
    static void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &);                     \
    PYBIND11_PLUGIN_IMPL(name) {                                                                  \
        PYBIND11_CHECK_PYTHON_VERSION                                                             \
        PYBIND11_ENSURE_INTERNALS_READY                                                           \
        auto m = ::pybind11::module_::create_extension_module(                                    \
            PYBIND11_TOSTRING(name),                                                              \
            nullptr,                                                                              \
            &PYBIND11_CONCAT(pybind11_module_def_, name),                                         \
            ##__VA_ARGS__);                                                                       \
        try {                                                                                     \
            PYBIND11_CONCAT(pybind11_init_, name)(m);                                             \
            return m.ptr();                                                                       \
        }                                                                                         \
        PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \
    }                                                                                             \
    void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ & (variable))
PYBIND11_WARNING_POP

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

using ssize_t = Py_ssize_t;
using size_t = std::size_t;

template <typename IntType>
inline ssize_t ssize_t_cast(const IntType &val) {
    static_assert(sizeof(IntType) <= sizeof(ssize_t), "Implicit narrowing is not permitted.");
    return static_cast<ssize_t>(val);
}

/// Approach used to cast a previously unknown C++ instance into a Python object
enum class return_value_policy : uint8_t {
    /** This is the default return value policy, which falls back to the policy
        return_value_policy::take_ownership when the return value is a pointer.
        Otherwise, it uses return_value::move or return_value::copy for rvalue
        and lvalue references, respectively. See below for a description of what
        all of these different policies do. */
    automatic = 0,

    /** As above, but use policy return_value_policy::reference when the return
        value is a pointer. This is the default conversion policy for function
        arguments when calling Python functions manually from C++ code (i.e. via
        handle::operator()). You probably won't need to use this. */
    automatic_reference,

    /** Reference an existing object (i.e. do not create a new copy) and take
        ownership. Python will call the destructor and delete operator when the
        object's reference count reaches zero. Undefined behavior ensues when
        the C++ side does the same.. */
    take_ownership,

    /** Create a new copy of the returned object, which will be owned by
        Python. This policy is comparably safe because the lifetimes of the two
        instances are decoupled. */
    copy,

    /** Use std::move to move the return value contents into a new instance
        that will be owned by Python. This policy is comparably safe because the
        lifetimes of the two instances (move source and destination) are
        decoupled. */
    move,

    /** Reference an existing object, but do not take ownership. The C++ side
        is responsible for managing the object's lifetime and deallocating it
        when it is no longer used. Warning: undefined behavior will ensue when
        the C++ side deletes an object that is still referenced and used by
        Python. */
    reference,

    /** This policy only applies to methods and properties. It references the
        object without taking ownership similar to the above
        return_value_policy::reference policy. In contrast to that policy, the
        function or property's implicit this argument (called the parent) is
        considered to be the owner of the return value (the child).
        pybind11 then couples the lifetime of the parent to the child via a
        reference relationship that ensures that the parent cannot be garbage
        collected while Python is still using the child. More advanced
        variations of this scheme are also possible using combinations of
        return_value_policy::reference and the keep_alive call policy */
    reference_internal
};

PYBIND11_NAMESPACE_BEGIN(detail)

inline static constexpr int log2(size_t n, int k = 0) {
    return (n <= 1) ? k : log2(n >> 1, k + 1);
}

// Returns the size as a multiple of sizeof(void *), rounded up.
inline static constexpr size_t size_in_ptrs(size_t s) {
    return 1 + ((s - 1) >> log2(sizeof(void *)));
}

/**
 * The space to allocate for simple layout instance holders (see below) in multiple of the size of
 * a pointer (e.g.  2 means 16 bytes on 64-bit architectures).  The default is the minimum required
 * to holder either a std::unique_ptr or std::shared_ptr (which is almost always
 * sizeof(std::shared_ptr<T>)).
 */
constexpr size_t instance_simple_holder_in_ptrs() {
    static_assert(sizeof(std::shared_ptr<int>) >= sizeof(std::unique_ptr<int>),
                  "pybind assumes std::shared_ptrs are at least as big as std::unique_ptrs");
    return size_in_ptrs(sizeof(std::shared_ptr<int>));
}

// Forward declarations
struct type_info;
struct value_and_holder;

struct nonsimple_values_and_holders {
    void **values_and_holders;
    uint8_t *status;
};

/// The 'instance' type which needs to be standard layout (need to be able to use 'offsetof')
struct instance {
    PyObject_HEAD
    /// Storage for pointers and holder; see simple_layout, below, for a description
    union {
        void *simple_value_holder[1 + instance_simple_holder_in_ptrs()];
        nonsimple_values_and_holders nonsimple;
    };
    /// Weak references
    PyObject *weakrefs;
    /// If true, the pointer is owned which means we're free to manage it with a holder.
    bool owned : 1;
    /**
     * An instance has two possible value/holder layouts.
     *
     * Simple layout (when this flag is true), means the `simple_value_holder` is set with a
     * pointer and the holder object governing that pointer, i.e. [val1*][holder].  This layout is
     * applied whenever there is no python-side multiple inheritance of bound C++ types *and* the
     * type's holder will fit in the default space (which is large enough to hold either a
     * std::unique_ptr or std::shared_ptr).
     *
     * Non-simple layout applies when using custom holders that require more space than
     * `shared_ptr` (which is typically the size of two pointers), or when multiple inheritance is
     * used on the python side.  Non-simple layout allocates the required amount of memory to have
     * multiple bound C++ classes as parents.  Under this layout, `nonsimple.values_and_holders` is
     * set to a pointer to allocated space of the required space to hold a sequence of value
     * pointers and holders followed `status`, a set of bit flags (1 byte each), i.e.
     * [val1*][holder1][val2*][holder2]...[bb...]  where each [block] is rounded up to a multiple
     * of `sizeof(void *)`.  `nonsimple.status` is, for convenience, a pointer to the beginning of
     * the [bb...] block (but not independently allocated).
     *
     * Status bits indicate whether the associated holder is constructed (&
     * status_holder_constructed) and whether the value pointer is registered (&
     * status_instance_registered) in `registered_instances`.
     */
    bool simple_layout : 1;
    /// For simple layout, tracks whether the holder has been constructed
    bool simple_holder_constructed : 1;
    /// For simple layout, tracks whether the instance is registered in `registered_instances`
    bool simple_instance_registered : 1;
    /// If true, get_internals().patients has an entry for this object
    bool has_patients : 1;
	bool has_alias : 1;
	bool is_alias : 1;

    /// Initializes all of the above type/values/holders data (but not the instance values
    /// themselves)
    void allocate_layout();

    /// Destroys/deallocates all of the above
    void deallocate_layout();

    /// Returns the value_and_holder wrapper for the given type (or the first, if `find_type`
    /// omitted).  Returns a default-constructed (with `.inst = nullptr`) object on failure if
    /// `throw_if_missing` is false.
    value_and_holder get_value_and_holder(const type_info *find_type = nullptr,
                                          bool throw_if_missing = true);

    /// Bit values for the non-simple status flags
    static constexpr uint8_t status_holder_constructed = 1;
    static constexpr uint8_t status_instance_registered = 2;
};

static_assert(std::is_standard_layout<instance>::value,
              "Internal error: `pybind11::detail::instance` is not standard layout!");

/// from __cpp_future__ import (convenient aliases from C++14/17)
#if defined(PYBIND11_CPP14)
using std::conditional_t;
using std::enable_if_t;
using std::remove_cv_t;
using std::remove_reference_t;
#else
template <bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
template <bool B, typename T, typename F>
using conditional_t = typename std::conditional<B, T, F>::type;
template <typename T>
using remove_cv_t = typename std::remove_cv<T>::type;
template <typename T>
using remove_reference_t = typename std::remove_reference<T>::type;
#endif

#if defined(PYBIND11_CPP20)
using std::remove_cvref;
using std::remove_cvref_t;
#else
template <class T>
struct remove_cvref {
    using type = remove_cv_t<remove_reference_t<T>>;
};
template <class T>
using remove_cvref_t = typename remove_cvref<T>::type;
#endif

/// Example usage: is_same_ignoring_cvref<T, PyObject *>::value
template <typename T, typename U>
using is_same_ignoring_cvref = std::is_same<detail::remove_cvref_t<T>, U>;

/// Index sequences
#if defined(PYBIND11_CPP14)
using std::index_sequence;
using std::make_index_sequence;
#else
template <size_t...>
struct index_sequence {};
template <size_t N, size_t... S>
struct make_index_sequence_impl : make_index_sequence_impl<N - 1, N - 1, S...> {};
template <size_t... S>
struct make_index_sequence_impl<0, S...> {
    using type = index_sequence<S...>;
};
template <size_t N>
using make_index_sequence = typename make_index_sequence_impl<N>::type;
#endif

/// Make an index sequence of the indices of true arguments
template <typename ISeq, size_t, bool...>
struct select_indices_impl {
    using type = ISeq;
};
template <size_t... IPrev, size_t I, bool B, bool... Bs>
struct select_indices_impl<index_sequence<IPrev...>, I, B, Bs...>
    : select_indices_impl<conditional_t<B, index_sequence<IPrev..., I>, index_sequence<IPrev...>>,
                          I + 1,
                          Bs...> {};
template <bool... Bs>
using select_indices = typename select_indices_impl<index_sequence<>, 0, Bs...>::type;

/// Backports of std::bool_constant and std::negation to accommodate older compilers
template <bool B>
using bool_constant = std::integral_constant<bool, B>;
template <typename T>
struct negation : bool_constant<!T::value> {};

// PGI/Intel cannot detect operator delete with the "compatible" void_t impl, so
// using the new one (C++14 defect, so generally works on newer compilers, even
// if not in C++17 mode)
#if defined(__PGIC__) || defined(__INTEL_COMPILER)
template <typename...>
using void_t = void;
#else
template <typename...>
struct void_t_impl {
    using type = void;
};
template <typename... Ts>
using void_t = typename void_t_impl<Ts...>::type;
#endif

/// Compile-time all/any/none of that check the boolean value of all template types
#if defined(__cpp_fold_expressions) && !(defined(_MSC_VER) && (_MSC_VER < 1916))
template <class... Ts>
using all_of = bool_constant<(Ts::value && ...)>;
template <class... Ts>
using any_of = bool_constant<(Ts::value || ...)>;
#elif !defined(_MSC_VER)
template <bool...>
struct bools {};
template <class... Ts>
using all_of = std::is_same<bools<Ts::value..., true>, bools<true, Ts::value...>>;
template <class... Ts>
using any_of = negation<all_of<negation<Ts>...>>;
#else
// MSVC has trouble with the above, but supports std::conjunction, which we can use instead (albeit
// at a slight loss of compilation efficiency).
template <class... Ts>
using all_of = std::conjunction<Ts...>;
template <class... Ts>
using any_of = std::disjunction<Ts...>;
#endif
template <class... Ts>
using none_of = negation<any_of<Ts...>>;

template <class T, template <class> class... Predicates>
using satisfies_all_of = all_of<Predicates<T>...>;
template <class T, template <class> class... Predicates>
using satisfies_any_of = any_of<Predicates<T>...>;
template <class T, template <class> class... Predicates>
using satisfies_none_of = none_of<Predicates<T>...>;

/// Strip the class from a method type
template <typename T>
struct remove_class {};
template <typename C, typename R, typename... A>
struct remove_class<R (C::*)(A...)> {
    using type = R(A...);
};
template <typename C, typename R, typename... A>
struct remove_class<R (C::*)(A...) const> {
    using type = R(A...);
};
#ifdef __cpp_noexcept_function_type
template <typename C, typename R, typename... A>
struct remove_class<R (C::*)(A...) noexcept> {
    using type = R(A...);
};
template <typename C, typename R, typename... A>
struct remove_class<R (C::*)(A...) const noexcept> {
    using type = R(A...);
};
#endif
/// Helper template to strip away type modifiers
template <typename T>
struct intrinsic_type {
    using type = T;
};
template <typename T>
struct intrinsic_type<const T> {
    using type = typename intrinsic_type<T>::type;
};
template <typename T>
struct intrinsic_type<T *> {
    using type = typename intrinsic_type<T>::type;
};
template <typename T>
struct intrinsic_type<T &> {
    using type = typename intrinsic_type<T>::type;
};
template <typename T>
struct intrinsic_type<T &&> {
    using type = typename intrinsic_type<T>::type;
};
template <typename T, size_t N>
struct intrinsic_type<const T[N]> {
    using type = typename intrinsic_type<T>::type;
};
template <typename T, size_t N>
struct intrinsic_type<T[N]> {
    using type = typename intrinsic_type<T>::type;
};
template <typename T>
using intrinsic_t = typename intrinsic_type<T>::type;

/// Helper type to replace 'void' in some expressions
struct void_type {};

/// Helper template which holds a list of types
template <typename...>
struct type_list {};

/// Compile-time integer sum
#ifdef __cpp_fold_expressions
template <typename... Ts>
constexpr size_t constexpr_sum(Ts... ns) {
    return (0 + ... + size_t{ns});
}
#else
constexpr size_t constexpr_sum() { return 0; }
template <typename T, typename... Ts>
constexpr size_t constexpr_sum(T n, Ts... ns) {
    return size_t{n} + constexpr_sum(ns...);
}
#endif

PYBIND11_NAMESPACE_BEGIN(constexpr_impl)
/// Implementation details for constexpr functions
constexpr int first(int i) { return i; }
template <typename T, typename... Ts>
constexpr int first(int i, T v, Ts... vs) {
    return v ? i : first(i + 1, vs...);
}

constexpr int last(int /*i*/, int result) { return result; }
template <typename T, typename... Ts>
constexpr int last(int i, int result, T v, Ts... vs) {
    return last(i + 1, v ? i : result, vs...);
}
PYBIND11_NAMESPACE_END(constexpr_impl)

/// Return the index of the first type in Ts which satisfies Predicate<T>.
/// Returns sizeof...(Ts) if none match.
template <template <typename> class Predicate, typename... Ts>
constexpr int constexpr_first() {
    return constexpr_impl::first(0, Predicate<Ts>::value...);
}

/// Return the index of the last type in Ts which satisfies Predicate<T>, or -1 if none match.
template <template <typename> class Predicate, typename... Ts>
constexpr int constexpr_last() {
    return constexpr_impl::last(0, -1, Predicate<Ts>::value...);
}

/// Return the Nth element from the parameter pack
template <size_t N, typename T, typename... Ts>
struct pack_element {
    using type = typename pack_element<N - 1, Ts...>::type;
};
template <typename T, typename... Ts>
struct pack_element<0, T, Ts...> {
    using type = T;
};

/// Return the one and only type which matches the predicate, or Default if none match.
/// If more than one type matches the predicate, fail at compile-time.
template <template <typename> class Predicate, typename Default, typename... Ts>
struct exactly_one {
    static constexpr auto found = constexpr_sum(Predicate<Ts>::value...);
    static_assert(found <= 1, "Found more than one type matching the predicate");

    static constexpr auto index = found ? constexpr_first<Predicate, Ts...>() : 0;
    using type = conditional_t<found, typename pack_element<index, Ts...>::type, Default>;
};
template <template <typename> class P, typename Default>
struct exactly_one<P, Default> {
    using type = Default;
};

template <template <typename> class Predicate, typename Default, typename... Ts>
using exactly_one_t = typename exactly_one<Predicate, Default, Ts...>::type;

/// Defer the evaluation of type T until types Us are instantiated
template <typename T, typename... /*Us*/>
struct deferred_type {
    using type = T;
};
template <typename T, typename... Us>
using deferred_t = typename deferred_type<T, Us...>::type;

/// Like is_base_of, but requires a strict base (i.e. `is_strict_base_of<T, T>::value == false`,
/// unlike `std::is_base_of`)
template <typename Base, typename Derived>
using is_strict_base_of
    = bool_constant<std::is_base_of<Base, Derived>::value && !std::is_same<Base, Derived>::value>;

/// Like is_base_of, but also requires that the base type is accessible (i.e. that a Derived
/// pointer can be converted to a Base pointer) For unions, `is_base_of<T, T>::value` is False, so
/// we need to check `is_same` as well.
template <typename Base, typename Derived>
using is_accessible_base_of
    = bool_constant<(std::is_same<Base, Derived>::value || std::is_base_of<Base, Derived>::value)
                    && std::is_convertible<Derived *, Base *>::value>;

template <template <typename...> class Base>
struct is_template_base_of_impl {
    template <typename... Us>
    static std::true_type check(Base<Us...> *);
    static std::false_type check(...);
};

/// Check if a template is the base of a type. For example:
/// `is_template_base_of<Base, T>` is true if `struct T : Base<U> {}` where U can be anything
template <template <typename...> class Base, typename T>
// Sadly, all MSVC versions incl. 2022 need the workaround, even in C++20 mode.
// See also: https://github.com/pybind/pybind11/pull/3741
#if !defined(_MSC_VER)
using is_template_base_of
    = decltype(is_template_base_of_impl<Base>::check((intrinsic_t<T> *) nullptr));
#else
struct is_template_base_of
    : decltype(is_template_base_of_impl<Base>::check((intrinsic_t<T> *) nullptr)){};
#endif

/// Check if T is an instantiation of the template `Class`. For example:
/// `is_instantiation<shared_ptr, T>` is true if `T == shared_ptr<U>` where U can be anything.
template <template <typename...> class Class, typename T>
struct is_instantiation : std::false_type {};
template <template <typename...> class Class, typename... Us>
struct is_instantiation<Class, Class<Us...>> : std::true_type {};

/// Check if T is std::shared_ptr<U> where U can be anything
template <typename T>
using is_shared_ptr = is_instantiation<std::shared_ptr, T>;

/// Check if T looks like an input iterator
template <typename T, typename = void>
struct is_input_iterator : std::false_type {};
template <typename T>
struct is_input_iterator<T,
                         void_t<decltype(*std::declval<T &>()), decltype(++std::declval<T &>())>>
    : std::true_type {};

template <typename T>
using is_function_pointer
    = bool_constant<std::is_pointer<T>::value
                    && std::is_function<typename std::remove_pointer<T>::type>::value>;

template <typename F>
struct strip_function_object {
    // If you are encountering an
    // 'error: name followed by "::" must be a class or namespace name'
    // with the Intel compiler and a noexcept function here,
    // try to use noexcept(true) instead of plain noexcept.
    using type = typename remove_class<decltype(&F::operator())>::type;
};

// Extracts the function signature from a function, function pointer or lambda.
template <typename Function, typename F = remove_reference_t<Function>>
using function_signature_t = 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>;

/// Returns true if the type looks like a lambda: that is, isn't a function, pointer or member
/// pointer.  Note that this can catch all sorts of other things, too; this is intended to be used
/// in a place where passing a lambda makes sense.
template <typename T>
using is_lambda = satisfies_none_of<remove_reference_t<T>,
                                    std::is_function,
                                    std::is_pointer,
                                    std::is_member_pointer>;

// [workaround(intel)] Internal error on fold expression
/// Apply a function over each element of a parameter pack
#if defined(__cpp_fold_expressions) && !defined(__INTEL_COMPILER)
// Intel compiler produces an internal error on this fold expression (tested with ICC 19.0.2)
#    define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN) (((PATTERN), void()), ...)
#else
using expand_side_effects = bool[];
#    define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN)                                                 \
        (void) pybind11::detail::expand_side_effects { ((PATTERN), void(), false)..., false }
#endif

PYBIND11_NAMESPACE_END(detail)

/// C++ bindings of builtin Python exceptions
class PYBIND11_EXPORT_EXCEPTION builtin_exception : public std::runtime_error {
public:
    using std::runtime_error::runtime_error;
    /// Set the error using the Python C API
    virtual void set_error() const = 0;
};

#define PYBIND11_RUNTIME_EXCEPTION(name, type)                                                    \
    class PYBIND11_EXPORT_EXCEPTION name : public builtin_exception {                             \
    public:                                                                                       \
        using builtin_exception::builtin_exception;                                               \
        name() : name("") {}                                                                      \
        void set_error() const override { PyErr_SetString(type, what()); }                        \
    };

PYBIND11_RUNTIME_EXCEPTION(stop_iteration, PyExc_StopIteration)
PYBIND11_RUNTIME_EXCEPTION(index_error, PyExc_IndexError)
PYBIND11_RUNTIME_EXCEPTION(key_error, PyExc_KeyError)
PYBIND11_RUNTIME_EXCEPTION(value_error, PyExc_ValueError)
PYBIND11_RUNTIME_EXCEPTION(type_error, PyExc_TypeError)
PYBIND11_RUNTIME_EXCEPTION(buffer_error, PyExc_BufferError)
PYBIND11_RUNTIME_EXCEPTION(import_error, PyExc_ImportError)
PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError)
PYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or
                                                           /// handle::call fail due to a type
                                                           /// casting error
PYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally

[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason) {
    assert(!PyErr_Occurred());
    throw std::runtime_error(reason);
}
[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const std::string &reason) {
    assert(!PyErr_Occurred());
    throw std::runtime_error(reason);
}

template <typename T, typename SFINAE = void>
struct format_descriptor {};

template <typename T>
struct format_descriptor<
    T,
    detail::enable_if_t<detail::is_same_ignoring_cvref<T, PyObject *>::value>> {
    static constexpr const char c = 'O';
    static constexpr const char value[2] = {c, '\0'};
    static std::string format() { return std::string(1, c); }
};

PYBIND11_NAMESPACE_BEGIN(detail)
// Returns the index of the given type in the type char array below, and in the list in numpy.h
// The order here is: bool; 8 ints ((signed,unsigned)x(8,16,32,64)bits); float,double,long double;
// complex float,double,long double.  Note that the long double types only participate when long
// double is actually longer than double (it isn't under MSVC).
// NB: not only the string below but also complex.h and numpy.h rely on this order.
template <typename T, typename SFINAE = void>
struct is_fmt_numeric {
    static constexpr bool value = false;
};
template <typename T>
struct is_fmt_numeric<T, enable_if_t<std::is_arithmetic<T>::value>> {
    static constexpr bool value = true;
    static constexpr int index
        = std::is_same<T, bool>::value
              ? 0
              : 1
                    + (std::is_integral<T>::value
                           ? detail::log2(sizeof(T)) * 2 + std::is_unsigned<T>::value
                           : 8
                                 + (std::is_same<T, double>::value        ? 1
                                    : std::is_same<T, long double>::value ? 2
                                                                          : 0));
};
PYBIND11_NAMESPACE_END(detail)

template <typename T>
struct format_descriptor<T, detail::enable_if_t<std::is_arithmetic<T>::value>> {
    static constexpr const char c = "?bBhHiIqQfdg"[detail::is_fmt_numeric<T>::index];
    static constexpr const char value[2] = {c, '\0'};
    static std::string format() { return std::string(1, c); }
};

#if !defined(PYBIND11_CPP17)

template <typename T>
constexpr const char
    format_descriptor<T, detail::enable_if_t<std::is_arithmetic<T>::value>>::value[2];

#endif

/// RAII wrapper that temporarily clears any Python error state
struct error_scope {
    PyObject *type, *value, *trace;
    error_scope() { PyErr_Fetch(&type, &value, &trace); }
    error_scope(const error_scope &) = delete;
    error_scope &operator=(const error_scope &) = delete;
    ~error_scope() { PyErr_Restore(type, value, trace); }
};

/// Dummy destructor wrapper that can be used to expose classes with a private destructor
struct nodelete {
    template <typename T>
    void operator()(T *) {}
};

PYBIND11_NAMESPACE_BEGIN(detail)
template <typename... Args>
struct overload_cast_impl {
    template <typename Return>
    constexpr auto operator()(Return (*pf)(Args...)) const noexcept -> decltype(pf) {
        return pf;
    }

    template <typename Return, typename Class>
    constexpr auto operator()(Return (Class::*pmf)(Args...),
                              std::false_type = {}) const noexcept -> decltype(pmf) {
        return pmf;
    }

    template <typename Return, typename Class>
    constexpr auto operator()(Return (Class::*pmf)(Args...) const,
                              std::true_type) const noexcept -> decltype(pmf) {
        return pmf;
    }
};
PYBIND11_NAMESPACE_END(detail)

// overload_cast requires variable templates: C++14
#if defined(PYBIND11_CPP14)
#    define PYBIND11_OVERLOAD_CAST 1
/// Syntax sugar for resolving overloaded function pointers:
///  - regular: static_cast<Return (Class::*)(Arg0, Arg1, Arg2)>(&Class::func)
///  - sweet:   overload_cast<Arg0, Arg1, Arg2>(&Class::func)
template <typename... Args>
static constexpr detail::overload_cast_impl<Args...> overload_cast{};
#endif

/// Const member function selector for overload_cast
///  - regular: static_cast<Return (Class::*)(Arg) const>(&Class::func)
///  - sweet:   overload_cast<Arg>(&Class::func, const_)
static constexpr auto const_ = std::true_type{};

#if !defined(PYBIND11_CPP14) // no overload_cast: providing something that static_assert-fails:
template <typename... Args>
struct overload_cast {
    static_assert(detail::deferred_t<std::false_type, Args...>::value,
                  "pybind11::overload_cast<...> requires compiling in C++14 mode");
};
#endif // overload_cast

PYBIND11_NAMESPACE_BEGIN(detail)

// Adaptor for converting arbitrary container arguments into a vector; implicitly convertible from
// any standard container (or C-style array) supporting std::begin/std::end, any singleton
// arithmetic type (if T is arithmetic), or explicitly constructible from an iterator pair.
template <typename T>
class any_container {
    std::vector<T> v;

public:
    any_container() = default;

    // Can construct from a pair of iterators
    template <typename It, typename = enable_if_t<is_input_iterator<It>::value>>
    any_container(It first, It last) : v(first, last) {}

    // Implicit conversion constructor from any arbitrary container type
    // with values convertible to T
    template <typename Container,
              typename = enable_if_t<
                  std::is_convertible<decltype(*std::begin(std::declval<const Container &>())),
                                      T>::value>>
    // NOLINTNEXTLINE(google-explicit-constructor)
    any_container(const Container &c) : any_container(std::begin(c), std::end(c)) {}

    // initializer_list's aren't deducible, so don't get matched by the above template;
    // we need this to explicitly allow implicit conversion from one:
    template <typename TIn, typename = enable_if_t<std::is_convertible<TIn, T>::value>>
    any_container(const std::initializer_list<TIn> &c) : any_container(c.begin(), c.end()) {}

    // Avoid copying if given an rvalue vector of the correct type.
    // NOLINTNEXTLINE(google-explicit-constructor)
    any_container(std::vector<T> &&v) : v(std::move(v)) {}

    // Moves the vector out of an rvalue any_container
    // NOLINTNEXTLINE(google-explicit-constructor)
    operator std::vector<T> &&() && { return std::move(v); }

    // Dereferencing obtains a reference to the underlying vector
    std::vector<T> &operator*() { return v; }
    const std::vector<T> &operator*() const { return v; }

    // -> lets you call methods on the underlying vector
    std::vector<T> *operator->() { return &v; }
    const std::vector<T> *operator->() const { return &v; }
};

// Forward-declaration; see detail/class.h
std::string get_fully_qualified_tp_name(PyTypeObject *);

template <typename T>
inline static std::shared_ptr<T>
try_get_shared_from_this(std::enable_shared_from_this<T> *holder_value_ptr) {
// Pre C++17, this code path exploits undefined behavior, but is known to work on many platforms.
// Use at your own risk!
// See also https://en.cppreference.com/w/cpp/memory/enable_shared_from_this, and in particular
// the `std::shared_ptr<Good> gp1 = not_so_good.getptr();` and `try`-`catch` parts of the example.
#if defined(__cpp_lib_enable_shared_from_this) && (!defined(_MSC_VER) || _MSC_VER >= 1912)
    return holder_value_ptr->weak_from_this().lock();
#else
    try {
        return holder_value_ptr->shared_from_this();
    } catch (const std::bad_weak_ptr &) {
        return nullptr;
    }
#endif
}

// For silencing "unused" compiler warnings in special situations.
template <typename... Args>
#if defined(_MSC_VER) && _MSC_VER < 1920 // MSVC 2017
constexpr
#endif
    inline void
    silence_unused_warnings(Args &&...) {
}

// MSVC warning C4100: Unreferenced formal parameter
#if defined(_MSC_VER) && _MSC_VER <= 1916
#    define PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(...)                                         \
        detail::silence_unused_warnings(__VA_ARGS__)
#else
#    define PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(...)
#endif

// GCC -Wunused-but-set-parameter  All GCC versions (as of July 2021).
#if defined(__GNUG__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
#    define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)                       \
        detail::silence_unused_warnings(__VA_ARGS__)
#else
#    define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)
#endif

#if defined(__clang__)                                                                            \
    && (defined(__apple_build_version__) /* AppleClang 13.0.0.13000029 was the only data point    \
                                            available. */                                         \
        || (__clang_major__ >= 7                                                                  \
            && __clang_major__ <= 12) /* Clang 3, 5, 13, 14, 15 do not generate the warning. */   \
    )
#    define PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
// Example:
// tests/test_kwargs_and_defaults.cpp:46:68: error: local variable 'args' will be copied despite
// being returned by name [-Werror,-Wreturn-std-move]
//     m.def("args_function", [](py::args args) -> py::tuple { return args; });
//                                                                    ^~~~
// test_kwargs_and_defaults.cpp:46:68: note: call 'std::move' explicitly to avoid copying
//     m.def("args_function", [](py::args args) -> py::tuple { return args; });
//                                                                    ^~~~
//                                                                    std::move(args)
#endif

// Pybind offers detailed error messages by default for all builts that are debug (through the
// negation of NDEBUG). This can also be manually enabled by users, for any builds, through
// defining PYBIND11_DETAILED_ERROR_MESSAGES. This information is primarily useful for those
// who are writing (as opposed to merely using) libraries that use pybind11.
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES) && !defined(NDEBUG)
#    define PYBIND11_DETAILED_ERROR_MESSAGES
#endif

PYBIND11_NAMESPACE_END(detail)
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

init.h
/*
    pybind11/detail/init.h: init factory function implementation and support code.

    Copyright (c) 2017 Jason Rhinelander <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#pragma once

#include "class.h"

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

PYBIND11_WARNING_DISABLE_MSVC(4127)

PYBIND11_NAMESPACE_BEGIN(detail)

template <>
class type_caster<value_and_holder> {
public:
    bool load(handle h, bool) {
        value = reinterpret_cast<value_and_holder *>(h.ptr());
        return true;
    }

    template <typename>
    using cast_op_type = value_and_holder &;
    explicit operator value_and_holder &() { return *value; }
    static constexpr auto name = const_name<value_and_holder>();

private:
    value_and_holder *value = nullptr;
};

PYBIND11_NAMESPACE_BEGIN(initimpl)

inline void no_nullptr(void *ptr) {
    if (!ptr) {
        throw type_error("pybind11::init(): factory function returned nullptr");
    }
}

// Implementing functions for all forms of py::init<...> and py::init(...)
template <typename Class>
using Cpp = typename Class::type;
template <typename Class>
using Alias = typename Class::type_alias;
template <typename Class>
using Holder = typename Class::holder_type;

template <typename Class>
using is_alias_constructible = std::is_constructible<Alias<Class>, Cpp<Class> &&>;

// Takes a Cpp pointer and returns true if it actually is a polymorphic Alias instance.
template <typename Class, enable_if_t<Class::has_alias, int> = 0>
bool is_alias(Cpp<Class> *ptr) {
    return dynamic_cast<Alias<Class> *>(ptr) != nullptr;
}
// Failing fallback version of the above for a no-alias class (always returns false)
template <typename /*Class*/>
constexpr bool is_alias(void *) {
    return false;
}

// Constructs and returns a new object; if the given arguments don't map to a constructor, we fall
// back to brace aggregate initialization so that for aggregate initialization can be used with
// py::init, e.g.  `py::init<int, int>` to initialize a `struct T { int a; int b; }`.  For
// non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually
// works, but will not do the expected thing when `T` has an `initializer_list<T>` constructor).
template <typename Class,
          typename... Args,
          detail::enable_if_t<std::is_constructible<Class, Args...>::value, int> = 0>
inline Class *construct_or_initialize(Args &&...args) {
    return new Class(std::forward<Args>(args)...);
}
template <typename Class,
          typename... Args,
          detail::enable_if_t<!std::is_constructible<Class, Args...>::value, int> = 0>
inline Class *construct_or_initialize(Args &&...args) {
    return new Class{std::forward<Args>(args)...};
}

// Attempts to constructs an alias using a `Alias(Cpp &&)` constructor.  This allows types with
// an alias to provide only a single Cpp factory function as long as the Alias can be
// constructed from an rvalue reference of the base Cpp type.  This means that Alias classes
// can, when appropriate, simply define a `Alias(Cpp &&)` constructor rather than needing to
// inherit all the base class constructors.
template <typename Class>
void construct_alias_from_cpp(std::true_type /*is_alias_constructible*/,
                              value_and_holder &v_h,
                              Cpp<Class> &&base) {
    v_h.value_ptr() = new Alias<Class>(std::move(base));
}
template <typename Class>
[[noreturn]] void construct_alias_from_cpp(std::false_type /*!is_alias_constructible*/,
                                           value_and_holder &,
                                           Cpp<Class> &&) {
    throw type_error("pybind11::init(): unable to convert returned instance to required "
                     "alias class: no `Alias<Class>(Class &&)` constructor available");
}

// Error-generating fallback for factories that don't match one of the below construction
// mechanisms.
template <typename Class>
void construct(...) {
    static_assert(!std::is_same<Class, Class>::value /* always false */,
                  "pybind11::init(): init function must return a compatible pointer, "
                  "holder, or value");
}

// Pointer return v1: the factory function returns a class pointer for a registered class.
// If we don't need an alias (because this class doesn't have one, or because the final type is
// inherited on the Python side) we can simply take over ownership.  Otherwise we need to try to
// construct an Alias from the returned base instance.
template <typename Class>
void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
    no_nullptr(ptr);
    if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
        // We're going to try to construct an alias by moving the cpp type.  Whether or not
        // that succeeds, we still need to destroy the original cpp pointer (either the
        // moved away leftover, if the alias construction works, or the value itself if we
        // throw an error), but we can't just call `delete ptr`: it might have a special
        // deleter, or might be shared_from_this.  So we construct a holder around it as if
        // it was a normal instance, then steal the holder away into a local variable; thus
        // the holder and destruction happens when we leave the C++ scope, and the holder
        // class gets to handle the destruction however it likes.
        v_h.value_ptr() = ptr;
        v_h.set_instance_registered(true); // Trick to prevent init_instance from registering it
        // DANGER ZONE BEGIN: exceptions will leave v_h in an invalid state.
        v_h.type->init_instance(v_h.inst, nullptr);                        // Set up the holder
        Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>())); // Steal the holder
        v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null
        v_h.set_instance_registered(false);
        // DANGER ZONE END.

        construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(*ptr));
    } else {
        // Otherwise the type isn't inherited, so we don't need an Alias
        v_h.value_ptr() = ptr;
    }
}

// Pointer return v2: a factory that always returns an alias instance ptr.  We simply take over
// ownership of the pointer.
template <typename Class, enable_if_t<Class::has_alias, int> = 0>
void construct(value_and_holder &v_h, Alias<Class> *alias_ptr, bool) {
    no_nullptr(alias_ptr);
    v_h.value_ptr() = static_cast<Cpp<Class> *>(alias_ptr);
}

// Holder return: copy its pointer, and move or copy the returned holder into the new instance's
// holder.  This also handles types like std::shared_ptr<T> and std::unique_ptr<T> where T is a
// derived type (through those holder's implicit conversion from derived class holder
// constructors).
template <typename Class>
void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
    auto *ptr = holder_helper<Holder<Class>>::get(holder);
    no_nullptr(ptr);
    // If we need an alias, check that the held pointer is actually an alias instance
    if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
        throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance "
                         "is not an alias instance");
    }

    v_h.value_ptr() = ptr;
    v_h.type->init_instance(v_h.inst, &holder);
}

// return-by-value version 1: returning a cpp class by value.  If the class has an alias and an
// alias is required the alias must have an `Alias(Cpp &&)` constructor so that we can construct
// the alias from the base when needed (i.e. because of Python-side inheritance).  When we don't
// need it, we simply move-construct the cpp value into a new instance.
template <typename Class>
void construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {
    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
    static_assert(is_move_constructible<Cpp<Class>>::value,
                  "pybind11::init() return-by-value factory function requires a movable class");
    if (Class::has_alias && need_alias) {
        construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
    } else {
        v_h.value_ptr() = new Cpp<Class>(std::move(result));
    }
}

// return-by-value version 2: returning a value of the alias type itself.  We move-construct an
// Alias instance (even if no the python-side inheritance is involved).  The is intended for
// cases where Alias initialization is always desired.
template <typename Class>
void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
    static_assert(
        is_move_constructible<Alias<Class>>::value,
        "pybind11::init() return-by-alias-value factory function requires a movable alias class");
    v_h.value_ptr() = new Alias<Class>(std::move(result));
}

// Implementing class for py::init<...>()
template <typename... Args>
struct constructor {
    template <typename Class, typename... Extra, enable_if_t<!Class::has_alias, int> = 0>
    static void execute(Class &cl, const Extra &...extra) {
        cl.def(
            "__init__",
            [](value_and_holder &v_h, Args... args) {
                v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
            },
            is_new_style_constructor(),
            extra...);
    }

    template <
        typename Class,
        typename... Extra,
        enable_if_t<Class::has_alias && std::is_constructible<Cpp<Class>, Args...>::value, int>
        = 0>
    static void execute(Class &cl, const Extra &...extra) {
        cl.def(
            "__init__",
            [](value_and_holder &v_h, Args... args) {
                if (Py_TYPE(v_h.inst) == v_h.type->type) {
                    v_h.value_ptr()
                        = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
                } else {
                    v_h.value_ptr()
                        = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
                }
            },
            is_new_style_constructor(),
            extra...);
    }

    template <
        typename Class,
        typename... Extra,
        enable_if_t<Class::has_alias && !std::is_constructible<Cpp<Class>, Args...>::value, int>
        = 0>
    static void execute(Class &cl, const Extra &...extra) {
        cl.def(
            "__init__",
            [](value_and_holder &v_h, Args... args) {
                v_h.value_ptr()
                    = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
            },
            is_new_style_constructor(),
            extra...);
    }
};

// Implementing class for py::init_alias<...>()
template <typename... Args>
struct alias_constructor {
    template <
        typename Class,
        typename... Extra,
        enable_if_t<Class::has_alias && std::is_constructible<Alias<Class>, Args...>::value, int>
        = 0>
    static void execute(Class &cl, const Extra &...extra) {
        cl.def(
            "__init__",
            [](value_and_holder &v_h, Args... args) {
                v_h.value_ptr()
                    = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
            },
            is_new_style_constructor(),
            extra...);
    }
};

// Implementation class for py::init(Func) and py::init(Func, AliasFunc)
template <typename CFunc,
          typename AFunc = void_type (*)(),
          typename = function_signature_t<CFunc>,
          typename = function_signature_t<AFunc>>
struct factory;

// Specialization for py::init(Func)
template <typename Func, typename Return, typename... Args>
struct factory<Func, void_type (*)(), Return(Args...)> {
    remove_reference_t<Func> class_factory;

    // NOLINTNEXTLINE(google-explicit-constructor)
    factory(Func &&f) : class_factory(std::forward<Func>(f)) {}

    // The given class either has no alias or has no separate alias factory;
    // this always constructs the class itself.  If the class is registered with an alias
    // type and an alias instance is needed (i.e. because the final type is a Python class
    // inheriting from the C++ type) the returned value needs to either already be an alias
    // instance, or the alias needs to be constructible from a `Class &&` argument.
    template <typename Class, typename... Extra>
    void execute(Class &cl, const Extra &...extra) && {
#if defined(PYBIND11_CPP14)
        cl.def(
            "__init__",
            [func = std::move(class_factory)]
#else
        auto &func = class_factory;
        cl.def(
            "__init__",
            [func]
#endif
            (value_and_holder &v_h, Args... args) {
                construct<Class>(
                    v_h, func(std::forward<Args>(args)...), Py_TYPE(v_h.inst) != v_h.type->type);
            },
            is_new_style_constructor(),
            extra...);
    }
};

// Specialization for py::init(Func, AliasFunc)
template <typename CFunc,
          typename AFunc,
          typename CReturn,
          typename... CArgs,
          typename AReturn,
          typename... AArgs>
struct factory<CFunc, AFunc, CReturn(CArgs...), AReturn(AArgs...)> {
    static_assert(sizeof...(CArgs) == sizeof...(AArgs),
                  "pybind11::init(class_factory, alias_factory): class and alias factories "
                  "must have identical argument signatures");
    static_assert(all_of<std::is_same<CArgs, AArgs>...>::value,
                  "pybind11::init(class_factory, alias_factory): class and alias factories "
                  "must have identical argument signatures");

    remove_reference_t<CFunc> class_factory;
    remove_reference_t<AFunc> alias_factory;

    factory(CFunc &&c, AFunc &&a)
        : class_factory(std::forward<CFunc>(c)), alias_factory(std::forward<AFunc>(a)) {}

    // The class factory is called when the `self` type passed to `__init__` is the direct
    // class (i.e. not inherited), the alias factory when `self` is a Python-side subtype.
    template <typename Class, typename... Extra>
    void execute(Class &cl, const Extra &...extra) && {
        static_assert(Class::has_alias,
                      "The two-argument version of `py::init()` can "
                      "only be used if the class has an alias");
#if defined(PYBIND11_CPP14)
        cl.def(
            "__init__",
            [class_func = std::move(class_factory), alias_func = std::move(alias_factory)]
#else
        auto &class_func = class_factory;
        auto &alias_func = alias_factory;
        cl.def(
            "__init__",
            [class_func, alias_func]
#endif
            (value_and_holder &v_h, CArgs... args) {
                if (Py_TYPE(v_h.inst) == v_h.type->type) {
                    // If the instance type equals the registered type we don't have inheritance,
                    // so don't need the alias and can construct using the class function:
                    construct<Class>(v_h, class_func(std::forward<CArgs>(args)...), false);
                } else {
                    construct<Class>(v_h, alias_func(std::forward<CArgs>(args)...), true);
                }
            },
            is_new_style_constructor(),
            extra...);
    }
};

/// Set just the C++ state. Same as `__init__`.
template <typename Class, typename T>
void setstate(value_and_holder &v_h, T &&result, bool need_alias) {
    construct<Class>(v_h, std::forward<T>(result), need_alias);
}

/// Set both the C++ and Python states
template <typename Class,
          typename T,
          typename O,
          enable_if_t<std::is_convertible<O, handle>::value, int> = 0>
void setstate(value_and_holder &v_h, std::pair<T, O> &&result, bool need_alias) {
    construct<Class>(v_h, std::move(result.first), need_alias);
    auto d = handle(result.second);
    if (PyDict_Check(d.ptr()) && PyDict_Size(d.ptr()) == 0) {
        // Skipping setattr below, to not force use of py::dynamic_attr() for Class unnecessarily.
        // See PR #2972 for details.
        return;
    }
    setattr((PyObject *) v_h.inst, "__dict__", d);
}

/// Implementation for py::pickle(GetState, SetState)
template <typename Get,
          typename Set,
          typename = function_signature_t<Get>,
          typename = function_signature_t<Set>>
struct pickle_factory;

template <typename Get,
          typename Set,
          typename RetState,
          typename Self,
          typename NewInstance,
          typename ArgState>
struct pickle_factory<Get, Set, RetState(Self), NewInstance(ArgState)> {
    static_assert(std::is_same<intrinsic_t<RetState>, intrinsic_t<ArgState>>::value,
                  "The type returned by `__getstate__` must be the same "
                  "as the argument accepted by `__setstate__`");

    remove_reference_t<Get> get;
    remove_reference_t<Set> set;

    pickle_factory(Get get, Set set) : get(std::forward<Get>(get)), set(std::forward<Set>(set)) {}

    template <typename Class, typename... Extra>
    void execute(Class &cl, const Extra &...extra) && {
        cl.def("__getstate__", std::move(get));

#if defined(PYBIND11_CPP14)
        cl.def(
            "__setstate__",
            [func = std::move(set)]
#else
        auto &func = set;
        cl.def(
            "__setstate__",
            [func]
#endif
            (value_and_holder &v_h, ArgState state) {
                setstate<Class>(
                    v_h, func(std::forward<ArgState>(state)), Py_TYPE(v_h.inst) != v_h.type->type);
            },
            is_new_style_constructor(),
            extra...);
    }
};

PYBIND11_NAMESPACE_END(initimpl)
PYBIND11_NAMESPACE_END(detail)
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

type_caster_base.h
/*
    pybind11/detail/type_caster_base.h (originally first part of pybind11/cast.h)

    Copyright (c) 2016 Wenzel Jakob <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#pragma once

#include <pybind11/pytypes.h>

#include "common.h"
#include "descr.h"
#include "internals.h"
#include "typeid.h"
#include "value_and_holder.h"

#include <cstdint>
#include <iterator>
#include <new>
#include <string>
#include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <utility>
#include <vector>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)

/// A life support system for temporary objects created by `type_caster::load()`.
/// Adding a patient will keep it alive up until the enclosing function returns.
class loader_life_support {
private:
    loader_life_support *parent = nullptr;
    std::unordered_set<PyObject *> keep_alive;

    // Store stack pointer in thread-local storage.
    static PYBIND11_TLS_KEY_REF get_stack_tls_key() {
#if PYBIND11_INTERNALS_VERSION == 4
        return get_local_internals().loader_life_support_tls_key;
#else
        return get_internals().loader_life_support_tls_key;
#endif
    }
    static loader_life_support *get_stack_top() {
        return static_cast<loader_life_support *>(PYBIND11_TLS_GET_VALUE(get_stack_tls_key()));
    }
    static void set_stack_top(loader_life_support *value) {
        PYBIND11_TLS_REPLACE_VALUE(get_stack_tls_key(), value);
    }

public:
    /// A new patient frame is created when a function is entered
    loader_life_support() : parent{get_stack_top()} { set_stack_top(this); }

    /// ... and destroyed after it returns
    ~loader_life_support() {
        if (get_stack_top() != this) {
            pybind11_fail("loader_life_support: internal error");
        }
        set_stack_top(parent);
        for (auto *item : keep_alive) {
            Py_DECREF(item);
        }
    }

    /// This can only be used inside a pybind11-bound function, either by `argument_loader`
    /// at argument preparation time or by `py::cast()` at execution time.
    PYBIND11_NOINLINE static void add_patient(handle h) {
        loader_life_support *frame = get_stack_top();
        if (!frame) {
            // NOTE: It would be nice to include the stack frames here, as this indicates
            // use of pybind11::cast<> outside the normal call framework, finding such
            // a location is challenging. Developers could consider printing out
            // stack frame addresses here using something like __builtin_frame_address(0)
            throw cast_error("When called outside a bound function, py::cast() cannot "
                             "do Python -> C++ conversions which require the creation "
                             "of temporary values");
        }

        if (frame->keep_alive.insert(h.ptr()).second) {
            Py_INCREF(h.ptr());
        }
    }
};

// Gets the cache entry for the given type, creating it if necessary.  The return value is the pair
// returned by emplace, i.e. an iterator for the entry and a bool set to `true` if the entry was
// just created.
inline std::pair<decltype(internals::registered_types_py)::iterator, bool>
all_type_info_get_cache(PyTypeObject *type);

// Band-aid workaround to fix a subtle but serious bug in a minimalistic fashion. See PR #4762.
inline void all_type_info_add_base_most_derived_first(std::vector<type_info *> &bases,
                                                      type_info *addl_base) {
    for (auto it = bases.begin(); it != bases.end(); it++) {
        type_info *existing_base = *it;
        if (PyType_IsSubtype(addl_base->type, existing_base->type) != 0) {
            bases.insert(it, addl_base);
            return;
        }
    }
    bases.push_back(addl_base);
}

// Populates a just-created cache entry.
PYBIND11_NOINLINE void all_type_info_populate(PyTypeObject *t, std::vector<type_info *> &bases) {
    assert(bases.empty());
    std::vector<PyTypeObject *> check;
    for (handle parent : reinterpret_borrow<tuple>(t->tp_bases)) {
        check.push_back((PyTypeObject *) parent.ptr());
    }

    auto const &type_dict = get_internals().registered_types_py;
    for (size_t i = 0; i < check.size(); i++) {
        auto *type = check[i];
        // Ignore Python2 old-style class super type:
        if (!PyType_Check((PyObject *) type)) {
            continue;
        }

        // Check `type` in the current set of registered python types:
        auto it = type_dict.find(type);
        if (it != type_dict.end()) {
            // We found a cache entry for it, so it's either pybind-registered or has pre-computed
            // pybind bases, but we have to make sure we haven't already seen the type(s) before:
            // we want to follow Python/virtual C++ rules that there should only be one instance of
            // a common base.
            for (auto *tinfo : it->second) {
                // NB: Could use a second set here, rather than doing a linear search, but since
                // having a large number of immediate pybind11-registered types seems fairly
                // unlikely, that probably isn't worthwhile.
                bool found = false;
                for (auto *known : bases) {
                    if (known == tinfo) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    all_type_info_add_base_most_derived_first(bases, tinfo);
                }
            }
        } else if (type->tp_bases) {
            // It's some python type, so keep follow its bases classes to look for one or more
            // registered types
            if (i + 1 == check.size()) {
                // When we're at the end, we can pop off the current element to avoid growing
                // `check` when adding just one base (which is typical--i.e. when there is no
                // multiple inheritance)
                check.pop_back();
                i--;
            }
            for (handle parent : reinterpret_borrow<tuple>(type->tp_bases)) {
                check.push_back((PyTypeObject *) parent.ptr());
            }
        }
    }
}

/**
 * Extracts vector of type_info pointers of pybind-registered roots of the given Python type.  Will
 * be just 1 pybind type for the Python type of a pybind-registered class, or for any Python-side
 * derived class that uses single inheritance.  Will contain as many types as required for a Python
 * class that uses multiple inheritance to inherit (directly or indirectly) from multiple
 * pybind-registered classes.  Will be empty if neither the type nor any base classes are
 * pybind-registered.
 *
 * The value is cached for the lifetime of the Python type.
 */
inline const std::vector<detail::type_info *> &all_type_info(PyTypeObject *type) {
    auto ins = all_type_info_get_cache(type);
    if (ins.second) {
        // New cache entry: populate it
        all_type_info_populate(type, ins.first->second);
    }

    return ins.first->second;
}

/**
 * Gets a single pybind11 type info for a python type.  Returns nullptr if neither the type nor any
 * ancestors are pybind11-registered.  Throws an exception if there are multiple bases--use
 * `all_type_info` instead if you want to support multiple bases.
 */
PYBIND11_NOINLINE detail::type_info *get_type_info(PyTypeObject *type) {
    const auto &bases = all_type_info(type);
    if (bases.empty()) {
        return nullptr;
    }
    if (bases.size() > 1) {
        pybind11_fail(
            "pybind11::detail::get_type_info: type has multiple pybind11-registered bases");
    }
    return bases.front();
}

inline detail::type_info *get_local_type_info(const std::type_index &tp) {
    auto &locals = get_local_internals().registered_types_cpp;
    auto it = locals.find(tp);
    if (it != locals.end()) {
        return it->second;
    }
    return nullptr;
}

inline detail::type_info *get_global_type_info(const std::type_index &tp) {
    return with_internals([&](internals &internals) {
        detail::type_info *type_info = nullptr;
        auto &types = internals.registered_types_cpp;
        auto it = types.find(tp);
        if (it != types.end()) {
            type_info = it->second;
        }
        return type_info;
    });
}

/// Return the type info for a given C++ type; on lookup failure can either throw or return
/// nullptr.
PYBIND11_NOINLINE detail::type_info *get_type_info(const std::type_index &tp,
                                                   bool throw_if_missing = false) {
    if (auto *ltype = get_local_type_info(tp)) {
        return ltype;
    }
    if (auto *gtype = get_global_type_info(tp)) {
        return gtype;
    }

    if (throw_if_missing) {
        std::string tname = tp.name();
        detail::clean_type_id(tname);
        pybind11_fail("pybind11::detail::get_type_info: unable to find type info for \""
                      + std::move(tname) + '"');
    }
    return nullptr;
}

PYBIND11_NOINLINE handle get_type_handle(const std::type_info &tp, bool throw_if_missing) {
    detail::type_info *type_info = get_type_info(tp, throw_if_missing);
    return handle(type_info ? ((PyObject *) type_info->type) : nullptr);
}

// Searches the inheritance graph for a registered Python instance, using all_type_info().
PYBIND11_NOINLINE handle find_registered_python_instance(void *src,
                                                         const detail::type_info *tinfo) {
    return with_instance_map(src, [&](instance_map &instances) {
        auto it_instances = instances.equal_range(src);
        for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) {
            for (auto *instance_type : detail::all_type_info(Py_TYPE(it_i->second))) {
                if (instance_type && same_type(*instance_type->cpptype, *tinfo->cpptype)) {
                    return handle((PyObject *) it_i->second).inc_ref();
                }
            }
        }
        return handle();
    });
}

// Container for accessing and iterating over an instance's values/holders
struct values_and_holders {
private:
    instance *inst;
    using type_vec = std::vector<detail::type_info *>;
    const type_vec &tinfo;

public:
    explicit values_and_holders(instance *inst)
        : inst{inst}, tinfo(all_type_info(Py_TYPE(inst))) {}

    explicit values_and_holders(PyObject *obj)
        : inst{nullptr}, tinfo(all_type_info(Py_TYPE(obj))) {
        if (!tinfo.empty()) {
            inst = reinterpret_cast<instance *>(obj);
        }
    }

    struct iterator {
    private:
        instance *inst = nullptr;
        const type_vec *types = nullptr;
        value_and_holder curr;
        friend struct values_and_holders;
        iterator(instance *inst, const type_vec *tinfo) : inst{inst}, types{tinfo} {
            if (inst != nullptr) {
                assert(!types->empty());
                curr = value_and_holder(
                    inst /* instance */,
                    (*types)[0] /* type info */,
                    0, /* vpos: (non-simple types only): the first vptr comes first */
                    0 /* index */);
            }
        }
        // Past-the-end iterator:
        explicit iterator(size_t end) : curr(end) {}

    public:
        bool operator==(const iterator &other) const { return curr.index == other.curr.index; }
        bool operator!=(const iterator &other) const { return curr.index != other.curr.index; }
        iterator &operator++() {
            if (!inst->simple_layout) {
                curr.vh += 1 + (*types)[curr.index]->holder_size_in_ptrs;
            }
            ++curr.index;
            curr.type = curr.index < types->size() ? (*types)[curr.index] : nullptr;
            return *this;
        }
        value_and_holder &operator*() { return curr; }
        value_and_holder *operator->() { return &curr; }
    };

    iterator begin() { return iterator(inst, &tinfo); }
    iterator end() { return iterator(tinfo.size()); }

    iterator find(const type_info *find_type) {
        auto it = begin(), endit = end();
        while (it != endit && it->type != find_type) {
            ++it;
        }
        return it;
    }

    size_t size() { return tinfo.size(); }

    // Band-aid workaround to fix a subtle but serious bug in a minimalistic fashion. See PR #4762.
    bool is_redundant_value_and_holder(const value_and_holder &vh) {
        for (size_t i = 0; i < vh.index; i++) {
            if (PyType_IsSubtype(tinfo[i]->type, tinfo[vh.index]->type) != 0) {
                return true;
            }
        }
        return false;
    }
};

/**
 * Extracts C++ value and holder pointer references from an instance (which may contain multiple
 * values/holders for python-side multiple inheritance) that match the given type.  Throws an error
 * if the given type (or ValueType, if omitted) is not a pybind11 base of the given instance.  If
 * `find_type` is omitted (or explicitly specified as nullptr) the first value/holder are returned,
 * regardless of type (and the resulting .type will be nullptr).
 *
 * The returned object should be short-lived: in particular, it must not outlive the called-upon
 * instance.
 */
PYBIND11_NOINLINE value_and_holder
instance::get_value_and_holder(const type_info *find_type /*= nullptr default in common.h*/,
                               bool throw_if_missing /*= true in common.h*/) {
    // Optimize common case:
    if (!find_type || Py_TYPE(this) == find_type->type) {
        return value_and_holder(this, find_type, 0, 0);
    }

    detail::values_and_holders vhs(this);
    auto it = vhs.find(find_type);
    if (it != vhs.end()) {
        return *it;
    }

    if (!throw_if_missing) {
        return value_and_holder();
    }

#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
    pybind11_fail("pybind11::detail::instance::get_value_and_holder: `"
                  + get_fully_qualified_tp_name(find_type->type)
                  + "' is not a pybind11 base of the given `"
                  + get_fully_qualified_tp_name(Py_TYPE(this)) + "' instance");
#else
    pybind11_fail(
        "pybind11::detail::instance::get_value_and_holder: "
        "type is not a pybind11 base of the given instance "
        "(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for type details)");
#endif
}

PYBIND11_NOINLINE void instance::allocate_layout() {
    const auto &tinfo = all_type_info(Py_TYPE(this));

    const size_t n_types = tinfo.size();

    if (n_types == 0) {
        pybind11_fail(
            "instance allocation failed: new instance has no pybind11-registered base types");
    }

    simple_layout
        = n_types == 1 && tinfo.front()->holder_size_in_ptrs <= instance_simple_holder_in_ptrs();

    // Simple path: no python-side multiple inheritance, and a small-enough holder
    if (simple_layout) {
        simple_value_holder[0] = nullptr;
        simple_holder_constructed = false;
        simple_instance_registered = false;
    } else { // multiple base types or a too-large holder
        // Allocate space to hold: [v1*][h1][v2*][h2]...[bb...] where [vN*] is a value pointer,
        // [hN] is the (uninitialized) holder instance for value N, and [bb...] is a set of bool
        // values that tracks whether each associated holder has been initialized.  Each [block] is
        // padded, if necessary, to an integer multiple of sizeof(void *).
        size_t space = 0;
        for (auto *t : tinfo) {
            space += 1;                      // value pointer
            space += t->holder_size_in_ptrs; // holder instance
        }
        size_t flags_at = space;
        space += size_in_ptrs(n_types); // status bytes (holder_constructed and
                                        // instance_registered)

        // Allocate space for flags, values, and holders, and initialize it to 0 (flags and values,
        // in particular, need to be 0).  Use Python's memory allocation
        // functions: Python is using pymalloc, which is designed to be
        // efficient for small allocations like the one we're doing here;
        // for larger allocations they are just wrappers around malloc.
        // TODO: is this still true for pure Python 3.6?
        nonsimple.values_and_holders = (void **) PyMem_Calloc(space, sizeof(void *));
        if (!nonsimple.values_and_holders) {
            throw std::bad_alloc();
        }
        nonsimple.status
            = reinterpret_cast<std::uint8_t *>(&nonsimple.values_and_holders[flags_at]);
    }
    owned = true;
}

// NOLINTNEXTLINE(readability-make-member-function-const)
PYBIND11_NOINLINE void instance::deallocate_layout() {
    if (!simple_layout) {
        PyMem_Free(reinterpret_cast<void *>(nonsimple.values_and_holders));
    }
}

PYBIND11_NOINLINE bool isinstance_generic(handle obj, const std::type_info &tp) {
    handle type = detail::get_type_handle(tp, false);
    if (!type) {
        return false;
    }
    return isinstance(obj, type);
}

PYBIND11_NOINLINE handle get_object_handle(const void *ptr, const detail::type_info *type) {
    return with_instance_map(ptr, [&](instance_map &instances) {
        auto range = instances.equal_range(ptr);
        for (auto it = range.first; it != range.second; ++it) {
            for (const auto &vh : values_and_holders(it->second)) {
                if (vh.type == type) {
                    return handle((PyObject *) it->second);
                }
            }
        }
        return handle();
    });
}

inline PyThreadState *get_thread_state_unchecked() {
#if defined(PYPY_VERSION)
    return PyThreadState_GET();
#elif PY_VERSION_HEX < 0x030D0000
    return _PyThreadState_UncheckedGet();
#else
    return PyThreadState_GetUnchecked();
#endif
}

// Forward declarations
void keep_alive_impl(handle nurse, handle patient);
inline PyObject *make_new_instance(PyTypeObject *type);

class type_caster_generic {
public:
    PYBIND11_NOINLINE explicit type_caster_generic(const std::type_info &type_info)
        : typeinfo(get_type_info(type_info)), cpptype(&type_info) {}

    explicit type_caster_generic(const type_info *typeinfo)
        : typeinfo(typeinfo), cpptype(typeinfo ? typeinfo->cpptype : nullptr) {}

    bool load(handle src, bool convert) { return load_impl<type_caster_generic>(src, convert); }

    PYBIND11_NOINLINE static handle cast(const void *_src,
                                         return_value_policy policy,
                                         handle parent,
                                         const detail::type_info *tinfo,
                                         void *(*copy_constructor)(const void *),
                                         void *(*move_constructor)(const void *),
                                         const void *existing_holder = nullptr) {
        if (!tinfo) { // no type info: error will be set already
            return handle();
        }

        void *src = const_cast<void *>(_src);
        if (src == nullptr) {
            return none().release();
        }

        if (handle registered_inst = find_registered_python_instance(src, tinfo)) {
            return registered_inst;
        }

        auto inst = reinterpret_steal<object>(make_new_instance(tinfo->type));
        auto *wrapper = reinterpret_cast<instance *>(inst.ptr());
        wrapper->owned = false;
        void *&valueptr = values_and_holders(wrapper).begin()->value_ptr();

        switch (policy) {
            case return_value_policy::automatic:
            case return_value_policy::take_ownership:
                valueptr = src;
                wrapper->owned = true;
                break;

            case return_value_policy::automatic_reference:
            case return_value_policy::reference:
                valueptr = src;
                wrapper->owned = false;
                break;

            case return_value_policy::copy:
                if (copy_constructor) {
                    valueptr = copy_constructor(src);
                } else {
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
                    std::string type_name(tinfo->cpptype->name());
                    detail::clean_type_id(type_name);
                    throw cast_error("return_value_policy = copy, but type " + type_name
                                     + " is non-copyable!");
#else
                    throw cast_error("return_value_policy = copy, but type is "
                                     "non-copyable! (#define PYBIND11_DETAILED_ERROR_MESSAGES or "
                                     "compile in debug mode for details)");
#endif
                }
                wrapper->owned = true;
                break;

            case return_value_policy::move:
                if (move_constructor) {
                    valueptr = move_constructor(src);
                } else if (copy_constructor) {
                    valueptr = copy_constructor(src);
                } else {
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
                    std::string type_name(tinfo->cpptype->name());
                    detail::clean_type_id(type_name);
                    throw cast_error("return_value_policy = move, but type " + type_name
                                     + " is neither movable nor copyable!");
#else
                    throw cast_error("return_value_policy = move, but type is neither "
                                     "movable nor copyable! "
                                     "(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in "
                                     "debug mode for details)");
#endif
                }
                wrapper->owned = true;
                break;

            case return_value_policy::reference_internal:
                valueptr = src;
                wrapper->owned = false;
                keep_alive_impl(inst, parent);
                break;

            default:
                throw cast_error("unhandled return_value_policy: should not happen!");
        }

        tinfo->init_instance(wrapper, existing_holder);

        return inst.release();
    }

    // Base methods for generic caster; there are overridden in copyable_holder_caster
    void load_value(value_and_holder &&v_h) {
        auto *&vptr = v_h.value_ptr();
        // Lazy allocation for unallocated values:
        if (vptr == nullptr) {
            const auto *type = v_h.type ? v_h.type : typeinfo;
            if (type->operator_new) {
                vptr = type->operator_new(type->type_size);
            } else {
#if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912)
                if (type->type_align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
                    vptr = ::operator new(type->type_size, std::align_val_t(type->type_align));
                } else {
                    vptr = ::operator new(type->type_size);
                }
#else
                vptr = ::operator new(type->type_size);
#endif
            }
        }
        value = vptr;
    }
    bool try_implicit_casts(handle src, bool convert) {
        for (const auto &cast : typeinfo->implicit_casts) {
            type_caster_generic sub_caster(*cast.first);
            if (sub_caster.load(src, convert)) {
                value = cast.second(sub_caster.value);
                return true;
            }
        }
        return false;
    }
    bool try_direct_conversions(handle src) {
        for (auto &converter : *typeinfo->direct_conversions) {
            if (converter(src.ptr(), value)) {
                return true;
            }
        }
        return false;
    }
    void check_holder_compat() {}

    PYBIND11_NOINLINE static void *local_load(PyObject *src, const type_info *ti) {
        auto caster = type_caster_generic(ti);
        if (caster.load(src, false)) {
            return caster.value;
        }
        return nullptr;
    }

    /// Try to load with foreign typeinfo, if available. Used when there is no
    /// native typeinfo, or when the native one wasn't able to produce a value.
    PYBIND11_NOINLINE bool try_load_foreign_module_local(handle src) {
        constexpr auto *local_key = PYBIND11_MODULE_LOCAL_ID;
        const auto pytype = type::handle_of(src);
        if (!hasattr(pytype, local_key)) {
            return false;
        }

        type_info *foreign_typeinfo = reinterpret_borrow<capsule>(getattr(pytype, local_key));
        // Only consider this foreign loader if actually foreign and is a loader of the correct cpp
        // type
        if (foreign_typeinfo->module_local_load == &local_load
            || (cpptype && !same_type(*cpptype, *foreign_typeinfo->cpptype))) {
            return false;
        }

        if (auto *result = foreign_typeinfo->module_local_load(src.ptr(), foreign_typeinfo)) {
            value = result;
            return true;
        }
        return false;
    }

    // Implementation of `load`; this takes the type of `this` so that it can dispatch the relevant
    // bits of code between here and copyable_holder_caster where the two classes need different
    // logic (without having to resort to virtual inheritance).
    template <typename ThisT>
    PYBIND11_NOINLINE bool load_impl(handle src, bool convert) {
        if (!src) {
            return false;
        }
        if (!typeinfo) {
            return try_load_foreign_module_local(src);
        }

        auto &this_ = static_cast<ThisT &>(*this);
        this_.check_holder_compat();

        PyTypeObject *srctype = Py_TYPE(src.ptr());

        // Case 1: If src is an exact type match for the target type then we can reinterpret_cast
        // the instance's value pointer to the target type:
        if (srctype == typeinfo->type) {
            this_.load_value(reinterpret_cast<instance *>(src.ptr())->get_value_and_holder());
            return true;
        }
        // Case 2: We have a derived class
        if (PyType_IsSubtype(srctype, typeinfo->type)) {
            const auto &bases = all_type_info(srctype);
            bool no_cpp_mi = typeinfo->simple_type;

            // Case 2a: the python type is a Python-inherited derived class that inherits from just
            // one simple (no MI) pybind11 class, or is an exact match, so the C++ instance is of
            // the right type and we can use reinterpret_cast.
            // (This is essentially the same as case 2b, but because not using multiple inheritance
            // is extremely common, we handle it specially to avoid the loop iterator and type
            // pointer lookup overhead)
            if (bases.size() == 1 && (no_cpp_mi || bases.front()->type == typeinfo->type)) {
                this_.load_value(reinterpret_cast<instance *>(src.ptr())->get_value_and_holder());
                return true;
            }
            // Case 2b: the python type inherits from multiple C++ bases.  Check the bases to see
            // if we can find an exact match (or, for a simple C++ type, an inherited match); if
            // so, we can safely reinterpret_cast to the relevant pointer.
            if (bases.size() > 1) {
                for (auto *base : bases) {
                    if (no_cpp_mi ? PyType_IsSubtype(base->type, typeinfo->type)
                                  : base->type == typeinfo->type) {
                        this_.load_value(
                            reinterpret_cast<instance *>(src.ptr())->get_value_and_holder(base));
                        return true;
                    }
                }
            }

            // Case 2c: C++ multiple inheritance is involved and we couldn't find an exact type
            // match in the registered bases, above, so try implicit casting (needed for proper C++
            // casting when MI is involved).
            if (this_.try_implicit_casts(src, convert)) {
                return true;
            }
        }

        // Perform an implicit conversion
        if (convert) {
            for (const auto &converter : typeinfo->implicit_conversions) {
                auto temp = reinterpret_steal<object>(converter(src.ptr(), typeinfo->type));
                if (load_impl<ThisT>(temp, false)) {
                    loader_life_support::add_patient(temp);
                    return true;
                }
            }
            if (this_.try_direct_conversions(src)) {
                return true;
            }
        }

        // Failed to match local typeinfo. Try again with global.
        if (typeinfo->module_local) {
            if (auto *gtype = get_global_type_info(*typeinfo->cpptype)) {
                typeinfo = gtype;
                return load(src, false);
            }
        }

        // Global typeinfo has precedence over foreign module_local
        if (try_load_foreign_module_local(src)) {
            return true;
        }

        // Custom converters didn't take None, now we convert None to nullptr.
        if (src.is_none()) {
            // Defer accepting None to other overloads (if we aren't in convert mode):
            if (!convert) {
                return false;
            }
            value = nullptr;
            return true;
        }

        return false;
    }

    // Called to do type lookup and wrap the pointer and type in a pair when a dynamic_cast
    // isn't needed or can't be used.  If the type is unknown, sets the error and returns a pair
    // with .second = nullptr.  (p.first = nullptr is not an error: it becomes None).
    PYBIND11_NOINLINE static std::pair<const void *, const type_info *>
    src_and_type(const void *src,
                 const std::type_info &cast_type,
                 const std::type_info *rtti_type = nullptr) {
        if (auto *tpi = get_type_info(cast_type)) {
            return {src, const_cast<const type_info *>(tpi)};
        }

        // Not found, set error:
        std::string tname = rtti_type ? rtti_type->name() : cast_type.name();
        detail::clean_type_id(tname);
        std::string msg = "Unregistered type : " + tname;
        set_error(PyExc_TypeError, msg.c_str());
        return {nullptr, nullptr};
    }

    const type_info *typeinfo = nullptr;
    const std::type_info *cpptype = nullptr;
    void *value = nullptr;
};

/**
 * Determine suitable casting operator for pointer-or-lvalue-casting type casters.  The type caster
 * needs to provide `operator T*()` and `operator T&()` operators.
 *
 * If the type supports moving the value away via an `operator T&&() &&` method, it should use
 * `movable_cast_op_type` instead.
 */
template <typename T>
using cast_op_type = conditional_t<std::is_pointer<remove_reference_t<T>>::value,
                                   typename std::add_pointer<intrinsic_t<T>>::type,
                                   typename std::add_lvalue_reference<intrinsic_t<T>>::type>;

/**
 * Determine suitable casting operator for a type caster with a movable value.  Such a type caster
 * needs to provide `operator T*()`, `operator T&()`, and `operator T&&() &&`.  The latter will be
 * called in appropriate contexts where the value can be moved rather than copied.
 *
 * These operator are automatically provided when using the PYBIND11_TYPE_CASTER macro.
 */
template <typename T>
using movable_cast_op_type
    = conditional_t<std::is_pointer<typename std::remove_reference<T>::type>::value,
                    typename std::add_pointer<intrinsic_t<T>>::type,
                    conditional_t<std::is_rvalue_reference<T>::value,
                                  typename std::add_rvalue_reference<intrinsic_t<T>>::type,
                                  typename std::add_lvalue_reference<intrinsic_t<T>>::type>>;

// Does the container have a mapped type and is it recursive?
// Implemented by specializations below.
template <typename Container, typename SFINAE = void>
struct container_mapped_type_traits {
    static constexpr bool has_mapped_type = false;
    static constexpr bool has_recursive_mapped_type = false;
};

template <typename Container>
struct container_mapped_type_traits<
    Container,
    typename std::enable_if<
        std::is_same<typename Container::mapped_type, Container>::value>::type> {
    static constexpr bool has_mapped_type = true;
    static constexpr bool has_recursive_mapped_type = true;
};

template <typename Container>
struct container_mapped_type_traits<
    Container,
    typename std::enable_if<
        negation<std::is_same<typename Container::mapped_type, Container>>::value>::type> {
    static constexpr bool has_mapped_type = true;
    static constexpr bool has_recursive_mapped_type = false;
};

// Does the container have a value type and is it recursive?
// Implemented by specializations below.
template <typename Container, typename SFINAE = void>
struct container_value_type_traits : std::false_type {
    static constexpr bool has_value_type = false;
    static constexpr bool has_recursive_value_type = false;
};

template <typename Container>
struct container_value_type_traits<
    Container,
    typename std::enable_if<
        std::is_same<typename Container::value_type, Container>::value>::type> {
    static constexpr bool has_value_type = true;
    static constexpr bool has_recursive_value_type = true;
};

template <typename Container>
struct container_value_type_traits<
    Container,
    typename std::enable_if<
        negation<std::is_same<typename Container::value_type, Container>>::value>::type> {
    static constexpr bool has_value_type = true;
    static constexpr bool has_recursive_value_type = false;
};

/*
 * Tag to be used for representing the bottom of recursively defined types.
 * Define this tag so we don't have to use void.
 */
struct recursive_bottom {};

/*
 * Implementation detail of `recursive_container_traits` below.
 * `T` is the `value_type` of the container, which might need to be modified to
 * avoid recursive types and const types.
 */
template <typename T, bool is_this_a_map>
struct impl_type_to_check_recursively {
    /*
     * If the container is recursive, then no further recursion should be done.
     */
    using if_recursive = recursive_bottom;
    /*
     * Otherwise yield `T` unchanged.
     */
    using if_not_recursive = T;
};

/*
 * For pairs - only as value type of a map -, the first type should remove the `const`.
 * Also, if the map is recursive, then the recursive checking should consider
 * the first type only.
 */
template <typename A, typename B>
struct impl_type_to_check_recursively<std::pair<A, B>, /* is_this_a_map = */ true> {
    using if_recursive = typename std::remove_const<A>::type;
    using if_not_recursive = std::pair<typename std::remove_const<A>::type, B>;
};

/*
 * Implementation of `recursive_container_traits` below.
 */
template <typename Container, typename SFINAE = void>
struct impl_recursive_container_traits {
    using type_to_check_recursively = recursive_bottom;
};

template <typename Container>
struct impl_recursive_container_traits<
    Container,
    typename std::enable_if<container_value_type_traits<Container>::has_value_type>::type> {
    static constexpr bool is_recursive
        = container_mapped_type_traits<Container>::has_recursive_mapped_type
          || container_value_type_traits<Container>::has_recursive_value_type;
    /*
     * This member dictates which type Pybind11 should check recursively in traits
     * such as `is_move_constructible`, `is_copy_constructible`, `is_move_assignable`, ...
     * Direct access to `value_type` should be avoided:
     * 1. `value_type` might recursively contain the type again
     * 2. `value_type` of STL map types is `std::pair<A const, B>`, the `const`
     *    should be removed.
     *
     */
    using type_to_check_recursively = typename std::conditional<
        is_recursive,
        typename impl_type_to_check_recursively<
            typename Container::value_type,
            container_mapped_type_traits<Container>::has_mapped_type>::if_recursive,
        typename impl_type_to_check_recursively<
            typename Container::value_type,
            container_mapped_type_traits<Container>::has_mapped_type>::if_not_recursive>::type;
};

/*
 * This trait defines the `type_to_check_recursively` which is needed to properly
 * handle recursively defined traits such as `is_move_constructible` without going
 * into an infinite recursion.
 * Should be used instead of directly accessing the `value_type`.
 * It cancels the recursion by returning the `recursive_bottom` tag.
 *
 * The default definition of `type_to_check_recursively` is as follows:
 *
 * 1. By default, it is `recursive_bottom`, so that the recursion is canceled.
 * 2. If the type is non-recursive and defines a `value_type`, then the `value_type` is used.
 *    If the `value_type` is a pair and a `mapped_type` is defined,
 *    then the `const` is removed from the first type.
 * 3. If the type is recursive and `value_type` is not a pair, then `recursive_bottom` is returned.
 * 4. If the type is recursive and `value_type` is a pair and a `mapped_type` is defined,
 *    then `const` is removed from the first type and the first type is returned.
 *
 * This behavior can be extended by the user as seen in test_stl_binders.cpp.
 *
 * This struct is exactly the same as impl_recursive_container_traits.
 * The duplication achieves that user-defined specializations don't compete
 * with internal specializations, but take precedence.
 */
template <typename Container, typename SFINAE = void>
struct recursive_container_traits : impl_recursive_container_traits<Container> {};

template <typename T>
struct is_move_constructible
    : all_of<std::is_move_constructible<T>,
             is_move_constructible<
                 typename recursive_container_traits<T>::type_to_check_recursively>> {};

template <>
struct is_move_constructible<recursive_bottom> : std::true_type {};

// Likewise for std::pair
// (after C++17 it is mandatory that the move constructor not exist when the two types aren't
// themselves move constructible, but this can not be relied upon when T1 or T2 are themselves
// containers).
template <typename T1, typename T2>
struct is_move_constructible<std::pair<T1, T2>>
    : all_of<is_move_constructible<T1>, is_move_constructible<T2>> {};

// std::is_copy_constructible isn't quite enough: it lets std::vector<T> (and similar) through when
// T is non-copyable, but code containing such a copy constructor fails to actually compile.
template <typename T>
struct is_copy_constructible
    : all_of<std::is_copy_constructible<T>,
             is_copy_constructible<
                 typename recursive_container_traits<T>::type_to_check_recursively>> {};

template <>
struct is_copy_constructible<recursive_bottom> : std::true_type {};

// Likewise for std::pair
// (after C++17 it is mandatory that the copy constructor not exist when the two types aren't
// themselves copy constructible, but this can not be relied upon when T1 or T2 are themselves
// containers).
template <typename T1, typename T2>
struct is_copy_constructible<std::pair<T1, T2>>
    : all_of<is_copy_constructible<T1>, is_copy_constructible<T2>> {};

// The same problems arise with std::is_copy_assignable, so we use the same workaround.
template <typename T>
struct is_copy_assignable
    : all_of<
          std::is_copy_assignable<T>,
          is_copy_assignable<typename recursive_container_traits<T>::type_to_check_recursively>> {
};

template <>
struct is_copy_assignable<recursive_bottom> : std::true_type {};

template <typename T1, typename T2>
struct is_copy_assignable<std::pair<T1, T2>>
    : all_of<is_copy_assignable<T1>, is_copy_assignable<T2>> {};

PYBIND11_NAMESPACE_END(detail)

// polymorphic_type_hook<itype>::get(src, tinfo) determines whether the object pointed
// to by `src` actually is an instance of some class derived from `itype`.
// If so, it sets `tinfo` to point to the std::type_info representing that derived
// type, and returns a pointer to the start of the most-derived object of that type
// (in which `src` is a subobject; this will be the same address as `src` in most
// single inheritance cases). If not, or if `src` is nullptr, it simply returns `src`
// and leaves `tinfo` at its default value of nullptr.
//
// The default polymorphic_type_hook just returns src. A specialization for polymorphic
// types determines the runtime type of the passed object and adjusts the this-pointer
// appropriately via dynamic_cast<void*>. This is what enables a C++ Animal* to appear
// to Python as a Dog (if Dog inherits from Animal, Animal is polymorphic, Dog is
// registered with pybind11, and this Animal is in fact a Dog).
//
// You may specialize polymorphic_type_hook yourself for types that want to appear
// polymorphic to Python but do not use C++ RTTI. (This is a not uncommon pattern
// in performance-sensitive applications, used most notably in LLVM.)
//
// polymorphic_type_hook_base allows users to specialize polymorphic_type_hook with
// std::enable_if. User provided specializations will always have higher priority than
// the default implementation and specialization provided in polymorphic_type_hook_base.
template <typename itype, typename SFINAE = void>
struct polymorphic_type_hook_base {
    static const void *get(const itype *src, const std::type_info *&) { return src; }
};
template <typename itype>
struct polymorphic_type_hook_base<itype, detail::enable_if_t<std::is_polymorphic<itype>::value>> {
    static const void *get(const itype *src, const std::type_info *&type) {
        type = src ? &typeid(*src) : nullptr;
        return dynamic_cast<const void *>(src);
    }
};
template <typename itype, typename SFINAE = void>
struct polymorphic_type_hook : public polymorphic_type_hook_base<itype> {};

PYBIND11_NAMESPACE_BEGIN(detail)

/// Generic type caster for objects stored on the heap
template <typename type>
class type_caster_base : public type_caster_generic {
    using itype = intrinsic_t<type>;

public:
    static constexpr auto name = const_name<type>();

    type_caster_base() : type_caster_base(typeid(type)) {}
    explicit type_caster_base(const std::type_info &info) : type_caster_generic(info) {}

    static handle cast(const itype &src, return_value_policy policy, handle parent) {
        if (policy == return_value_policy::automatic
            || policy == return_value_policy::automatic_reference) {
            policy = return_value_policy::copy;
        }
        return cast(std::addressof(src), policy, parent);
    }

    static handle cast(itype &&src, return_value_policy, handle parent) {
        return cast(std::addressof(src), return_value_policy::move, parent);
    }

    // Returns a (pointer, type_info) pair taking care of necessary type lookup for a
    // polymorphic type (using RTTI by default, but can be overridden by specializing
    // polymorphic_type_hook). If the instance isn't derived, returns the base version.
    static std::pair<const void *, const type_info *> src_and_type(const itype *src) {
        const auto &cast_type = typeid(itype);
        const std::type_info *instance_type = nullptr;
        const void *vsrc = polymorphic_type_hook<itype>::get(src, instance_type);
        if (instance_type && !same_type(cast_type, *instance_type)) {
            // This is a base pointer to a derived type. If the derived type is registered
            // with pybind11, we want to make the full derived object available.
            // In the typical case where itype is polymorphic, we get the correct
            // derived pointer (which may be != base pointer) by a dynamic_cast to
            // most derived type. If itype is not polymorphic, we won't get here
            // except via a user-provided specialization of polymorphic_type_hook,
            // and the user has promised that no this-pointer adjustment is
            // required in that case, so it's OK to use static_cast.
            if (const auto *tpi = get_type_info(*instance_type)) {
                return {vsrc, tpi};
            }
        }
        // Otherwise we have either a nullptr, an `itype` pointer, or an unknown derived pointer,
        // so don't do a cast
        return type_caster_generic::src_and_type(src, cast_type, instance_type);
    }

    static handle cast(const itype *src, return_value_policy policy, handle parent) {
        auto st = src_and_type(src);
        return type_caster_generic::cast(st.first,
                                         policy,
                                         parent,
                                         st.second,
                                         make_copy_constructor(src),
                                         make_move_constructor(src));
    }

    static handle cast_holder(const itype *src, const void *holder) {
        auto st = src_and_type(src);
        return type_caster_generic::cast(st.first,
                                         return_value_policy::take_ownership,
                                         {},
                                         st.second,
                                         nullptr,
                                         nullptr,
                                         holder);
    }

    template <typename T>
    using cast_op_type = detail::cast_op_type<T>;

    // NOLINTNEXTLINE(google-explicit-constructor)
    operator itype *() { return (type *) value; }
    // NOLINTNEXTLINE(google-explicit-constructor)
    operator itype &() {
        if (!value) {
            throw reference_cast_error();
        }
        return *((itype *) value);
    }

protected:
    using Constructor = void *(*) (const void *);

    /* Only enabled when the types are {copy,move}-constructible *and* when the type
       does not have a private operator new implementation. A comma operator is used in the
       decltype argument to apply SFINAE to the public copy/move constructors.*/
    template <typename T, typename = enable_if_t<is_copy_constructible<T>::value>>
    static auto make_copy_constructor(const T *) -> decltype(new T(std::declval<const T>()),
                                                             Constructor{}) {
        return [](const void *arg) -> void * { return new T(*reinterpret_cast<const T *>(arg)); };
    }

    template <typename T, typename = enable_if_t<is_move_constructible<T>::value>>
    static auto make_move_constructor(const T *) -> decltype(new T(std::declval<T &&>()),
                                                             Constructor{}) {
        return [](const void *arg) -> void * {
            return new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg))));
        };
    }

    static Constructor make_copy_constructor(...) { return nullptr; }
    static Constructor make_move_constructor(...) { return nullptr; }
};

inline std::string quote_cpp_type_name(const std::string &cpp_type_name) {
    return cpp_type_name; // No-op for now. See PR #4888
}

PYBIND11_NOINLINE std::string type_info_description(const std::type_info &ti) {
    if (auto *type_data = get_type_info(ti)) {
        handle th((PyObject *) type_data->type);
        return th.attr("__module__").cast<std::string>() + '.'
               + th.attr("__qualname__").cast<std::string>();
    }
    return quote_cpp_type_name(clean_type_id(ti.name()));
}

PYBIND11_NAMESPACE_END(detail)
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

class.h

/*
    pybind11/detail/class.h: Python C API implementation details for py::class_

    Copyright (c) 2017 Wenzel Jakob <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#pragma once

#include <pybind11/attr.h>
#include <pybind11/options.h>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)

#if !defined(PYPY_VERSION)
#    define PYBIND11_BUILTIN_QUALNAME
#    define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)
#else
// In PyPy, we still set __qualname__ so that we can produce reliable function type
// signatures; in CPython this macro expands to nothing:
#    define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)                                             \
        setattr((PyObject *) obj, "__qualname__", nameobj)
#endif

inline std::string get_fully_qualified_tp_name(PyTypeObject *type) {
#if !defined(PYPY_VERSION)
    return type->tp_name;
#else
    auto module_name = handle((PyObject *) type).attr("__module__").cast<std::string>();
    if (module_name == PYBIND11_BUILTINS_MODULE)
        return type->tp_name;
    else
        return std::move(module_name) + "." + type->tp_name;
#endif
}

inline PyTypeObject *type_incref(PyTypeObject *type) {
    Py_INCREF(type);
    return type;
}

#if !defined(PYPY_VERSION)

/// `pybind11_static_property.__get__()`: Always pass the class instead of the instance.
extern "C" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) {
    return PyProperty_Type.tp_descr_get(self, cls, cls);
}

/// `pybind11_static_property.__set__()`: Just like the above `__get__()`.
extern "C" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) {
    PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj);
    return PyProperty_Type.tp_descr_set(self, cls, value);
}

// Forward declaration to use in `make_static_property_type()`
inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type);

/** A `static_property` is the same as a `property` but the `__get__()` and `__set__()`
    methods are modified to always use the object type instead of a concrete instance.
    Return value: New reference. */
inline PyTypeObject *make_static_property_type() {
    constexpr auto *name = "pybind11_static_property";
    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));

    /* Danger zone: from now (and until PyType_Ready), make sure to
       issue no Python C API calls which could potentially invoke the
       garbage collector (the GC will call type_traverse(), which will in
       turn find the newly constructed type in an invalid state) */
    auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
    if (!heap_type) {
        pybind11_fail("make_static_property_type(): error allocating type!");
    }

    heap_type->ht_name = name_obj.inc_ref().ptr();
#    ifdef PYBIND11_BUILTIN_QUALNAME
    heap_type->ht_qualname = name_obj.inc_ref().ptr();
#    endif

    auto *type = &heap_type->ht_type;
    type->tp_name = name;
    type->tp_base = type_incref(&PyProperty_Type);
    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
    type->tp_descr_get = pybind11_static_get;
    type->tp_descr_set = pybind11_static_set;

#    if PY_VERSION_HEX >= 0x030C0000
    // Since Python-3.12 property-derived types are required to
    // have dynamic attributes (to set `__doc__`)
    enable_dynamic_attributes(heap_type);
#    endif

    if (PyType_Ready(type) < 0) {
        pybind11_fail("make_static_property_type(): failure in PyType_Ready()!");
    }

    setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);

    return type;
}

#else // PYPY

/** PyPy has some issues with the above C API, so we evaluate Python code instead.
    This function will only be called once so performance isn't really a concern.
    Return value: New reference. */
inline PyTypeObject *make_static_property_type() {
    auto d = dict();
    PyObject *result = PyRun_String(R"(\
class pybind11_static_property(property):
    def __get__(self, obj, cls):
        return property.__get__(self, cls, cls)

    def __set__(self, obj, value):
        cls = obj if isinstance(obj, type) else type(obj)
        property.__set__(self, cls, value)
)",
                                    Py_file_input,
                                    d.ptr(),
                                    d.ptr());
    if (result == nullptr)
        throw error_already_set();
    Py_DECREF(result);
    return (PyTypeObject *) d["pybind11_static_property"].cast<object>().release().ptr();
}

#endif // PYPY

/** Types with static properties need to handle `Type.static_prop = x` in a specific way.
    By default, Python replaces the `static_property` itself, but for wrapped C++ types
    we need to call `static_property.__set__()` in order to propagate the new value to
    the underlying C++ data structure. */
extern "C" inline int pybind11_meta_setattro(PyObject *obj, PyObject *name, PyObject *value) {
    // Use `_PyType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw
    // descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`).
    PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);

    // The following assignment combinations are possible:
    //   1. `Type.static_prop = value`             --> descr_set: `Type.static_prop.__set__(value)`
    //   2. `Type.static_prop = other_static_prop` --> setattro:  replace existing `static_prop`
    //   3. `Type.regular_attribute = value`       --> setattro:  regular attribute assignment
    auto *const static_prop = (PyObject *) get_internals().static_property_type;
    const auto call_descr_set = (descr != nullptr) && (value != nullptr)
                                && (PyObject_IsInstance(descr, static_prop) != 0)
                                && (PyObject_IsInstance(value, static_prop) == 0);
    if (call_descr_set) {
        // Call `static_property.__set__()` instead of replacing the `static_property`.
#if !defined(PYPY_VERSION)
        return Py_TYPE(descr)->tp_descr_set(descr, obj, value);
#else
        if (PyObject *result = PyObject_CallMethod(descr, "__set__", "OO", obj, value)) {
            Py_DECREF(result);
            return 0;
        } else {
            return -1;
        }
#endif
    } else {
        // Replace existing attribute.
        return PyType_Type.tp_setattro(obj, name, value);
    }
}

/**
 * Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing
 * methods via cls.attr("m2") = cls.attr("m1"): instead the tp_descr_get returns a plain function,
 * when called on a class, or a PyMethod, when called on an instance.  Override that behaviour here
 * to do a special case bypass for PyInstanceMethod_Types.
 */
extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) {
    PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);
    if (descr && PyInstanceMethod_Check(descr)) {
        Py_INCREF(descr);
        return descr;
    }
    return PyType_Type.tp_getattro(obj, name);
}

/// metaclass `__call__` function that is used to create all pybind11 objects.
extern "C" inline PyObject *pybind11_meta_call(PyObject *type, PyObject *args, PyObject *kwargs) {

    // use the default metaclass call to create/initialize the object
    PyObject *self = PyType_Type.tp_call(type, args, kwargs);
    if (self == nullptr) {
        return nullptr;
    }

	auto instance = reinterpret_cast<detail::instance*>(self);
	instance->is_alias = instance->has_alias;

    // Ensure that the base __init__ function(s) were called
    values_and_holders vhs(self);
    for (const auto &vh : vhs) {
        if (!vh.holder_constructed() && !vhs.is_redundant_value_and_holder(vh)) {
            PyErr_Format(PyExc_TypeError,
                         "%.200s.__init__() must be called when overriding __init__",
                         get_fully_qualified_tp_name(vh.type->type).c_str());
            Py_DECREF(self);
            return nullptr;
        }
    }

    return self;
}

/// Cleanup the type-info for a pybind11-registered type.
extern "C" inline void pybind11_meta_dealloc(PyObject *obj) {
    with_internals([obj](internals &internals) {
        auto *type = (PyTypeObject *) obj;

        // A pybind11-registered type will:
        // 1) be found in internals.registered_types_py
        // 2) have exactly one associated `detail::type_info`
        auto found_type = internals.registered_types_py.find(type);
        if (found_type != internals.registered_types_py.end() && found_type->second.size() == 1
            && found_type->second[0]->type == type) {

            auto *tinfo = found_type->second[0];
            auto tindex = std::type_index(*tinfo->cpptype);
            internals.direct_conversions.erase(tindex);

            if (tinfo->module_local) {
                get_local_internals().registered_types_cpp.erase(tindex);
            } else {
                internals.registered_types_cpp.erase(tindex);
            }
            internals.registered_types_py.erase(tinfo->type);

            // Actually just `std::erase_if`, but that's only available in C++20
            auto &cache = internals.inactive_override_cache;
            for (auto it = cache.begin(), last = cache.end(); it != last;) {
                if (it->first == (PyObject *) tinfo->type) {
                    it = cache.erase(it);
                } else {
                    ++it;
                }
            }

            delete tinfo;
        }
    });

    PyType_Type.tp_dealloc(obj);
}

/** This metaclass is assigned by default to all pybind11 types and is required in order
    for static properties to function correctly. Users may override this using `py::metaclass`.
    Return value: New reference. */
inline PyTypeObject *make_default_metaclass() {
    constexpr auto *name = "pybind11_type";
    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));

    /* Danger zone: from now (and until PyType_Ready), make sure to
       issue no Python C API calls which could potentially invoke the
       garbage collector (the GC will call type_traverse(), which will in
       turn find the newly constructed type in an invalid state) */
    auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
    if (!heap_type) {
        pybind11_fail("make_default_metaclass(): error allocating metaclass!");
    }

    heap_type->ht_name = name_obj.inc_ref().ptr();
#ifdef PYBIND11_BUILTIN_QUALNAME
    heap_type->ht_qualname = name_obj.inc_ref().ptr();
#endif

    auto *type = &heap_type->ht_type;
    type->tp_name = name;
    type->tp_base = type_incref(&PyType_Type);
    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;

    type->tp_call = pybind11_meta_call;

    type->tp_setattro = pybind11_meta_setattro;
    type->tp_getattro = pybind11_meta_getattro;

    type->tp_dealloc = pybind11_meta_dealloc;

    if (PyType_Ready(type) < 0) {
        pybind11_fail("make_default_metaclass(): failure in PyType_Ready()!");
    }

    setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);

    return type;
}

/// For multiple inheritance types we need to recursively register/deregister base pointers for any
/// base classes with pointers that are difference from the instance value pointer so that we can
/// correctly recognize an offset base class pointer. This calls a function with any offset base
/// ptrs.
inline void traverse_offset_bases(void *valueptr,
                                  const detail::type_info *tinfo,
                                  instance *self,
                                  bool (*f)(void * /*parentptr*/, instance * /*self*/)) {
    for (handle h : reinterpret_borrow<tuple>(tinfo->type->tp_bases)) {
        if (auto *parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) {
            for (auto &c : parent_tinfo->implicit_casts) {
                if (c.first == tinfo->cpptype) {
                    auto *parentptr = c.second(valueptr);
                    if (parentptr != valueptr) {
                        f(parentptr, self);
                    }
                    traverse_offset_bases(parentptr, parent_tinfo, self, f);
                    break;
                }
            }
        }
    }
}

inline bool register_instance_impl(void *ptr, instance *self) {
    with_instance_map(ptr, [&](instance_map &instances) { instances.emplace(ptr, self); });
    return true; // unused, but gives the same signature as the deregister func
}
inline bool deregister_instance_impl(void *ptr, instance *self) {
    return with_instance_map(ptr, [&](instance_map &instances) {
        auto range = instances.equal_range(ptr);
        for (auto it = range.first; it != range.second; ++it) {
            if (self == it->second) {
                instances.erase(it);
                return true;
            }
        }
        return false;
    });
}

inline void register_instance(instance *self, void *valptr, const type_info *tinfo) {
    register_instance_impl(valptr, self);
    if (!tinfo->simple_ancestors) {
        traverse_offset_bases(valptr, tinfo, self, register_instance_impl);
    }
}

inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) {
    bool ret = deregister_instance_impl(valptr, self);
    if (!tinfo->simple_ancestors) {
        traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl);
    }
    return ret;
}

/// Instance creation function for all pybind11 types. It allocates the internal instance layout
/// for holding C++ objects and holders.  Allocation is done lazily (the first time the instance is
/// cast to a reference or pointer), and initialization is done by an `__init__` function.
inline PyObject *make_new_instance(PyTypeObject *type) {
#if defined(PYPY_VERSION)
    // PyPy gets tp_basicsize wrong (issue 2482) under multiple inheritance when the first
    // inherited object is a plain Python type (i.e. not derived from an extension type).  Fix it.
    ssize_t instance_size = static_cast<ssize_t>(sizeof(instance));
    if (type->tp_basicsize < instance_size) {
        type->tp_basicsize = instance_size;
    }
#endif
    PyObject *self = type->tp_alloc(type, 0);
    auto *inst = reinterpret_cast<instance *>(self);
    // Allocate the value/holder internals:
    inst->allocate_layout();

    return self;
}

/// Instance creation function for all pybind11 types. It only allocates space for the
/// C++ object, but doesn't call the constructor -- an `__init__` function must do that.
extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) {
    return make_new_instance(type);
}

/// An `__init__` function constructs the C++ object. Users should provide at least one
/// of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the
/// following default function will be used which simply throws an exception.
extern "C" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) {
    PyTypeObject *type = Py_TYPE(self);
    std::string msg = get_fully_qualified_tp_name(type) + ": No constructor defined!";
    set_error(PyExc_TypeError, msg.c_str());
    return -1;
}

inline void add_patient(PyObject *nurse, PyObject *patient) {
    auto *instance = reinterpret_cast<detail::instance *>(nurse);
    instance->has_patients = true;
    Py_INCREF(patient);

    with_internals([&](internals &internals) { internals.patients[nurse].push_back(patient); });
}

inline void clear_patients(PyObject *self) {
    auto *instance = reinterpret_cast<detail::instance *>(self);
    std::vector<PyObject *> patients;

    with_internals([&](internals &internals) {
        auto pos = internals.patients.find(self);

        if (pos == internals.patients.end()) {
            pybind11_fail(
                "FATAL: Internal consistency check failed: Invalid clear_patients() call.");
        }

        // Clearing the patients can cause more Python code to run, which
        // can invalidate the iterator. Extract the vector of patients
        // from the unordered_map first.
        patients = std::move(pos->second);
        internals.patients.erase(pos);
    });

    instance->has_patients = false;
    for (PyObject *&patient : patients) {
        Py_CLEAR(patient);
    }
}

/// Clears all internal data from the instance and removes it from registered instances in
/// preparation for deallocation.
inline void clear_instance(PyObject *self) {
    auto *instance = reinterpret_cast<detail::instance *>(self);

    // Deallocate any values/holders, if present:
    for (auto &v_h : values_and_holders(instance)) {
        if (v_h) {

            // We have to deregister before we call dealloc because, for virtual MI types, we still
            // need to be able to get the parent pointers.
            if (v_h.instance_registered()
                && !deregister_instance(instance, v_h.value_ptr(), v_h.type)) {
                pybind11_fail(
                    "pybind11_object_dealloc(): Tried to deallocate unregistered instance!");
            }

            if (instance->owned || v_h.holder_constructed()) {
                v_h.type->dealloc(v_h);
            }
        }
    }
    // Deallocate the value/holder layout internals:
    instance->deallocate_layout();

    if (instance->weakrefs) {
        PyObject_ClearWeakRefs(self);
    }

    PyObject **dict_ptr = _PyObject_GetDictPtr(self);
    if (dict_ptr) {
        Py_CLEAR(*dict_ptr);
    }

    if (instance->has_patients) {
        clear_patients(self);
    }
}

/// Instance destructor function for all pybind11 types. It calls `type_info.dealloc`
/// to destroy the C++ object itself, while the rest is Python bookkeeping.
extern "C" inline void pybind11_object_dealloc(PyObject *self) {
    auto *type = Py_TYPE(self);

    // If this is a GC tracked object, untrack it first
    // Note that the track call is implicitly done by the
    // default tp_alloc, which we never override.
    if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) != 0) {
        PyObject_GC_UnTrack(self);
    }

    clear_instance(self);

    type->tp_free(self);

#if PY_VERSION_HEX < 0x03080000
    // `type->tp_dealloc != pybind11_object_dealloc` means that we're being called
    // as part of a derived type's dealloc, in which case we're not allowed to decref
    // the type here. For cross-module compatibility, we shouldn't compare directly
    // with `pybind11_object_dealloc`, but with the common one stashed in internals.
    auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base;
    if (type->tp_dealloc == pybind11_object_type->tp_dealloc)
        Py_DECREF(type);
#else
    // This was not needed before Python 3.8 (Python issue 35810)
    // https://github.com/pybind/pybind11/issues/1946
    Py_DECREF(type);
#endif
}

std::string error_string();

/** Create the type which can be used as a common base for all classes.  This is
    needed in order to satisfy Python's requirements for multiple inheritance.
    Return value: New reference. */
inline PyObject *make_object_base_type(PyTypeObject *metaclass) {
    constexpr auto *name = "pybind11_object";
    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));

    /* Danger zone: from now (and until PyType_Ready), make sure to
       issue no Python C API calls which could potentially invoke the
       garbage collector (the GC will call type_traverse(), which will in
       turn find the newly constructed type in an invalid state) */
    auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);
    if (!heap_type) {
        pybind11_fail("make_object_base_type(): error allocating type!");
    }

    heap_type->ht_name = name_obj.inc_ref().ptr();
#ifdef PYBIND11_BUILTIN_QUALNAME
    heap_type->ht_qualname = name_obj.inc_ref().ptr();
#endif

    auto *type = &heap_type->ht_type;
    type->tp_name = name;
    type->tp_base = type_incref(&PyBaseObject_Type);
    type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));
    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;

    type->tp_new = pybind11_object_new;
    type->tp_init = pybind11_object_init;
    type->tp_dealloc = pybind11_object_dealloc;

    /* Support weak references (needed for the keep_alive feature) */
    type->tp_weaklistoffset = offsetof(instance, weakrefs);

    if (PyType_Ready(type) < 0) {
        pybind11_fail("PyType_Ready failed in make_object_base_type(): " + error_string());
    }

    setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);

    assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));
    return (PyObject *) heap_type;
}

/// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`.
extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) {
#if PY_VERSION_HEX >= 0x030D0000
    PyObject_VisitManagedDict(self, visit, arg);
#else
    PyObject *&dict = *_PyObject_GetDictPtr(self);
    Py_VISIT(dict);
#endif
// https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_traverse
#if PY_VERSION_HEX >= 0x03090000
    Py_VISIT(Py_TYPE(self));
#endif
    return 0;
}

/// dynamic_attr: Allow the GC to clear the dictionary.
extern "C" inline int pybind11_clear(PyObject *self) {
#if PY_VERSION_HEX >= 0x030D0000
    PyObject_ClearManagedDict(self);
#else
    PyObject *&dict = *_PyObject_GetDictPtr(self);
    Py_CLEAR(dict);
#endif
    return 0;
}

/// Give instances of this type a `__dict__` and opt into garbage collection.
inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
    auto *type = &heap_type->ht_type;
    type->tp_flags |= Py_TPFLAGS_HAVE_GC;
#if PY_VERSION_HEX < 0x030B0000
    type->tp_dictoffset = type->tp_basicsize;           // place dict at the end
    type->tp_basicsize += (ssize_t) sizeof(PyObject *); // and allocate enough space for it
#else
    type->tp_flags |= Py_TPFLAGS_MANAGED_DICT;
#endif
    type->tp_traverse = pybind11_traverse;
    type->tp_clear = pybind11_clear;

    static PyGetSetDef getset[]
        = {{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, nullptr, nullptr},
           {nullptr, nullptr, nullptr, nullptr, nullptr}};
    type->tp_getset = getset;
}

/// buffer_protocol: Fill in the view as specified by flags.
extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) {
    // Look for a `get_buffer` implementation in this type's info or any bases (following MRO).
    type_info *tinfo = nullptr;
    for (auto type : reinterpret_borrow<tuple>(Py_TYPE(obj)->tp_mro)) {
        tinfo = get_type_info((PyTypeObject *) type.ptr());
        if (tinfo && tinfo->get_buffer) {
            break;
        }
    }
    if (view == nullptr || !tinfo || !tinfo->get_buffer) {
        if (view) {
            view->obj = nullptr;
        }
        set_error(PyExc_BufferError, "pybind11_getbuffer(): Internal error");
        return -1;
    }
    std::memset(view, 0, sizeof(Py_buffer));
    buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data);
    if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE && info->readonly) {
        delete info;
        // view->obj = nullptr;  // Was just memset to 0, so not necessary
        set_error(PyExc_BufferError, "Writable buffer requested for readonly storage");
        return -1;
    }
    view->obj = obj;
    view->ndim = 1;
    view->internal = info;
    view->buf = info->ptr;
    view->itemsize = info->itemsize;
    view->len = view->itemsize;
    for (auto s : info->shape) {
        view->len *= s;
    }
    view->readonly = static_cast<int>(info->readonly);
    if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
        view->format = const_cast<char *>(info->format.c_str());
    }
    if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
        view->ndim = (int) info->ndim;
        view->strides = info->strides.data();
        view->shape = info->shape.data();
    }
    Py_INCREF(view->obj);
    return 0;
}

/// buffer_protocol: Release the resources of the buffer.
extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) {
    delete (buffer_info *) view->internal;
}

/// Give this type a buffer interface.
inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) {
    heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer;

    heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer;
    heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer;
}

/** Create a brand new Python type according to the `type_record` specification.
    Return value: New reference. */
inline PyObject *make_new_python_type(const type_record &rec) {
    auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING(rec.name));

    auto qualname = name;
    if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, "__qualname__")) {
        qualname = reinterpret_steal<object>(
            PyUnicode_FromFormat("%U.%U", rec.scope.attr("__qualname__").ptr(), name.ptr()));
    }

    object module_;
    if (rec.scope) {
        if (hasattr(rec.scope, "__module__")) {
            module_ = rec.scope.attr("__module__");
        } else if (hasattr(rec.scope, "__name__")) {
            module_ = rec.scope.attr("__name__");
        }
    }

    const auto *full_name = c_str(
#if !defined(PYPY_VERSION)
        module_ ? str(module_).cast<std::string>() + "." + rec.name :
#endif
                rec.name);

    char *tp_doc = nullptr;
    if (rec.doc && options::show_user_defined_docstrings()) {
        /* Allocate memory for docstring (Python will free this later on) */
        size_t size = std::strlen(rec.doc) + 1;
#if PY_VERSION_HEX >= 0x030D0000
        tp_doc = (char *) PyMem_MALLOC(size);
#else
        tp_doc = (char *) PyObject_MALLOC(size);
#endif
        std::memcpy((void *) tp_doc, rec.doc, size);
    }

    auto &internals = get_internals();
    auto bases = tuple(rec.bases);
    auto *base = (bases.empty()) ? internals.instance_base : bases[0].ptr();

    /* Danger zone: from now (and until PyType_Ready), make sure to
       issue no Python C API calls which could potentially invoke the
       garbage collector (the GC will call type_traverse(), which will in
       turn find the newly constructed type in an invalid state) */
    auto *metaclass
        = rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr() : internals.default_metaclass;

    auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);
    if (!heap_type) {
        pybind11_fail(std::string(rec.name) + ": Unable to create type object!");
    }

    heap_type->ht_name = name.release().ptr();
#ifdef PYBIND11_BUILTIN_QUALNAME
    heap_type->ht_qualname = qualname.inc_ref().ptr();
#endif

    auto *type = &heap_type->ht_type;
    type->tp_name = full_name;
    type->tp_doc = tp_doc;
    type->tp_base = type_incref((PyTypeObject *) base);
    type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));
    if (!bases.empty()) {
        type->tp_bases = bases.release().ptr();
    }

    /* Don't inherit base __init__ */
    type->tp_init = pybind11_object_init;

    /* Supported protocols */
    type->tp_as_number = &heap_type->as_number;
    type->tp_as_sequence = &heap_type->as_sequence;
    type->tp_as_mapping = &heap_type->as_mapping;
    type->tp_as_async = &heap_type->as_async;

    /* Flags */
    type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
    if (!rec.is_final) {
        type->tp_flags |= Py_TPFLAGS_BASETYPE;
    }

    if (rec.dynamic_attr) {
        enable_dynamic_attributes(heap_type);
    }

    if (rec.buffer_protocol) {
        enable_buffer_protocol(heap_type);
    }

    if (rec.custom_type_setup_callback) {
        rec.custom_type_setup_callback(heap_type);
    }

    if (PyType_Ready(type) < 0) {
        pybind11_fail(std::string(rec.name) + ": PyType_Ready failed: " + error_string());
    }

    assert(!rec.dynamic_attr || PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));

    /* Register type with the parent scope */
    if (rec.scope) {
        setattr(rec.scope, rec.name, (PyObject *) type);
    } else {
        Py_INCREF(type); // Keep it alive forever (reference leak)
    }

    if (module_) { // Needed by pydoc
        setattr((PyObject *) type, "__module__", module_);
    }

    PYBIND11_SET_OLDPY_QUALNAME(type, qualname);

    return (PyObject *) type;
}

PYBIND11_NAMESPACE_END(detail)
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)