smart_holder_poc_test.cpp 11.6 KB
Newer Older
1
#include "pybind11/detail/smart_holder_poc.h"
2
3
4
5
6
7
8
9

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

using pybindit::memory::smart_holder;

namespace helpers {

10
struct movable_int {
11
12
13
14
15
16
    int valu;
    movable_int(int v) : valu{v} {}
    movable_int(movable_int &&other) {
        valu       = other.valu;
        other.valu = 91;
    }
17
18
};

19
20
template <typename T>
struct functor_builtin_delete {
21
    void operator()(T *ptr) { delete ptr; }
22
23
};

24
25
26
template <typename T>
struct functor_other_delete : functor_builtin_delete<T> {};

27
} // namespace helpers
28

29
TEST_CASE("from_raw_ptr_unowned+as_raw_ptr_unowned", "[S]") {
30
31
32
    static int value = 19;
    auto hld         = smart_holder::from_raw_ptr_unowned(&value);
    REQUIRE(*hld.as_raw_ptr_unowned<int>() == 19);
33
34
}

35
TEST_CASE("from_raw_ptr_unowned+as_lvalue_ref", "[S]") {
36
37
    static int value = 19;
    auto hld         = smart_holder::from_raw_ptr_unowned(&value);
38
    REQUIRE(hld.as_lvalue_ref<int>() == 19);
39
40
}

41
TEST_CASE("from_raw_ptr_unowned+as_rvalue_ref", "[S]") {
42
43
44
    helpers::movable_int orig(19);
    {
        auto hld = smart_holder::from_raw_ptr_unowned(&orig);
45
        helpers::movable_int othr(hld.as_rvalue_ref<helpers::movable_int>());
46
47
48
        REQUIRE(othr.valu == 19);
        REQUIRE(orig.valu == 91);
    }
49
50
}

51
TEST_CASE("from_raw_ptr_unowned+as_raw_ptr_release_ownership", "[E]") {
52
53
54
55
    static int value = 19;
    auto hld         = smart_holder::from_raw_ptr_unowned(&value);
    REQUIRE_THROWS_WITH(hld.as_raw_ptr_release_ownership<int>(),
                        "Cannot disown non-owning holder (as_raw_ptr_release_ownership).");
56
}
57

58
TEST_CASE("from_raw_ptr_unowned+as_unique_ptr", "[E]") {
59
60
61
62
    static int value = 19;
    auto hld         = smart_holder::from_raw_ptr_unowned(&value);
    REQUIRE_THROWS_WITH(hld.as_unique_ptr<int>(),
                        "Cannot disown non-owning holder (as_unique_ptr).");
63
}
64

65
TEST_CASE("from_raw_ptr_unowned+as_unique_ptr_with_deleter", "[E]") {
66
67
68
    static int value        = 19;
    auto hld                = smart_holder::from_raw_ptr_unowned(&value);
    auto condense_for_macro = [](smart_holder &hld) {
69
        hld.as_unique_ptr<int, helpers::functor_builtin_delete<int>>();
70
    };
71
    REQUIRE_THROWS_WITH(condense_for_macro(hld), "Missing unique_ptr deleter (as_unique_ptr).");
72
}
73
74

TEST_CASE("from_raw_ptr_unowned+as_shared_ptr", "[S]") {
75
76
77
    static int value = 19;
    auto hld         = smart_holder::from_raw_ptr_unowned(&value);
    REQUIRE(*hld.as_shared_ptr<int>() == 19);
78
79
}

80
TEST_CASE("from_raw_ptr_take_ownership+as_lvalue_ref", "[S]") {
81
82
    auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19));
    REQUIRE(hld.has_pointee());
83
    REQUIRE(hld.as_lvalue_ref<int>() == 19);
84
85
86
}

