File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/XS/Framework.x/i/xs/Scalar.h
Criterion Covered Total %
statement 3 15 20.0
branch 2 10 20.0
condition n/a
subroutine n/a
pod n/a
total 5 25 20.0


line stmt bran cond sub pod time code
1             #pragma once
2             #include <xs/Sv.h>
3             #include <panda/string.h>
4              
5             namespace xs {
6              
7             using xs::my_perl;
8              
9             namespace detail {
10             template <typename T> inline panda::enable_if_signed_integral_t<T> _getnum (SV* sv) { return SvIV(sv); }
11             template <typename T> inline panda::enable_if_unsigned_integral_t<T> _getnum (SV* sv) { return SvUV(sv); }
12 3454 100         template <typename T> inline panda::enable_if_floatp_t<T> _getnum (SV* sv) { return SvNV(sv); }
13              
14             struct AutoNumber {
15             AutoNumber(SV* sv) : sv(sv) {}
16              
17             template <class T, typename = panda::enable_if_arithmetic_t<T>>
18             operator T () const { return sv ? _getnum<T>(sv) : T(); }
19              
20             private:
21             SV* sv;
22             };
23             }
24              
25 0           struct Scalar : Sv {
26             static const Scalar undef;
27             static const Scalar yes;
28             static const Scalar no;
29              
30             static Scalar create () { return Scalar(newSV(0), NONE); }
31              
32             static Scalar noinc (SV* val) { return Scalar(val, NONE); }
33             static Scalar noinc (GV* val) { return Scalar(val, NONE); }
34              
35 288           Scalar (std::nullptr_t = nullptr) {}
36              
37 0 0         Scalar (SV* sv, bool policy = INCREMENT) : Sv(sv, policy) { _validate(); }
38             Scalar (GV* sv, bool policy = INCREMENT) : Sv(sv, policy) {}
39              
40             Scalar (const Scalar& oth) : Sv(oth) {}
41             Scalar (Scalar&& oth) : Sv(std::move(oth)) {}
42 6           Scalar (const Sv& oth) : Scalar(oth.get()) {}
43             Scalar (Sv&& oth) : Sv(std::move(oth)) { _validate(); }
44              
45             Scalar (const Array&) = delete;
46             Scalar (const Hash&) = delete;
47             Scalar (const Sub&) = delete;
48             Scalar (const Io&) = delete;
49              
50 0           Scalar& operator= (SV* val) {
51 0           Sv::operator=(val);
52 0           _validate();
53 0           return *this;
54             }
55              
56             Scalar& operator= (GV* val) {
57             Sv::operator=(val);
58             return *this;
59             }
60              
61             Scalar& operator= (const Scalar& oth) {
62             Sv::operator=(oth.sv);
63             return *this;
64             }
65              
66 0           Scalar& operator= (Scalar&& oth) {
67 0           Sv::operator=(std::move(oth));
68 0           return *this;
69             }
70              
71             Scalar& operator= (const Sv& oth) { return operator=(oth.get()); }
72              
73             Scalar& operator= (Sv&& oth) {
74             Sv::operator=(std::move(oth));
75             _validate();
76             return *this;
77             }
78              
79             Scalar& operator= (const Array&) = delete;
80             Scalar& operator= (const Hash&) = delete;
81             Scalar& operator= (const Sub&) = delete;
82             Scalar& operator= (const Io&) = delete;
83              
84             void set (SV* val) { Sv::operator=(val); }
85             void set (GV* val) { Sv::operator=(val); }
86              
87             operator AV* () const = delete;
88             operator HV* () const = delete;
89             operator CV* () const = delete;
90             operator IO* () const = delete;
91              
92             template <class T = SV> panda::enable_if_one_of_t<T,SV,GV>* get () const { return (T*)sv; }
93              
94             void upgrade (svtype type) {
95             if (type > SVt_PVMG && type != SVt_PVGV) throw std::logic_error("can't upgrade Scalar to something bigger than PVMG (and != PVGV)");
96             Sv::upgrade(type);
97             }
98              
99             template <class T = panda::string>
100             T as_string () const {
101             if (!sv) return T();
102             STRLEN len;
103             const char* buf = SvPV_const(sv, len);
104             return T(buf, len);
105             }
106              
107             template <class T = int> T as_number () const { return sv ? detail::_getnum<T>(sv) : T(); }
108              
109             detail::AutoNumber number () const { return detail::AutoNumber(sv); }
110              
111             static void __at_perl_destroy ();
112              
113             private:
114             void _validate_rest();
115              
116 0           void _validate () {
117 0 0         if (!sv || SvTYPE(sv) <= SVt_PVMG || SvTYPE(sv) == SVt_PVGV) return;
    0          
    0          
118 0           _validate_rest();
119             }
120             };
121              
122             }