File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/XS/Framework.x/i/xs/Ref.h
Criterion Covered Total %
statement 10 13 76.9
branch 5 14 35.7
condition n/a
subroutine n/a
pod n/a
total 15 27 55.5


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 10           struct Ref : Scalar {
9             Ref (std::nullptr_t = nullptr) {}
10 5 50         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              
25 5           static Ref create (SV* sv = nullptr, bool policy = INCREMENT) {
26             SV* rv;
27 5 50         if (sv) rv = (policy == INCREMENT) ? newRV(sv) : newRV_noinc(sv);
    50          
28 0           else rv = newRV_noinc(newSV(0));
29 5           return Ref(rv, NONE);
30             }
31             static Ref create (AV* sv, bool policy = INCREMENT) { return create((SV*)sv, policy); }
32             static Ref create (HV* sv, bool policy = INCREMENT) { return create((SV*)sv, policy); }
33             static Ref create (CV* sv, bool policy = INCREMENT) { return create((SV*)sv, policy); }
34             static Ref create (GV* sv, bool policy = INCREMENT) { return create((SV*)sv, policy); }
35              
36 10           static Ref create (const Sv& o) { return create(o.get()); }
37              
38             Ref& operator= (SV* val) {
39             Scalar::operator=(val);
40             _validate();
41             return *this;
42             }
43              
44             Ref& operator= (const Ref& oth) {
45             Scalar::operator=(oth.sv);
46             return *this;
47             }
48              
49             Ref& operator= (Ref&& oth) {
50             Scalar::operator=(std::move(oth));
51             return *this;
52             }
53              
54             Ref& operator= (const Scalar& oth) {
55             Scalar::operator=(oth);
56             _validate();
57             return *this;
58             }
59              
60             Ref& operator= (Scalar&& oth) {
61             Scalar::operator=(std::move(oth));
62             _validate();
63             return *this;
64             }
65              
66             Ref& operator= (const Sv& oth) { return operator=(oth.get()); }
67              
68             Ref& operator= (Sv&& oth) {
69             Scalar::operator=(std::move(oth));
70             _validate();
71             return *this;
72             }
73              
74             Ref& operator= (const Simple&) = delete;
75             Ref& operator= (const Glob&) = delete;
76             Ref& operator= (const Array&) = delete;
77             Ref& operator= (const Hash&) = delete;
78             Ref& operator= (const Sub&) = delete;
79              
80             void set (SV* val) { Scalar::set(val); }
81              
82             template enable_if_sv_t value () const { return T(sv ? SvRV(sv) : NULL); }
83              
84             void value (SV* val, bool policy = INCREMENT) {
85             if (!val) val = &PL_sv_undef;
86             else if (policy == INCREMENT) SvREFCNT_inc_simple_void_NN(val);
87             if (sv) {
88             SvREFCNT_dec_NN(SvRV(sv));
89             SvRV_set(sv, val);
90             }
91             else sv = newRV_noinc(val);
92             }
93             void value (AV* val, bool policy = INCREMENT) { value((SV*)val, policy); }
94             void value (HV* val, bool policy = INCREMENT) { value((SV*)val, policy); }
95             void value (CV* val, bool policy = INCREMENT) { value((SV*)val, policy); }
96             void value (GV* val, bool policy = INCREMENT) { value((SV*)val, policy); }
97             void value (const Sv& val) { value(val.get()); }
98             void value (std::nullptr_t) { value((SV*)nullptr); }
99              
100             private:
101 5           inline void _validate () {
102 5 50         if (!sv) return;
103 5 50         if (SvROK(sv)) return;
104 0 0         if (is_undef()) return reset();
105 0           reset();
106 5 0         throw std::invalid_argument("wrong SV* type for Ref");
107             }
108             };
109              
110             }