TEST_CASE("from_raw_ptr_take_ownership+as_raw_ptr_release_ownership1", "[S]") {
87
88
89
90
    auto hld       = smart_holder::from_raw_ptr_take_ownership(new int(19));
    auto new_owner = std::unique_ptr<int>(hld.as_raw_ptr_release_ownership<int>());
    REQUIRE(!hld.has_pointee());
    REQUIRE(*new_owner == 19);
91
92
}

93
TEST_CASE("from_raw_ptr_take_ownership+as_raw_ptr_release_ownership2", "[E]") {
94
95
96
97
    auto hld     = smart_holder::from_raw_ptr_take_ownership(new int(19));
    auto shd_ptr = hld.as_shared_ptr<int>();
    REQUIRE_THROWS_WITH(hld.as_raw_ptr_release_ownership<int>(),
                        "Cannot disown use_count != 1 (as_raw_ptr_release_ownership).");
98
}
99
100

TEST_CASE("from_raw_ptr_take_ownership+as_unique_ptr1", "[S]") {
101
102
103
104
    auto hld                       = smart_holder::from_raw_ptr_take_ownership(new int(19));
    std::unique_ptr<int> new_owner = hld.as_unique_ptr<int>();
    REQUIRE(!hld.has_pointee());
    REQUIRE(*new_owner == 19);
105
106
}

107
TEST_CASE("from_raw_ptr_take_ownership+as_unique_ptr2", "[E]") {
108
109
110
    auto hld     = smart_holder::from_raw_ptr_take_ownership(new int(19));
    auto shd_ptr = hld.as_shared_ptr<int>();
    REQUIRE_THROWS_WITH(hld.as_unique_ptr<int>(), "Cannot disown use_count != 1 (as_unique_ptr).");
111
}
112

113
TEST_CASE("from_raw_ptr_take_ownership+as_unique_ptr_with_deleter", "[E]") {
114
115
    auto hld                = smart_holder::from_raw_ptr_take_ownership(new int(19));
    auto condense_for_macro = [](smart_holder &hld) {
116
        hld.as_unique_ptr<int, helpers::functor_builtin_delete<int>>();
117
    };
118
    REQUIRE_THROWS_WITH(condense_for_macro(hld), "Missing unique_ptr deleter (as_unique_ptr).");
119
}
120
121

TEST_CASE("from_raw_ptr_take_ownership+as_shared_ptr", "[S]") {
122
123
124
125
    auto hld                       = smart_holder::from_raw_ptr_take_ownership(new int(19));
    std::shared_ptr<int> new_owner = hld.as_shared_ptr<int>();
    REQUIRE(hld.has_pointee());
    REQUIRE(*new_owner == 19);
126
127
}

128
TEST_CASE("from_unique_ptr+as_lvalue_ref", "[S]") {
129
130
131
    std::unique_ptr<int> orig_owner(new int(19));
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
    REQUIRE(orig_owner.get() == nullptr);
132
    REQUIRE(hld.as_lvalue_ref<int>() == 19);
133
134
}

135
TEST_CASE("from_unique_ptr+as_raw_ptr_release_ownership1", "[S]") {
136
137
138
139
140
141
    std::unique_ptr<int> orig_owner(new int(19));
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
    REQUIRE(orig_owner.get() == nullptr);
    auto new_owner = std::unique_ptr<int>(hld.as_raw_ptr_release_ownership<int>());
    REQUIRE(!hld.has_pointee());
    REQUIRE(*new_owner == 19);
142
143
}

144
TEST_CASE("from_unique_ptr+as_raw_ptr_release_ownership2", "[E]") {
145
146
147
148
149
150
    std::unique_ptr<int> orig_owner(new int(19));
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
    REQUIRE(orig_owner.get() == nullptr);
    auto shd_ptr = hld.as_shared_ptr<int>();
    REQUIRE_THROWS_WITH(hld.as_raw_ptr_release_ownership<int>(),
                        "Cannot disown use_count != 1 (as_raw_ptr_release_ownership).");
151
}
152
153

