| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | #pragma once | 
| 2 |  |  |  |  |  |  | #include | 
| 3 |  |  |  |  |  |  | #include | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  | namespace xs { | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | using xs::my_perl; | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | struct Simple; | 
| 10 |  |  |  |  |  |  |  | 
| 11 | 14 |  |  |  |  |  | struct Array : Sv { | 
| 12 |  |  |  |  |  |  | enum create_type_t { ALIAS, COPY }; | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | static Array create () { return Array(newAV(), NONE); } | 
| 15 |  |  |  |  |  |  |  | 
| 16 | 7 |  |  |  |  |  | static Array create (size_t cap) { | 
| 17 | 7 |  |  |  |  |  | Array ret(newAV(), NONE); | 
| 18 | 7 | 50 |  |  |  |  | ret.reserve(cap); | 
| 19 | 7 |  |  |  |  |  | return ret; | 
| 20 |  |  |  |  |  |  | } | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | static Array create (size_t size, SV** content, create_type_t type = ALIAS); | 
| 23 |  |  |  |  |  |  | static Array create (const std::initializer_list& l, create_type_t type = ALIAS) { return Array(l, type); } | 
| 24 |  |  |  |  |  |  | static Array create (const Array& from, create_type_t type = ALIAS) { return create(from.size(), from._svlist(), type); } | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | static Array noinc  (SV* val) { return Array(val, NONE); } | 
| 27 |  |  |  |  |  |  | static Array noinc  (AV* val) { return Array(val, NONE); } | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | Array (std::nullptr_t = nullptr) {} | 
| 30 |  |  |  |  |  |  | Array (SV* sv, bool policy = INCREMENT) : Sv(sv, policy) { _validate(); } | 
| 31 | 14 |  |  |  |  |  | Array (AV* sv, bool policy = INCREMENT) : Sv(sv, policy) {} | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | Array (const Array& oth) : Sv(oth)            {} | 
| 34 |  |  |  |  |  |  | Array (Array&& oth)      : Sv(std::move(oth)) {} | 
| 35 |  |  |  |  |  |  | Array (const Sv& oth)    : Sv(oth)            { _validate(); } | 
| 36 |  |  |  |  |  |  | Array (Sv&& oth)         : Sv(std::move(oth)) { _validate(); } | 
| 37 |  |  |  |  |  |  | Array (const Simple&)    = delete; | 
| 38 |  |  |  |  |  |  | Array (const Hash&)      = delete; | 
| 39 |  |  |  |  |  |  | Array (const Sub&)       = delete; | 
| 40 |  |  |  |  |  |  | Array (const Glob&)      = delete; | 
| 41 |  |  |  |  |  |  | Array (const Io&)        = delete; | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | Array (const std::initializer_list& l, create_type_t type = ALIAS); | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | Array& operator= (SV* val)          { Sv::operator=(val); _validate(); return *this; } | 
| 46 |  |  |  |  |  |  | Array& operator= (AV* val)          { Sv::operator=(val); return *this; } | 
| 47 |  |  |  |  |  |  | Array& operator= (const Array& oth) { Sv::operator=(oth); return *this; } | 
| 48 |  |  |  |  |  |  | Array& operator= (Array&& oth)      { Sv::operator=(std::move(oth)); return *this; } | 
| 49 |  |  |  |  |  |  | Array& operator= (const Sv& oth)    { return operator=(oth.get()); } | 
| 50 |  |  |  |  |  |  | Array& operator= (Sv&& oth)         { Sv::operator=(std::move(oth)); _validate(); return *this; } | 
| 51 |  |  |  |  |  |  | Array& operator= (const Simple&)    = delete; | 
| 52 |  |  |  |  |  |  | Array& operator= (const Hash&)      = delete; | 
| 53 |  |  |  |  |  |  | Array& operator= (const Sub&)       = delete; | 
| 54 |  |  |  |  |  |  | Array& operator= (const Glob&)      = delete; | 
| 55 |  |  |  |  |  |  | Array& operator= (const Io&)        = delete; | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | void set (SV* val) { Sv::operator=(val); } | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | operator AV* () const { return (AV*)sv; } | 
| 60 |  |  |  |  |  |  | operator HV* () const = delete; | 
| 61 |  |  |  |  |  |  | operator CV* () const = delete; | 
| 62 |  |  |  |  |  |  | operator GV* () const = delete; | 
| 63 |  |  |  |  |  |  | operator IO* () const = delete; | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | AV* operator-> () const { return (AV*)sv; } | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | template  panda::enable_if_one_of_t* get () const { return (T*)sv; } | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | Scalar fetch (size_t key) const { | 
| 70 |  |  |  |  |  |  | if (!sv) return Scalar(); | 
| 71 |  |  |  |  |  |  | if (key >= _size()) return Scalar(); | 
| 72 |  |  |  |  |  |  | Scalar ret; | 
| 73 |  |  |  |  |  |  | ret.set(_svlist()[key]); | 
| 74 |  |  |  |  |  |  | return ret; | 
| 75 |  |  |  |  |  |  | } | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  | Scalar front () const { return fetch(0); } | 
| 78 |  |  |  |  |  |  | Scalar back  () const { return sv && _size() ? fetch(_topi()) : Scalar(); } | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | Scalar at (size_t key) const { | 
| 81 |  |  |  |  |  |  | Scalar ret = fetch(key); | 
| 82 |  |  |  |  |  |  | if (!ret) throw std::out_of_range("at: no key"); | 
| 83 |  |  |  |  |  |  | return ret; | 
| 84 |  |  |  |  |  |  | } | 
| 85 |  |  |  |  |  |  |  | 
| 86 |  |  |  |  |  |  | template > | 
| 87 |  |  |  |  |  |  | Scalar operator[] (T key) const { | 
| 88 |  |  |  |  |  |  | Scalar ret; | 
| 89 |  |  |  |  |  |  | ret.set(_svlist()[key]); | 
| 90 |  |  |  |  |  |  | return ret; | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | void store (size_t key, const Scalar& val); | 
| 94 |  |  |  |  |  |  | void store (size_t key, std::nullptr_t) { store(key, Scalar()); } | 
| 95 |  |  |  |  |  |  | void store (size_t key, SV* v)          { store(key, Scalar(v)); } | 
| 96 |  |  |  |  |  |  | void store (size_t key, const Sv& v)    { store(key, Scalar(v)); } | 
| 97 |  |  |  |  |  |  | void store (size_t key, const Array&)   = delete; | 
| 98 |  |  |  |  |  |  | void store (size_t key, const Hash&)    = delete; | 
| 99 |  |  |  |  |  |  | void store (size_t key, const Sub&)     = delete; | 
| 100 |  |  |  |  |  |  | void store (size_t key, const Io&)      = delete; | 
| 101 |  |  |  |  |  |  |  | 
| 102 |  |  |  |  |  |  | template > | 
| 103 |  |  |  |  |  |  | KeyProxy operator[] (T key) { return KeyProxy(_svlist() + key, true); } | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | bool exists (size_t key) const { | 
| 106 |  |  |  |  |  |  | if (key >= size()) return false; | 
| 107 |  |  |  |  |  |  | return _svlist()[key]; | 
| 108 |  |  |  |  |  |  | } | 
| 109 |  |  |  |  |  |  |  | 
| 110 |  |  |  |  |  |  | Scalar del (size_t key) { | 
| 111 |  |  |  |  |  |  | Scalar ret = fetch(key); | 
| 112 |  |  |  |  |  |  | if (ret) (*this)[key] = nullptr; | 
| 113 |  |  |  |  |  |  | return ret; | 
| 114 |  |  |  |  |  |  | } | 
| 115 |  |  |  |  |  |  |  | 
| 116 |  |  |  |  |  |  | size_t  size      () const { return sv ? _size() : 0; } | 
| 117 |  |  |  |  |  |  | size_t  capacity  () const { return sv ? _cap()  : 0; } | 
| 118 |  |  |  |  |  |  | SSize_t top_index () const { return sv ? _topi() : -1; } | 
| 119 |  |  |  |  |  |  |  | 
| 120 |  |  |  |  |  |  | void resize  (size_t newsz)  { av_fill((AV*)sv, (SSize_t)newsz - 1); } | 
| 121 | 14 |  |  |  |  |  | void reserve (size_t newcap) { av_extend((AV*)sv, (SSize_t)newcap - 1); } | 
| 122 |  |  |  |  |  |  |  | 
| 123 |  |  |  |  |  |  | Scalar shift () { | 
| 124 |  |  |  |  |  |  | if (!sv) return Scalar(); | 
| 125 |  |  |  |  |  |  | SV* retsv = av_shift((AV*)sv); | 
| 126 |  |  |  |  |  |  | if (retsv == &PL_sv_undef) return Scalar(); | 
| 127 |  |  |  |  |  |  | Scalar ret; | 
| 128 |  |  |  |  |  |  | ret.set(retsv); | 
| 129 |  |  |  |  |  |  | SvREFCNT_dec(retsv); // because av_shift does not decrement, just transfers ownership | 
| 130 |  |  |  |  |  |  | return ret; | 
| 131 |  |  |  |  |  |  | } | 
| 132 |  |  |  |  |  |  |  | 
| 133 |  |  |  |  |  |  | Scalar pop () { | 
| 134 |  |  |  |  |  |  | if (!sv) return Scalar(); | 
| 135 |  |  |  |  |  |  | SV* retsv = av_pop((AV*)sv); | 
| 136 |  |  |  |  |  |  | if (retsv == &PL_sv_undef) return Scalar(); | 
| 137 |  |  |  |  |  |  | Scalar ret; | 
| 138 |  |  |  |  |  |  | ret.set(retsv); | 
| 139 |  |  |  |  |  |  | SvREFCNT_dec(retsv); // because av_pop does not decrement, just transfers ownership | 
| 140 |  |  |  |  |  |  | return ret; | 
| 141 |  |  |  |  |  |  | } | 
| 142 |  |  |  |  |  |  |  | 
| 143 |  |  |  |  |  |  | void push (const std::initializer_list& l); | 
| 144 |  |  |  |  |  |  | void push (const List& l); | 
| 145 |  |  |  |  |  |  | void push (const Scalar& v); | 
| 146 |  |  |  |  |  |  | void push (const Array&) = delete; | 
| 147 |  |  |  |  |  |  | void push (const Hash&)  = delete; | 
| 148 |  |  |  |  |  |  | void push (const Sub&)   = delete; | 
| 149 |  |  |  |  |  |  | void push (const Io&)    = delete; | 
| 150 |  |  |  |  |  |  | void push (SV* v)        { push(Scalar(v)); } | 
| 151 | 68 | 50 |  |  |  |  | void push (const Sv& v)  { push(Scalar(v)); } | 
| 152 |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  | void unshift (const std::initializer_list& l); | 
| 154 |  |  |  |  |  |  | void unshift (const List& l); | 
| 155 |  |  |  |  |  |  | void unshift (const Scalar& v); | 
| 156 |  |  |  |  |  |  | void unshift (const Array&) = delete; | 
| 157 |  |  |  |  |  |  | void unshift (const Hash&)  = delete; | 
| 158 |  |  |  |  |  |  | void unshift (const Sub&)   = delete; | 
| 159 |  |  |  |  |  |  | void unshift (const Io&)    = delete; | 
| 160 |  |  |  |  |  |  | void unshift (SV* v)        { unshift(Scalar(v)); } | 
| 161 |  |  |  |  |  |  | void unshift (const Sv& v)  { unshift(Scalar(v)); } | 
| 162 |  |  |  |  |  |  |  | 
| 163 |  |  |  |  |  |  | void undef () { if (sv) av_undef((AV*)sv); } | 
| 164 |  |  |  |  |  |  | void clear () { if (sv) av_clear((AV*)sv); } | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | struct const_iterator : private std::iterator { | 
| 167 |  |  |  |  |  |  | const_iterator ()                          : cur(nullptr) {} | 
| 168 |  |  |  |  |  |  | const_iterator (SV** avfirst)              : cur(avfirst) {} | 
| 169 |  |  |  |  |  |  |  | 
| 170 |  |  |  |  |  |  | const_iterator& operator++ () { ++cur; return *this; } | 
| 171 |  |  |  |  |  |  | const_iterator& operator-- () { --cur; return *this; } | 
| 172 |  |  |  |  |  |  |  | 
| 173 |  |  |  |  |  |  | const_iterator operator++ (int) { const_iterator ret = *this; operator++(); return ret; } | 
| 174 |  |  |  |  |  |  | const_iterator operator-- (int) { const_iterator ret = *this; operator--(); return ret; } | 
| 175 |  |  |  |  |  |  |  | 
| 176 |  |  |  |  |  |  | const_iterator& operator+= (ptrdiff_t n) { cur += n; return *this; } | 
| 177 |  |  |  |  |  |  | const_iterator& operator-= (ptrdiff_t n) { cur -= n; return *this; } | 
| 178 |  |  |  |  |  |  |  | 
| 179 |  |  |  |  |  |  | bool operator== (const const_iterator& oth) const { return cur == oth.cur; } | 
| 180 |  |  |  |  |  |  | bool operator!= (const const_iterator& oth) const { return cur != oth.cur; } | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | const Scalar* operator-> () { return (const Scalar*)cur; } | 
| 183 |  |  |  |  |  |  | const Scalar& operator*  () { return *((const Scalar*)cur); } | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | ptrdiff_t operator- (const const_iterator& rh) { return cur - rh.cur; } | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | bool operator<  (const const_iterator& rh) { return cur < rh.cur; } | 
| 188 |  |  |  |  |  |  | bool operator<= (const const_iterator& rh) { return cur <= rh.cur; } | 
| 189 |  |  |  |  |  |  | bool operator>  (const const_iterator& rh) { return cur > rh.cur; } | 
| 190 |  |  |  |  |  |  | bool operator>= (const const_iterator& rh) { return cur >= rh.cur; } | 
| 191 |  |  |  |  |  |  |  | 
| 192 |  |  |  |  |  |  | const Scalar& operator[] (size_t key) { return *((const Scalar*)(cur+key)); } | 
| 193 |  |  |  |  |  |  |  | 
| 194 |  |  |  |  |  |  | protected: | 
| 195 |  |  |  |  |  |  | SV** cur; | 
| 196 |  |  |  |  |  |  | }; | 
| 197 |  |  |  |  |  |  |  | 
| 198 |  |  |  |  |  |  | struct iterator : private std::iterator, const_iterator { | 
| 199 |  |  |  |  |  |  | using const_iterator::const_iterator; | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | iterator& operator++ () { const_iterator::operator++(); return *this; } | 
| 202 |  |  |  |  |  |  | iterator& operator-- () { const_iterator::operator--(); return *this; } | 
| 203 |  |  |  |  |  |  |  | 
| 204 |  |  |  |  |  |  | iterator operator++ (int) { iterator ret = *this; const_iterator::operator++(); return ret; } | 
| 205 |  |  |  |  |  |  | iterator operator-- (int) { iterator ret = *this; const_iterator::operator--(); return ret; } | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | iterator& operator+= (ptrdiff_t n) { const_iterator::operator+=(n); return *this; } | 
| 208 |  |  |  |  |  |  | iterator& operator-= (ptrdiff_t n) { const_iterator::operator-=(n); return *this; } | 
| 209 |  |  |  |  |  |  |  | 
| 210 |  |  |  |  |  |  | Scalar*  operator-> ()           { return (Scalar*)cur; } | 
| 211 |  |  |  |  |  |  | KeyProxy operator*  ()           { return KeyProxy(cur, true); } | 
| 212 |  |  |  |  |  |  | KeyProxy operator[] (size_t key) { return KeyProxy(cur+key, true); } | 
| 213 |  |  |  |  |  |  | }; | 
| 214 |  |  |  |  |  |  |  | 
| 215 |  |  |  |  |  |  | const_iterator cbegin () const { return sv ? const_iterator(_svlist()) : const_iterator(); } | 
| 216 |  |  |  |  |  |  | const_iterator cend   () const { return sv ? const_iterator(_svlist()+_size()) : const_iterator(); } | 
| 217 |  |  |  |  |  |  | const_iterator begin  () const { return cbegin(); } | 
| 218 |  |  |  |  |  |  | const_iterator end    () const { return cend(); } | 
| 219 |  |  |  |  |  |  | iterator       begin  ()       { return sv ? iterator(_svlist()) : iterator(); } | 
| 220 |  |  |  |  |  |  | iterator       end    ()       { return sv ? iterator(_svlist()+_size()) : iterator(); } | 
| 221 |  |  |  |  |  |  |  | 
| 222 |  |  |  |  |  |  | U32 push_on_stack (SV** sp, U32 max = 0) const; | 
| 223 |  |  |  |  |  |  |  | 
| 224 |  |  |  |  |  |  | private: | 
| 225 |  |  |  |  |  |  | inline SV**    _svlist () const   { return AvARRAY((AV*)sv); } | 
| 226 |  |  |  |  |  |  | inline size_t  _size   () const   { return (size_t)(_topi()+1); } | 
| 227 |  |  |  |  |  |  | inline void    _size   (size_t i) { AvFILLp((AV*)sv) = (SSize_t)i-1; } | 
| 228 |  |  |  |  |  |  | inline size_t  _cap    () const   { return (size_t)(AvMAX((AV*)sv)+1); } | 
| 229 |  |  |  |  |  |  | inline SSize_t _topi   () const   { return AvFILLp((AV*)sv); } | 
| 230 |  |  |  |  |  |  |  | 
| 231 |  |  |  |  |  |  | void _validate () { | 
| 232 |  |  |  |  |  |  | if (!sv) return; | 
| 233 |  |  |  |  |  |  | if (SvTYPE(sv) == SVt_PVAV) return; | 
| 234 |  |  |  |  |  |  | if (SvROK(sv)) {           // reference to array? | 
| 235 |  |  |  |  |  |  | SV* val = SvRV(sv); | 
| 236 |  |  |  |  |  |  | if (SvTYPE(val) == SVt_PVAV) { | 
| 237 |  |  |  |  |  |  | Sv::operator=(val); | 
| 238 |  |  |  |  |  |  | return; | 
| 239 |  |  |  |  |  |  | } | 
| 240 |  |  |  |  |  |  | } | 
| 241 |  |  |  |  |  |  | if (is_undef()) return reset(); | 
| 242 |  |  |  |  |  |  | reset(); | 
| 243 |  |  |  |  |  |  | throw std::invalid_argument("SV is not an Array or Array reference"); | 
| 244 |  |  |  |  |  |  | } | 
| 245 |  |  |  |  |  |  | }; | 
| 246 |  |  |  |  |  |  |  | 
| 247 |  |  |  |  |  |  | inline xs::Array::const_iterator operator+ (const xs::Array::const_iterator& lh, ptrdiff_t rh) { return xs::Array::const_iterator(lh) += rh; } | 
| 248 |  |  |  |  |  |  | inline xs::Array::const_iterator operator+ (ptrdiff_t lh, const xs::Array::const_iterator& rh) { return xs::Array::const_iterator(rh) += lh; } | 
| 249 |  |  |  |  |  |  | inline xs::Array::const_iterator operator- (const xs::Array::const_iterator& lh, ptrdiff_t rh) { return xs::Array::const_iterator(lh) -= rh; } | 
| 250 |  |  |  |  |  |  | inline xs::Array::iterator       operator+ (const xs::Array::iterator& lh, ptrdiff_t rh)       { return xs::Array::iterator(lh) += rh; } | 
| 251 |  |  |  |  |  |  | inline xs::Array::iterator       operator+ (ptrdiff_t lh, const xs::Array::iterator& rh)       { return xs::Array::iterator(rh) += lh; } | 
| 252 |  |  |  |  |  |  | inline xs::Array::iterator       operator- (const xs::Array::iterator& lh, ptrdiff_t rh)       { return xs::Array::iterator(lh) -= rh; } | 
| 253 |  |  |  |  |  |  |  | 
| 254 |  |  |  |  |  |  | struct List : public Array { | 
| 255 |  |  |  |  |  |  | List () {} | 
| 256 |  |  |  |  |  |  | List (SV* sv, bool policy = INCREMENT) : Array(sv, policy) {} | 
| 257 |  |  |  |  |  |  | List (AV* sv, bool policy = INCREMENT) : Array(sv, policy) {} | 
| 258 |  |  |  |  |  |  |  | 
| 259 |  |  |  |  |  |  | List (const Array& oth) : Array(oth)            {} | 
| 260 |  |  |  |  |  |  | List (Array&&      oth) : Array(std::move(oth)) {} | 
| 261 |  |  |  |  |  |  | List (const Sv&    oth) : Array(oth)            {} | 
| 262 |  |  |  |  |  |  | List (Sv&&         oth) : Array(std::move(oth)) {} | 
| 263 |  |  |  |  |  |  |  | 
| 264 |  |  |  |  |  |  | List (const Simple&) = delete; | 
| 265 |  |  |  |  |  |  | List (const Hash&)   = delete; | 
| 266 |  |  |  |  |  |  | List (const Sub&)    = delete; | 
| 267 |  |  |  |  |  |  | List (const Glob&)   = delete; | 
| 268 |  |  |  |  |  |  | List (const Io&)     = delete; | 
| 269 |  |  |  |  |  |  |  | 
| 270 |  |  |  |  |  |  | List& operator= (SV* val)          { Array::operator=(val); return *this; } | 
| 271 |  |  |  |  |  |  | List& operator= (AV* val)          { Array::operator=(val); return *this; } | 
| 272 |  |  |  |  |  |  | List& operator= (const Array& oth) { Array::operator=(oth); return *this; } | 
| 273 |  |  |  |  |  |  | List& operator= (Array&& oth)      { Array::operator=(std::move(oth)); return *this; } | 
| 274 |  |  |  |  |  |  | List& operator= (const Sv& oth)    { Array::operator=(oth); return *this; } | 
| 275 |  |  |  |  |  |  | List& operator= (Sv&& oth)         { Array::operator=(std::move(oth)); return *this; } | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  | List& operator= (const Simple&) = delete; | 
| 278 |  |  |  |  |  |  | List& operator= (const Hash&)   = delete; | 
| 279 |  |  |  |  |  |  | List& operator= (const Sub&)    = delete; | 
| 280 |  |  |  |  |  |  | List& operator= (const Glob&)   = delete; | 
| 281 |  |  |  |  |  |  | List& operator= (const Io&)     = delete; | 
| 282 |  |  |  |  |  |  | }; | 
| 283 |  |  |  |  |  |  |  | 
| 284 |  |  |  |  |  |  | } | 
| 285 |  |  |  |  |  |  |  | 
| 286 |  |  |  |  |  |  | // DEPRECATED, will be removed, use Array.begin()/end() instead | 
| 287 |  |  |  |  |  |  | #define XS_AV_ITER(av,code) {                                           \ | 
| 288 |  |  |  |  |  |  | SV** list = AvARRAY(av);                                            \ | 
| 289 |  |  |  |  |  |  | SSize_t fillp = AvFILLp(av);                                        \ | 
| 290 |  |  |  |  |  |  | for (SSize_t i = 0; i <= fillp; ++i) { SV* elem = *list++; code }   \ | 
| 291 |  |  |  |  |  |  | } | 
| 292 |  |  |  |  |  |  | #define XS_AV_ITER_NE(av,code) XS_AV_ITER(av,{if(!elem) continue; code}) | 
| 293 |  |  |  |  |  |  | #define XS_AV_ITER_NU(av,code) XS_AV_ITER(av,{if(!elem || !SvOK(elem)) continue; code}) | 
| 294 |  |  |  |  |  |  |  |