File indexing completed on 2025-01-18 10:06:12
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #pragma once
0011
0012 #include "common.h"
0013
0014 #if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
0015 # include <pybind11/gil.h>
0016 #endif
0017
0018 #include <pybind11/pytypes.h>
0019
0020 #include <exception>
0021 #include <mutex>
0022 #include <thread>
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #ifndef PYBIND11_INTERNALS_VERSION
0039 # if PY_VERSION_HEX >= 0x030C0000 || defined(_MSC_VER)
0040
0041
0042 # define PYBIND11_INTERNALS_VERSION 5
0043 # else
0044 # define PYBIND11_INTERNALS_VERSION 4
0045 # endif
0046 #endif
0047
0048
0049 static_assert(PY_VERSION_HEX < 0x030C0000 || PYBIND11_INTERNALS_VERSION >= 5,
0050 "pybind11 ABI version 5 is the minimum for Python 3.12+");
0051
0052 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0053
0054 using ExceptionTranslator = void (*)(std::exception_ptr);
0055
0056 PYBIND11_NAMESPACE_BEGIN(detail)
0057
0058 constexpr const char *internals_function_record_capsule_name = "pybind11_function_record_capsule";
0059
0060
0061 inline PyTypeObject *make_static_property_type();
0062 inline PyTypeObject *make_default_metaclass();
0063 inline PyObject *make_object_base_type(PyTypeObject *metaclass);
0064
0065
0066
0067
0068
0069 #if PYBIND11_INTERNALS_VERSION > 4
0070 # define PYBIND11_TLS_KEY_REF Py_tss_t &
0071 # if defined(__clang__)
0072 # define PYBIND11_TLS_KEY_INIT(var) \
0073 _Pragma("clang diagnostic push") \
0074 _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") \
0075 Py_tss_t var \
0076 = Py_tss_NEEDS_INIT; \
0077 _Pragma("clang diagnostic pop")
0078 # elif defined(__GNUC__) && !defined(__INTEL_COMPILER)
0079 # define PYBIND11_TLS_KEY_INIT(var) \
0080 _Pragma("GCC diagnostic push") \
0081 _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") \
0082 Py_tss_t var \
0083 = Py_tss_NEEDS_INIT; \
0084 _Pragma("GCC diagnostic pop")
0085 # else
0086 # define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;
0087 # endif
0088 # define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)
0089 # define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))
0090 # define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))
0091 # define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)
0092 # define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))
0093 #else
0094 # define PYBIND11_TLS_KEY_REF Py_tss_t *
0095 # define PYBIND11_TLS_KEY_INIT(var) Py_tss_t *var = nullptr;
0096 # define PYBIND11_TLS_KEY_CREATE(var) \
0097 (((var) = PyThread_tss_alloc()) != nullptr && (PyThread_tss_create((var)) == 0))
0098 # define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get((key))
0099 # define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set((key), (value))
0100 # define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set((key), nullptr)
0101 # define PYBIND11_TLS_FREE(key) PyThread_tss_free(key)
0102 #endif
0103
0104
0105
0106
0107
0108
0109
0110 #if (PYBIND11_INTERNALS_VERSION <= 4 && defined(__GLIBCXX__)) \
0111 || (PYBIND11_INTERNALS_VERSION >= 5 && !defined(_LIBCPP_VERSION))
0112 inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; }
0113 using type_hash = std::hash<std::type_index>;
0114 using type_equal_to = std::equal_to<std::type_index>;
0115 #else
0116 inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) {
0117 return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
0118 }
0119
0120 struct type_hash {
0121 size_t operator()(const std::type_index &t) const {
0122 size_t hash = 5381;
0123 const char *ptr = t.name();
0124 while (auto c = static_cast<unsigned char>(*ptr++)) {
0125 hash = (hash * 33) ^ c;
0126 }
0127 return hash;
0128 }
0129 };
0130
0131 struct type_equal_to {
0132 bool operator()(const std::type_index &lhs, const std::type_index &rhs) const {
0133 return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
0134 }
0135 };
0136 #endif
0137
0138 template <typename value_type>
0139 using type_map = std::unordered_map<std::type_index, value_type, type_hash, type_equal_to>;
0140
0141 struct override_hash {
0142 inline size_t operator()(const std::pair<const PyObject *, const char *> &v) const {
0143 size_t value = std::hash<const void *>()(v.first);
0144 value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value << 6) + (value >> 2);
0145 return value;
0146 }
0147 };
0148
0149 using instance_map = std::unordered_multimap<const void *, instance *>;
0150
0151 #ifdef Py_GIL_DISABLED
0152
0153 class pymutex {
0154 PyMutex mutex;
0155
0156 public:
0157 pymutex() : mutex({}) {}
0158 void lock() { PyMutex_Lock(&mutex); }
0159 void unlock() { PyMutex_Unlock(&mutex); }
0160 };
0161
0162
0163 struct instance_map_shard {
0164 instance_map registered_instances;
0165 pymutex mutex;
0166
0167 char padding[64 - (sizeof(instance_map) + sizeof(pymutex)) % 64];
0168 };
0169
0170 static_assert(sizeof(instance_map_shard) % 64 == 0,
0171 "instance_map_shard size is not a multiple of 64 bytes");
0172 #endif
0173
0174
0175
0176
0177 struct internals {
0178 #ifdef Py_GIL_DISABLED
0179 pymutex mutex;
0180 #endif
0181
0182 type_map<type_info *> registered_types_cpp;
0183
0184 std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py;
0185 #ifdef Py_GIL_DISABLED
0186 std::unique_ptr<instance_map_shard[]> instance_shards;
0187 size_t instance_shards_mask;
0188 #else
0189 instance_map registered_instances;
0190 #endif
0191 std::unordered_set<std::pair<const PyObject *, const char *>, override_hash>
0192 inactive_override_cache;
0193 type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
0194 std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;
0195 std::forward_list<ExceptionTranslator> registered_exception_translators;
0196 std::unordered_map<std::string, void *> shared_data;
0197
0198 #if PYBIND11_INTERNALS_VERSION == 4
0199 std::vector<PyObject *> unused_loader_patient_stack_remove_at_v5;
0200 #endif
0201 std::forward_list<std::string> static_strings;
0202
0203 PyTypeObject *static_property_type;
0204 PyTypeObject *default_metaclass;
0205 PyObject *instance_base;
0206
0207 PYBIND11_TLS_KEY_INIT(tstate)
0208 #if PYBIND11_INTERNALS_VERSION > 4
0209 PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
0210 #endif
0211
0212 PyInterpreterState *istate = nullptr;
0213
0214 #if PYBIND11_INTERNALS_VERSION > 4
0215
0216
0217 std::string function_record_capsule_name = internals_function_record_capsule_name;
0218 #endif
0219
0220 internals() = default;
0221 internals(const internals &other) = delete;
0222 internals &operator=(const internals &other) = delete;
0223 ~internals() {
0224 #if PYBIND11_INTERNALS_VERSION > 4
0225 PYBIND11_TLS_FREE(loader_life_support_tls_key);
0226 #endif
0227
0228
0229
0230
0231
0232
0233
0234
0235 PYBIND11_TLS_FREE(tstate);
0236 }
0237 };
0238
0239
0240
0241 struct type_info {
0242 PyTypeObject *type;
0243 const std::type_info *cpptype;
0244 size_t type_size, type_align, holder_size_in_ptrs;
0245 void *(*operator_new)(size_t);
0246 void (*init_instance)(instance *, const void *);
0247 void (*dealloc)(value_and_holder &v_h);
0248 std::vector<PyObject *(*) (PyObject *, PyTypeObject *)> implicit_conversions;
0249 std::vector<std::pair<const std::type_info *, void *(*) (void *)>> implicit_casts;
0250 std::vector<bool (*)(PyObject *, void *&)> *direct_conversions;
0251 buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;
0252 void *get_buffer_data = nullptr;
0253 void *(*module_local_load)(PyObject *, const type_info *) = nullptr;
0254
0255
0256
0257
0258 bool simple_type : 1;
0259
0260 bool simple_ancestors : 1;
0261
0262 bool default_holder : 1;
0263
0264 bool module_local : 1;
0265 };
0266
0267
0268 #if defined(_MSC_VER) && defined(_DEBUG)
0269 # define PYBIND11_BUILD_TYPE "_debug"
0270 #else
0271 # define PYBIND11_BUILD_TYPE ""
0272 #endif
0273
0274
0275
0276
0277 #ifndef PYBIND11_COMPILER_TYPE
0278 # if defined(_MSC_VER)
0279 # define PYBIND11_COMPILER_TYPE "_msvc"
0280 # elif defined(__INTEL_COMPILER)
0281 # define PYBIND11_COMPILER_TYPE "_icc"
0282 # elif defined(__clang__)
0283 # define PYBIND11_COMPILER_TYPE "_clang"
0284 # elif defined(__PGI)
0285 # define PYBIND11_COMPILER_TYPE "_pgi"
0286 # elif defined(__MINGW32__)
0287 # define PYBIND11_COMPILER_TYPE "_mingw"
0288 # elif defined(__CYGWIN__)
0289 # define PYBIND11_COMPILER_TYPE "_gcc_cygwin"
0290 # elif defined(__GNUC__)
0291 # define PYBIND11_COMPILER_TYPE "_gcc"
0292 # else
0293 # define PYBIND11_COMPILER_TYPE "_unknown"
0294 # endif
0295 #endif
0296
0297
0298 #ifndef PYBIND11_STDLIB
0299 # if defined(_LIBCPP_VERSION)
0300 # define PYBIND11_STDLIB "_libcpp"
0301 # elif defined(__GLIBCXX__) || defined(__GLIBCPP__)
0302 # define PYBIND11_STDLIB "_libstdcpp"
0303 # else
0304 # define PYBIND11_STDLIB ""
0305 # endif
0306 #endif
0307
0308
0309
0310 #ifndef PYBIND11_BUILD_ABI
0311 # if defined(__GXX_ABI_VERSION)
0312 # define PYBIND11_BUILD_ABI "_cxxabi" PYBIND11_TOSTRING(__GXX_ABI_VERSION)
0313 # elif defined(_MSC_VER)
0314 # define PYBIND11_BUILD_ABI "_mscver" PYBIND11_TOSTRING(_MSC_VER)
0315 # else
0316 # define PYBIND11_BUILD_ABI ""
0317 # endif
0318 #endif
0319
0320 #ifndef PYBIND11_INTERNALS_KIND
0321 # define PYBIND11_INTERNALS_KIND ""
0322 #endif
0323
0324 #define PYBIND11_INTERNALS_ID \
0325 "__pybind11_internals_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
0326 PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB \
0327 PYBIND11_BUILD_ABI PYBIND11_BUILD_TYPE "__"
0328
0329 #define PYBIND11_MODULE_LOCAL_ID \
0330 "__pybind11_module_local_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
0331 PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB \
0332 PYBIND11_BUILD_ABI PYBIND11_BUILD_TYPE "__"
0333
0334
0335
0336 inline internals **&get_internals_pp() {
0337 static internals **internals_pp = nullptr;
0338 return internals_pp;
0339 }
0340
0341
0342 inline void translate_exception(std::exception_ptr);
0343
0344 template <class T,
0345 enable_if_t<std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
0346 bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
0347 std::exception_ptr nested = exc.nested_ptr();
0348 if (nested != nullptr && nested != p) {
0349 translate_exception(nested);
0350 return true;
0351 }
0352 return false;
0353 }
0354
0355 template <class T,
0356 enable_if_t<!std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
0357 bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
0358 if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(exc))) {
0359 return handle_nested_exception(*nep, p);
0360 }
0361 return false;
0362 }
0363
0364 inline bool raise_err(PyObject *exc_type, const char *msg) {
0365 if (PyErr_Occurred()) {
0366 raise_from(exc_type, msg);
0367 return true;
0368 }
0369 set_error(exc_type, msg);
0370 return false;
0371 }
0372
0373 inline void translate_exception(std::exception_ptr p) {
0374 if (!p) {
0375 return;
0376 }
0377 try {
0378 std::rethrow_exception(p);
0379 } catch (error_already_set &e) {
0380 handle_nested_exception(e, p);
0381 e.restore();
0382 return;
0383 } catch (const builtin_exception &e) {
0384
0385 if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(e))) {
0386 handle_nested_exception(*nep, p);
0387 }
0388 e.set_error();
0389 return;
0390 } catch (const std::bad_alloc &e) {
0391 handle_nested_exception(e, p);
0392 raise_err(PyExc_MemoryError, e.what());
0393 return;
0394 } catch (const std::domain_error &e) {
0395 handle_nested_exception(e, p);
0396 raise_err(PyExc_ValueError, e.what());
0397 return;
0398 } catch (const std::invalid_argument &e) {
0399 handle_nested_exception(e, p);
0400 raise_err(PyExc_ValueError, e.what());
0401 return;
0402 } catch (const std::length_error &e) {
0403 handle_nested_exception(e, p);
0404 raise_err(PyExc_ValueError, e.what());
0405 return;
0406 } catch (const std::out_of_range &e) {
0407 handle_nested_exception(e, p);
0408 raise_err(PyExc_IndexError, e.what());
0409 return;
0410 } catch (const std::range_error &e) {
0411 handle_nested_exception(e, p);
0412 raise_err(PyExc_ValueError, e.what());
0413 return;
0414 } catch (const std::overflow_error &e) {
0415 handle_nested_exception(e, p);
0416 raise_err(PyExc_OverflowError, e.what());
0417 return;
0418 } catch (const std::exception &e) {
0419 handle_nested_exception(e, p);
0420 raise_err(PyExc_RuntimeError, e.what());
0421 return;
0422 } catch (const std::nested_exception &e) {
0423 handle_nested_exception(e, p);
0424 raise_err(PyExc_RuntimeError, "Caught an unknown nested exception!");
0425 return;
0426 } catch (...) {
0427 raise_err(PyExc_RuntimeError, "Caught an unknown exception!");
0428 return;
0429 }
0430 }
0431
0432 #if !defined(__GLIBCXX__)
0433 inline void translate_local_exception(std::exception_ptr p) {
0434 try {
0435 if (p) {
0436 std::rethrow_exception(p);
0437 }
0438 } catch (error_already_set &e) {
0439 e.restore();
0440 return;
0441 } catch (const builtin_exception &e) {
0442 e.set_error();
0443 return;
0444 }
0445 }
0446 #endif
0447
0448 inline object get_python_state_dict() {
0449 object state_dict;
0450 #if PYBIND11_INTERNALS_VERSION <= 4 || PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
0451 state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
0452 #else
0453 # if PY_VERSION_HEX < 0x03090000
0454 PyInterpreterState *istate = _PyInterpreterState_Get();
0455 # else
0456 PyInterpreterState *istate = PyInterpreterState_Get();
0457 # endif
0458 if (istate) {
0459 state_dict = reinterpret_borrow<object>(PyInterpreterState_GetDict(istate));
0460 }
0461 #endif
0462 if (!state_dict) {
0463 raise_from(PyExc_SystemError, "pybind11::detail::get_python_state_dict() FAILED");
0464 throw error_already_set();
0465 }
0466 return state_dict;
0467 }
0468
0469 inline object get_internals_obj_from_state_dict(handle state_dict) {
0470 return reinterpret_steal<object>(
0471 dict_getitemstringref(state_dict.ptr(), PYBIND11_INTERNALS_ID));
0472 }
0473
0474 inline internals **get_internals_pp_from_capsule(handle obj) {
0475 void *raw_ptr = PyCapsule_GetPointer(obj.ptr(), nullptr);
0476 if (raw_ptr == nullptr) {
0477 raise_from(PyExc_SystemError, "pybind11::detail::get_internals_pp_from_capsule() FAILED");
0478 throw error_already_set();
0479 }
0480 return static_cast<internals **>(raw_ptr);
0481 }
0482
0483 inline uint64_t round_up_to_next_pow2(uint64_t x) {
0484
0485
0486 x--;
0487 x |= (x >> 1);
0488 x |= (x >> 2);
0489 x |= (x >> 4);
0490 x |= (x >> 8);
0491 x |= (x >> 16);
0492 x |= (x >> 32);
0493 x++;
0494 return x;
0495 }
0496
0497
0498 PYBIND11_NOINLINE internals &get_internals() {
0499 auto **&internals_pp = get_internals_pp();
0500 if (internals_pp && *internals_pp) {
0501 return **internals_pp;
0502 }
0503
0504 #if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
0505 gil_scoped_acquire gil;
0506 #else
0507
0508
0509 struct gil_scoped_acquire_local {
0510 gil_scoped_acquire_local() : state(PyGILState_Ensure()) {}
0511 gil_scoped_acquire_local(const gil_scoped_acquire_local &) = delete;
0512 gil_scoped_acquire_local &operator=(const gil_scoped_acquire_local &) = delete;
0513 ~gil_scoped_acquire_local() { PyGILState_Release(state); }
0514 const PyGILState_STATE state;
0515 } gil;
0516 #endif
0517 error_scope err_scope;
0518
0519 dict state_dict = get_python_state_dict();
0520 if (object internals_obj = get_internals_obj_from_state_dict(state_dict)) {
0521 internals_pp = get_internals_pp_from_capsule(internals_obj);
0522 }
0523 if (internals_pp && *internals_pp) {
0524
0525
0526
0527
0528
0529
0530
0531 #if !defined(__GLIBCXX__)
0532 (*internals_pp)->registered_exception_translators.push_front(&translate_local_exception);
0533 #endif
0534 } else {
0535 if (!internals_pp) {
0536 internals_pp = new internals *();
0537 }
0538 auto *&internals_ptr = *internals_pp;
0539 internals_ptr = new internals();
0540
0541 PyThreadState *tstate = PyThreadState_Get();
0542
0543 if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->tstate)) {
0544 pybind11_fail("get_internals: could not successfully initialize the tstate TSS key!");
0545 }
0546 PYBIND11_TLS_REPLACE_VALUE(internals_ptr->tstate, tstate);
0547
0548 #if PYBIND11_INTERNALS_VERSION > 4
0549
0550 if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->loader_life_support_tls_key)) {
0551 pybind11_fail("get_internals: could not successfully initialize the "
0552 "loader_life_support TSS key!");
0553 }
0554 #endif
0555 internals_ptr->istate = tstate->interp;
0556 state_dict[PYBIND11_INTERNALS_ID] = capsule(reinterpret_cast<void *>(internals_pp));
0557 internals_ptr->registered_exception_translators.push_front(&translate_exception);
0558 internals_ptr->static_property_type = make_static_property_type();
0559 internals_ptr->default_metaclass = make_default_metaclass();
0560 internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass);
0561 #ifdef Py_GIL_DISABLED
0562
0563 auto num_shards
0564 = static_cast<size_t>(round_up_to_next_pow2(2 * std::thread::hardware_concurrency()));
0565 if (num_shards == 0) {
0566 num_shards = 1;
0567 }
0568 internals_ptr->instance_shards.reset(new instance_map_shard[num_shards]);
0569 internals_ptr->instance_shards_mask = num_shards - 1;
0570 #endif
0571 }
0572 return **internals_pp;
0573 }
0574
0575
0576
0577
0578
0579
0580
0581 struct local_internals {
0582 type_map<type_info *> registered_types_cpp;
0583 std::forward_list<ExceptionTranslator> registered_exception_translators;
0584 #if PYBIND11_INTERNALS_VERSION == 4
0585
0586
0587
0588
0589
0590
0591
0592 PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
0593
0594
0595 struct shared_loader_life_support_data {
0596 PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
0597 shared_loader_life_support_data() {
0598
0599 if (!PYBIND11_TLS_KEY_CREATE(loader_life_support_tls_key)) {
0600 pybind11_fail("local_internals: could not successfully initialize the "
0601 "loader_life_support TLS key!");
0602 }
0603 }
0604
0605 };
0606
0607 local_internals() {
0608 auto &internals = get_internals();
0609
0610 auto &ptr = internals.shared_data["_life_support"];
0611 if (!ptr) {
0612 ptr = new shared_loader_life_support_data;
0613 }
0614 loader_life_support_tls_key
0615 = static_cast<shared_loader_life_support_data *>(ptr)->loader_life_support_tls_key;
0616 }
0617 #endif
0618 };
0619
0620
0621 inline local_internals &get_local_internals() {
0622
0623
0624
0625
0626
0627 static auto *locals = new local_internals();
0628 return *locals;
0629 }
0630
0631 #ifdef Py_GIL_DISABLED
0632 # define PYBIND11_LOCK_INTERNALS(internals) std::unique_lock<pymutex> lock((internals).mutex)
0633 #else
0634 # define PYBIND11_LOCK_INTERNALS(internals)
0635 #endif
0636
0637 template <typename F>
0638 inline auto with_internals(const F &cb) -> decltype(cb(get_internals())) {
0639 auto &internals = get_internals();
0640 PYBIND11_LOCK_INTERNALS(internals);
0641 return cb(internals);
0642 }
0643
0644 inline std::uint64_t mix64(std::uint64_t z) {
0645
0646
0647
0648 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
0649 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
0650 return z ^ (z >> 31);
0651 }
0652
0653 template <typename F>
0654 inline auto with_instance_map(const void *ptr,
0655 const F &cb) -> decltype(cb(std::declval<instance_map &>())) {
0656 auto &internals = get_internals();
0657
0658 #ifdef Py_GIL_DISABLED
0659
0660
0661
0662
0663
0664 auto addr = reinterpret_cast<std::uintptr_t>(ptr);
0665 auto hash = mix64(static_cast<std::uint64_t>(addr >> 20));
0666 auto idx = static_cast<size_t>(hash & internals.instance_shards_mask);
0667
0668 auto &shard = internals.instance_shards[idx];
0669 std::unique_lock<pymutex> lock(shard.mutex);
0670 return cb(shard.registered_instances);
0671 #else
0672 (void) ptr;
0673 return cb(internals.registered_instances);
0674 #endif
0675 }
0676
0677
0678
0679 inline size_t num_registered_instances() {
0680 auto &internals = get_internals();
0681 #ifdef Py_GIL_DISABLED
0682 size_t count = 0;
0683 for (size_t i = 0; i <= internals.instance_shards_mask; ++i) {
0684 auto &shard = internals.instance_shards[i];
0685 std::unique_lock<pymutex> lock(shard.mutex);
0686 count += shard.registered_instances.size();
0687 }
0688 return count;
0689 #else
0690 return internals.registered_instances.size();
0691 #endif
0692 }
0693
0694
0695
0696
0697
0698 template <typename... Args>
0699 const char *c_str(Args &&...args) {
0700
0701
0702 auto &internals = get_internals();
0703 PYBIND11_LOCK_INTERNALS(internals);
0704 auto &strings = internals.static_strings;
0705 strings.emplace_front(std::forward<Args>(args)...);
0706 return strings.front().c_str();
0707 }
0708
0709 inline const char *get_function_record_capsule_name() {
0710 #if PYBIND11_INTERNALS_VERSION > 4
0711 return get_internals().function_record_capsule_name.c_str();
0712 #else
0713 return nullptr;
0714 #endif
0715 }
0716
0717
0718
0719
0720
0721
0722
0723 inline bool is_function_record_capsule(const capsule &cap) {
0724
0725 return cap.name() == get_function_record_capsule_name();
0726 }
0727
0728 PYBIND11_NAMESPACE_END(detail)
0729
0730
0731
0732
0733 PYBIND11_NOINLINE void *get_shared_data(const std::string &name) {
0734 return detail::with_internals([&](detail::internals &internals) {
0735 auto it = internals.shared_data.find(name);
0736 return it != internals.shared_data.end() ? it->second : nullptr;
0737 });
0738 }
0739
0740
0741 PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) {
0742 return detail::with_internals([&](detail::internals &internals) {
0743 internals.shared_data[name] = data;
0744 return data;
0745 });
0746 }
0747
0748
0749
0750
0751 template <typename T>
0752 T &get_or_create_shared_data(const std::string &name) {
0753 return *detail::with_internals([&](detail::internals &internals) {
0754 auto it = internals.shared_data.find(name);
0755 T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr);
0756 if (!ptr) {
0757 ptr = new T();
0758 internals.shared_data[name] = ptr;
0759 }
0760 return ptr;
0761 });
0762 }
0763
0764 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)