1bb611c8fSApple OSS Distributions //
2bb611c8fSApple OSS Distributions // Tests for
3bb611c8fSApple OSS Distributions //  void reset(pointer p, retain_t) noexcept;
4bb611c8fSApple OSS Distributions //
5bb611c8fSApple OSS Distributions 
6bb611c8fSApple OSS Distributions #include <libkern/c++/intrusive_shared_ptr.h>
7bb611c8fSApple OSS Distributions #include <darwintest.h>
8bb611c8fSApple OSS Distributions #include "test_policy.h"
9bb611c8fSApple OSS Distributions 
10bb611c8fSApple OSS Distributions struct T {
11bb611c8fSApple OSS Distributions 	int i;
12bb611c8fSApple OSS Distributions };
13bb611c8fSApple OSS Distributions 
14bb611c8fSApple OSS Distributions template <typename T>
15bb611c8fSApple OSS Distributions static void
tests()16bb611c8fSApple OSS Distributions tests()
17bb611c8fSApple OSS Distributions {
18bb611c8fSApple OSS Distributions 	T obj1{1};
19bb611c8fSApple OSS Distributions 	T obj2{2};
20bb611c8fSApple OSS Distributions 
21bb611c8fSApple OSS Distributions 	// reset() non-null shared pointer to non-null raw pointer
22bb611c8fSApple OSS Distributions 	{
23bb611c8fSApple OSS Distributions 		tracked_shared_ptr<T> ptr(&obj1, libkern::retain);
24bb611c8fSApple OSS Distributions 		tracking_policy::reset();
25bb611c8fSApple OSS Distributions 		ptr.reset(&obj2, libkern::retain);
26bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::releases == 1);
27bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::retains == 1);
28bb611c8fSApple OSS Distributions 		CHECK(ptr.get() == &obj2);
29bb611c8fSApple OSS Distributions 	}
30bb611c8fSApple OSS Distributions 
31bb611c8fSApple OSS Distributions 	// reset() non-null shared pointer to null raw pointer
32bb611c8fSApple OSS Distributions 	{
33bb611c8fSApple OSS Distributions 		tracked_shared_ptr<T> ptr(&obj1, libkern::retain);
34bb611c8fSApple OSS Distributions 		tracking_policy::reset();
35bb611c8fSApple OSS Distributions 		ptr.reset(nullptr, libkern::retain);
36bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::releases == 1);
37bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::retains == 0);
38bb611c8fSApple OSS Distributions 		CHECK(ptr.get() == nullptr);
39bb611c8fSApple OSS Distributions 	}
40bb611c8fSApple OSS Distributions 
41bb611c8fSApple OSS Distributions 	// reset() null shared pointer to non-null raw pointer
42bb611c8fSApple OSS Distributions 	{
43bb611c8fSApple OSS Distributions 		tracked_shared_ptr<T> ptr = nullptr;
44bb611c8fSApple OSS Distributions 		tracking_policy::reset();
45bb611c8fSApple OSS Distributions 		ptr.reset(&obj2, libkern::retain);
46bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::releases == 0);
47bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::retains == 1);
48bb611c8fSApple OSS Distributions 		CHECK(ptr.get() == &obj2);
49bb611c8fSApple OSS Distributions 	}
50bb611c8fSApple OSS Distributions 
51bb611c8fSApple OSS Distributions 	// reset() null shared pointer to null raw pointer
52bb611c8fSApple OSS Distributions 	{
53bb611c8fSApple OSS Distributions 		tracked_shared_ptr<T> ptr = nullptr;
54bb611c8fSApple OSS Distributions 		tracking_policy::reset();
55bb611c8fSApple OSS Distributions 		ptr.reset(nullptr, libkern::retain);
56bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::releases == 0);
57bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::retains == 0);
58bb611c8fSApple OSS Distributions 		CHECK(ptr.get() == nullptr);
59bb611c8fSApple OSS Distributions 	}
60bb611c8fSApple OSS Distributions 
61bb611c8fSApple OSS Distributions 	// self-reset() should not cause the refcount to hit 0, ever
62bb611c8fSApple OSS Distributions 	{
63bb611c8fSApple OSS Distributions 		tracking_policy::reset();
64bb611c8fSApple OSS Distributions 		tracked_shared_ptr<T> ptr(&obj1, libkern::retain);
65bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::retains == 1);
66bb611c8fSApple OSS Distributions 		ptr.reset(ptr.get(), libkern::retain);
67bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::retains == 2);
68bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::releases == 1);
69bb611c8fSApple OSS Distributions 		CHECK(tracking_policy::refcount == 1);
70bb611c8fSApple OSS Distributions 		CHECK(!tracking_policy::hit_zero);
71bb611c8fSApple OSS Distributions 		CHECK(ptr.get() == &obj1);
72bb611c8fSApple OSS Distributions 	}
73bb611c8fSApple OSS Distributions 
74bb611c8fSApple OSS Distributions 	// reset() as a self-reference
75bb611c8fSApple OSS Distributions 	{
76bb611c8fSApple OSS Distributions 		tracked_shared_ptr<T> ptr;
77bb611c8fSApple OSS Distributions 		tracked_shared_ptr<T> ptr2;
78bb611c8fSApple OSS Distributions 		CHECK(ptr.reset(&obj2, libkern::retain));
79bb611c8fSApple OSS Distributions 
80bb611c8fSApple OSS Distributions 		// check short-circuiting
81bb611c8fSApple OSS Distributions 		bool ok =  (ptr.reset() && ptr2.reset(&obj1, libkern::retain));
82bb611c8fSApple OSS Distributions 		CHECK(ptr2.get() == nullptr);
83bb611c8fSApple OSS Distributions 	}
84bb611c8fSApple OSS Distributions }
85bb611c8fSApple OSS Distributions 
86*8d741a5dSApple OSS Distributions T_DECL(reset_retain, "intrusive_shared_ptr.reset.retain", T_META_TAG_VM_PREFERRED) {
87bb611c8fSApple OSS Distributions 	tests<T>();
88bb611c8fSApple OSS Distributions 	tests<T const>();
89bb611c8fSApple OSS Distributions }
90