TEST_CASE("from_unique_ptr+as_unique_ptr1", "[S]") {
154
155
156
157
158
159
    std::unique_ptr<int> orig_owner(new int(19));
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
    REQUIRE(orig_owner.get() == nullptr);
    std::unique_ptr<int> new_owner = hld.as_unique_ptr<int>();
    REQUIRE(!hld.has_pointee());
    REQUIRE(*new_owner == 19);
160
161
}

162
TEST_CASE("from_unique_ptr+as_unique_ptr2", "[E]") {
163
164
165
166
167
    std::unique_ptr<int> orig_owner(new int(19));
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
    REQUIRE(orig_owner.get() == nullptr);
    auto shd_ptr = hld.as_shared_ptr<int>();
    REQUIRE_THROWS_WITH(hld.as_unique_ptr<int>(), "Cannot disown use_count != 1 (as_unique_ptr).");
168
}
169

170
TEST_CASE("from_unique_ptr+as_unique_ptr_with_deleter", "[E]") {
171
172
173
174
    std::unique_ptr<int> orig_owner(new int(19));
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
    REQUIRE(orig_owner.get() == nullptr);
    auto condense_for_macro = [](smart_holder &hld) {
175
        hld.as_unique_ptr<int, helpers::functor_builtin_delete<int>>();
176
177
    };
    REQUIRE_THROWS_WITH(condense_for_macro(hld),
178
                        "Incompatible unique_ptr deleter (as_unique_ptr).");
179
}
180
181

TEST_CASE("from_unique_ptr+as_shared_ptr", "[S]") {
182
183
184
185
186
187
    std::unique_ptr<int> orig_owner(new int(19));
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
    REQUIRE(orig_owner.get() == nullptr);
    std::shared_ptr<int> new_owner = hld.as_shared_ptr<int>();
    REQUIRE(hld.has_pointee());
    REQUIRE(*new_owner == 19);
188
189
}

190
TEST_CASE("from_unique_ptr_with_deleter+as_lvalue_ref", "[S]") {
191
    std::unique_ptr<int, helpers::functor_builtin_delete<int>> orig_owner(new int(19));
192
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
193
    REQUIRE(orig_owner.get() == nullptr);
194
    REQUIRE(hld.as_lvalue_ref<int>() == 19);
195
196
}

197
TEST_CASE("from_unique_ptr_with_deleter+as_raw_ptr_release_ownership", "[E]") {
198
    std::unique_ptr<int, helpers::functor_builtin_delete<int>> orig_owner(new int(19));
199
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
200
201
202
    REQUIRE(orig_owner.get() == nullptr);
    REQUIRE_THROWS_WITH(hld.as_raw_ptr_release_ownership<int>(),
                        "Cannot disown custom deleter (as_raw_ptr_release_ownership).");
203
}
204

205
TEST_CASE("from_unique_ptr_with_deleter+as_unique_ptr", "[E]") {
206
    std::unique_ptr<int, helpers::functor_builtin_delete<int>> orig_owner(new int(19));
207
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
208
    REQUIRE(orig_owner.get() == nullptr);
209
210
    REQUIRE_THROWS_WITH(hld.as_unique_ptr<int>(),
                        "Incompatible unique_ptr deleter (as_unique_ptr).");
211
}
212
213

TEST_CASE("from_unique_ptr_with_deleter+as_unique_ptr_with_deleter1", "[S]") {
214
    std::unique_ptr<int, helpers::functor_builtin_delete<int>> orig_owner(new int(19));
215
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
216
217
    REQUIRE(orig_owner.get() == nullptr);
    std::unique_ptr<int, helpers::functor_builtin_delete<int>> new_owner
218
        = hld.as_unique_ptr<int, helpers::functor_builtin_delete<int>>();
219
220
    REQUIRE(!hld.has_pointee());
    REQUIRE(*new_owner == 19);
221
222
}

