line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#pragma once |
2
|
|
|
|
|
|
|
#include |
3
|
|
|
|
|
|
|
#include |
4
|
|
|
|
|
|
|
#include |
5
|
|
|
|
|
|
|
#include |
6
|
|
|
|
|
|
|
#include |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
namespace xs { |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
class Backref { |
11
|
|
|
|
|
|
|
public: |
12
|
|
|
|
|
|
|
mutable SV* svobj; |
13
|
|
|
|
|
|
|
mutable bool zombie; |
14
|
|
|
|
|
|
|
mutable bool in_cdtor; |
15
|
|
|
|
|
|
|
|
16
|
1152
|
|
|
|
|
|
template static const Backref* get (T* var) { return panda::dyn_cast(var); } |
17
|
|
|
|
|
|
|
template static const Backref* get (const panda::iptr& var) { return panda::dyn_cast(var.get()); } |
18
|
|
|
|
|
|
|
template static const Backref* get (const std::shared_ptr& var) { return panda::dyn_cast(var.get()); } |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
protected: |
21
|
26
|
|
|
|
|
|
Backref () : svobj(NULL), zombie(false), in_cdtor(false) {} |
22
|
|
|
|
|
|
|
|
23
|
26
|
|
|
|
|
|
void dtor () const { |
24
|
26
|
|
|
|
|
|
in_cdtor = true; |
25
|
26
|
100
|
|
|
|
|
if (!svobj) return; |
26
|
23
|
|
|
|
|
|
auto tmp = svobj; |
27
|
23
|
|
|
|
|
|
svobj = NULL; |
28
|
26
|
50
|
|
|
|
|
SvREFCNT_dec_NN(tmp); |
29
|
|
|
|
|
|
|
}; |
30
|
|
|
|
|
|
|
|
31
|
52
|
50
|
|
|
|
|
virtual ~Backref () { if (!in_cdtor) _throw_no_dtor(); } // protect against forgetting calling the dtor() |
|
|
50
|
|
|
|
|
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
private: |
34
|
0
|
|
|
|
|
|
static void _throw_no_dtor () { |
35
|
0
|
0
|
|
|
|
|
throw std::logic_error("~Backref panic: dtor() wasn't called - you must explicitly call Backref::dtor() or use make_backref()"); |
36
|
|
|
|
|
|
|
} |
37
|
|
|
|
|
|
|
}; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
template |
40
|
|
|
|
|
|
|
class BackrefWrapper : public CLASS, public Backref { |
41
|
|
|
|
|
|
|
~BackrefWrapper () override { Backref::dtor(); } |
42
|
|
|
|
|
|
|
public: |
43
|
|
|
|
|
|
|
template BackrefWrapper (Args&&... args) : CLASS(std::forward(args)...) {} |
44
|
|
|
|
|
|
|
}; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
template inline CLASS* make_backref (Args&&... args) { |
47
|
|
|
|
|
|
|
return new BackrefWrapper(std::forward(args)...); |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
} |