test_class.cpp
Go to the documentation of this file.
1 /*
2  tests/test_class.cpp -- test py::class_ definitions and basic functionality
3 
4  Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
5 
6  All rights reserved. Use of this source code is governed by a
7  BSD-style license that can be found in the LICENSE file.
8 */
9 
10 #if defined(__INTEL_COMPILER) && __cplusplus >= 201703L
11 // Intel compiler requires a separate header file to support aligned new operators
12 // and does not set the __cpp_aligned_new feature macro.
13 // This header needs to be included before pybind11.
14 # include <aligned_new>
15 #endif
16 
17 #include <pybind11/stl.h>
18 
19 #include "constructor_stats.h"
20 #include "local_bindings.h"
21 #include "pybind11_tests.h"
22 
23 #include <utility>
24 
26 // warning C4324: structure was padded due to alignment specifier
27 
28 // test_brace_initialization
30  explicit NoBraceInitialization(std::vector<int> v) : vec{std::move(v)} {}
31  template <typename T>
32  NoBraceInitialization(std::initializer_list<T> l) : vec(l) {}
33 
34  std::vector<int> vec;
35 };
36 
37 namespace test_class {
38 namespace pr4220_tripped_over_this { // PR #4227
39 
40 template <int>
41 struct SoEmpty {};
42 
43 template <typename T>
44 std::string get_msg(const T &) {
45  return "This is really only meant to exercise successful compilation.";
46 }
47 
49 
50 void bind_empty0(py::module_ &m) {
51  py::class_<Empty0>(m, "Empty0").def(py::init<>()).def("get_msg", get_msg<Empty0>);
52 }
53 
54 } // namespace pr4220_tripped_over_this
55 } // namespace test_class
56 
57 TEST_SUBMODULE(class_, m) {
58  m.def("obj_class_name", [](py::handle obj) { return py::detail::obj_class_name(obj.ptr()); });
59 
60  // test_instance
61  struct NoConstructor {
62  NoConstructor() = default;
63  NoConstructor(const NoConstructor &) = default;
64  NoConstructor(NoConstructor &&) = default;
65  static NoConstructor *new_instance() {
66  auto *ptr = new NoConstructor();
67  print_created(ptr, "via new_instance");
68  return ptr;
69  }
70  ~NoConstructor() { print_destroyed(this); }
71  };
72  struct NoConstructorNew {
73  NoConstructorNew() = default;
74  NoConstructorNew(const NoConstructorNew &) = default;
75  NoConstructorNew(NoConstructorNew &&) = default;
76  static NoConstructorNew *new_instance() {
77  auto *ptr = new NoConstructorNew();
78  print_created(ptr, "via new_instance");
79  return ptr;
80  }
81  ~NoConstructorNew() { print_destroyed(this); }
82  };
83 
84  py::class_<NoConstructor>(m, "NoConstructor")
85  .def_static("new_instance", &NoConstructor::new_instance, "Return an instance");
86 
87  py::class_<NoConstructorNew>(m, "NoConstructorNew")
88  .def(py::init([]() { return nullptr; })) // Need a NOOP __init__
89  .def_static("__new__",
90  [](const py::object &) { return NoConstructorNew::new_instance(); });
91 
92  // test_inheritance
93  class Pet {
94  public:
95  Pet(const std::string &name, const std::string &species)
96  : m_name(name), m_species(species) {}
97  std::string name() const { return m_name; }
98  std::string species() const { return m_species; }
99 
100  private:
101  std::string m_name;
102  std::string m_species;
103  };
104 
105  class Dog : public Pet {
106  public:
107  explicit Dog(const std::string &name) : Pet(name, "dog") {}
108  std::string bark() const { return "Woof!"; }
109  };
110 
111  class Rabbit : public Pet {
112  public:
113  explicit Rabbit(const std::string &name) : Pet(name, "parrot") {}
114  };
115 
116  class Hamster : public Pet {
117  public:
118  explicit Hamster(const std::string &name) : Pet(name, "rodent") {}
119  };
120 
121  class Chimera : public Pet {
122  Chimera() : Pet("Kimmy", "chimera") {}
123  };
124 
125  py::class_<Pet> pet_class(m, "Pet");
126  pet_class.def(py::init<std::string, std::string>())
127  .def("name", &Pet::name)
128  .def("species", &Pet::species);
129 
130  /* One way of declaring a subclass relationship: reference parent's class_ object */
131  py::class_<Dog>(m, "Dog", pet_class).def(py::init<std::string>());
132 
133  /* Another way of declaring a subclass relationship: reference parent's C++ type */
134  py::class_<Rabbit, Pet>(m, "Rabbit").def(py::init<std::string>());
135 
136  /* And another: list parent in class template arguments */
137  py::class_<Hamster, Pet>(m, "Hamster").def(py::init<std::string>());
138 
139  /* Constructors are not inherited by default */
140  py::class_<Chimera, Pet>(m, "Chimera");
141 
142  m.def("pet_name_species",
143  [](const Pet &pet) { return pet.name() + " is a " + pet.species(); });
144  m.def("dog_bark", [](const Dog &dog) { return dog.bark(); });
145 
146  // test_automatic_upcasting
147  struct BaseClass {
148  BaseClass() = default;
149  BaseClass(const BaseClass &) = default;
150  BaseClass(BaseClass &&) = default;
151  virtual ~BaseClass() = default;
152  };
153  struct DerivedClass1 : BaseClass {};
154  struct DerivedClass2 : BaseClass {};
155 
156  py::class_<BaseClass>(m, "BaseClass").def(py::init<>());
157  py::class_<DerivedClass1>(m, "DerivedClass1").def(py::init<>());
158  py::class_<DerivedClass2>(m, "DerivedClass2").def(py::init<>());
159 
160  m.def("return_class_1", []() -> BaseClass * { return new DerivedClass1(); });
161  m.def("return_class_2", []() -> BaseClass * { return new DerivedClass2(); });
162  m.def("return_class_n", [](int n) -> BaseClass * {
163  if (n == 1) {
164  return new DerivedClass1();
165  }
166  if (n == 2) {
167  return new DerivedClass2();
168  }
169  return new BaseClass();
170  });
171  m.def("return_none", []() -> BaseClass * { return nullptr; });
172 
173  // test_isinstance
174  m.def("check_instances", [](const py::list &l) {
175  return py::make_tuple(py::isinstance<py::tuple>(l[0]),
176  py::isinstance<py::dict>(l[1]),
177  py::isinstance<Pet>(l[2]),
178  py::isinstance<Pet>(l[3]),
179  py::isinstance<Dog>(l[4]),
180  py::isinstance<Rabbit>(l[5]),
181  py::isinstance<UnregisteredType>(l[6]));
182  });
183 
184  struct Invalid {};
185 
186  // test_type
187  m.def("check_type", [](int category) {
188  // Currently not supported (via a fail at compile time)
189  // See https://github.com/pybind/pybind11/issues/2486
190  // if (category == 2)
191  // return py::type::of<int>();
192  if (category == 1) {
193  return py::type::of<DerivedClass1>();
194  }
195  return py::type::of<Invalid>();
196  });
197 
198  m.def("get_type_of", [](py::object ob) { return py::type::of(std::move(ob)); });
199 
200  m.def("get_type_classic", [](py::handle h) { return h.get_type(); });
201 
202  m.def("as_type", [](const py::object &ob) { return py::type(ob); });
203 
204  // test_mismatched_holder
205  struct MismatchBase1 {};
206  struct MismatchDerived1 : MismatchBase1 {};
207 
208  struct MismatchBase2 {};
209  struct MismatchDerived2 : MismatchBase2 {};
210 
211  m.def("mismatched_holder_1", []() {
212  auto mod = py::module_::import("__main__");
213  py::class_<MismatchBase1, std::shared_ptr<MismatchBase1>>(mod, "MismatchBase1");
214  py::class_<MismatchDerived1, MismatchBase1>(mod, "MismatchDerived1");
215  });
216  m.def("mismatched_holder_2", []() {
217  auto mod = py::module_::import("__main__");
218  py::class_<MismatchBase2>(mod, "MismatchBase2");
219  py::class_<MismatchDerived2, std::shared_ptr<MismatchDerived2>, MismatchBase2>(
220  mod, "MismatchDerived2");
221  });
222 
223  // test_override_static
224  // #511: problem with inheritance + overwritten def_static
225  struct MyBase {
226  static std::unique_ptr<MyBase> make() { return std::unique_ptr<MyBase>(new MyBase()); }
227  };
228 
229  struct MyDerived : MyBase {
230  static std::unique_ptr<MyDerived> make() {
231  return std::unique_ptr<MyDerived>(new MyDerived());
232  }
233  };
234 
235  py::class_<MyBase>(m, "MyBase").def_static("make", &MyBase::make);
236 
237  py::class_<MyDerived, MyBase>(m, "MyDerived")
238  .def_static("make", &MyDerived::make)
239  .def_static("make2", &MyDerived::make);
240 
241  // test_implicit_conversion_life_support
242  struct ConvertibleFromUserType {
243  int i;
244 
245  explicit ConvertibleFromUserType(UserType u) : i(u.value()) {}
246  };
247 
248  py::class_<ConvertibleFromUserType>(m, "AcceptsUserType").def(py::init<UserType>());
249  py::implicitly_convertible<UserType, ConvertibleFromUserType>();
250 
251  m.def("implicitly_convert_argument", [](const ConvertibleFromUserType &r) { return r.i; });
252  m.def("implicitly_convert_variable", [](const py::object &o) {
253  // `o` is `UserType` and `r` is a reference to a temporary created by implicit
254  // conversion. This is valid when called inside a bound function because the temp
255  // object is attached to the same life support system as the arguments.
256  const auto &r = o.cast<const ConvertibleFromUserType &>();
257  return r.i;
258  });
259  m.add_object("implicitly_convert_variable_fail", [&] {
260  auto f = [](PyObject *, PyObject *args) -> PyObject * {
261  auto o = py::reinterpret_borrow<py::tuple>(args)[0];
262  try { // It should fail here because there is no life support.
263  o.cast<const ConvertibleFromUserType &>();
264  } catch (const py::cast_error &e) {
265  return py::str(e.what()).release().ptr();
266  }
267  return py::str().release().ptr();
268  };
269 
270  auto *def = new PyMethodDef{"f", f, METH_VARARGS, nullptr};
271  py::capsule def_capsule(def,
272  [](void *ptr) { delete reinterpret_cast<PyMethodDef *>(ptr); });
273  return py::reinterpret_steal<py::object>(
274  PyCFunction_NewEx(def, def_capsule.ptr(), m.ptr()));
275  }());
276 
277  // test_operator_new_delete
278  struct HasOpNewDel {
280  static void *operator new(size_t s) {
281  py::print("A new", s);
282  return ::operator new(s);
283  }
284  static void *operator new(size_t s, void *ptr) {
285  py::print("A placement-new", s);
286  return ptr;
287  }
288  static void operator delete(void *p) {
289  py::print("A delete");
290  return ::operator delete(p);
291  }
292  };
293  struct HasOpNewDelSize {
295  static void *operator new(size_t s) {
296  py::print("B new", s);
297  return ::operator new(s);
298  }
299  static void *operator new(size_t s, void *ptr) {
300  py::print("B placement-new", s);
301  return ptr;
302  }
303  static void operator delete(void *p, size_t s) {
304  py::print("B delete", s);
305  return ::operator delete(p);
306  }
307  };
308  struct AliasedHasOpNewDelSize {
310  static void *operator new(size_t s) {
311  py::print("C new", s);
312  return ::operator new(s);
313  }
314  static void *operator new(size_t s, void *ptr) {
315  py::print("C placement-new", s);
316  return ptr;
317  }
318  static void operator delete(void *p, size_t s) {
319  py::print("C delete", s);
320  return ::operator delete(p);
321  }
322  virtual ~AliasedHasOpNewDelSize() = default;
323  AliasedHasOpNewDelSize() = default;
324  AliasedHasOpNewDelSize(const AliasedHasOpNewDelSize &) = delete;
325  };
326  struct PyAliasedHasOpNewDelSize : AliasedHasOpNewDelSize {
327  PyAliasedHasOpNewDelSize() = default;
328  explicit PyAliasedHasOpNewDelSize(int) {}
330  };
331  struct HasOpNewDelBoth {
332  std::uint32_t i[8];
333  static void *operator new(size_t s) {
334  py::print("D new", s);
335  return ::operator new(s);
336  }
337  static void *operator new(size_t s, void *ptr) {
338  py::print("D placement-new", s);
339  return ptr;
340  }
341  static void operator delete(void *p) {
342  py::print("D delete");
343  return ::operator delete(p);
344  }
345  static void operator delete(void *p, size_t s) {
346  py::print("D wrong delete", s);
347  return ::operator delete(p);
348  }
349  };
350  py::class_<HasOpNewDel>(m, "HasOpNewDel").def(py::init<>());
351  py::class_<HasOpNewDelSize>(m, "HasOpNewDelSize").def(py::init<>());
352  py::class_<HasOpNewDelBoth>(m, "HasOpNewDelBoth").def(py::init<>());
353  py::class_<AliasedHasOpNewDelSize, PyAliasedHasOpNewDelSize> aliased(m,
354  "AliasedHasOpNewDelSize");
355  aliased.def(py::init<>());
356  aliased.attr("size_noalias") = py::int_(sizeof(AliasedHasOpNewDelSize));
357  aliased.attr("size_alias") = py::int_(sizeof(PyAliasedHasOpNewDelSize));
358 
359  // This test is actually part of test_local_bindings (test_duplicate_local), but we need a
360  // definition in a different compilation unit within the same module:
361  bind_local<LocalExternal, 17>(m, "LocalExternal", py::module_local());
362 
363  // test_bind_protected_functions
364  class ProtectedA {
365  protected:
366  int foo() const { return value; }
367 
368  private:
369  int value = 42;
370  };
371 
372  class PublicistA : public ProtectedA {
373  public:
374  using ProtectedA::foo;
375  };
376 
377  py::class_<ProtectedA>(m, "ProtectedA").def(py::init<>()).def("foo", &PublicistA::foo);
378 
379  class ProtectedB {
380  public:
381  virtual ~ProtectedB() = default;
382  ProtectedB() = default;
383  ProtectedB(const ProtectedB &) = delete;
384 
385  protected:
386  virtual int foo() const { return value; }
387  virtual void *void_foo() { return static_cast<void *>(&value); }
388  virtual void *get_self() { return static_cast<void *>(this); }
389 
390  private:
391  int value = 42;
392  };
393 
394  class TrampolineB : public ProtectedB {
395  public:
396  int foo() const override { PYBIND11_OVERRIDE(int, ProtectedB, foo, ); }
397  void *void_foo() override { PYBIND11_OVERRIDE(void *, ProtectedB, void_foo, ); }
398  void *get_self() override { PYBIND11_OVERRIDE(void *, ProtectedB, get_self, ); }
399  };
400 
401  class PublicistB : public ProtectedB {
402  public:
403  // [workaround(intel)] = default does not work here
404  // Removing or defaulting this destructor results in linking errors with the Intel compiler
405  // (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827)
406  ~PublicistB() override{}; // NOLINT(modernize-use-equals-default)
407  using ProtectedB::foo;
408  using ProtectedB::get_self;
409  using ProtectedB::void_foo;
410  };
411 
412  m.def("read_foo", [](const void *original) {
413  const int *ptr = reinterpret_cast<const int *>(original);
414  return *ptr;
415  });
416 
417  m.def("pointers_equal",
418  [](const void *original, const void *comparison) { return original == comparison; });
419 
420  py::class_<ProtectedB, TrampolineB>(m, "ProtectedB")
421  .def(py::init<>())
422  .def("foo", &PublicistB::foo)
423  .def("void_foo", &PublicistB::void_foo)
424  .def("get_self", &PublicistB::get_self);
425 
426  // test_brace_initialization
427  struct BraceInitialization {
428  int field1;
429  std::string field2;
430  };
431 
432  py::class_<BraceInitialization>(m, "BraceInitialization")
433  .def(py::init<int, const std::string &>())
434  .def_readwrite("field1", &BraceInitialization::field1)
435  .def_readwrite("field2", &BraceInitialization::field2);
436  // We *don't* want to construct using braces when the given constructor argument maps to a
437  // constructor, because brace initialization could go to the wrong place (in particular when
438  // there is also an `initializer_list<T>`-accept constructor):
439  py::class_<NoBraceInitialization>(m, "NoBraceInitialization")
440  .def(py::init<std::vector<int>>())
441  .def_readonly("vec", &NoBraceInitialization::vec);
442 
443  // test_reentrant_implicit_conversion_failure
444  // #1035: issue with runaway reentrant implicit conversion
445  struct BogusImplicitConversion {
446  BogusImplicitConversion(const BogusImplicitConversion &) = default;
447  };
448 
449  py::class_<BogusImplicitConversion>(m, "BogusImplicitConversion")
450  .def(py::init<const BogusImplicitConversion &>());
451 
452  py::implicitly_convertible<int, BogusImplicitConversion>();
453 
454  // test_qualname
455  // #1166: nested class docstring doesn't show nested name
456  // Also related: tests that __qualname__ is set properly
457  struct NestBase {};
458  struct Nested {};
459  py::class_<NestBase> base(m, "NestBase");
460  base.def(py::init<>());
461  py::class_<Nested>(base, "Nested")
462  .def(py::init<>())
463  .def("fn", [](Nested &, int, NestBase &, Nested &) {})
464  .def(
465  "fa", [](Nested &, int, NestBase &, Nested &) {}, "a"_a, "b"_a, "c"_a);
466  base.def("g", [](NestBase &, Nested &) {});
467  base.def("h", []() { return NestBase(); });
468 
469  // test_error_after_conversion
470  // The second-pass path through dispatcher() previously didn't
471  // remember which overload was used, and would crash trying to
472  // generate a useful error message
473 
474  struct NotRegistered {};
475  struct StringWrapper {
476  std::string str;
477  };
478  m.def("test_error_after_conversions", [](int) {});
479  m.def("test_error_after_conversions",
480  [](const StringWrapper &) -> NotRegistered { return {}; });
481  py::class_<StringWrapper>(m, "StringWrapper").def(py::init<std::string>());
482  py::implicitly_convertible<std::string, StringWrapper>();
483 
484 #if defined(PYBIND11_CPP17)
485  struct alignas(1024) Aligned {
486  std::uintptr_t ptr() const { return (uintptr_t) this; }
487  };
488  py::class_<Aligned>(m, "Aligned").def(py::init<>()).def("ptr", &Aligned::ptr);
489 #endif
490 
491  // test_final
492  struct IsFinal final {};
493  py::class_<IsFinal>(m, "IsFinal", py::is_final());
494 
495  // test_non_final_final
496  struct IsNonFinalFinal {};
497  py::class_<IsNonFinalFinal>(m, "IsNonFinalFinal", py::is_final());
498 
499  // test_exception_rvalue_abort
500  struct PyPrintDestructor {
501  PyPrintDestructor() = default;
502  ~PyPrintDestructor() { py::print("Print from destructor"); }
503  void throw_something() { throw std::runtime_error("error"); }
504  };
505  py::class_<PyPrintDestructor>(m, "PyPrintDestructor")
506  .def(py::init<>())
507  .def("throw_something", &PyPrintDestructor::throw_something);
508 
509  // test_multiple_instances_with_same_pointer
510  struct SamePointer {};
511  static SamePointer samePointer;
512  py::class_<SamePointer, std::unique_ptr<SamePointer, py::nodelete>>(m, "SamePointer")
513  .def(py::init([]() { return &samePointer; }));
514 
515  struct Empty {};
516  py::class_<Empty>(m, "Empty").def(py::init<>());
517 
518  // test_base_and_derived_nested_scope
519  struct BaseWithNested {
520  struct Nested {};
521  };
522 
523  struct DerivedWithNested : BaseWithNested {
524  struct Nested {};
525  };
526 
527  py::class_<BaseWithNested> baseWithNested_class(m, "BaseWithNested");
528  py::class_<DerivedWithNested, BaseWithNested> derivedWithNested_class(m, "DerivedWithNested");
529  py::class_<BaseWithNested::Nested>(baseWithNested_class, "Nested")
530  .def_static("get_name", []() { return "BaseWithNested::Nested"; });
531  py::class_<DerivedWithNested::Nested>(derivedWithNested_class, "Nested")
532  .def_static("get_name", []() { return "DerivedWithNested::Nested"; });
533 
534  // test_register_duplicate_class
535  struct Duplicate {};
536  struct OtherDuplicate {};
537  struct DuplicateNested {};
538  struct OtherDuplicateNested {};
539 
540  m.def("register_duplicate_class_name", [](const py::module_ &m) {
541  py::class_<Duplicate>(m, "Duplicate");
542  py::class_<OtherDuplicate>(m, "Duplicate");
543  });
544  m.def("register_duplicate_class_type", [](const py::module_ &m) {
545  py::class_<OtherDuplicate>(m, "OtherDuplicate");
546  py::class_<OtherDuplicate>(m, "YetAnotherDuplicate");
547  });
548  m.def("register_duplicate_nested_class_name", [](const py::object &gt) {
549  py::class_<DuplicateNested>(gt, "DuplicateNested");
550  py::class_<OtherDuplicateNested>(gt, "DuplicateNested");
551  });
552  m.def("register_duplicate_nested_class_type", [](const py::object &gt) {
553  py::class_<OtherDuplicateNested>(gt, "OtherDuplicateNested");
554  py::class_<OtherDuplicateNested>(gt, "YetAnotherDuplicateNested");
555  });
556 
558 }
559 
560 template <int N>
561 class BreaksBase {
562 public:
563  virtual ~BreaksBase() = default;
564  BreaksBase() = default;
565  BreaksBase(const BreaksBase &) = delete;
566 };
567 template <int N>
568 class BreaksTramp : public BreaksBase<N> {};
569 // These should all compile just fine:
570 using DoesntBreak1 = py::class_<BreaksBase<1>, std::unique_ptr<BreaksBase<1>>, BreaksTramp<1>>;
571 using DoesntBreak2 = py::class_<BreaksBase<2>, BreaksTramp<2>, std::unique_ptr<BreaksBase<2>>>;
572 using DoesntBreak3 = py::class_<BreaksBase<3>, std::unique_ptr<BreaksBase<3>>>;
573 using DoesntBreak4 = py::class_<BreaksBase<4>, BreaksTramp<4>>;
574 using DoesntBreak5 = py::class_<BreaksBase<5>>;
575 using DoesntBreak6 = py::class_<BreaksBase<6>, std::shared_ptr<BreaksBase<6>>, BreaksTramp<6>>;
576 using DoesntBreak7 = py::class_<BreaksBase<7>, BreaksTramp<7>, std::shared_ptr<BreaksBase<7>>>;
577 using DoesntBreak8 = py::class_<BreaksBase<8>, std::shared_ptr<BreaksBase<8>>>;
578 #define CHECK_BASE(N) \
579  static_assert(std::is_same<typename DoesntBreak##N::type, BreaksBase<(N)>>::value, \
580  "DoesntBreak" #N " has wrong type!")
581 CHECK_BASE(1);
582 CHECK_BASE(2);
583 CHECK_BASE(3);
584 CHECK_BASE(4);
585 CHECK_BASE(5);
586 CHECK_BASE(6);
587 CHECK_BASE(7);
588 CHECK_BASE(8);
589 #define CHECK_ALIAS(N) \
590  static_assert( \
591  DoesntBreak##N::has_alias \
592  && std::is_same<typename DoesntBreak##N::type_alias, BreaksTramp<(N)>>::value, \
593  "DoesntBreak" #N " has wrong type_alias!")
594 #define CHECK_NOALIAS(N) \
595  static_assert(!DoesntBreak##N::has_alias \
596  && std::is_void<typename DoesntBreak##N::type_alias>::value, \
597  "DoesntBreak" #N " has type alias, but shouldn't!")
598 CHECK_ALIAS(1);
599 CHECK_ALIAS(2);
600 CHECK_NOALIAS(3);
601 CHECK_ALIAS(4);
602 CHECK_NOALIAS(5);
603 CHECK_ALIAS(6);
604 CHECK_ALIAS(7);
605 CHECK_NOALIAS(8);
606 #define CHECK_HOLDER(N, TYPE) \
607  static_assert(std::is_same<typename DoesntBreak##N::holder_type, \
608  std::TYPE##_ptr<BreaksBase<(N)>>>::value, \
609  "DoesntBreak" #N " has wrong holder_type!")
610 CHECK_HOLDER(1, unique);
611 CHECK_HOLDER(2, unique);
612 CHECK_HOLDER(3, unique);
613 CHECK_HOLDER(4, unique);
614 CHECK_HOLDER(5, unique);
615 CHECK_HOLDER(6, shared);
616 CHECK_HOLDER(7, shared);
617 CHECK_HOLDER(8, shared);
618 
619 // There's no nice way to test that these fail because they fail to compile; leave them here,
620 // though, so that they can be manually tested by uncommenting them (and seeing that compilation
621 // failures occurs).
622 
623 // We have to actually look into the type: the typedef alone isn't enough to instantiate the type:
624 #define CHECK_BROKEN(N) \
625  static_assert(std::is_same<typename Breaks##N::type, BreaksBase<-(N)>>::value, \
626  "Breaks1 has wrong type!");
627 
628 #ifdef PYBIND11_NEVER_DEFINED_EVER
629 // Two holder classes:
630 typedef py::
631  class_<BreaksBase<-1>, std::unique_ptr<BreaksBase<-1>>, std::unique_ptr<BreaksBase<-1>>>
632  Breaks1;
633 CHECK_BROKEN(1);
634 // Two aliases:
635 typedef py::class_<BreaksBase<-2>, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2;
636 CHECK_BROKEN(2);
637 // Holder + 2 aliases
638 typedef py::
639  class_<BreaksBase<-3>, std::unique_ptr<BreaksBase<-3>>, BreaksTramp<-3>, BreaksTramp<-3>>
640  Breaks3;
641 CHECK_BROKEN(3);
642 // Alias + 2 holders
643 typedef py::class_<BreaksBase<-4>,
644  std::unique_ptr<BreaksBase<-4>>,
645  BreaksTramp<-4>,
646  std::shared_ptr<BreaksBase<-4>>>
647  Breaks4;
648 CHECK_BROKEN(4);
649 // Invalid option (not a subclass or holder)
650 typedef py::class_<BreaksBase<-5>, BreaksTramp<-4>> Breaks5;
651 CHECK_BROKEN(5);
652 // Invalid option: multiple inheritance not supported:
653 template <>
654 struct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {};
655 typedef py::class_<BreaksBase<-8>, BreaksBase<-6>, BreaksBase<-7>> Breaks8;
656 CHECK_BROKEN(8);
657 #endif
DoesntBreak6
py::class_< BreaksBase< 6 >, std::shared_ptr< BreaksBase< 6 > >, BreaksTramp< 6 > > DoesntBreak6
Definition: test_class.cpp:575
Eigen::internal::print
EIGEN_STRONG_INLINE Packet4f print(const Packet4f &a)
Definition: NEON/PacketMath.h:3115
name
Annotation for function names.
Definition: attr.h:51
base
Annotation indicating that a class derives from another given type.
Definition: attr.h:64
gtsam.examples.DogLegOptimizerExample.type
type
Definition: DogLegOptimizerExample.py:111
s
RealScalar s
Definition: level1_cplx_impl.h:126
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
CHECK_BASE
#define CHECK_BASE(N)
Definition: test_class.cpp:578
DoesntBreak2
py::class_< BreaksBase< 2 >, BreaksTramp< 2 >, std::unique_ptr< BreaksBase< 2 > >> DoesntBreak2
Definition: test_class.cpp:571
uint32_t
unsigned int uint32_t
Definition: ms_stdint.h:85
NoBraceInitialization::NoBraceInitialization
NoBraceInitialization(std::initializer_list< T > l)
Definition: test_class.cpp:32
test_class::pr4220_tripped_over_this::SoEmpty
Definition: test_class.cpp:41
CHECK_NOALIAS
#define CHECK_NOALIAS(N)
Definition: test_class.cpp:594
stl.h
TEST_SUBMODULE
TEST_SUBMODULE(class_, m)
Definition: test_class.cpp:57
h
const double h
Definition: testSimpleHelicopter.cpp:19
constructor_stats.h
DoesntBreak8
py::class_< BreaksBase< 8 >, std::shared_ptr< BreaksBase< 8 > >> DoesntBreak8
Definition: test_class.cpp:577
DoesntBreak3
py::class_< BreaksBase< 3 >, std::unique_ptr< BreaksBase< 3 > >> DoesntBreak3
Definition: test_class.cpp:572
DoesntBreak5
py::class_< BreaksBase< 5 > > DoesntBreak5
Definition: test_class.cpp:574
name
static char name[]
Definition: rgamma.c:72
process_shonan_timing_results.args
args
Definition: process_shonan_timing_results.py:163
n
int n
Definition: BiCGSTAB_simple.cpp:1
BreaksBase::BreaksBase
BreaksBase()=default
test_class
Definition: test_class.cpp:37
CHECK_ALIAS
#define CHECK_ALIAS(N)
Definition: test_class.cpp:589
j
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
make_tuple
tuple make_tuple()
Definition: cast.h:1248
BreaksBase
Definition: test_class.cpp:561
internal::Colamd::Empty
const int Empty
Definition: Eigen_Colamd.h:116
test_class::pr4220_tripped_over_this::get_msg
std::string get_msg(const T &)
Definition: test_class.cpp:44
l
static const Line3 l(Rot3(), 1, 1)
NoBraceInitialization::NoBraceInitialization
NoBraceInitialization(std::vector< int > v)
Definition: test_class.cpp:30
foo
void foo(CV_QUALIFIER Matrix3d &m)
Definition: block_nonconst_ctor_on_const_xpr_0.cpp:11
DoesntBreak7
py::class_< BreaksBase< 7 >, BreaksTramp< 7 >, std::shared_ptr< BreaksBase< 7 > >> DoesntBreak7
Definition: test_class.cpp:576
m
Matrix3f m
Definition: AngleAxis_mimic_euler.cpp:1
Eigen::Triplet< double >
Dog
Definition: test_tagbased_polymorphic.cpp:41
init
detail::initimpl::constructor< Args... > init()
Binds an existing constructor taking arguments Args...
Definition: pybind11.h:1912
PYBIND11_OVERRIDE
#define PYBIND11_OVERRIDE(ret_type, cname, fn,...)
Definition: pybind11.h:2854
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
DoesntBreak4
py::class_< BreaksBase< 4 >, BreaksTramp< 4 > > DoesntBreak4
Definition: test_class.cpp:573
Dog::Dog
Dog(const std::string &_name, Kind _kind=Kind::Dog)
Definition: test_tagbased_polymorphic.cpp:42
CHECK_HOLDER
#define CHECK_HOLDER(N, TYPE)
Definition: test_class.cpp:606
PYBIND11_WARNING_DISABLE_MSVC
PYBIND11_WARNING_PUSH PYBIND11_WARNING_DISABLE_MSVC(5054) PYBIND11_WARNING_POP static_assert(EIGEN_VERSION_AT_LEAST(3
pybind11_tests.h
BreaksBase::~BreaksBase
virtual ~BreaksBase()=default
args
Definition: pytypes.h:2163
print_destroyed
void print_destroyed(T *inst, Values &&...values)
Definition: constructor_stats.h:314
p
float * p
Definition: Tutorial_Map_using.cpp:9
v
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
uint64_t
unsigned __int64 uint64_t
Definition: ms_stdint.h:95
test_class::pr4220_tripped_over_this::bind_empty0
void bind_empty0(py::module_ &m)
Definition: test_class.cpp:50
BreaksTramp
Definition: test_class.cpp:568
NoBraceInitialization
Definition: test_class.cpp:29
gtsam.examples.ShonanAveragingCLI.str
str
Definition: ShonanAveragingCLI.py:115
DoesntBreak1
py::class_< BreaksBase< 1 >, std::unique_ptr< BreaksBase< 1 > >, BreaksTramp< 1 > > DoesntBreak1
Definition: test_class.cpp:570
CHECK_BROKEN
#define CHECK_BROKEN(N)
Definition: test_class.cpp:624
gtsam::make
static LabeledSymbol make(gtsam::Key key)
Definition: LabeledSymbol.cpp:109
Dog::bark
std::string bark() const
Definition: test_tagbased_polymorphic.cpp:43
test_callbacks.value
value
Definition: test_callbacks.py:158
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
obj_class_name
const char * obj_class_name(PyObject *obj)
Definition: pytypes.h:470
uintptr_t
_W64 unsigned int uintptr_t
Definition: ms_stdint.h:124
print_created
void print_created(T *inst, Values &&...values)
Definition: constructor_stats.h:309
NoBraceInitialization::vec
std::vector< int > vec
Definition: test_class.cpp:34
Eigen::Aligned
@ Aligned
Definition: Constants.h:240
local_bindings.h


gtsam
Author(s):
autogenerated on Tue Jun 25 2024 03:05:28