File Coverage

src/xs/Ref.h
Criterion Covered Total %
statement 0 12 0.0
branch 0 8 0.0
condition n/a
subroutine n/a
pod n/a
total 0 20 0.0


line stmt bran cond sub pod time code
1             #pragma once
2             #include
3              
4             namespace xs {
5              
6             using xs::my_perl;
7              
8 0           struct Ref : Scalar {
9 0           Ref (std::nullptr_t = nullptr) {}
10             Ref (SV* sv, bool policy = INCREMENT) : Scalar(sv, policy) { _validate(); }
11              
12             Ref (const Ref& oth) : Scalar(oth) {}
13             Ref (Ref&& oth) : Scalar(std::move(oth)) {}
14             Ref (const Scalar& oth) : Scalar(oth) { _validate(); }
15             Ref (Scalar&& oth) : Scalar(std::move(oth)) { _validate(); }
16             Ref (const Sv& oth) : Ref(oth.get()) {}
17             Ref (Sv&& oth) : Scalar(std::move(oth)) { _validate(); }
18              
19             Ref (const Simple&) = delete;
20             Ref (const Glob&) = delete;
21             Ref (const Array&) = delete;
22             Ref (const Hash&) = delete;
23             Ref (const Sub&) = delete;
24             Ref (const Io&) = delete;
25              
26             static Ref create (SV* sv = nullptr, bool policy = INCREMENT) {
27             SV* rv;
28             if (sv) rv = (policy == INCREMENT) ? newRV(sv) : newRV_noinc(sv);
29             else rv = newRV_noinc(newSV(0));
30             return Ref(rv, NONE);
31             }
32             static Ref create (AV* sv, bool policy = INCREMENT) { return create((SV*)sv, policy); }
33             static Ref create (HV* sv, bool policy = INCREMENT) { return create((SV*)sv, policy); }
34             static Ref create (CV* sv, bool policy = INCREMENT) { return create((SV*)sv, policy); }
35             static Ref create (GV* sv, bool policy = INCREMENT) { return create((SV*)sv, policy); }
36             static Ref create (IO* sv, bool policy = INCREMENT) { return create((SV*)sv, policy); }
37              
38             static Ref create (const Sv& o) { return create(o.get()); }
39              
40 0           Ref& operator= (SV* val) {
41 0           Scalar::operator=(val);
42 0           _validate();
43 0           return *this;
44             }
45              
46             Ref& operator= (const Ref& oth) {
47             Scalar::operator=(oth.sv);
48             return *this;
49             }
50              
51             Ref& operator= (Ref&& oth) {
52             Scalar::operator=(std::move(oth));
53             return *this;
54             }
55              
56             Ref& operator= (const Scalar& oth) {
57             Scalar::operator=(oth);
58             _validate();
59             return *this;
60             }
61              
62             Ref& operator= (Scalar&& oth) {
63             Scalar::operator=(std::move(oth));
64             _validate();
65             return *this;
66             }
67              
68             Ref& operator= (const Sv& oth) { return operator=(oth.get()); }
69              
70             Ref& operator= (Sv&& oth) {
71             Scalar::operator=(std::move(oth));
72             _validate();
73             return *this;
74             }
75              
76             Ref& operator= (const Simple&) = delete;
77             Ref& operator= (const Glob&) = delete;
78             Ref& operator= (const Array&) = delete;
79             Ref& operator= (const Hash&) = delete;
80             Ref& operator= (const Sub&) = delete;
81             Ref& operator= (const Io&) = delete;
82              
83             void set (SV* val) { Scalar::set(val); }
84              
85             template enable_if_sv_t value () const { return T(sv ? SvRV(sv) : nullptr); }
86              
87             void value (SV* val, bool policy = INCREMENT) {
88             if (!val) val = &PL_sv_undef;
89             else if (policy == INCREMENT) SvREFCNT_inc_simple_void_NN(val);
90             if (sv) {
91             SvREFCNT_dec_NN(SvRV(sv));
92             SvRV_set(sv, val);
93             }
94             else sv = newRV_noinc(val);
95             }
96             void value (AV* val, bool policy = INCREMENT) { value((SV*)val, policy); }
97             void value (HV* val, bool policy = INCREMENT) { value((SV*)val, policy); }
98             void value (CV* val, bool policy = INCREMENT) { value((SV*)val, policy); }
99             void value (GV* val, bool policy = INCREMENT) { value((SV*)val, policy); }
100             void value (IO* val, bool policy = INCREMENT) { value((SV*)val, policy); }
101             void value (const Sv& val) { value(val.get()); }
102             void value (std::nullptr_t) { value((SV*)nullptr); }
103              
104             private:
105 0           inline void _validate () {
106 0 0         if (!sv) return;
107 0 0         if (SvROK(sv)) return;
108 0 0         if (is_undef()) return reset();
109 0           reset();
110 0 0         throw std::invalid_argument("SV is not a reference");
111             }
112             };
113              
114             }