source: mainline/uspace/lib/cpp/include/impl/string.hpp@ 836ecad

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 836ecad was 98c99ba, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: fixed reverse iterator generators of vector and string

  • Property mode set to 100644
File size: 19.0 KB
Line 
1/*
2 * Copyright (c) 2017 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_STRING
30#define LIBCPP_STRING
31
32#include <initializer_list>
33#include <iosfwd>
34#include <cstdio>
35#include <cstdlib>
36#include <cstring>
37
38namespace std
39{
40
41 /**
42 * 21.2, char_traits:
43 */
44
45 template<class Char>
46 struct char_traits;
47
48 /**
49 * 21.2.3, char_traits specializations:
50 */
51
52 template<>
53 struct char_traits<char>
54 {
55 using char_type = char;
56 using int_type = int;
57 using off_type = streamoff;
58 using pos_type = streampos;
59 /* using state_type = mbstate_t; */
60
61 static void assign(char_type& c1, char_type& c2) noexcept
62 {
63 c1 = c2;
64 }
65
66 static constexpr bool eq(char_type c1, char_type c2) noexcept
67 {
68 return c1 == c2;
69 }
70
71 static constexpr bool lt(char_type c1, char_type c2) noexcept
72 {
73 return c1 < c2;
74 }
75
76 static int compare(const char_type* s1, const char_type* s2, size_t n)
77 {
78 return std::str_lcmp(s1, s2, n);
79 }
80
81 static size_t length(const char_type* s)
82 {
83 return std::str_size(s);
84 }
85
86 static const char_type* find(const char_type* s, size_t n, const char_type& c)
87 {
88 size_t i{};
89 while (i++ < n)
90 {
91 if (s[i] == c)
92 return s + i;
93 }
94
95 return nullptr;
96 }
97
98 static char_type* move(char_type* s1, const char_type* s2, size_t n)
99 {
100 return static_cast<char_type*>(memmove(s1, s2, n));
101 }
102
103 static char_type* copy(char_type* s1, const char_type* s2, size_t n)
104 {
105 return static_cast<char_type*>(memcpy(s1, s2, n));
106 }
107
108 static char_type* assign(char_type* s, size_t n, char_type c)
109 {
110 /**
111 * Note: Even though memset accepts int as its second argument,
112 * the actual implementation assigns that int to a dereferenced
113 * char pointer.
114 */
115 return static_cast<char_type*>(memset(s, static_cast<int>(c), n));
116 }
117
118 static constexpr int_type not_eof(int_type c) noexcept
119 {
120 if (!eq_int_type(c, eof()))
121 return c;
122 else
123 return to_int_type('a'); // We just need something that is not eof.
124 }
125
126 static constexpr char_type to_char_type(int_type c) noexcept
127 {
128 return static_cast<char_type>(c);
129 }
130
131 static constexpr int_type to_int_type(char_type c) noexcept
132 {
133 return static_cast<int_type>(c);
134 }
135
136 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
137 {
138 return c1 == c2;
139 }
140
141 static constexpr int_type eof() noexcept
142 {
143 return static_cast<int_type>(EOF);
144 }
145 };
146
147 template<>
148 struct char_traits<char16_t>
149 { /* TODO: implement */ };
150
151 template<>
152 struct char_traits<char32_t>
153 { /* TODO: implement */ };
154
155 template<>
156 struct char_traits<wchar_t>
157 {
158 using char_type = wchar_t;
159 using int_type = wint_t;
160 using off_type = streamoff;
161 using pos_type = wstreampos;
162 /* using state_type = mbstate_t; */
163
164 static void assign(char_type& c1, char_type& c2) noexcept
165 {
166 c1 = c2;
167 }
168
169 static constexpr bool eq(char_type c1, char_type c2) noexcept
170 {
171 return c1 == c2;
172 }
173
174 static constexpr bool lt(char_type c1, char_type c2) noexcept
175 {
176 return c1 < c2;
177 }
178
179 static int compare(const char_type* s1, const char_type* s2, size_t n)
180 {
181 return std::wstr_lcmp(s1, s2, n);
182 }
183
184 static size_t length(const char_type* s)
185 {
186 return std::wstr_size(s);
187 }
188
189 static const char_type* find(const char_type* s, size_t n, const char_type& c)
190 {
191 size_t i{};
192 while (i++ < n)
193 {
194 if (s[i] == c)
195 return s + i;
196 }
197
198 return nullptr;
199 }
200
201 static char_type* move(char_type* s1, const char_type* s2, size_t n)
202 {
203 return static_cast<char_type*>(memmove(s1, s2, n * sizeof(wchar_t)));
204 }
205
206 static char_type* copy(char_type* s1, const char_type* s2, size_t n)
207 {
208 return static_cast<char_type*>(memcpy(s1, s2, n * sizeof(wchar_t)));
209 }
210
211 static char_type* assign(char_type* s, size_t n, char_type c)
212 {
213 return static_cast<char_type*>(memset(s, static_cast<int>(c), n * sizeof(wchar_t)));
214 }
215
216 static constexpr int_type not_eof(int_type c) noexcept
217 {
218 if (!eq_int_type(c, eof()))
219 return c;
220 else
221 return to_int_type(L'a'); // We just need something that is not eof.
222 }
223
224 static constexpr char_type to_char_type(int_type c) noexcept
225 {
226 return static_cast<char_type>(c);
227 }
228
229 static constexpr int_type to_int_type(char_type c) noexcept
230 {
231 return static_cast<int_type>(c);
232 }
233
234 static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept
235 {
236 return c1 == c2;
237 }
238
239 static constexpr int_type eof() noexcept
240 {
241 return static_cast<int_type>(EOF);
242 }
243 };
244
245 /**
246 * 21.4, class template basic_string:
247 */
248
249 template<class Char, class Traits = char_traits<Char>,
250 class Allocator = allocator<Char>>
251 class basic_string
252 {
253 public:
254 using traits_type = Traits;
255 using value_type = typename traits_type::char_type;
256 using allocator_type = Allocator;
257 using size_type = typename allocator_traits<allocator_type>::size_type;
258 using difference_type = typename allocator_traits<allocator_type>::difference_type;
259
260 using reference = value_type&;
261 using const_reference = const value_type&;
262 using pointer = allocator_traits<allocator_type>::pointer;
263 using const_pointer = allocator_traits<allocator_type>::const_pointer;
264
265 using iterator = pointer;
266 using const_iterator = const_pointer;
267 using reverse_iterator = std::reverse_iterator<iterator>;
268 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
269
270 static constexpr size_type npos = -1;
271
272 /**
273 * 21.4.2, construct/copy/destroy:
274 */
275 basic_string() noexcept
276 : basic_string(allocator_type{})
277 { /* DUMMY BODY */ }
278
279 explicit basic_string(const allocator_type& alloc);
280
281 basic_string(const basic_string& other);
282
283 basic_string(basic_string&& other);
284
285 basic_string(const basic_string& other, size_type pos, size_type n = npos,
286 const allocator_type& alloc = allocator_type{});
287
288 basic_string(const value_type*, size_type n, const allocator_type& alloc = allocator{});
289
290 basic_string(const value_type*, const allocator_type& alloc = allocator{});
291
292 basic_string(size_type n, value_type c, const allocator_type& alloc = allocator{});
293
294 template<class InputIterator>
295 basic_string(InputIterator first, InputIterator last,
296 const allocator_type& alloc = allocator{});
297
298 basic_string(initializer_list<value_type> init, const allocator_type& alloc = allocator{});
299
300 basic_string(const basic_string& other, const allocator_type& alloc);
301
302 basic_string(basic_string&& other, const allocator_type& alloc);
303
304 ~basic_string();
305
306 basic_string& operator=(const basic_string& other);
307
308 basic_string& operator=(basic_string&& other)
309 noexcept(allocator_traits<allocator_type>::propagate_on_container_move_assignment::value ||
310 allocator_traits<allocator_type>::is_always_equal::value);
311
312 basic_string& operator=(const value_type* other);
313
314 basic_string& operator=(value_type c);
315
316 basic_string& operator=(initializer_list<value_type>);
317
318 /**
319 * 21.4.3, iterators:
320 */
321
322 iterator begin() noexcept;
323
324 const_iterator begin() const noexcept;
325
326 iterator end() noexcept;
327
328 const_iterator end() const noexcept;
329
330 reverse_iterator rbegin() noexcept
331 {
332 return make_reverse_iterator(end());
333 }
334
335 const_reverse_iterator rbegin() const noexcept
336 {
337 return make_reverse_iterator(cend());
338 }
339
340 reverse_iterator rend() noexcept
341 {
342 return make_reverse_iterator(begin());
343 }
344
345 const_reverse_iterator rend() const noexcept
346 {
347 return make_reverse_iterator(cbegin());
348 }
349
350 const_iterator cbegin() const noexcept;
351
352 const_iterator cend() const noexcept;
353
354 const_reverse_iterator crbegin() const noexcept
355 {
356 return rbegin();
357 }
358
359 const_reverse_iterator crend() const noexcept
360 {
361 return rend();
362 }
363
364 /**
365 * 21.4.4, capacity:
366 */
367
368 size_type size() const noexcept;
369
370 size_type length() const noexcept;
371
372 size_type max_size() const noexcept;
373
374 void resize(size_type n, value_type c);
375
376 void resize(size_type n);
377
378 size_type capacity() const noexcept;
379
380 void reserve(size_type res_arg = 0);
381
382 void shrink_to_fit();
383
384 void clear() noexcept;
385
386 bool empty() const noexcept;
387
388 /**
389 * 21.4.5, element access:
390 */
391
392 const_reference operator[](size_type idx) const;
393
394 reference operator[](size_type idx);
395
396 const_reference at(size_type idx) const;
397
398 reference at(size_type idx);
399
400 const_reference front() const;
401
402 reference front();
403
404 const_reference back() const;
405
406 reference back();
407
408 /**
409 * 21.4.6, modifiers:
410 */
411
412 basic_string& operator+=(const basic_string& str);
413
414 basic_string& operator+=(const value_type* str);
415
416 basic_string& operator+=(value_type c);
417
418 basic_string& operator+=(initializer_list<value_type> init);
419
420 basic_string& append(const basic_string& str);
421
422 basic_string& append(const basic_string& str, size_type pos
423 size_type n = npos);
424
425 basic_string& append(const value_type* str, size_type n);
426
427 basic_string& append(const value_type* str);
428
429 basic_string& append(size_type n, value_type c);
430
431 template<class InputIterator>
432 basic_string& append(InputIterator first, InputIterator last);
433
434 basic_string& append(initializer_list<value_type> init);
435
436 void push_back(value_type c);
437
438 basic_string& assign(const basic_string& str);
439
440 basic_string& assign(basic_string&& str);
441
442 basic_string& assign(const basic_string& str, size_type pos,
443 size_type n = npos);
444
445 basic_string& assign(const value_type* str, size_type n);
446
447 basic_string& assign(const value_type* str);
448
449 basic_string& assign(size_type n, value_type c);
450
451 template<class InputIterator>
452 basic_string& assign(InputIterator first, InputIterator last);
453
454 basic_string& assign(initializer_list<value_type> init);
455
456 basic_string& insert(size_type pos, const basic_string& str);
457
458 basic_string& insert(size_type pos1, const basic_string& str,
459 size_type pos2, size_type n = npos);
460
461 basic_string& insert(size_type pos, const value_type* str, size_type n);
462
463 basic_string& insert(size_type pos, const value_type* str);
464
465 basic_string& insert(size_type pos, size_type n, value_type c);
466
467 iterator insert(const_iterator pos, value_type c);
468
469 iterator insert(const_iterator pos, size_type n, value_type c);
470
471 template<class InputIterator>
472 iterator insert(const_iterator pos, InputIterator first,
473 InputIterator last);
474
475 iterator insert(const_iterator pos, initializer_list<value_type>);
476
477 basic_string& erase(size_type pos = 0; size_type n = npos);
478
479 iterator erase(const_iterator pos);
480
481 iterator erase(const_iterator pos, const_iterator last);
482
483 void pop_back();
484
485 basic_string& replace(size_type pos, size_type n, const basic_string& str);
486
487 basic_string& replace(size_type pos1, size_type n1, const basic_string& str
488 size_type pos2, size_type n2);
489
490 basic_string& replace(size_type pos, size_type n1, const value_type* str,
491 size_type n2);
492
493 basic_string& replace(size_type pos, size_type n, const value_type* str);
494
495 basic_string& replace(size_type pos, size_type n1, size_type n2,
496 value_type c);
497
498 basic_string& replace(const_iterator i1, const_iterator i2,
499 const basic_string& str);
500
501 basic_string& replace(const_iterator i1, const_iterator i2,
502 const value_type* str, size_type n);
503
504 basic_string& replace(const_iterator i1, const_iterator i2,
505 const value_type* str);
506
507 basic_string& replace(const_iterator i1, const_iterator i2,
508 value_type c);
509
510 template<class InputIterator>
511 basic_string& replace(const_iterator i1, const_iterator i2,
512 InputIterator j1, InputIterator j2);
513
514 basic_string& replace(const_iterator i1, const_iterator i2,
515 initializer_list<value_type> init);
516
517 size_type copy(value_type* str, size_type n, size_type pos = 0) const;
518
519 void swap(basic_string& other)
520 noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
521 allocator_traits<allocator_type>::is_always_equal);
522
523 /**
524 * 21.4.7, string operations:
525 */
526
527 const value_type* c_str() const noexcept;
528
529 const value_type* data() const noexcept;
530
531 allocator_type get_allocator() const noexcept;
532
533 size_type find(const basic_string& str, size_type pos = 0) const noexcept;
534
535 size_type find(const value_type* str, size_type pos, size_type n) const;
536
537 size_type find(const value_type* str, size_type pos = 0) const;
538
539 size_type find(value_type c, size_type pos = 0) const;
540
541 size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
542
543 size_type rfind(const value_type* str, size_type pos, size_type n) const;
544
545 size_type rfind(const value_type* str, size_type pos = npos) const;
546
547 size_type rfind(value_type c, size_type pos = npos) const;
548
549 size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
550
551 size_type find_first_of(const value_type* str, size_type pos, size_type n) const;
552
553 size_type find_first_of(const value_type* str, size_type pos = 0) const;
554
555 size_type find_first_of(value_type c, size_type pos = 0) const;
556
557 size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
558
559 size_type find_last_of(const value_type* str, size_type pos, size_type n) const;
560
561 size_type find_last_of(const value_type* str, size_type pos = npos) const;
562
563 size_type find_last_of(value_type c, size_type pos = npos) const;
564
565 size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
566
567 size_type find_first_not_of(const value_type* str, size_type pos, size_type n) const;
568
569 size_type find_first_not_of(const value_type* str, size_type pos = 0) const;
570
571 size_type find_first_not_of(value_type c, size_type pos = 0) const;
572
573 size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
574
575 size_type find_last_not_of(const value_type* str, size_type pos, size_type n) const;
576
577 size_type find_last_not_of(const value_type* str, size_type pos = npos) const;
578
579 size_type find_last_not_of(value_type c, size_type pos = npos) const;
580
581 basic_string substr(size_type pos = 0, size_type n = npos) const;
582
583 int compare(const basic_string& other) const noexcept;
584
585 int compare(size_type pos, size_type n, const basic_string& other) const;
586
587 int compare(size_type pos1, size_type n1, const basic_string& other,
588 size_type pos2, size_type n2 = npos) const;
589
590 int compare(const value_type* other) const;
591
592 int compare(size_type pos, size_type n, const value_type* other) const;
593
594 int compare(size_type pos1, size_type n1,
595 const value_type* other, size_type n2) const;
596 };
597}
598
599#endif
Note: See TracBrowser for help on using the repository browser.