File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/XS/Framework.x/i/xs/Simple.h
Criterion Covered Total %
statement 14 21 66.6
branch 10 32 31.2
condition n/a
subroutine n/a
pod n/a
total 24 53 45.2


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             using xs::my_perl;
11              
12             namespace detail {
13 4328           template inline SV* _newnum (T val, panda::enable_if_signed_integral_t* = nullptr) { return newSViv(val); }
14 16           template inline SV* _newnum (T val, panda::enable_if_unsigned_integral_t* = nullptr) { return newSVuv(val); }
15             template inline SV* _newnum (T val, panda::enable_if_floatp_t* = nullptr) { return newSVnv(val); }
16              
17             template inline panda::enable_if_signed_integral_t _getrawnum (const SV* sv) { return SvIVX(sv); }
18             template inline panda::enable_if_unsigned_integral_t _getrawnum (const SV* sv) { return SvUVX(sv); }
19             template inline panda::enable_if_floatp_t _getrawnum (const SV* sv) { return SvNVX(sv); }
20              
21 10 50         template inline panda::enable_if_signed_integral_t _getnum (SV* sv) { return SvIV_nomg(sv); }
22 24 50         template inline panda::enable_if_unsigned_integral_t _getnum (SV* sv) { return SvUV_nomg(sv); }
    50          
23 334 50         template inline panda::enable_if_floatp_t _getnum (SV* sv) { return SvNV_nomg(sv); }
24              
25             template inline void _setrawnum (SV* sv, T val, panda::enable_if_signed_integral_t* = nullptr) { SvIV_set(sv, val); }
26             template inline void _setrawnum (SV* sv, T val, panda::enable_if_unsigned_integral_t* = nullptr) { SvUV_set(sv, val); }
27             template inline void _setrawnum (SV* sv, T val, panda::enable_if_floatp_t* = nullptr) { SvNV_set(sv, val); }
28              
29             template inline void _setnum (SV* sv, T val, panda::enable_if_signed_integral_t* = nullptr) { sv_setiv(sv, val); }
30             template inline void _setnum (SV* sv, T val, panda::enable_if_unsigned_integral_t* = nullptr) { sv_setuv(sv, val); }
31             template inline void _setnum (SV* sv, T val, panda::enable_if_floatp_t* = nullptr) { sv_setnv(sv, val); }
32             }
33              
34 0           struct Simple : Scalar {
35             static const Simple undef;
36             static const Simple yes;
37             static const Simple no;
38              
39             static Simple create (size_t capacity) {
40             SV* sv = newSV(capacity+1);
41             SvPOK_on(sv);
42             SvCUR_set(sv, 0);
43             return Simple(sv, NONE);
44             }
45              
46             static Simple shared (HEK* k) { return newSVhek(k); }
47             static Simple shared (const panda::string_view& s, U32 hash = 0) { return newSVpvn_share(s.data(), s.length(), hash); }
48              
49             static Simple format (const char*const pat, ...);
50              
51 8444           Simple (std::nullptr_t = nullptr) {}
52              
53 0 0         Simple (SV* sv, bool policy = INCREMENT) : Scalar(sv, policy) { _validate(); }
54              
55             Simple (const Simple& oth) : Scalar(oth) {}
56             Simple (Simple&& oth) : Scalar(std::move(oth)) {}
57             Simple (const Scalar& oth) : Scalar(oth) { _validate(); }
58             Simple (Scalar&& oth) : Scalar(std::move(oth)) { _validate(); }
59 74           Simple (const Sv& oth) : Simple(oth.get()) {}
60             Simple (Sv&& oth) : Scalar(std::move(oth)) { _validate(); }
61              
62             Simple (const Ref&) = delete;
63             Simple (const Glob&) = delete;
64             Simple (const Array&) = delete;
65             Simple (const Hash&) = delete;
66             Simple (const Sub&) = delete;
67              
68             template >
69             explicit
70 2172 50         Simple (T val) { sv = detail::_newnum(val); }
    50          
    50          
71              
72             explicit
73             Simple (const panda::string_view& s) { sv = newSVpvn(s.data(), s.length()); }
74              
75             static Simple noinc (SV* val) { return Simple(val, NONE); }
76              
77             Simple& operator= (SV* val) {
78             Scalar::operator=(val);
79             _validate();
80             return *this;
81             }
82              
83             Simple& operator= (const Simple& oth) {
84             Scalar::operator=(oth);
85             return *this;
86             }
87              
88             Simple& operator= (Simple&& oth) {
89             Scalar::operator=(std::move(oth));
90             return *this;
91             }
92              
93             Simple& operator= (const Scalar& oth) {
94             Scalar::operator=(oth);
95             _validate();
96             return *this;
97             }
98              
99             Simple& operator= (Scalar&& oth) {
100             Scalar::operator=(std::move(oth));
101             _validate();
102             return *this;
103             }
104              
105             Simple& operator= (const Sv& oth) { return operator=(oth.get()); }
106              
107             Simple& operator= (Sv&& oth) {
108             Scalar::operator=(std::move(oth));
109             _validate();
110             return *this;
111             }
112              
113             Simple& operator= (const Ref&) = delete;
114             Simple& operator= (const Glob&) = delete;
115             Simple& operator= (const Array&) = delete;
116             Simple& operator= (const Hash&) = delete;
117             Simple& operator= (const Sub&) = delete;
118              
119             // safe setters (slower)
120             template >
121             Simple& operator= (T val) {
122             if (sv) detail::_setnum(sv, val);
123             else sv = detail::_newnum(val);
124             return *this;
125             }
126              
127             Simple& operator= (const panda::string_view& s) {
128             if (sv) sv_setpvn(sv, s.data(), s.length());
129             else sv = newSVpvn(s.data(), s.length());
130             return *this;
131             }
132              
133             template >
134             void set (T val) { detail::_setrawnum(sv, val); }
135             void set (panda::string_view s) { sv_setpvn(sv, s.data(), s.length()); }
136             void set (SV* val) { Scalar::set(val); }
137              
138             using Sv::operator bool; // otherwise, operator arithmetic_t will be in priority
139              
140             template >
141 334 50         operator T () const { return sv ? detail::_getnum(sv) : T(); }
142              
143             const char* c_str () const { return sv ? SvPV_nomg_const_nolen(sv) : NULL; }
144              
145 2           operator panda::string_view () const { return as_string(); }
146              
147             // unsafe getters (faster)
148             template panda::enable_if_arithmetic_t get () const { return detail::_getrawnum(sv); }
149             template panda::enable_if_one_of_t get () const { return SvPVX(sv); }
150             template panda::enable_if_one_of_t get () const { return panda::string_view(SvPVX(sv), SvCUR(sv)); }
151             template panda::enable_if_one_of_t* get () const { return sv; }
152              
153             template
154 1           T as_string () const {
155 1 50         if (!sv) return T();
156             STRLEN len;
157 1 50         const char* buf = SvPV_nomg(sv, len);
    0          
158 1           return T(buf, len);
159             }
160              
161             char operator[] (size_t i) const { return SvPVX_const(sv)[i]; }
162             char& operator[] (size_t i) { return SvPVX(sv)[i]; }
163              
164             char at (size_t i) {
165             if (!sv) throw std::out_of_range("at: no sv");
166             STRLEN len;
167             auto buf = SvPV_const(sv, len);
168             if (i >= len) throw std::out_of_range("at: index out of bounds");
169             return buf[i];
170             }
171              
172             bool is_string () const { return sv && SvPOK(sv); }
173             bool is_shared () const { return sv && SvIsCOW_shared_hash(sv); }
174             STRLEN length () const { return SvCUR(sv); }
175             void length (STRLEN newlen) { SvCUR_set(sv, newlen); }
176             STRLEN capacity () const { return SvLEN(sv); }
177             bool utf8 () const { return SvUTF8(sv); }
178             void utf8 (bool val) { if (val) SvUTF8_on(sv); else SvUTF8_off(sv); }
179              
180             U32 hash () const;
181              
182             HEK* hek () const { return SvSHARED_HEK_FROM_PV(SvPVX_const(sv)); }
183              
184             static void __at_perl_destroy ();
185              
186             private:
187 0           void _validate () {
188 0 0         if (!sv) return;
189 0 0         if (SvTYPE(sv) > SVt_PVMG || SvROK(sv)) {
    0          
190 0           reset();
191 0 0         throw std::invalid_argument("wrong SV* type for Simple");
192             }
193             }
194             };
195              
196             template T Scalar::as_string () const { return Simple(sv).as_string(); }
197             template T Scalar::as_number () const { return Simple(sv); }
198              
199             template > inline bool operator== (const Simple& lhs, T rhs) { return (T)lhs == rhs; }
200             template > inline bool operator== (T lhs, const Simple& rhs) { return lhs == (T)rhs; }
201             template > inline bool operator!= (const Simple& lhs, T rhs) { return (T)lhs != rhs; }
202             template > inline bool operator!= (T lhs, const Simple& rhs) { return lhs != (T)rhs; }
203             template > inline bool operator> (const Simple& lhs, T rhs) { return (T)lhs > rhs; }
204             template > inline bool operator> (T lhs, const Simple& rhs) { return lhs > (T)rhs; }
205             template > inline bool operator>= (const Simple& lhs, T rhs) { return (T)lhs >= rhs; }
206             template > inline bool operator>= (T lhs, const Simple& rhs) { return lhs >= (T)rhs; }
207             template > inline bool operator< (const Simple& lhs, T rhs) { return (T)lhs < rhs; }
208             template > inline bool operator< (T lhs, const Simple& rhs) { return lhs < (T)rhs; }
209             template > inline bool operator<= (const Simple& lhs, T rhs) { return (T)lhs <= rhs; }
210             template > inline bool operator<= (T lhs, const Simple& rhs) { return lhs <= (T)rhs; }
211              
212             inline bool operator== (const Simple& lhs, const panda::string_view& rhs) { return (panda::string_view)lhs == rhs; }
213             inline bool operator== (const panda::string_view& lhs, const Simple& rhs) { return lhs == (panda::string_view)rhs; }
214             inline bool operator!= (const Simple& lhs, const panda::string_view& rhs) { return (panda::string_view)lhs != rhs; }
215             inline bool operator!= (const panda::string_view& lhs, const Simple& rhs) { return lhs != (panda::string_view)rhs; }
216             inline bool operator> (const Simple& lhs, const panda::string_view& rhs) { return (panda::string_view)lhs > rhs; }
217             inline bool operator> (const panda::string_view& lhs, const Simple& rhs) { return lhs > (panda::string_view)rhs; }
218             inline bool operator>= (const Simple& lhs, const panda::string_view& rhs) { return (panda::string_view)lhs >= rhs; }
219             inline bool operator>= (const panda::string_view& lhs, const Simple& rhs) { return lhs >= (panda::string_view)rhs; }
220             inline bool operator< (const Simple& lhs, const panda::string_view& rhs) { return (panda::string_view)lhs < rhs; }
221             inline bool operator< (const panda::string_view& lhs, const Simple& rhs) { return lhs < (panda::string_view)rhs; }
222             inline bool operator<= (const Simple& lhs, const panda::string_view& rhs) { return (panda::string_view)lhs <= rhs; }
223             inline bool operator<= (const panda::string_view& lhs, const Simple& rhs) { return lhs <= (panda::string_view)rhs; }
224              
225             inline bool operator== (const Simple& lhs, const char* rhs) { return (panda::string_view)lhs == panda::string_view(rhs); }
226             inline bool operator== (const char* lhs, const Simple& rhs) { return panda::string_view(lhs) == (panda::string_view)rhs; }
227             inline bool operator!= (const Simple& lhs, const char* rhs) { return (panda::string_view)lhs != panda::string_view(rhs); }
228             inline bool operator!= (const char* lhs, const Simple& rhs) { return panda::string_view(lhs) != (panda::string_view)rhs; }
229             inline bool operator> (const Simple& lhs, const char* rhs) { return (panda::string_view)lhs > panda::string_view(rhs); }
230             inline bool operator> (const char* lhs, const Simple& rhs) { return panda::string_view(lhs) > (panda::string_view)rhs; }
231             inline bool operator>= (const Simple& lhs, const char* rhs) { return (panda::string_view)lhs >= panda::string_view(rhs); }
232             inline bool operator>= (const char* lhs, const Simple& rhs) { return panda::string_view(lhs) >= (panda::string_view)rhs; }
233             inline bool operator< (const Simple& lhs, const char* rhs) { return (panda::string_view)lhs < panda::string_view(rhs); }
234             inline bool operator< (const char* lhs, const Simple& rhs) { return panda::string_view(lhs) < (panda::string_view)rhs; }
235             inline bool operator<= (const Simple& lhs, const char* rhs) { return (panda::string_view)lhs <= panda::string_view(rhs); }
236             inline bool operator<= (const char* lhs, const Simple& rhs) { return panda::string_view(lhs) <= (panda::string_view)rhs; }
237              
238             inline bool operator== (const Simple& lhs, char* rhs) { return (panda::string_view)lhs == panda::string_view(rhs); }
239             inline bool operator== (char* lhs, const Simple& rhs) { return panda::string_view(lhs) == (panda::string_view)rhs; }
240             inline bool operator!= (const Simple& lhs, char* rhs) { return (panda::string_view)lhs != panda::string_view(rhs); }
241             inline bool operator!= (char* lhs, const Simple& rhs) { return panda::string_view(lhs) != (panda::string_view)rhs; }
242             inline bool operator> (const Simple& lhs, char* rhs) { return (panda::string_view)lhs > panda::string_view(rhs); }
243             inline bool operator> (char* lhs, const Simple& rhs) { return panda::string_view(lhs) > (panda::string_view)rhs; }
244             inline bool operator>= (const Simple& lhs, char* rhs) { return (panda::string_view)lhs >= panda::string_view(rhs); }
245             inline bool operator>= (char* lhs, const Simple& rhs) { return panda::string_view(lhs) >= (panda::string_view)rhs; }
246             inline bool operator< (const Simple& lhs, char* rhs) { return (panda::string_view)lhs < panda::string_view(rhs); }
247             inline bool operator< (char* lhs, const Simple& rhs) { return panda::string_view(lhs) < (panda::string_view)rhs; }
248             inline bool operator<= (const Simple& lhs, char* rhs) { return (panda::string_view)lhs <= panda::string_view(rhs); }
249             inline bool operator<= (char* lhs, const Simple& rhs) { return panda::string_view(lhs) <= (panda::string_view)rhs; }
250             }