File indexing completed on 2025-01-18 10:17:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <pybind11/functional.h>
0011
0012 #include "constructor_stats.h"
0013 #include "pybind11_tests.h"
0014
0015 #include <thread>
0016
0017
0018 class ExampleVirt {
0019 public:
0020 explicit ExampleVirt(int state) : state(state) { print_created(this, state); }
0021 ExampleVirt(const ExampleVirt &e) : state(e.state) { print_copy_created(this); }
0022 ExampleVirt(ExampleVirt &&e) noexcept : state(e.state) {
0023 print_move_created(this);
0024 e.state = 0;
0025 }
0026 virtual ~ExampleVirt() { print_destroyed(this); }
0027
0028 virtual int run(int value) {
0029 py::print("Original implementation of "
0030 "ExampleVirt::run(state={}, value={}, str1={}, str2={})"_s.format(
0031 state, value, get_string1(), *get_string2()));
0032 return state + value;
0033 }
0034
0035 virtual bool run_bool() = 0;
0036 virtual void pure_virtual() = 0;
0037
0038
0039
0040
0041 virtual const std::string &get_string1() { return str1; }
0042 virtual const std::string *get_string2() { return &str2; }
0043
0044 private:
0045 int state;
0046 const std::string str1{"default1"}, str2{"default2"};
0047 };
0048
0049
0050 class PyExampleVirt : public ExampleVirt {
0051 public:
0052 using ExampleVirt::ExampleVirt;
0053
0054 int run(int value) override {
0055
0056 PYBIND11_OVERRIDE(int,
0057 ExampleVirt,
0058 run,
0059 value
0060 );
0061 }
0062
0063 bool run_bool() override {
0064 PYBIND11_OVERRIDE_PURE(bool,
0065 ExampleVirt,
0066 run_bool,
0067
0068
0069 );
0070 }
0071
0072 void pure_virtual() override {
0073 PYBIND11_OVERRIDE_PURE(void,
0074 ExampleVirt,
0075 pure_virtual,
0076
0077
0078 );
0079 }
0080
0081
0082
0083 const std::string &get_string1() override {
0084 PYBIND11_OVERRIDE(const std::string &,
0085 ExampleVirt,
0086 get_string1,
0087
0088 );
0089 }
0090
0091 const std::string *get_string2() override {
0092 PYBIND11_OVERRIDE(const std::string *,
0093 ExampleVirt,
0094 get_string2,
0095
0096 );
0097 }
0098 };
0099
0100 class NonCopyable {
0101 public:
0102 NonCopyable(int a, int b) : value{new int(a * b)} { print_created(this, a, b); }
0103 NonCopyable(NonCopyable &&o) noexcept : value{std::move(o.value)} { print_move_created(this); }
0104 NonCopyable(const NonCopyable &) = delete;
0105 NonCopyable() = delete;
0106 void operator=(const NonCopyable &) = delete;
0107 void operator=(NonCopyable &&) = delete;
0108 std::string get_value() const {
0109 if (value) {
0110 return std::to_string(*value);
0111 }
0112 return "(null)";
0113 }
0114 ~NonCopyable() { print_destroyed(this); }
0115
0116 private:
0117 std::unique_ptr<int> value;
0118 };
0119
0120
0121
0122 class Movable {
0123 public:
0124 Movable(int a, int b) : value{a + b} { print_created(this, a, b); }
0125 Movable(const Movable &m) : value{m.value} { print_copy_created(this); }
0126 Movable(Movable &&m) noexcept : value{m.value} { print_move_created(this); }
0127 std::string get_value() const { return std::to_string(value); }
0128 ~Movable() { print_destroyed(this); }
0129
0130 private:
0131 int value;
0132 };
0133
0134 class NCVirt {
0135 public:
0136 virtual ~NCVirt() = default;
0137 NCVirt() = default;
0138 NCVirt(const NCVirt &) = delete;
0139 virtual NonCopyable get_noncopyable(int a, int b) { return NonCopyable(a, b); }
0140 virtual Movable get_movable(int a, int b) = 0;
0141
0142 std::string print_nc(int a, int b) { return get_noncopyable(a, b).get_value(); }
0143 std::string print_movable(int a, int b) { return get_movable(a, b).get_value(); }
0144 };
0145 class NCVirtTrampoline : public NCVirt {
0146 #if !defined(__INTEL_COMPILER) && !defined(__CUDACC__) && !defined(__PGIC__)
0147 NonCopyable get_noncopyable(int a, int b) override {
0148 PYBIND11_OVERRIDE(NonCopyable, NCVirt, get_noncopyable, a, b);
0149 }
0150 #endif
0151 Movable get_movable(int a, int b) override {
0152 PYBIND11_OVERRIDE_PURE(Movable, NCVirt, get_movable, a, b);
0153 }
0154 };
0155
0156 struct Base {
0157 virtual std::string dispatch() const = 0;
0158 virtual ~Base() = default;
0159 Base() = default;
0160 Base(const Base &) = delete;
0161 };
0162
0163 struct DispatchIssue : Base {
0164 std::string dispatch() const override {
0165 PYBIND11_OVERRIDE_PURE(std::string, Base, dispatch, );
0166 }
0167 };
0168
0169
0170
0171 struct AdderBase {
0172 struct Data {};
0173 using DataVisitor = std::function<void(const Data &)>;
0174
0175 virtual void
0176 operator()(const Data &first, const Data &second, const DataVisitor &visitor) const
0177 = 0;
0178 virtual ~AdderBase() = default;
0179 AdderBase() = default;
0180 AdderBase(const AdderBase &) = delete;
0181 };
0182
0183 struct Adder : AdderBase {
0184 void
0185 operator()(const Data &first, const Data &second, const DataVisitor &visitor) const override {
0186 PYBIND11_OVERRIDE_PURE_NAME(
0187 void, AdderBase, "__call__", operator(), first, second, visitor);
0188 }
0189 };
0190
0191 static void test_gil() {
0192 {
0193 py::gil_scoped_acquire lock;
0194 py::print("1st lock acquired");
0195 }
0196
0197 {
0198 py::gil_scoped_acquire lock;
0199 py::print("2nd lock acquired");
0200 }
0201 }
0202
0203 static void test_gil_from_thread() {
0204 py::gil_scoped_release release;
0205
0206 std::thread t(test_gil);
0207 t.join();
0208 }
0209
0210 class test_override_cache_helper {
0211
0212 public:
0213 virtual int func() { return 0; }
0214
0215 test_override_cache_helper() = default;
0216 virtual ~test_override_cache_helper() = default;
0217
0218 test_override_cache_helper &operator=(test_override_cache_helper const &Right) = delete;
0219 test_override_cache_helper(test_override_cache_helper const &Copy) = delete;
0220 };
0221
0222 class test_override_cache_helper_trampoline : public test_override_cache_helper {
0223 int func() override { PYBIND11_OVERRIDE(int, test_override_cache_helper, func); }
0224 };
0225
0226 inline int test_override_cache(std::shared_ptr<test_override_cache_helper> const &instance) {
0227 return instance->func();
0228 }
0229
0230
0231
0232 void initialize_inherited_virtuals(py::module_ &m);
0233
0234 TEST_SUBMODULE(virtual_functions, m) {
0235
0236 py::class_<ExampleVirt, PyExampleVirt>(m, "ExampleVirt")
0237 .def(py::init<int>())
0238
0239 .def("run", &ExampleVirt::run)
0240 .def("run_bool", &ExampleVirt::run_bool)
0241 .def("pure_virtual", &ExampleVirt::pure_virtual);
0242
0243 py::class_<NonCopyable>(m, "NonCopyable").def(py::init<int, int>());
0244
0245 py::class_<Movable>(m, "Movable").def(py::init<int, int>());
0246
0247
0248 #if !defined(__INTEL_COMPILER) && !defined(__CUDACC__) && !defined(__PGIC__)
0249 py::class_<NCVirt, NCVirtTrampoline>(m, "NCVirt")
0250 .def(py::init<>())
0251 .def("get_noncopyable", &NCVirt::get_noncopyable)
0252 .def("get_movable", &NCVirt::get_movable)
0253 .def("print_nc", &NCVirt::print_nc)
0254 .def("print_movable", &NCVirt::print_movable);
0255 #endif
0256
0257 m.def("runExampleVirt", [](ExampleVirt *ex, int value) { return ex->run(value); });
0258 m.def("runExampleVirtBool", [](ExampleVirt *ex) { return ex->run_bool(); });
0259 m.def("runExampleVirtVirtual", [](ExampleVirt *ex) { ex->pure_virtual(); });
0260
0261 m.def("cstats_debug", &ConstructorStats::get<ExampleVirt>);
0262 initialize_inherited_virtuals(m);
0263
0264
0265
0266
0267 struct A {
0268 A() = default;
0269 A(const A &) = delete;
0270 virtual ~A() = default;
0271 virtual void f() { py::print("A.f()"); }
0272 };
0273
0274 struct PyA : A {
0275 PyA() { py::print("PyA.PyA()"); }
0276 PyA(const PyA &) = delete;
0277 ~PyA() override { py::print("PyA.~PyA()"); }
0278
0279 void f() override {
0280 py::print("PyA.f()");
0281
0282
0283 PYBIND11_OVERRIDE(PYBIND11_TYPE(typename std::enable_if<true, void>::type), A, f);
0284 }
0285 };
0286
0287 py::class_<A, PyA>(m, "A").def(py::init<>()).def("f", &A::f);
0288
0289 m.def("call_f", [](A *a) { a->f(); });
0290
0291
0292
0293 struct A2 {
0294 A2() = default;
0295 A2(const A2 &) = delete;
0296 virtual ~A2() = default;
0297 virtual void f() { py::print("A2.f()"); }
0298 };
0299
0300 struct PyA2 : A2 {
0301 PyA2() { py::print("PyA2.PyA2()"); }
0302 PyA2(const PyA2 &) = delete;
0303 ~PyA2() override { py::print("PyA2.~PyA2()"); }
0304 void f() override {
0305 py::print("PyA2.f()");
0306 PYBIND11_OVERRIDE(void, A2, f);
0307 }
0308 };
0309
0310 py::class_<A2, PyA2>(m, "A2")
0311 .def(py::init_alias<>())
0312 .def(py::init([](int) { return new PyA2(); }))
0313 .def("f", &A2::f);
0314
0315 m.def("call_f", [](A2 *a2) { a2->f(); });
0316
0317
0318
0319 py::class_<Base, DispatchIssue>(m, "DispatchIssue")
0320 .def(py::init<>())
0321 .def("dispatch", &Base::dispatch);
0322
0323 m.def("dispatch_issue_go", [](const Base *b) { return b->dispatch(); });
0324
0325
0326
0327 pybind11::class_<AdderBase, Adder>(m, "Adder")
0328 .def(pybind11::init<>())
0329 .def("__call__", &AdderBase::operator());
0330
0331 pybind11::class_<AdderBase::Data>(m, "Data").def(pybind11::init<>());
0332
0333 m.def("add2",
0334 [](const AdderBase::Data &first,
0335 const AdderBase::Data &second,
0336 const AdderBase &adder,
0337 const AdderBase::DataVisitor &visitor) { adder(first, second, visitor); });
0338
0339 m.def("add3",
0340 [](const AdderBase::Data &first,
0341 const AdderBase::Data &second,
0342 const AdderBase::Data &third,
0343 const AdderBase &adder,
0344 const AdderBase::DataVisitor &visitor) {
0345 adder(first, second, [&](const AdderBase::Data &first_plus_second) {
0346
0347 adder(first_plus_second, third, visitor);
0348 });
0349 });
0350
0351
0352
0353 class OverrideTest {
0354 public:
0355 struct A {
0356 std::string value = "hi";
0357 };
0358 std::string v;
0359 A a;
0360 explicit OverrideTest(const std::string &v) : v{v} {}
0361 OverrideTest() = default;
0362 OverrideTest(const OverrideTest &) = delete;
0363 virtual std::string str_value() { return v; }
0364 virtual std::string &str_ref() { return v; }
0365 virtual A A_value() { return a; }
0366 virtual A &A_ref() { return a; }
0367 virtual ~OverrideTest() = default;
0368 };
0369
0370 class PyOverrideTest : public OverrideTest {
0371 public:
0372 using OverrideTest::OverrideTest;
0373 std::string str_value() override {
0374 PYBIND11_OVERRIDE(std::string, OverrideTest, str_value);
0375 }
0376
0377
0378
0379 #ifdef PYBIND11_NEVER_DEFINED_EVER
0380 std::string &str_ref() override {
0381 PYBIND11_OVERRIDE(std::string &, OverrideTest, str_ref);
0382 }
0383 #endif
0384
0385 private:
0386 std::string _tmp;
0387 std::string str_ref_helper() { PYBIND11_OVERRIDE(std::string, OverrideTest, str_ref); }
0388
0389 public:
0390 std::string &str_ref() override { return _tmp = str_ref_helper(); }
0391
0392 A A_value() override { PYBIND11_OVERRIDE(A, OverrideTest, A_value); }
0393 A &A_ref() override { PYBIND11_OVERRIDE(A &, OverrideTest, A_ref); }
0394 };
0395
0396 py::class_<OverrideTest::A>(m, "OverrideTest_A")
0397 .def_readwrite("value", &OverrideTest::A::value);
0398 py::class_<OverrideTest, PyOverrideTest>(m, "OverrideTest")
0399 .def(py::init<const std::string &>())
0400 .def("str_value", &OverrideTest::str_value)
0401 #ifdef PYBIND11_NEVER_DEFINED_EVER
0402 .def("str_ref", &OverrideTest::str_ref)
0403 #endif
0404 .def("A_value", &OverrideTest::A_value)
0405 .def("A_ref", &OverrideTest::A_ref);
0406
0407 py::class_<test_override_cache_helper,
0408 test_override_cache_helper_trampoline,
0409 std::shared_ptr<test_override_cache_helper>>(m, "test_override_cache_helper")
0410 .def(py::init_alias<>())
0411 .def("func", &test_override_cache_helper::func);
0412
0413 m.def("test_override_cache", test_override_cache);
0414 }
0415
0416
0417
0418
0419
0420
0421
0422
0423 class A_Repeat {
0424 #define A_METHODS \
0425 public: \
0426 virtual int unlucky_number() = 0; \
0427 virtual std::string say_something(unsigned times) { \
0428 std::string s = ""; \
0429 for (unsigned i = 0; i < times; ++i) \
0430 s += "hi"; \
0431 return s; \
0432 } \
0433 std::string say_everything() { \
0434 return say_something(1) + " " + std::to_string(unlucky_number()); \
0435 }
0436 A_METHODS
0437 A_Repeat() = default;
0438 A_Repeat(const A_Repeat &) = delete;
0439 virtual ~A_Repeat() = default;
0440 };
0441 class B_Repeat : public A_Repeat {
0442 #define B_METHODS \
0443 public: \
0444 int unlucky_number() override { return 13; } \
0445 std::string say_something(unsigned times) override { \
0446 return "B says hi " + std::to_string(times) + " times"; \
0447 } \
0448 virtual double lucky_number() { return 7.0; }
0449 B_METHODS
0450 };
0451 class C_Repeat : public B_Repeat {
0452 #define C_METHODS \
0453 public: \
0454 int unlucky_number() override { return 4444; } \
0455 double lucky_number() override { return 888; }
0456 C_METHODS
0457 };
0458 class D_Repeat : public C_Repeat {
0459 #define D_METHODS
0460 D_METHODS
0461 };
0462
0463
0464 class A_Tpl {
0465 A_METHODS;
0466 A_Tpl() = default;
0467 A_Tpl(const A_Tpl &) = delete;
0468 virtual ~A_Tpl() = default;
0469 };
0470 class B_Tpl : public A_Tpl {
0471 B_METHODS
0472 };
0473 class C_Tpl : public B_Tpl {
0474 C_METHODS
0475 };
0476 class D_Tpl : public C_Tpl {
0477 D_METHODS
0478 };
0479
0480
0481 class PyA_Repeat : public A_Repeat {
0482 public:
0483 using A_Repeat::A_Repeat;
0484 int unlucky_number() override { PYBIND11_OVERRIDE_PURE(int, A_Repeat, unlucky_number, ); }
0485 std::string say_something(unsigned times) override {
0486 PYBIND11_OVERRIDE(std::string, A_Repeat, say_something, times);
0487 }
0488 };
0489 class PyB_Repeat : public B_Repeat {
0490 public:
0491 using B_Repeat::B_Repeat;
0492 int unlucky_number() override { PYBIND11_OVERRIDE(int, B_Repeat, unlucky_number, ); }
0493 std::string say_something(unsigned times) override {
0494 PYBIND11_OVERRIDE(std::string, B_Repeat, say_something, times);
0495 }
0496 double lucky_number() override { PYBIND11_OVERRIDE(double, B_Repeat, lucky_number, ); }
0497 };
0498 class PyC_Repeat : public C_Repeat {
0499 public:
0500 using C_Repeat::C_Repeat;
0501 int unlucky_number() override { PYBIND11_OVERRIDE(int, C_Repeat, unlucky_number, ); }
0502 std::string say_something(unsigned times) override {
0503 PYBIND11_OVERRIDE(std::string, C_Repeat, say_something, times);
0504 }
0505 double lucky_number() override { PYBIND11_OVERRIDE(double, C_Repeat, lucky_number, ); }
0506 };
0507 class PyD_Repeat : public D_Repeat {
0508 public:
0509 using D_Repeat::D_Repeat;
0510 int unlucky_number() override { PYBIND11_OVERRIDE(int, D_Repeat, unlucky_number, ); }
0511 std::string say_something(unsigned times) override {
0512 PYBIND11_OVERRIDE(std::string, D_Repeat, say_something, times);
0513 }
0514 double lucky_number() override { PYBIND11_OVERRIDE(double, D_Repeat, lucky_number, ); }
0515 };
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531 template <class Base = A_Tpl>
0532 class PyA_Tpl : public Base {
0533 public:
0534 using Base::Base;
0535 int unlucky_number() override { PYBIND11_OVERRIDE_PURE(int, Base, unlucky_number, ); }
0536 std::string say_something(unsigned times) override {
0537 PYBIND11_OVERRIDE(std::string, Base, say_something, times);
0538 }
0539 };
0540 template <class Base = B_Tpl>
0541 class PyB_Tpl : public PyA_Tpl<Base> {
0542 public:
0543 using PyA_Tpl<Base>::PyA_Tpl;
0544
0545 int unlucky_number() override { PYBIND11_OVERRIDE(int, Base, unlucky_number, ); }
0546 double lucky_number() override { PYBIND11_OVERRIDE(double, Base, lucky_number, ); }
0547 };
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561 void initialize_inherited_virtuals(py::module_ &m) {
0562
0563
0564
0565 py::class_<A_Repeat, PyA_Repeat>(m, "A_Repeat")
0566 .def(py::init<>())
0567 .def("unlucky_number", &A_Repeat::unlucky_number)
0568 .def("say_something", &A_Repeat::say_something)
0569 .def("say_everything", &A_Repeat::say_everything);
0570 py::class_<B_Repeat, A_Repeat, PyB_Repeat>(m, "B_Repeat")
0571 .def(py::init<>())
0572 .def("lucky_number", &B_Repeat::lucky_number);
0573 py::class_<C_Repeat, B_Repeat, PyC_Repeat>(m, "C_Repeat").def(py::init<>());
0574 py::class_<D_Repeat, C_Repeat, PyD_Repeat>(m, "D_Repeat").def(py::init<>());
0575
0576
0577
0578 py::class_<A_Tpl, PyA_Tpl<>>(m, "A_Tpl")
0579 .def(py::init<>())
0580 .def("unlucky_number", &A_Tpl::unlucky_number)
0581 .def("say_something", &A_Tpl::say_something)
0582 .def("say_everything", &A_Tpl::say_everything);
0583 py::class_<B_Tpl, A_Tpl, PyB_Tpl<>>(m, "B_Tpl")
0584 .def(py::init<>())
0585 .def("lucky_number", &B_Tpl::lucky_number);
0586 py::class_<C_Tpl, B_Tpl, PyB_Tpl<C_Tpl>>(m, "C_Tpl").def(py::init<>());
0587 py::class_<D_Tpl, C_Tpl, PyB_Tpl<D_Tpl>>(m, "D_Tpl").def(py::init<>());
0588
0589
0590 m.def("test_gil", &test_gil);
0591 m.def("test_gil_from_thread", &test_gil_from_thread);
0592 };