smart_holder_poc_test.cpp 11.9 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
69
70
71
72
    static int value        = 19;
    auto hld                = smart_holder::from_raw_ptr_unowned(&value);
    auto condense_for_macro = [](smart_holder &hld) {
        hld.as_unique_ptr_with_deleter<int, helpers::functor_builtin_delete<int>>();
    };
    REQUIRE_THROWS_WITH(condense_for_macro(hld),
                        "Missing unique_ptr deleter (as_unique_ptr_with_deleter).");
73
}
74
75

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

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

TEST_CASE("from_raw_ptr_take_ownership+as_raw_ptr_release_ownership1", "[S]") {
88
89
90
91
    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);
92
93
}

94
TEST_CASE("from_raw_ptr_take_ownership+as_raw_ptr_release_ownership2", "[E]") {
95
96
97
98
    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).");
99
}
100
101

TEST_CASE("from_raw_ptr_take_ownership+as_unique_ptr1", "[S]") {
102
103
104
105
    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);
106
107
}

108
TEST_CASE("from_raw_ptr_take_ownership+as_unique_ptr2", "[E]") {
109
110
111
    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).");
112
}
113

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

TEST_CASE("from_raw_ptr_take_ownership+as_shared_ptr", "[S]") {
124
125
126
127
    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);
128
129
}

130
TEST_CASE("from_unique_ptr+as_lvalue_ref", "[S]") {
131
132
133
    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);
134
    REQUIRE(hld.as_lvalue_ref<int>() == 19);
135
136
}

137
TEST_CASE("from_unique_ptr+as_raw_ptr_release_ownership1", "[S]") {
138
139
140
141
142
143
    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);
144
145
}

146
TEST_CASE("from_unique_ptr+as_raw_ptr_release_ownership2", "[E]") {
147
148
149
150
151
152
    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).");
153
}
154
155

TEST_CASE("from_unique_ptr+as_unique_ptr1", "[S]") {
156
157
158
159
160
161
    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);
162
163
}

164
TEST_CASE("from_unique_ptr+as_unique_ptr2", "[E]") {
165
166
167
168
169
    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).");
170
}
171

172
TEST_CASE("from_unique_ptr+as_unique_ptr_with_deleter", "[E]") {
173
174
175
176
177
178
179
180
    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) {
        hld.as_unique_ptr_with_deleter<int, helpers::functor_builtin_delete<int>>();
    };
    REQUIRE_THROWS_WITH(condense_for_macro(hld),
                        "Missing unique_ptr deleter (as_unique_ptr_with_deleter).");
181
}
182
183

TEST_CASE("from_unique_ptr+as_shared_ptr", "[S]") {
184
185
186
187
188
189
    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);
190
191
}

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

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

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

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

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

TEST_CASE("from_unique_ptr_with_deleter+as_shared_ptr", "[S]") {
236
237
238
239
240
241
    std::unique_ptr<int, helpers::functor_builtin_delete<int>> orig_owner(new int(19));
    auto hld = smart_holder::from_unique_ptr_with_deleter(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);
242
243
}

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

250
TEST_CASE("from_shared_ptr+as_raw_ptr_release_ownership", "[E]") {
251
252
253
254
    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).");
255
}
256

257
TEST_CASE("from_shared_ptr+as_unique_ptr", "[E]") {
258
259
260
261
    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).");
262
}
263

264
TEST_CASE("from_shared_ptr+as_unique_ptr_with_deleter", "[E]") {
265
266
267
268
269
270
271
    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) {
        hld.as_unique_ptr_with_deleter<int, helpers::functor_builtin_delete<int>>();
    };
    REQUIRE_THROWS_WITH(condense_for_macro(hld),
                        "Missing unique_ptr deleter (as_unique_ptr_with_deleter).");
272
}
273
274

TEST_CASE("from_shared_ptr+as_shared_ptr", "[S]") {
275
276
277
    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);
278
}
279
280

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

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

TEST_CASE("error_cannot_disown_nullptr", "[E]") {
292
293
294
    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).");
295
}