223
TEST_CASE("from_unique_ptr_with_deleter+as_unique_ptr_with_deleter2", "[E]") {
224
    std::unique_ptr<int, helpers::functor_builtin_delete<int>> orig_owner(new int(19));
225
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
226
    REQUIRE(orig_owner.get() == nullptr);
227
228
    auto condense_for_macro
        = [](smart_holder &hld) { hld.as_unique_ptr<int, helpers::functor_other_delete<int>>(); };
229
    REQUIRE_THROWS_WITH(condense_for_macro(hld),
230
                        "Incompatible unique_ptr deleter (as_unique_ptr).");
231
}
232
233

TEST_CASE("from_unique_ptr_with_deleter+as_shared_ptr", "[S]") {
234
    std::unique_ptr<int, helpers::functor_builtin_delete<int>> orig_owner(new int(19));
235
    auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
236
237
238
239
    REQUIRE(orig_owner.get() == nullptr);
    std::shared_ptr<int> new_owner = hld.as_shared_ptr<int>();
    REQUIRE(hld.has_pointee());
    REQUIRE(*new_owner == 19);
240
241
}

242
TEST_CASE("from_shared_ptr+as_lvalue_ref", "[S]") {
243
244
    std::shared_ptr<int> orig_owner(new int(19));
    auto hld = smart_holder::from_shared_ptr(orig_owner);
245
    REQUIRE(hld.as_lvalue_ref<int>() == 19);
246
247
}

248
TEST_CASE("from_shared_ptr+as_raw_ptr_release_ownership", "[E]") {
249
250
251
252
    std::shared_ptr<int> orig_owner(new int(19));
    auto hld = smart_holder::from_shared_ptr(orig_owner);
    REQUIRE_THROWS_WITH(hld.as_raw_ptr_release_ownership<int>(),
                        "Cannot disown external shared_ptr (as_raw_ptr_release_ownership).");
253
}
254

255
TEST_CASE("from_shared_ptr+as_unique_ptr", "[E]") {
256
257
258
259
    std::shared_ptr<int> orig_owner(new int(19));
    auto hld = smart_holder::from_shared_ptr(orig_owner);
    REQUIRE_THROWS_WITH(hld.as_unique_ptr<int>(),
                        "Cannot disown external shared_ptr (as_unique_ptr).");
260
}
261

262
TEST_CASE("from_shared_ptr+as_unique_ptr_with_deleter", "[E]") {
263
264
265
    std::shared_ptr<int> orig_owner(new int(19));
    auto hld                = smart_holder::from_shared_ptr(orig_owner);
    auto condense_for_macro = [](smart_holder &hld) {
266
        hld.as_unique_ptr<int, helpers::functor_builtin_delete<int>>();
267
    };
268
    REQUIRE_THROWS_WITH(condense_for_macro(hld), "Missing unique_ptr deleter (as_unique_ptr).");
269
}
270
271

TEST_CASE("from_shared_ptr+as_shared_ptr", "[S]") {
272
273
274
    std::shared_ptr<int> orig_owner(new int(19));
    auto hld = smart_holder::from_shared_ptr(orig_owner);
    REQUIRE(*hld.as_shared_ptr<int>() == 19);
275
}
276
277

TEST_CASE("error_unpopulated_holder", "[E]") {
278
    smart_holder hld;
279
    REQUIRE_THROWS_WITH(hld.as_lvalue_ref<int>(), "Unpopulated holder (as_lvalue_ref).");
280
281
282
}

TEST_CASE("error_disowned_holder", "[E]") {
283
284
    auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19));
    hld.as_unique_ptr<int>();
285
    REQUIRE_THROWS_WITH(hld.as_lvalue_ref<int>(), "Disowned holder (as_lvalue_ref).");
286
}
287
288

TEST_CASE("error_cannot_disown_nullptr", "[E]") {
289
290
291
    auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19));
    hld.as_unique_ptr<int>();
    REQUIRE_THROWS_WITH(hld.as_unique_ptr<int>(), "Cannot disown nullptr (as_unique_ptr).");
292
}