Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-27 09:46:18

0001 /*
0002     pybind11/attr.h: Infrastructure for processing custom
0003     type and function attributes
0004 
0005     Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
0006 
0007     All rights reserved. Use of this source code is governed by a
0008     BSD-style license that can be found in the LICENSE file.
0009 */
0010 
0011 #pragma once
0012 
0013 #include "detail/common.h"
0014 #include "cast.h"
0015 #include "trampoline_self_life_support.h"
0016 
0017 #include <functional>
0018 
0019 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0020 
0021 /// \addtogroup annotations
0022 /// @{
0023 
0024 /// Annotation for methods
0025 struct is_method {
0026     handle class_;
0027     explicit is_method(const handle &c) : class_(c) {}
0028 };
0029 
0030 /// Annotation for setters
0031 struct is_setter {};
0032 
0033 /// Annotation for operators
0034 struct is_operator {};
0035 
0036 /// Annotation for classes that cannot be subclassed
0037 struct is_final {};
0038 
0039 /// Annotation for parent scope
0040 struct scope {
0041     handle value;
0042     explicit scope(const handle &s) : value(s) {}
0043 };
0044 
0045 /// Annotation for documentation
0046 struct doc {
0047     const char *value;
0048     explicit doc(const char *value) : value(value) {}
0049 };
0050 
0051 /// Annotation for function names
0052 struct name {
0053     const char *value;
0054     explicit name(const char *value) : value(value) {}
0055 };
0056 
0057 /// Annotation indicating that a function is an overload associated with a given "sibling"
0058 struct sibling {
0059     handle value;
0060     explicit sibling(const handle &value) : value(value.ptr()) {}
0061 };
0062 
0063 /// Annotation indicating that a class derives from another given type
0064 template <typename T>
0065 struct base {
0066 
0067     PYBIND11_DEPRECATED(
0068         "base<T>() was deprecated in favor of specifying 'T' as a template argument to class_")
0069     base() = default;
0070 };
0071 
0072 /// Keep patient alive while nurse lives
0073 template <size_t Nurse, size_t Patient>
0074 struct keep_alive {};
0075 
0076 /// Annotation indicating that a class is involved in a multiple inheritance relationship
0077 struct multiple_inheritance {};
0078 
0079 /// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class
0080 struct dynamic_attr {};
0081 
0082 /// Annotation which enables the buffer protocol for a type
0083 struct buffer_protocol {};
0084 
0085 /// Annotation which enables releasing the GIL before calling the C++ destructor of wrapped
0086 /// instances (pybind/pybind11#1446).
0087 struct release_gil_before_calling_cpp_dtor {};
0088 
0089 /// Annotation which requests that a special metaclass is created for a type
0090 struct metaclass {
0091     handle value;
0092 
0093     PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.")
0094     metaclass() = default;
0095 
0096     /// Override pybind11's default metaclass
0097     explicit metaclass(handle value) : value(value) {}
0098 };
0099 
0100 /// Specifies a custom callback with signature `void (PyHeapTypeObject*)` that
0101 /// may be used to customize the Python type.
0102 ///
0103 /// The callback is invoked immediately before `PyType_Ready`.
0104 ///
0105 /// Note: This is an advanced interface, and uses of it may require changes to
0106 /// work with later versions of pybind11.  You may wish to consult the
0107 /// implementation of `make_new_python_type` in `detail/classes.h` to understand
0108 /// the context in which the callback will be run.
0109 struct custom_type_setup {
0110     using callback = std::function<void(PyHeapTypeObject *heap_type)>;
0111 
0112     explicit custom_type_setup(callback value) : value(std::move(value)) {}
0113 
0114     callback value;
0115 };
0116 
0117 /// Annotation that marks a class as local to the module:
0118 struct module_local {
0119     const bool value;
0120     constexpr explicit module_local(bool v = true) : value(v) {}
0121 };
0122 
0123 /// Annotation to mark enums as an arithmetic type
0124 struct arithmetic {};
0125 
0126 /// Mark a function for addition at the beginning of the existing overload chain instead of the end
0127 struct prepend {};
0128 
0129 /** \rst
0130     A call policy which places one or more guard variables (``Ts...``) around the function call.
0131 
0132     For example, this definition:
0133 
0134     .. code-block:: cpp
0135 
0136         m.def("foo", foo, py::call_guard<T>());
0137 
0138     is equivalent to the following pseudocode:
0139 
0140     .. code-block:: cpp
0141 
0142         m.def("foo", [](args...) {
0143             T scope_guard;
0144             return foo(args...); // forwarded arguments
0145         });
0146  \endrst */
0147 template <typename... Ts>
0148 struct call_guard;
0149 
0150 template <>
0151 struct call_guard<> {
0152     using type = detail::void_type;
0153 };
0154 
0155 template <typename T>
0156 struct call_guard<T> {
0157     static_assert(std::is_default_constructible<T>::value,
0158                   "The guard type must be default constructible");
0159 
0160     using type = T;
0161 };
0162 
0163 template <typename T, typename... Ts>
0164 struct call_guard<T, Ts...> {
0165     struct type {
0166         T guard{}; // Compose multiple guard types with left-to-right default-constructor order
0167         typename call_guard<Ts...>::type next{};
0168     };
0169 };
0170 
0171 /// @} annotations
0172 
0173 PYBIND11_NAMESPACE_BEGIN(detail)
0174 /* Forward declarations */
0175 enum op_id : int;
0176 enum op_type : int;
0177 struct undefined_t;
0178 template <op_id id, op_type ot, typename L = undefined_t, typename R = undefined_t>
0179 struct op_;
0180 void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret);
0181 
0182 /// Internal data structure which holds metadata about a keyword argument
0183 struct argument_record {
0184     const char *name;  ///< Argument name
0185     const char *descr; ///< Human-readable version of the argument value
0186     handle value;      ///< Associated Python object
0187     bool convert : 1;  ///< True if the argument is allowed to convert when loading
0188     bool none : 1;     ///< True if None is allowed when loading
0189 
0190     argument_record(const char *name, const char *descr, handle value, bool convert, bool none)
0191         : name(name), descr(descr), value(value), convert(convert), none(none) {}
0192 };
0193 
0194 /// Internal data structure which holds metadata about a bound function (signature, overloads,
0195 /// etc.)
0196 #define PYBIND11_DETAIL_FUNCTION_RECORD_ABI_ID "v1" // PLEASE UPDATE if the struct is changed.
0197 struct function_record {
0198     function_record()
0199         : is_constructor(false), is_new_style_constructor(false), is_stateless(false),
0200           is_operator(false), is_method(false), is_setter(false), has_args(false),
0201           has_kwargs(false), prepend(false) {}
0202 
0203     /// Function name
0204     char *name = nullptr; /* why no C++ strings? They generate heavier code.. */
0205 
0206     // User-specified documentation string
0207     char *doc = nullptr;
0208 
0209     /// Human-readable version of the function signature
0210     char *signature = nullptr;
0211 
0212     /// List of registered keyword arguments
0213     std::vector<argument_record> args;
0214 
0215     /// Pointer to lambda function which converts arguments and performs the actual call
0216     handle (*impl)(function_call &) = nullptr;
0217 
0218     /// Storage for the wrapped function pointer and captured data, if any
0219     void *data[3] = {};
0220 
0221     /// Pointer to custom destructor for 'data' (if needed)
0222     void (*free_data)(function_record *ptr) = nullptr;
0223 
0224     /// Return value policy associated with this function
0225     return_value_policy policy = return_value_policy::automatic;
0226 
0227     /// True if name == '__init__'
0228     bool is_constructor : 1;
0229 
0230     /// True if this is a new-style `__init__` defined in `detail/init.h`
0231     bool is_new_style_constructor : 1;
0232 
0233     /// True if this is a stateless function pointer
0234     bool is_stateless : 1;
0235 
0236     /// True if this is an operator (__add__), etc.
0237     bool is_operator : 1;
0238 
0239     /// True if this is a method
0240     bool is_method : 1;
0241 
0242     /// True if this is a setter
0243     bool is_setter : 1;
0244 
0245     /// True if the function has a '*args' argument
0246     bool has_args : 1;
0247 
0248     /// True if the function has a '**kwargs' argument
0249     bool has_kwargs : 1;
0250 
0251     /// True if this function is to be inserted at the beginning of the overload resolution chain
0252     bool prepend : 1;
0253 
0254     /// Number of arguments (including py::args and/or py::kwargs, if present)
0255     std::uint16_t nargs;
0256 
0257     /// Number of leading positional arguments, which are terminated by a py::args or py::kwargs
0258     /// argument or by a py::kw_only annotation.
0259     std::uint16_t nargs_pos = 0;
0260 
0261     /// Number of leading arguments (counted in `nargs`) that are positional-only
0262     std::uint16_t nargs_pos_only = 0;
0263 
0264     /// Python method object
0265     PyMethodDef *def = nullptr;
0266 
0267     /// Python handle to the parent scope (a class or a module)
0268     handle scope;
0269 
0270     /// Python handle to the sibling function representing an overload chain
0271     handle sibling;
0272 
0273     /// Pointer to next overload
0274     function_record *next = nullptr;
0275 };
0276 // The main purpose of this macro is to make it easy to pin-point the critically related code
0277 // sections.
0278 #define PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS(...)              \
0279     static_assert(                                                                                \
0280         __VA_ARGS__,                                                                              \
0281         "Violation of precondition for pybind11/functional.h performance optimizations!")
0282 
0283 /// Special data structure which (temporarily) holds metadata about a bound class
0284 struct type_record {
0285     PYBIND11_NOINLINE type_record()
0286         : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false),
0287           module_local(false), is_final(false), release_gil_before_calling_cpp_dtor(false) {}
0288 
0289     /// Handle to the parent scope
0290     handle scope;
0291 
0292     /// Name of the class
0293     const char *name = nullptr;
0294 
0295     // Pointer to RTTI type_info data structure
0296     const std::type_info *type = nullptr;
0297 
0298     /// How large is the underlying C++ type?
0299     size_t type_size = 0;
0300 
0301     /// What is the alignment of the underlying C++ type?
0302     size_t type_align = 0;
0303 
0304     /// How large is the type's holder?
0305     size_t holder_size = 0;
0306 
0307     /// The global operator new can be overridden with a class-specific variant
0308     void *(*operator_new)(size_t) = nullptr;
0309 
0310     /// Function pointer to class_<..>::init_instance
0311     void (*init_instance)(instance *, const void *) = nullptr;
0312 
0313     /// Function pointer to class_<..>::dealloc
0314     void (*dealloc)(detail::value_and_holder &) = nullptr;
0315 
0316     /// Function pointer for casting alias class (aka trampoline) pointer to
0317     /// trampoline_self_life_support pointer. Sidesteps cross-DSO RTTI issues
0318     /// on platforms like macOS (see PR #5728 for details).
0319     get_trampoline_self_life_support_fn get_trampoline_self_life_support
0320         = [](void *) -> trampoline_self_life_support * { return nullptr; };
0321 
0322     /// List of base classes of the newly created type
0323     list bases;
0324 
0325     /// Optional docstring
0326     const char *doc = nullptr;
0327 
0328     /// Custom metaclass (optional)
0329     handle metaclass;
0330 
0331     /// Custom type setup.
0332     custom_type_setup::callback custom_type_setup_callback;
0333 
0334     /// Multiple inheritance marker
0335     bool multiple_inheritance : 1;
0336 
0337     /// Does the class manage a __dict__?
0338     bool dynamic_attr : 1;
0339 
0340     /// Does the class implement the buffer protocol?
0341     bool buffer_protocol : 1;
0342 
0343     /// Is the class definition local to the module shared object?
0344     bool module_local : 1;
0345 
0346     /// Is the class inheritable from python classes?
0347     bool is_final : 1;
0348 
0349     /// Solves pybind/pybind11#1446
0350     bool release_gil_before_calling_cpp_dtor : 1;
0351 
0352     holder_enum_t holder_enum_v = holder_enum_t::undefined;
0353 
0354     PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) {
0355         auto *base_info = detail::get_type_info(base, false);
0356         if (!base_info) {
0357             std::string tname(base.name());
0358             detail::clean_type_id(tname);
0359             pybind11_fail("generic_type: type \"" + std::string(name)
0360                           + "\" referenced unknown base type \"" + tname + "\"");
0361         }
0362 
0363         // SMART_HOLDER_BAKEIN_FOLLOW_ON: Refine holder compatibility checks.
0364         bool this_has_unique_ptr_holder = (holder_enum_v == holder_enum_t::std_unique_ptr);
0365         bool base_has_unique_ptr_holder
0366             = (base_info->holder_enum_v == holder_enum_t::std_unique_ptr);
0367         if (this_has_unique_ptr_holder != base_has_unique_ptr_holder) {
0368             std::string tname(base.name());
0369             detail::clean_type_id(tname);
0370             pybind11_fail("generic_type: type \"" + std::string(name) + "\" "
0371                           + (this_has_unique_ptr_holder ? "does not have" : "has")
0372                           + " a non-default holder type while its base \"" + tname + "\" "
0373                           + (base_has_unique_ptr_holder ? "does not" : "does"));
0374         }
0375 
0376         bases.append(reinterpret_cast<PyObject *>(base_info->type));
0377 
0378 #ifdef PYBIND11_BACKWARD_COMPATIBILITY_TP_DICTOFFSET
0379         dynamic_attr |= base_info->type->tp_dictoffset != 0;
0380 #else
0381         dynamic_attr |= (base_info->type->tp_flags & Py_TPFLAGS_MANAGED_DICT) != 0;
0382 #endif
0383 
0384         if (caster) {
0385             base_info->implicit_casts.emplace_back(type, caster);
0386         }
0387     }
0388 };
0389 
0390 inline function_call::function_call(const function_record &f, handle p) : func(f), parent(p) {
0391     args.reserve(f.nargs);
0392     args_convert.reserve(f.nargs);
0393 }
0394 
0395 /// Tag for a new-style `__init__` defined in `detail/init.h`
0396 struct is_new_style_constructor {};
0397 
0398 /**
0399  * Partial template specializations to process custom attributes provided to
0400  * cpp_function_ and class_. These are either used to initialize the respective
0401  * fields in the type_record and function_record data structures or executed at
0402  * runtime to deal with custom call policies (e.g. keep_alive).
0403  */
0404 template <typename T, typename SFINAE = void>
0405 struct process_attribute;
0406 
0407 template <typename T>
0408 struct process_attribute_default {
0409     /// Default implementation: do nothing
0410     static void init(const T &, function_record *) {}
0411     static void init(const T &, type_record *) {}
0412     static void precall(function_call &) {}
0413     static void postcall(function_call &, handle) {}
0414 };
0415 
0416 /// Process an attribute specifying the function's name
0417 template <>
0418 struct process_attribute<name> : process_attribute_default<name> {
0419     static void init(const name &n, function_record *r) { r->name = const_cast<char *>(n.value); }
0420 };
0421 
0422 /// Process an attribute specifying the function's docstring
0423 template <>
0424 struct process_attribute<doc> : process_attribute_default<doc> {
0425     static void init(const doc &n, function_record *r) { r->doc = const_cast<char *>(n.value); }
0426 };
0427 
0428 /// Process an attribute specifying the function's docstring (provided as a C-style string)
0429 template <>
0430 struct process_attribute<const char *> : process_attribute_default<const char *> {
0431     static void init(const char *d, function_record *r) { r->doc = const_cast<char *>(d); }
0432     static void init(const char *d, type_record *r) { r->doc = d; }
0433 };
0434 template <>
0435 struct process_attribute<char *> : process_attribute<const char *> {};
0436 
0437 /// Process an attribute indicating the function's return value policy
0438 template <>
0439 struct process_attribute<return_value_policy> : process_attribute_default<return_value_policy> {
0440     static void init(const return_value_policy &p, function_record *r) { r->policy = p; }
0441 };
0442 
0443 /// Process an attribute which indicates that this is an overloaded function associated with a
0444 /// given sibling
0445 template <>
0446 struct process_attribute<sibling> : process_attribute_default<sibling> {
0447     static void init(const sibling &s, function_record *r) { r->sibling = s.value; }
0448 };
0449 
0450 /// Process an attribute which indicates that this function is a method
0451 template <>
0452 struct process_attribute<is_method> : process_attribute_default<is_method> {
0453     static void init(const is_method &s, function_record *r) {
0454         r->is_method = true;
0455         r->scope = s.class_;
0456     }
0457 };
0458 
0459 /// Process an attribute which indicates that this function is a setter
0460 template <>
0461 struct process_attribute<is_setter> : process_attribute_default<is_setter> {
0462     static void init(const is_setter &, function_record *r) { r->is_setter = true; }
0463 };
0464 
0465 /// Process an attribute which indicates the parent scope of a method
0466 template <>
0467 struct process_attribute<scope> : process_attribute_default<scope> {
0468     static void init(const scope &s, function_record *r) { r->scope = s.value; }
0469 };
0470 
0471 /// Process an attribute which indicates that this function is an operator
0472 template <>
0473 struct process_attribute<is_operator> : process_attribute_default<is_operator> {
0474     static void init(const is_operator &, function_record *r) { r->is_operator = true; }
0475 };
0476 
0477 template <>
0478 struct process_attribute<is_new_style_constructor>
0479     : process_attribute_default<is_new_style_constructor> {
0480     static void init(const is_new_style_constructor &, function_record *r) {
0481         r->is_new_style_constructor = true;
0482     }
0483 };
0484 
0485 inline void check_kw_only_arg(const arg &a, function_record *r) {
0486     if (r->args.size() > r->nargs_pos && (!a.name || a.name[0] == '\0')) {
0487         pybind11_fail("arg(): cannot specify an unnamed argument after a kw_only() annotation or "
0488                       "args() argument");
0489     }
0490 }
0491 
0492 inline void append_self_arg_if_needed(function_record *r) {
0493     if (r->is_method && r->args.empty()) {
0494         r->args.emplace_back("self", nullptr, handle(), /*convert=*/true, /*none=*/false);
0495     }
0496 }
0497 
0498 /// Process a keyword argument attribute (*without* a default value)
0499 template <>
0500 struct process_attribute<arg> : process_attribute_default<arg> {
0501     static void init(const arg &a, function_record *r) {
0502         append_self_arg_if_needed(r);
0503         r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none);
0504 
0505         check_kw_only_arg(a, r);
0506     }
0507 };
0508 
0509 /// Process a keyword argument attribute (*with* a default value)
0510 template <>
0511 struct process_attribute<arg_v> : process_attribute_default<arg_v> {
0512     static void init(const arg_v &a, function_record *r) {
0513         if (r->is_method && r->args.empty()) {
0514             r->args.emplace_back(
0515                 "self", /*descr=*/nullptr, /*parent=*/handle(), /*convert=*/true, /*none=*/false);
0516         }
0517 
0518         if (!a.value) {
0519 #if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
0520             std::string descr("'");
0521             if (a.name) {
0522                 descr += std::string(a.name) + ": ";
0523             }
0524             descr += a.type + "'";
0525             if (r->is_method) {
0526                 if (r->name) {
0527                     descr += " in method '" + (std::string) str(r->scope) + "."
0528                              + (std::string) r->name + "'";
0529                 } else {
0530                     descr += " in method of '" + (std::string) str(r->scope) + "'";
0531                 }
0532             } else if (r->name) {
0533                 descr += " in function '" + (std::string) r->name + "'";
0534             }
0535             pybind11_fail("arg(): could not convert default argument " + descr
0536                           + " into a Python object (type not registered yet?)");
0537 #else
0538             pybind11_fail("arg(): could not convert default argument "
0539                           "into a Python object (type not registered yet?). "
0540                           "#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
0541                           "more information.");
0542 #endif
0543         }
0544         r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none);
0545 
0546         check_kw_only_arg(a, r);
0547     }
0548 };
0549 
0550 /// Process a keyword-only-arguments-follow pseudo argument
0551 template <>
0552 struct process_attribute<kw_only> : process_attribute_default<kw_only> {
0553     static void init(const kw_only &, function_record *r) {
0554         append_self_arg_if_needed(r);
0555         if (r->has_args && r->nargs_pos != static_cast<std::uint16_t>(r->args.size())) {
0556             pybind11_fail("Mismatched args() and kw_only(): they must occur at the same relative "
0557                           "argument location (or omit kw_only() entirely)");
0558         }
0559         r->nargs_pos = static_cast<std::uint16_t>(r->args.size());
0560     }
0561 };
0562 
0563 /// Process a positional-only-argument maker
0564 template <>
0565 struct process_attribute<pos_only> : process_attribute_default<pos_only> {
0566     static void init(const pos_only &, function_record *r) {
0567         append_self_arg_if_needed(r);
0568         r->nargs_pos_only = static_cast<std::uint16_t>(r->args.size());
0569         if (r->nargs_pos_only > r->nargs_pos) {
0570             pybind11_fail("pos_only(): cannot follow a py::args() argument");
0571         }
0572         // It also can't follow a kw_only, but a static_assert in pybind11.h checks that
0573     }
0574 };
0575 
0576 /// Process a parent class attribute.  Single inheritance only (class_ itself already guarantees
0577 /// that)
0578 template <typename T>
0579 struct process_attribute<T, enable_if_t<is_pyobject<T>::value>>
0580     : process_attribute_default<handle> {
0581     static void init(const handle &h, type_record *r) { r->bases.append(h); }
0582 };
0583 
0584 /// Process a parent class attribute (deprecated, does not support multiple inheritance)
0585 template <typename T>
0586 struct process_attribute<base<T>> : process_attribute_default<base<T>> {
0587     static void init(const base<T> &, type_record *r) { r->add_base(typeid(T), nullptr); }
0588 };
0589 
0590 /// Process a multiple inheritance attribute
0591 template <>
0592 struct process_attribute<multiple_inheritance> : process_attribute_default<multiple_inheritance> {
0593     static void init(const multiple_inheritance &, type_record *r) {
0594         r->multiple_inheritance = true;
0595     }
0596 };
0597 
0598 template <>
0599 struct process_attribute<dynamic_attr> : process_attribute_default<dynamic_attr> {
0600     static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; }
0601 };
0602 
0603 template <>
0604 struct process_attribute<custom_type_setup> {
0605     static void init(const custom_type_setup &value, type_record *r) {
0606         r->custom_type_setup_callback = value.value;
0607     }
0608 };
0609 
0610 template <>
0611 struct process_attribute<is_final> : process_attribute_default<is_final> {
0612     static void init(const is_final &, type_record *r) { r->is_final = true; }
0613 };
0614 
0615 template <>
0616 struct process_attribute<buffer_protocol> : process_attribute_default<buffer_protocol> {
0617     static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; }
0618 };
0619 
0620 template <>
0621 struct process_attribute<metaclass> : process_attribute_default<metaclass> {
0622     static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; }
0623 };
0624 
0625 template <>
0626 struct process_attribute<module_local> : process_attribute_default<module_local> {
0627     static void init(const module_local &l, type_record *r) { r->module_local = l.value; }
0628 };
0629 
0630 template <>
0631 struct process_attribute<release_gil_before_calling_cpp_dtor>
0632     : process_attribute_default<release_gil_before_calling_cpp_dtor> {
0633     static void init(const release_gil_before_calling_cpp_dtor &, type_record *r) {
0634         r->release_gil_before_calling_cpp_dtor = true;
0635     }
0636 };
0637 
0638 /// Process a 'prepend' attribute, putting this at the beginning of the overload chain
0639 template <>
0640 struct process_attribute<prepend> : process_attribute_default<prepend> {
0641     static void init(const prepend &, function_record *r) { r->prepend = true; }
0642 };
0643 
0644 /// Process an 'arithmetic' attribute for enums (does nothing here)
0645 template <>
0646 struct process_attribute<arithmetic> : process_attribute_default<arithmetic> {};
0647 
0648 template <typename... Ts>
0649 struct process_attribute<call_guard<Ts...>> : process_attribute_default<call_guard<Ts...>> {};
0650 
0651 /**
0652  * Process a keep_alive call policy -- invokes keep_alive_impl during the
0653  * pre-call handler if both Nurse, Patient != 0 and use the post-call handler
0654  * otherwise
0655  */
0656 template <size_t Nurse, size_t Patient>
0657 struct process_attribute<keep_alive<Nurse, Patient>>
0658     : public process_attribute_default<keep_alive<Nurse, Patient>> {
0659     template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
0660     static void precall(function_call &call) {
0661         keep_alive_impl(Nurse, Patient, call, handle());
0662     }
0663     template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
0664     static void postcall(function_call &, handle) {}
0665     template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
0666     static void precall(function_call &) {}
0667     template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
0668     static void postcall(function_call &call, handle ret) {
0669         keep_alive_impl(Nurse, Patient, call, ret);
0670     }
0671 };
0672 
0673 /// Recursively iterate over variadic template arguments
0674 template <typename... Args>
0675 struct process_attributes {
0676     static void init(const Args &...args, function_record *r) {
0677         PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);
0678         PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);
0679         using expander = int[];
0680         (void) expander{
0681             0, ((void) process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};
0682     }
0683     static void init(const Args &...args, type_record *r) {
0684         PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);
0685         PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);
0686         using expander = int[];
0687         (void) expander{0,
0688                         (process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};
0689     }
0690     static void precall(function_call &call) {
0691         PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call);
0692         using expander = int[];
0693         (void) expander{0,
0694                         (process_attribute<typename std::decay<Args>::type>::precall(call), 0)...};
0695     }
0696     static void postcall(function_call &call, handle fn_ret) {
0697         PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call, fn_ret);
0698         PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(fn_ret);
0699         using expander = int[];
0700         (void) expander{
0701             0, (process_attribute<typename std::decay<Args>::type>::postcall(call, fn_ret), 0)...};
0702     }
0703 };
0704 
0705 template <typename T>
0706 struct is_keep_alive : std::false_type {};
0707 
0708 template <size_t Nurse, size_t Patient>
0709 struct is_keep_alive<keep_alive<Nurse, Patient>> : std::true_type {};
0710 
0711 template <typename T>
0712 using is_call_guard = is_instantiation<call_guard, T>;
0713 
0714 /// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found)
0715 template <typename... Extra>
0716 using extract_guard_t = typename exactly_one_t<is_call_guard, call_guard<>, Extra...>::type;
0717 
0718 /// Check the number of named arguments at compile time
0719 template <typename... Extra,
0720           size_t named = constexpr_sum(std::is_base_of<arg, Extra>::value...),
0721           size_t self = constexpr_sum(std::is_same<is_method, Extra>::value...)>
0722 constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) {
0723     PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(nargs, has_args, has_kwargs);
0724     return named == 0
0725            || (self + named + static_cast<size_t>(has_args) + static_cast<size_t>(has_kwargs))
0726                   == nargs;
0727 }
0728 
0729 PYBIND11_NAMESPACE_END(detail)
0730 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)