-
Notifications
You must be signed in to change notification settings - Fork 53
Expand file tree
/
Copy pathtest-external_pointer.cpp
More file actions
88 lines (66 loc) · 2.32 KB
/
test-external_pointer.cpp
File metadata and controls
88 lines (66 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <iostream>
#include "cpp11/external_pointer.hpp"
#include <testthat.h>
bool deleted = false;
void deleter(int* ptr) {
deleted = true;
delete ptr;
}
context("external_pointer-C++") {
test_that("external_pointer works") {
std::vector<int>* v = new std::vector<int>;
v->push_back(1);
v->push_back(2);
cpp11::external_pointer<std::vector<int>> p(v);
expect_true(p->at(0) == 1);
expect_true(p->at(1) == 2);
p.release();
// Double release should be a no-op
p.release();
expect_true(p.get() == nullptr);
}
test_that("external_pointer works with a custom deleter") {
deleted = false;
cpp11::external_pointer<int, deleter> uniq(new int);
expect_true(deleted == false);
uniq.reset();
expect_true(deleted == true);
}
test_that("external_pointer preserves attributes when moved (issue #308)") {
// Test move constructor
{
int* value = new int(42);
cpp11::external_pointer<int> p(value);
// Set an attribute on the external pointer
Rf_setAttrib(p, R_ClassSymbol, Rf_mkString("test_class"));
// Verify attribute exists before move
SEXP class_attr = Rf_getAttrib(p, R_ClassSymbol);
expect_true(class_attr != R_NilValue);
// Move the external pointer using move constructor
cpp11::external_pointer<int> p_moved = std::move(p);
// Verify attribute is preserved after move
SEXP class_attr_after = Rf_getAttrib(p_moved, R_ClassSymbol);
expect_true(class_attr_after != R_NilValue);
expect_true(strcmp(CHAR(STRING_ELT(class_attr_after, 0)), "test_class") == 0);
// Clean up
delete p_moved.release();
}
// Test move assignment operator
{
int* value1 = new int(1);
cpp11::external_pointer<int> p1(value1);
// Set an attribute on p1
Rf_setAttrib(p1, R_ClassSymbol, Rf_mkString("test_class"));
// Create p2 with nullptr (no memory leak)
cpp11::external_pointer<int> p2(nullptr);
// Move assign p1 to p2
p2 = std::move(p1);
// Verify attribute is preserved after move assignment
SEXP class_attr_after = Rf_getAttrib(p2, R_ClassSymbol);
expect_true(class_attr_after != R_NilValue);
expect_true(strcmp(CHAR(STRING_ELT(class_attr_after, 0)), "test_class") == 0);
// Clean up
delete p2.release();
}
}
}