20 class huge_unique_ptr {
21 std::unique_ptr<T> ptr;
25 explicit huge_unique_ptr(
T *
p) : ptr(p) {}
26 T *
get() {
return ptr.get(); }
31 class custom_unique_ptr {
32 std::unique_ptr<T> impl;
35 explicit custom_unique_ptr(
T *
p) : impl(p) {}
36 T *
get()
const {
return impl.get(); }
37 T *release_ptr() {
return impl.release(); }
44 class shared_ptr_with_addressof_operator {
45 std::shared_ptr<T> impl;
48 shared_ptr_with_addressof_operator() =
default;
49 explicit shared_ptr_with_addressof_operator(
T *
p) : impl(p) {}
50 T *
get()
const {
return impl.get(); }
51 T **
operator&() {
throw std::logic_error(
"Call of overloaded operator& is not expected"); }
58 class unique_ptr_with_addressof_operator {
59 std::unique_ptr<T> impl;
62 unique_ptr_with_addressof_operator() =
default;
63 explicit unique_ptr_with_addressof_operator(
T *
p) : impl(p) {}
64 T *
get()
const {
return impl.get(); }
65 T *release_ptr() {
return impl.release(); }
66 T **
operator&() {
throw std::logic_error(
"Call of overloaded operator& is not expected"); }
70 class MyObject1 :
public Object {
73 std::string toString()
const override {
return "MyObject1[" + std::to_string(value) +
"]"; }
85 MyObject2(
const MyObject2 &) =
default;
87 std::string toString()
const {
return "MyObject2[" + std::to_string(value) +
"]"; }
95 class MyObject3 :
public std::enable_shared_from_this<MyObject3> {
97 MyObject3(
const MyObject3 &) =
default;
99 std::string toString()
const {
return "MyObject3[" + std::to_string(value) +
"]"; }
109 std::unordered_set<MyObject4 *> myobject4_instances;
112 explicit MyObject4(
int value) : value{value} {
114 myobject4_instances.insert(
this);
118 static void cleanupAllInstances() {
119 auto tmp = std::move(myobject4_instances);
120 myobject4_instances.clear();
121 for (
auto *o : tmp) {
128 myobject4_instances.erase(
this);
137 std::unordered_set<MyObject4a *> myobject4a_instances;
140 explicit MyObject4a(
int i) : value{i} {
142 myobject4a_instances.insert(
this);
146 static void cleanupAllInstances() {
147 auto tmp = std::move(myobject4a_instances);
148 myobject4a_instances.clear();
149 for (
auto *o : tmp) {
155 virtual ~MyObject4a() {
156 myobject4a_instances.erase(
this);
162 class MyObject4b :
public MyObject4a {
164 explicit MyObject4b(
int i) : MyObject4a(i) {
print_created(
this); }
171 explicit MyObject5(
int value) : value{value} {
print_created(
this); }
177 struct SharedPtrRef {
186 std::shared_ptr<A> shared = std::make_shared<A>();
190 struct SharedFromThisRef {
191 struct B : std::enable_shared_from_this<B> {
200 std::shared_ptr<B> shared = std::make_shared<B>();
204 struct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> {
205 SharedFromThisVBase() =
default;
206 SharedFromThisVBase(
const SharedFromThisVBase &) =
default;
207 virtual ~SharedFromThisVBase() =
default;
209 struct SharedFromThisVirt :
virtual SharedFromThisVBase {};
218 struct TypeForHolderWithAddressOf {
220 TypeForHolderWithAddressOf(
const TypeForHolderWithAddressOf &) {
print_copy_created(
this); }
221 TypeForHolderWithAddressOf(TypeForHolderWithAddressOf &&) noexcept {
225 std::string toString()
const {
226 return "TypeForHolderWithAddressOf[" + std::to_string(value) +
"]";
232 struct TypeForMoveOnlyHolderWithAddressOf {
233 explicit TypeForMoveOnlyHolderWithAddressOf(
int value) : value{value} {
print_created(
this); }
235 std::string toString()
const {
236 return "MoveOnlyHolderWithAddressOf[" + std::to_string(value) +
"]";
242 struct HeldByDefaultHolder {};
247 virtual ~ElementBase() =
default;
248 ElementBase() =
default;
249 ElementBase(
const ElementBase &) =
delete;
252 struct ElementA : ElementBase {
253 explicit ElementA(
int v) : v(v) {}
254 int value()
const {
return v; }
259 void add(
const std::shared_ptr<ElementBase> &
e) {
l.push_back(e); }
260 std::vector<std::shared_ptr<ElementBase>>
l;
271 template <
typename T>
273 static const T *
get(
const ref<T> &
p) {
return p.get_ptr(); }
295 py::class_<Object, ref<Object>> obj(
m,
"Object");
298 py::class_<MyObject1, ref<MyObject1>>(
m,
"MyObject1", obj).def(py::init<int>());
299 py::implicitly_convertible<py::int_, MyObject1>();
301 m.def(
"make_object_1", []() ->
Object * {
return new MyObject1(1); });
303 m.def(
"make_myobject1_1", []() -> MyObject1 * {
return new MyObject1(4); });
309 m.def(
"print_myobject1_1", [](
const MyObject1 *obj) {
py::print(obj->toString()); });
315 m.def(
"cstats_ref", &ConstructorStats::get<ref_tag>);
317 py::class_<MyObject2, std::shared_ptr<MyObject2>>(
m,
"MyObject2").def(py::init<int>());
318 m.def(
"make_myobject2_1", []() {
return new MyObject2(6); });
319 m.def(
"make_myobject2_2", []() {
return std::make_shared<MyObject2>(7); });
320 m.def(
"print_myobject2_1", [](
const MyObject2 *obj) {
py::print(obj->toString()); });
322 m.def(
"print_myobject2_2", [](std::shared_ptr<MyObject2> obj) {
py::print(obj->toString()); });
323 m.def(
"print_myobject2_3",
324 [](
const std::shared_ptr<MyObject2> &obj) {
py::print(obj->toString()); });
325 m.def(
"print_myobject2_4",
326 [](
const std::shared_ptr<MyObject2> *obj) {
py::print((*obj)->toString()); });
328 py::class_<MyObject3, std::shared_ptr<MyObject3>>(
m,
"MyObject3").def(py::init<int>());
329 m.def(
"make_myobject3_1", []() {
return new MyObject3(8); });
330 m.def(
"make_myobject3_2", []() {
return std::make_shared<MyObject3>(9); });
331 m.def(
"print_myobject3_1", [](
const MyObject3 *obj) {
py::print(obj->toString()); });
333 m.def(
"print_myobject3_2", [](std::shared_ptr<MyObject3> obj) {
py::print(obj->toString()); });
334 m.def(
"print_myobject3_3",
335 [](
const std::shared_ptr<MyObject3> &obj) {
py::print(obj->toString()); });
336 m.def(
"print_myobject3_4",
337 [](
const std::shared_ptr<MyObject3> *obj) {
py::print((*obj)->toString()); });
340 m.def(
"test_object1_refcounting", []() {
342 bool good = o->getRefCount() == 1;
343 py::object o2 =
py::cast(o, py::return_value_policy::reference);
346 good &= o->getRefCount() == 2;
351 py::class_<MyObject4, std::unique_ptr<MyObject4, py::nodelete>>(
m,
"MyObject4")
352 .def(py::init<int>())
354 .def_static(
"cleanup_all_instances", &MyObject4::cleanupAllInstances);
357 py::class_<MyObject4a, std::unique_ptr<MyObject4a, py::nodelete>>(
m,
"MyObject4a")
358 .def(py::init<int>())
360 .def_static(
"cleanup_all_instances", &MyObject4a::cleanupAllInstances);
362 py::class_<MyObject4b, MyObject4a, std::unique_ptr<MyObject4b>>(
m,
"MyObject4b")
363 .def(py::init<int>());
366 py::class_<MyObject5, huge_unique_ptr<MyObject5>>(
m,
"MyObject5")
367 .def(py::init<int>())
372 py::class_<A, std::shared_ptr<A>>(
m,
"A");
373 py::class_<SharedPtrRef, std::unique_ptr<SharedPtrRef>>(
m,
"SharedPtrRef")
376 .def_property_readonly(
378 .def_readonly(
"holder_ref", &SharedPtrRef::shared)
379 .def_property_readonly(
381 [](
const SharedPtrRef &s) {
return s.shared; },
383 .def(
"set_ref", [](SharedPtrRef &,
const A &) {
return true; })
385 .def(
"set_holder", [](SharedPtrRef &, std::shared_ptr<A>) {
return true; });
389 py::class_<B, std::shared_ptr<B>>(
m,
"B");
390 py::class_<SharedFromThisRef, std::unique_ptr<SharedFromThisRef>>(
m,
"SharedFromThisRef")
393 .def_property_readonly(
"ref",
394 [](
const SharedFromThisRef &s) ->
const B & {
return *s.shared; })
395 .def_property_readonly(
397 [](
const SharedFromThisRef &s) {
return s.value; },
399 .def_readonly(
"holder_ref", &SharedFromThisRef::shared)
400 .def_property_readonly(
402 [](
const SharedFromThisRef &s) {
return s.shared; },
404 .def(
"set_ref", [](SharedFromThisRef &,
const B &) {
return true; })
406 .def(
"set_holder", [](SharedFromThisRef &, std::shared_ptr<B>) {
return true; });
409 static std::shared_ptr<SharedFromThisVirt> sft(
new SharedFromThisVirt());
410 py::class_<SharedFromThisVirt, std::shared_ptr<SharedFromThisVirt>>(
m,
"SharedFromThisVirt")
411 .def_static(
"get", []() {
return sft.get(); });
414 py::class_<C, custom_unique_ptr<C>>(
m,
"TypeWithMoveOnlyHolder")
415 .def_static(
"make", []() {
return custom_unique_ptr<C>(
new C); })
416 .def_static(
"make_as_object", []() {
return py::cast(custom_unique_ptr<C>(
new C)); });
419 using HolderWithAddressOf = shared_ptr_with_addressof_operator<TypeForHolderWithAddressOf>;
420 py::class_<TypeForHolderWithAddressOf, HolderWithAddressOf>(
m,
"TypeForHolderWithAddressOf")
421 .def_static(
"make", []() {
return HolderWithAddressOf(
new TypeForHolderWithAddressOf); })
422 .def(
"get", [](
const HolderWithAddressOf &
self) {
return self.get(); })
423 .def(
"print_object_1",
424 [](
const TypeForHolderWithAddressOf *obj) {
py::print(obj->toString()); })
426 .def(
"print_object_2", [](HolderWithAddressOf obj) {
py::print(obj.get()->toString()); })
427 .def(
"print_object_3",
428 [](
const HolderWithAddressOf &obj) {
py::print(obj.get()->toString()); })
429 .def(
"print_object_4",
430 [](
const HolderWithAddressOf *obj) {
py::print((*obj).get()->toString()); });
433 using MoveOnlyHolderWithAddressOf
434 = unique_ptr_with_addressof_operator<TypeForMoveOnlyHolderWithAddressOf>;
435 py::class_<TypeForMoveOnlyHolderWithAddressOf, MoveOnlyHolderWithAddressOf>(
436 m,
"TypeForMoveOnlyHolderWithAddressOf")
439 return MoveOnlyHolderWithAddressOf(
440 new TypeForMoveOnlyHolderWithAddressOf(0));
444 [](
const TypeForMoveOnlyHolderWithAddressOf *obj) {
py::print(obj->toString()); });
447 py::class_<HeldByDefaultHolder, std::unique_ptr<HeldByDefaultHolder>>(
m,
"HeldByDefaultHolder")
450 .def_static(
"load_shared_ptr", [](std::shared_ptr<HeldByDefaultHolder>) {});
454 py::class_<ElementBase, std::shared_ptr<ElementBase>>(
m,
"ElementBase");
456 py::class_<ElementA, ElementBase, std::shared_ptr<ElementA>>(
m,
"ElementA")
457 .def(py::init<int>())
460 py::class_<ElementList, std::shared_ptr<ElementList>>(
m,
"ElementList")
463 .def(
"get", [](ElementList &el) {
465 for (
auto &
e : el.l) {
466 list.append(py::cast(e));
Matrix< SCALARB, Dynamic, Dynamic, opt_B > B
Reference counted object base class.
TEST_SUBMODULE(smart_ptr, m)
void print_destroyed(T *inst, Values &&...values)
DiscreteKeys operator &(const DiscreteKey &key1, const DiscreteKey &key2)
Create a list from two keys.
EIGEN_STRONG_INLINE Packet4f print(const Packet4f &a)
void print_copy_created(T *inst, Values &&...values)
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
int getRefCount() const
Return the current reference count.
static const Line3 l(Rot3(), 1, 1)
Array< int, Dynamic, 1 > v
unsigned __int64 uint64_t
EIGEN_DEVICE_FUNC NewType cast(const OldType &x)
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Reference counting helper.
Matrix< Scalar, Dynamic, Dynamic > C
virtual std::string toString() const =0
void print_created(T *inst, Values &&...values)
graph add(PriorFactor< Pose2 >(1, priorMean, priorNoise))
int EIGEN_BLAS_FUNC() copy(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
void print_move_created(T *inst, Values &&...values)
PYBIND11_DECLARE_HOLDER_TYPE(T, ref< T >, true)