File Coverage

src/panda/basic_string_view.h
Criterion Covered Total %
statement 4 7 57.1
branch n/a
condition n/a
subroutine n/a
pod n/a
total 4 7 57.1


line stmt bran cond sub pod time code
1             #pragma once
2             #include
3             #include
4             #include
5             #include // swap
6             #include
7              
8             namespace panda {
9              
10             template >
11             class basic_string_view {
12             public:
13             typedef Traits traits_type;
14             typedef typename Traits::char_type value_type;
15             typedef value_type& reference;
16             typedef const value_type& const_reference;
17             typedef CharT* pointer;
18             typedef const CharT* const_pointer;
19             typedef CharT* iterator;
20             typedef const CharT* const_iterator;
21             typedef std::reverse_iterator reverse_iterator;
22             typedef std::reverse_iterator const_reverse_iterator;
23             typedef ptrdiff_t difference_type;
24             typedef size_t size_type;
25              
26             static const size_t npos = std::numeric_limits::max();
27              
28             private:
29             const CharT* _str;
30             size_t _length;
31              
32             static const CharT TERMINAL;
33              
34             public:
35              
36             constexpr basic_string_view () : _str(&TERMINAL), _length(0) {}
37              
38             constexpr basic_string_view (const basic_string_view& other) = default;
39              
40             constexpr basic_string_view (const CharT* s, size_t count) : _str(s), _length(count) {}
41              
42             template::value>::type>
43             constexpr basic_string_view (const _CharT* const& s) : _str(s), _length(traits_type::length(s)) {}
44              
45             template
46             constexpr basic_string_view (const CharT (&s)[SIZE]) : _str(s), _length(SIZE-1) {}
47              
48             basic_string_view& operator= (const basic_string_view& view) = default;
49              
50 0           constexpr const_iterator begin () const { return _str; }
51             constexpr const_iterator cbegin () const { return begin(); }
52 0           constexpr const_iterator end () const { return _str + _length; }
53             constexpr const_iterator cend () const { return end(); }
54             constexpr const_reverse_iterator rbegin () const { return const_reverse_iterator(end()); }
55             constexpr const_reverse_iterator crbegin () const { return rbegin(); }
56             constexpr const_reverse_iterator rend () const { return const_reverse_iterator(begin()); }
57             constexpr const_reverse_iterator crend () const { return rend(); }
58              
59             constexpr const_reference operator[] (size_t pos) const { return _str[pos]; }
60              
61             const_reference at (size_t pos) const {
62             if (pos >= _length) throw std::out_of_range("basic_string_view::at");
63             return _str[pos];
64             }
65              
66             constexpr const_reference front () const { return *_str; }
67             constexpr const_reference back () const { return _str[_length-1]; }
68 468           constexpr const_pointer data () const { return _str; }
69 0           constexpr size_t size () const { return _length; }
70 468           constexpr size_t length () const { return _length; }
71             constexpr size_t max_size () const { return npos - 1; }
72             constexpr bool empty () const { return _length == 0; }
73              
74             void remove_prefix (size_t n) {
75             _str += n;
76             _length -= n;
77             }
78              
79             void remove_suffix (size_t n) {
80             _length -= n;
81             }
82              
83             void swap (basic_string_view& v) {
84             std::swap(_str, v._str);
85             std::swap(_length, v._length);
86             }
87              
88             size_t copy (CharT* dest, size_t count, size_t pos = 0) const {
89             if (pos > _length) throw std::out_of_range("basic_string_view::copy");
90             if (count > _length - pos) count = _length - pos;
91             traits_type::copy(dest, _str, count);
92             return count;
93             }
94              
95             basic_string_view substr (size_t pos = 0, size_t count = npos) const {
96             if (pos > _length) throw std::out_of_range("basic_string_view::substr");
97             if (count > _length - pos) count = _length - pos;
98             return basic_string_view(_str + pos, count);
99             }
100              
101              
102             int compare (basic_string_view v) const {
103             return _compare(_str, _length, v._str, v._length);
104             }
105              
106             int compare (size_t pos1, size_t count1, basic_string_view v) const {
107             return _compare(pos1, count1, v._str, v._length);
108             }
109              
110             int compare (size_t pos1, size_t count1, basic_string_view v, size_t pos2, size_t count2) const {
111             if (pos2 > v._length) throw std::out_of_range("basic_string_view::compare");
112             if (count2 > v._length - pos2) count2 = v._length - pos2;
113             return _compare(pos1, count1, v._str + pos2, count2);
114             }
115              
116             template::value>::type>
117             int compare (const CharT* const& s) const {
118             return _compare(_str, _length, s, traits_type::length(s));
119             }
120              
121             template
122             int compare (const CharT (&s)[SIZE]) const {
123             return _compare(_str, _length, s, SIZE-1);
124             }
125              
126             template::value>::type>
127             int compare (size_t pos1, size_t count1, const CharT* const& s) const {
128             return compare(pos1, count1, s, traits_type::length(s));
129             }
130              
131             template
132             int compare (size_t pos1, size_t count1, const CharT (&s)[SIZE]) const {
133             return compare(pos1, count1, s, SIZE-1);
134             }
135              
136             int compare (size_t pos1, size_t count1, const CharT* s, size_t count2) const {
137             if (pos1 > _length) throw std::out_of_range("basic_string_view::compare");
138             if (count1 > _length - pos1) count1 = _length - pos1;
139             return _compare(_str + pos1, count1, s, count2);
140             }
141              
142              
143             size_t find (basic_string_view v, size_t pos = 0) const {
144             return find(v._str, pos, v._length);
145             }
146              
147             size_t find (CharT ch, size_t pos = 0) const {
148             if (pos >= _length) return npos;
149             const CharT* ptr = traits_type::find(_str + pos, _length - pos, ch);
150             if (ptr) return ptr - _str;
151             return npos;
152             }
153              
154             size_t find (const CharT* s, size_t pos, size_t count) const {
155             if (pos > _length) return npos;
156             if (count == 0) return pos;
157              
158             const CharT* ptr = traits_type::find(_str + pos, _length - pos, *s);
159             const CharT* end = _str + _length;
160             while (ptr && end - ptr >= count) {
161             if (traits_type::compare(ptr, s, count) == 0) return ptr - _str;
162             ptr = traits_type::find(ptr+1, end - ptr - 1, *s);
163             }
164              
165             return npos;
166             }
167              
168             template::value>::type>
169             size_t find (const _CharT* const& s, size_t pos = 0) const {
170             return find(s, pos, traits_type::length(s));
171             }
172              
173             template
174             size_t find (const CharT (&s)[SIZE], size_t pos = 0) const {
175             return find(s, pos, SIZE-1);
176             }
177              
178              
179             size_t rfind (basic_string_view v, size_t pos = npos) const {
180             return rfind(v._str, pos, v._length);
181             }
182              
183             size_t rfind (CharT ch, size_t pos = npos) const {
184             const CharT* ptr = _str + (pos >= _length ? _length : (pos+1));
185             while (--ptr >= _str) if (traits_type::eq(*ptr, ch)) return ptr - _str;
186             return npos;
187             }
188              
189             size_t rfind (const CharT* s, size_t pos, size_t count) const {
190             for (const CharT* ptr = _str + ((pos >= _length - count) ? (_length - count) : pos); ptr >= _str; --ptr)
191             if (traits_type::compare(ptr, s, count) == 0) return ptr - _str;
192             return npos;
193             }
194              
195             template::value>::type>
196             size_t rfind (const _CharT* const& s, size_t pos = 0) const {
197             return rfind(s, pos, traits_type::length(s));
198             }
199              
200             template
201             size_t rfind (const CharT (&s)[SIZE], size_t pos = 0) const {
202             return rfind(s, pos, SIZE-1);
203             }
204              
205              
206             size_t find_first_of (basic_string_view v, size_t pos = 0) const {
207             return find_first_of(v._str, pos, v._length);
208             }
209              
210             size_t find_first_of (CharT ch, size_t pos = 0) const {
211             return find(ch, pos);
212             }
213              
214             size_t find_first_of (const CharT* s, size_t pos, size_t count) const {
215             if (count == 0) return npos;
216             const CharT* end = _str + _length;
217             for (const CharT* ptr = _str + pos; ptr < end; ++ptr) if (traits_type::find(s, count, *ptr)) return ptr - _str;
218             return npos;
219             }
220              
221             template::value>::type>
222             size_t find_first_of (const _CharT* const& s, size_t pos = 0) const {
223             return find_first_of(s, pos, traits_type::length(s));
224             }
225              
226             template
227             size_t find_first_of (const CharT (&s)[SIZE], size_t pos = 0) const {
228             return find_first_of(s, pos, SIZE-1);
229             }
230              
231              
232             size_t find_last_of (basic_string_view v, size_t pos = 0) const {
233             return find_last_of(v._str, pos, v._length);
234             }
235              
236             size_t find_last_of (CharT ch, size_t pos = 0) const {
237             return rfind(ch, pos);
238             }
239              
240             size_t find_last_of (const CharT* s, size_t pos, size_t count) const {
241             if (count == 0) return npos;
242             for (const CharT* ptr = _str + (pos >= _length ? (_length - 1) : pos); ptr >= _str; --ptr)
243             if (traits_type::find(s, count, *ptr)) return ptr - _str;
244             return npos;
245             }
246              
247             template::value>::type>
248             size_t find_last_of (const _CharT* const& s, size_t pos = 0) const {
249             return find_last_of(s, pos, traits_type::length(s));
250             }
251              
252             template
253             size_t find_last_of (const CharT (&s)[SIZE], size_t pos = 0) const {
254             return find_last_of(s, pos, SIZE-1);
255             }
256              
257              
258             size_t find_first_not_of (basic_string_view v, size_t pos = 0) const {
259             return find_first_not_of(v._str, pos, v._length);
260             }
261              
262             size_t find_first_not_of (CharT ch, size_t pos = 0) const {
263             const CharT* end = _str + _length;
264             for (const CharT* ptr = _str + pos; ptr < end; ++ptr) if (!traits_type::eq(*ptr, ch)) return ptr - _str;
265             return npos;
266             }
267              
268             size_t find_first_not_of (const CharT* s, size_t pos, size_t count) const {
269             if (count == 0) return pos >= _length ? npos : pos;
270             const CharT* end = _str + _length;
271             for (const CharT* ptr = _str + pos; ptr < end; ++ptr) if (!traits_type::find(s, count, *ptr)) return ptr - _str;
272             return npos;
273             }
274              
275             template::value>::type>
276             size_t find_first_not_of (const _CharT* const& s, size_t pos = 0) const {
277             return find_first_not_of(s, pos, traits_type::length(s));
278             }
279              
280             template
281             size_t find_first_not_of (const CharT (&s)[SIZE], size_t pos = 0) const {
282             return find_first_not_of(s, pos, SIZE-1);
283             }
284              
285              
286             size_t find_last_not_of (basic_string_view v, size_t pos = 0) const {
287             return find_last_not_of(v._str, pos, v._length);
288             }
289              
290             size_t find_last_not_of (CharT ch, size_t pos = 0) const {
291             for (const CharT* ptr = _str + (pos >= _length ? (_length - 1) : pos); ptr >= _str; --ptr)
292             if (!traits_type::eq(*ptr, ch)) return ptr - _str;
293             return npos;
294             }
295              
296             size_t find_last_not_of (const CharT* s, size_t pos, size_t count) const {
297             if (count == 0) return pos >= _length ? (_length-1) : pos;
298             for (const CharT* ptr = _str + (pos >= _length ? (_length - 1) : pos); ptr >= _str; --ptr)
299             if (!traits_type::find(s, count, *ptr)) return ptr - _str;
300             return npos;
301             }
302              
303             template::value>::type>
304             size_t find_last_not_of (const _CharT* const& s, size_t pos = 0) const {
305             return find_last_not_of(s, pos, traits_type::length(s));
306             }
307              
308             template
309             size_t find_last_not_of (const CharT (&s)[SIZE], size_t pos = 0) const {
310             return find_last_not_of(s, pos, SIZE-1);
311             }
312              
313              
314             private:
315              
316             static int _compare (const CharT* ptr1, size_t len1, const CharT* ptr2, size_t len2) {
317             int r = traits_type::compare(ptr1, ptr2, std::min(len1, len2));
318             if (!r) r = (len1 < len2) ? -1 : (len1 > len2 ? 1 : 0);
319             return r;
320             }
321              
322             };
323              
324             template const C basic_string_view::TERMINAL = C();
325              
326             template inline bool operator== (basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) == 0; }
327             template inline bool operator== (const C* lhs, basic_string_view rhs) { return rhs.compare(lhs) == 0; }
328             template inline bool operator== (basic_string_view lhs, const C* rhs) { return lhs.compare(rhs) == 0; }
329              
330             template inline bool operator!= (basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) != 0; }
331             template inline bool operator!= (const C* lhs, basic_string_view rhs) { return rhs.compare(lhs) != 0; }
332             template inline bool operator!= (basic_string_view lhs, const C* rhs) { return lhs.compare(rhs) != 0; }
333              
334             template inline bool operator< (basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) < 0; }
335             template inline bool operator< (const C* lhs, basic_string_view rhs) { return rhs.compare(lhs) > 0; }
336             template inline bool operator< (basic_string_view lhs, const C* rhs) { return lhs.compare(rhs) < 0; }
337              
338             template inline bool operator<= (basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) <= 0; }
339             template inline bool operator<= (const C* lhs, basic_string_view rhs) { return rhs.compare(lhs) >= 0; }
340             template inline bool operator<= (basic_string_view lhs, const C* rhs) { return lhs.compare(rhs) <= 0; }
341              
342             template inline bool operator> (basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) > 0; }
343             template inline bool operator> (const C* lhs, basic_string_view rhs) { return rhs.compare(lhs) < 0; }
344             template inline bool operator> (basic_string_view lhs, const C* rhs) { return lhs.compare(rhs) > 0; }
345              
346             template inline bool operator>= (basic_string_view lhs, basic_string_view rhs) { return lhs.compare(rhs) >= 0; }
347             template inline bool operator>= (const C* lhs, basic_string_view rhs) { return rhs.compare(lhs) <= 0; }
348             template inline bool operator>= (basic_string_view lhs, const C* rhs) { return lhs.compare(rhs) >= 0; }
349              
350             template
351 30           inline std::basic_ostream& operator<< (std::basic_ostream& os, basic_string_view v) {
352 30           return os.write(v.data(), v.length());
353             }
354              
355             }