FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
cpp11/inst/include/cpp11/external_pointer.hpp at master · tmastny/cpp11 · GitHub
tmastny
/
cpp11
Public
forked from
r-lib/cpp11
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
cpp11
/
inst
/
include
/
cpp11
/
external_pointer.hpp
Copy path
More file actions
More file actions
Latest commit
History
History
History
162 lines (126 loc) · 4.02 KB
Breadcrumbs
cpp11
/
inst
/
include
/
cpp11
/
external_pointer.hpp
Copy path
File metadata and controls
162 lines (126 loc) · 4.02 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#
pragma
once
#
include
<
cstddef
>
//
for nullptr_t, NULL
#
include
<
memory
>
//
for bad_weak_ptr
#
include
<
type_traits
>
//
for add_lvalue_reference
#
include
"
cpp11/R.hpp
"
//
for SEXP, SEXPREC, TYPEOF, R_NilValue, R_C...
#
include
"
cpp11/protect.hpp
"
//
for protect, safe, protect::function
#
include
"
cpp11/r_vector.hpp
"
//
for type_error
#
include
"
cpp11/sexp.hpp
"
//
for sexp
namespace
cpp11
{
template
<
typename
T>
void
default_deleter
(T* obj) {
delete
obj;
}
template
<
typename
T,
void
Deleter
(T*) = default_deleter<T>>
class external_pointer {
private:
sexp data_ = R_NilValue;
static
SEXP
valid_type
(
SEXP
data) {
if
(
TYPEOF
(data) !=
EXTPTRSXP
) {
throw
type_error
(
EXTPTRSXP
,
TYPEOF
(data));
}
return
data;
}
static
void
r_deleter
(
SEXP
p) {
if
(
TYPEOF
(p) !=
EXTPTRSXP
)
return
;
T* ptr =
static_cast
<T*>(
R_ExternalPtrAddr
(p));
if
(ptr ==
NULL
) {
return
;
}
R_ClearExternalPtr
(p);
Deleter
(ptr);
}
public:
using
pointer = T*;
external_pointer
()
noexcept
{}
external_pointer
(std::
nullptr_t
)
noexcept
{}
external_pointer
(
SEXP
data) :
data_
(
valid_type
(data)) {}
external_pointer
(pointer p,
bool
use_deleter =
true
,
bool
finalize_on_exit =
true
)
:
data_
(safe[R_MakeExternalPtr]((
void
*)p, R_NilValue, R_NilValue)) {
if
(use_deleter) {
R_RegisterCFinalizerEx
(data_, r_deleter,
static_cast
<Rboolean>(finalize_on_exit));
}
}
external_pointer
(
const
external_pointer& rhs) {
data_ = safe[Rf_shallow_duplicate](rhs.
data_
);
}
external_pointer
(external_pointer&& rhs) {
reset
(rhs.
release
()); }
external_pointer&
operator
=(external_pointer&& rhs)
noexcept
{
reset
(rhs.
release
()); }
external_pointer&
operator
=(std::
nullptr_t
)
noexcept
{
reset
(); };
operator
SEXP
()
const
noexcept
{
return
data_; }
pointer
get
()
const
noexcept
{
pointer addr =
static_cast
<T*>(
R_ExternalPtrAddr
(data_));
if
(addr ==
nullptr
) {
return
nullptr
;
}
return
addr;
}
typename
std::add_lvalue_reference<T>::type
operator
*() {
pointer addr =
get
();
if
(addr ==
nullptr
) {
throw
std::bad_weak_ptr
();
}
return
*
get
();
}
pointer
operator
->()
const
{
pointer addr =
get
();
if
(addr ==
nullptr
) {
throw
std::bad_weak_ptr
();
}
return
get
();
}
pointer
release
()
noexcept
{
if
(
get
() ==
nullptr
) {
return
nullptr
;
}
pointer ptr =
get
();
R_ClearExternalPtr
(data_);
return
ptr;
}
void
reset
(pointer ptr =
pointer
()) {
SEXP
old_data = data_;
data_ = safe[R_MakeExternalPtr]((
void
*)ptr, R_NilValue, R_NilValue);
r_deleter
(old_data);
}
void
swap
(external_pointer& other)
noexcept
{
SEXP
tmp = other.
data_
;
other.
data_
= data_;
data_ = tmp;
}
operator
bool
()
noexcept
{
return
data_ !=
nullptr
; }
};
template
<
class
T
,
void
Deleter
(T*)>
void swap(external_pointer<T, Deleter>& lhs, external_pointer<T, Deleter>& rhs)
noexcept
{
lhs.
swap
(rhs);
}
template
<
class
T
,
void
Deleter
(T*)>
bool operator==(
const
external_pointer<T, Deleter>& x,
const
external_pointer<T, Deleter>& y) {
return
x.
data_
== y.
data_
;
}
template
<
class
T
,
void
Deleter
(T*)>
bool operator!=(
const
external_pointer<T, Deleter>& x,
const
external_pointer<T, Deleter>& y) {
return
x.
data_
!= y.
data_
;
}
template
<
class
T
,
void
Deleter
(T*)>
bool operator<(
const
external_pointer<T, Deleter>& x,
const
external_pointer<T, Deleter>& y) {
return
x.
data_
< y.
data_
;
}
template
<
class
T
,
void
Deleter
(T*)>
bool operator<=(
const
external_pointer<T, Deleter>& x,
const
external_pointer<T, Deleter>& y) {
return
x.
data_
<= y.
data_
;
}
template
<
class
T
,
void
Deleter
(T*)>
bool operator>(
const
external_pointer<T, Deleter>& x,
const
external_pointer<T, Deleter>& y) {
return
x.
data_
> y.
data_
;
}
template
<
class
T
,
void
Deleter
(T*)>
bool operator>=(
const
external_pointer<T, Deleter>& x,
const
external_pointer<T, Deleter>& y) {
return
x.
data_
>= y.
data_
;
}
}
//
namespace cpp11
Back
|
FazBrowse Home
|
New Git URL