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 3 4 75.0
branch 1 2 50.0
condition n/a
subroutine n/a
pod n/a
total 4 6 66.6


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