File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/XS/Framework.x/i/xs/Sv.h
Criterion Covered Total %
statement 0 11 0.0
branch 0 8 0.0
condition n/a
subroutine n/a
pod n/a
total 0 19 0.0


line stmt bran cond sub pod time code
1             #pragma once
2             #include "basic.h"
3             #include
4             #include
5             #include
6             #include
7              
8             namespace xs {
9              
10             struct Sv; struct Scalar; struct Simple; struct Ref; struct Array; struct Hash; struct List; struct Sub; struct Stash; struct Glob; struct Object; struct Io;
11             using xs::my_perl;
12              
13             template using enable_if_sv_t = std::enable_if_t::value, R>;
14             template using enable_if_rawsv_t = std::enable_if_t::value, R>;
15              
16             struct Sv {
17             static const bool INCREMENT = true;
18             static const bool NONE = false;
19              
20             static const Sv undef;
21             static const Sv yes;
22             static const Sv no;
23              
24             typedef int (*on_svdup_t) (pTHX_ MAGIC* mg, CLONE_PARAMS* param);
25             using payload_marker_t = MGVTBL;
26              
27             struct Payload {
28             void* ptr;
29             SV* obj;
30             };
31              
32             template struct PayloadMarker {
33             PANDA_GLOBAL_MEMBER_AS_PTR(PayloadMarker, payload_marker_t, get, payload_marker_t());
34             };
35              
36             static payload_marker_t* default_marker();
37              
38             template >
39             static Sv noinc (T* val) { return Sv((SV*)val, NONE); }
40              
41             static Sv create () { return Sv(newSV(0), NONE); }
42              
43 0           Sv (std::nullptr_t = nullptr) : sv(nullptr) {}
44              
45             template >
46 0 0         Sv (T* sv, bool policy = INCREMENT) : sv((SV*)sv) { if (policy == INCREMENT) SvREFCNT_inc_simple_void(sv); }
    0          
    0          
    0          
47              
48             Sv (const Sv& oth) : Sv(oth.sv) {}
49             Sv (Sv&& oth) : sv(oth.sv) { oth.sv = nullptr; }
50              
51 0           ~Sv () { SvREFCNT_dec(sv); }
52              
53             template >
54             Sv& operator= (T* val) {
55             SvREFCNT_inc_simple_void(val);
56             auto old = sv;
57             sv = (SV*)val;
58             SvREFCNT_dec(old);
59             return *this;
60             }
61              
62             Sv& operator= (const Sv& oth) { return operator=(oth.sv); }
63              
64 0           Sv& operator= (Sv&& oth) {
65 0           std::swap(sv, oth.sv);
66 0           return *this;
67             }
68              
69             // safe getters (slower)
70             operator SV* () const { return sv; }
71             operator AV* () const { return is_array() ? (AV*)sv : nullptr; }
72             operator HV* () const { return is_hash() ? (HV*)sv : nullptr; }
73             operator CV* () const { return is_sub() ? (CV*)sv : nullptr; }
74             operator GV* () const { return is_glob() ? (GV*)sv : nullptr; }
75             operator IO* () const { return is_io() ? (IO*)sv : nullptr; }
76             operator void* () const { return sv; } // resolves ambiguity for passing to perl-macros-api
77              
78             // unsafe getters (faster)
79             template enable_if_rawsv_t* get () const { return (T*)sv; }
80              
81             explicit operator bool () const { return sv; }
82 0           explicit operator bool () { return sv; }
83              
84             SV* operator-> () const { return sv; }
85              
86             bool defined () const { return sv && SvOK(sv); }
87             bool is_true () const { return SvTRUE_nomg(sv); }
88             svtype type () const { return SvTYPE(sv); }
89             bool readonly () const { return SvREADONLY(sv); }
90             U32 use_count () const { return sv ? SvREFCNT(sv) : 0; }
91             bool is_scalar () const { return sv && is_scalar_unsafe(); }
92             bool is_ref () const { return sv && SvROK(sv); }
93             bool is_simple () const { return sv && SvTYPE(sv) <= SVt_PVMG && !SvROK(sv); }
94             bool is_string () const { return sv && SvPOK(sv); }
95             bool is_like_number () const { return sv && looks_like_number(sv); }
96             bool is_array () const { return sv && type() == SVt_PVAV; }
97             bool is_array_ref () const { return is_ref_of_type(SVt_PVAV); }
98             bool is_hash () const { return sv && type() == SVt_PVHV; }
99             bool is_hash_ref () const { return is_ref_of_type(SVt_PVHV); }
100             bool is_sub () const { return sv && type() == SVt_PVCV; }
101             bool is_sub_ref () const { return is_ref_of_type(SVt_PVCV); }
102             bool is_glob () const { return sv && type() == SVt_PVGV; }
103             bool is_object () const { return sv && SvOBJECT(sv); }
104             bool is_object_ref () const { return is_ref() && SvOBJECT(SvRV(sv)); }
105             bool is_stash () const { return is_hash() && HvNAME(sv); }
106             bool is_io () const { return sv && type() == SVt_PVIO; }
107             bool is_io_ref () const { return is_ref_of_type(SVt_PVIO); }
108              
109             bool is_ref_of_type (svtype type) const { return sv && SvROK(sv) && SvTYPE(SvRV(sv)) == type; }
110              
111             void readonly (bool val) {
112             if (val) SvREADONLY_on(sv);
113             else SvREADONLY_off(sv);
114             }
115              
116             void upgrade (svtype type) {
117             if (SvREADONLY(sv)) throw "cannot upgrade readonly sv";
118             if (type > SVt_PVMG && SvOK(sv)) throw "only undefined scalars can be upgraded to something more than SVt_PVMG";
119             SvUPGRADE(sv, type);
120             }
121              
122             void dump () const { sv_dump(sv); }
123              
124             MAGIC* payload_attach (Payload p, const payload_marker_t* marker) { return payload_attach(p.ptr, p.obj, marker); }
125             MAGIC* payload_attach (void* ptr, SV* obj, const payload_marker_t* marker);
126             MAGIC* payload_attach (void* ptr, const Sv& obj, const payload_marker_t* marker) { return payload_attach(ptr, (SV*)obj, marker); }
127              
128             MAGIC* payload_attach (const Sv& obj, const payload_marker_t* marker) { return payload_attach(NULL, obj, marker); }
129             MAGIC* payload_attach (SV* obj, const payload_marker_t* marker) { return payload_attach(NULL, obj, marker); }
130             MAGIC* payload_attach (void* ptr, const payload_marker_t* marker) { return payload_attach(ptr, NULL, marker); }
131              
132             bool payload_exists (const payload_marker_t* marker) const {
133             if (type() < SVt_PVMG) return false;
134             for (MAGIC* mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) if (mg->mg_virtual == marker) return true;
135             return false;
136             }
137              
138             Payload payload (const payload_marker_t* marker) const {
139             if (type() < SVt_PVMG) return Payload();
140             for (MAGIC* mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) if (mg->mg_virtual == marker) return Payload { mg->mg_ptr, mg->mg_obj };
141             return Payload();
142             }
143              
144             int payload_detach (payload_marker_t* marker) {
145             if (type() < SVt_PVMG) return 0;
146             return sv_unmagicext(sv, PERL_MAGIC_ext, marker);
147             }
148              
149             void reset () {
150             SvREFCNT_dec(sv);
151             sv = nullptr;
152             }
153              
154 0           SV* detach () {
155 0           auto tmp = sv;
156 0           sv = nullptr;
157 0           return tmp;
158             }
159              
160             static void __at_perl_destroy ();
161              
162             protected:
163             friend void swap (Sv&, Sv&);
164              
165             inline bool is_undef() const { return (SvTYPE(sv) <= SVt_PVMG && !SvOK(sv)); }
166             inline bool is_scalar_unsafe() const { return (SvTYPE(sv) <= SVt_PVMG || SvTYPE(sv) == SVt_PVGV); }
167             SV* sv;
168             };
169              
170             inline bool operator== (const Sv& lh, const Sv& rh) { return lh.get() == rh.get(); }
171             inline bool operator!= (const Sv& lh, const Sv& rh) { return !(lh == rh); }
172              
173             template > inline bool operator== (const Sv& lh, T* rh) { return lh.get() == (SV*)rh; }
174             template > inline bool operator!= (const Sv& lh, T* rh) { return lh.get() != (SV*)rh; }
175             template > inline bool operator== (T* lh, const Sv& rh) { return rh.get() == (SV*)lh; }
176             template > inline bool operator!= (T* lh, const Sv& rh) { return rh.get() != (SV*)lh; }
177              
178             inline void swap (Sv& lh, Sv& rh) { std::swap(lh.sv, rh.sv); }
179              
180             std::ostream& operator<< (std::ostream& os, const Sv& sv);
181              
182             }