configure: enable -Wshadow-field
[babeltrace.git] / src / cpp-common / string_view.hpp
CommitLineData
225a4a84
PP
1/*
2 * Copyright (c) 2016 Matthew Rodusek <http://rodusek.me>
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7/**
8 * \file string_view.hpp
9 *
10 * \brief This header contains the definition of the string_view type, as
11 * described by the C++17 standard.
12 *
13 * \author Matthew Rodusek (matthew.rodusek@gmail.com)
14 * \copyright Matthew Rodusek
15 */
16
17/*
18 * The MIT License (MIT)
19 *
20 * Licensed under the MIT License <http://opensource.org/licenses/MIT>.
21 * Copyright (c) 2016 Matthew Rodusek <http://rodusek.me>
22 *
23 * Permission is hereby granted, free of charge, to any person obtaining a copy
24 * of this software and associated documentation files (the "Software"), to deal
25 * in the Software without restriction, including without limitation the rights
26 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 * copies of the Software, and to permit persons to whom the Software is
28 * furnished to do so, subject to the following conditions:
29 *
30 * The above copyright notice and this permission notice shall be included in all
31 * copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39 * SOFTWARE.
40 */
41#ifndef BPSTD_STRING_VIEW_HPP
42#define BPSTD_STRING_VIEW_HPP
43
44#include <algorithm> // std::
45#include <string> // std::char_traits
46#include <ostream> // std::basic_ostream
47#include <cstddef> // std::size_t
48#include <memory> // std::allocator
49#include <stdexcept> // std::out_of_range
50#include <iterator> // std::reverse_iterator
51namespace bpstd { // back-port std
52
53 ////////////////////////////////////////////////////////////////////////////
54 /// \brief A wrapper around non-owned strings.
55 ///
56 /// This is an implementation of the C++17 string_view proposal
57 ///
58 /// \ingroup core
59 ////////////////////////////////////////////////////////////////////////////
60 template<
61 typename CharT,
62 typename Traits = std::char_traits<CharT>
63 >
64 class basic_string_view final
65 {
66 //------------------------------------------------------------------------
67 // Public Member Types
68 //------------------------------------------------------------------------
69 public:
70
71 using char_type = CharT;
72 using traits_type = Traits;
73 using size_type = std::size_t;
74
75 using value_type = CharT;
76 using reference = value_type&;
77 using const_reference = const value_type&;
78 using pointer = value_type*;
79 using const_pointer = const value_type*;
80
81 using iterator = const CharT*;
82 using const_iterator = const CharT*;
83 using reverse_iterator = std::reverse_iterator<iterator>;
84 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
85
86 //------------------------------------------------------------------------
87 // Public Members
88 //------------------------------------------------------------------------
89 public:
90
91 static constexpr size_type npos = size_type(-1);
92
93 //------------------------------------------------------------------------
94 // Constructors
95 //------------------------------------------------------------------------
96 public:
97
98 /// \brief Default constructs a basic_string_view without any content
99 constexpr basic_string_view() noexcept;
100
101 /// \brief Constructs a basic_string_view by copying another one
102 ///
103 /// \param other the string view being copied
104 constexpr basic_string_view(const basic_string_view& other) noexcept = default;
105
106 /// \brief Constructs a basic_string_view by moving anothe rone
107 ///
108 /// \param other the string view being moved
109 constexpr basic_string_view(basic_string_view&& other) noexcept = default;
110
111 /// \brief Constructs a basic_string_view from a std::basic_string
112 ///
113 /// \param str the string to view
114 template<typename Allocator>
115 basic_string_view(const std::basic_string<CharT,Traits,Allocator>& str) noexcept;
116
117 /// \brief Constructs a basic_string_view from an ansi-string
118 ///
119 /// \param str the string to view
120 constexpr basic_string_view(const char_type* str) noexcept;
121
122 /// \brief Constructs a basic_string_view from an ansi string of a given size
123 ///
124 /// \param str the string to view
125 /// \param count the size of the string
126 constexpr basic_string_view(const char_type* str, size_type count) noexcept;
127
128 //------------------------------------------------------------------------
129 // Assignment
130 //------------------------------------------------------------------------
131 public:
132
133 /// \brief Assigns a basic_string_view from an ansi-string
134 ///
135 /// \param view the string to view
136 /// \return reference to \c (*this)
137 basic_string_view& operator=(const basic_string_view& view) = default;
138
139 //------------------------------------------------------------------------
140 // Capacity
141 //------------------------------------------------------------------------
142 public:
143
144 /// \brief Returns the length of the string, in terms of bytes
145 ///
146 /// \return the length of the string, in terms of bytes
147 constexpr size_type size() const noexcept;
148
149 /// \copydoc basic_string_view::size
150 constexpr size_type length() const noexcept;
151
152 /// \brief The largest possible number of char-like objects that can be
153 /// referred to by a basic_string_view.
154 /// \return Maximum number of characters
155 constexpr size_type max_size() const noexcept;
156
157 /// \brief Returns whether the basic_string_view is empty
158 /// (i.e. whether its length is 0).
159 ///
160 /// \return whether the basic_string_view is empty
161 constexpr bool empty() const noexcept;
162
163 //------------------------------------------------------------------------
164 // Element Access
165 //------------------------------------------------------------------------
166 public:
167
168 /// \brief Gets the ansi-string of the current basic_string_view
169 ///
170 /// \return the ansi-string pointer
171 constexpr const char_type* c_str() const noexcept;
172
173 /// \brief Gets the data of the current basic_string_view
174 ///
175 /// \note This is an alias of #c_str
176 ///
177 /// \return the data this basic_string_view contains
178 constexpr const char_type* data() const noexcept;
179
180 /// \brief Accesses the element at index \p pos
181 ///
182 /// \param pos the index to access
183 /// \return const reference to the character
184 constexpr const_reference operator[](size_type pos) const noexcept;
185
186 /// \brief Accesses the element at index \p pos
187 ///
188 /// \param pos the index to access
189 /// \return const reference to the character
190 constexpr const_reference at(size_type pos) const;
191
192 /// \brief Access the first character of the string
193 ///
194 /// \note Undefined behavior if basic_string_view is empty
195 ///
196 /// \return reference to the first character of the string
197 constexpr const_reference front() const noexcept;
198
199 /// \brief References the last character of the string
200 ///
201 /// \note Undefined behavior if basic_string_view is empty
202 ///
203 /// \return reference to the last character of the string
204 constexpr const_reference back() const noexcept;
205
206 //------------------------------------------------------------------------
207 // Modifiers
208 //------------------------------------------------------------------------
209 public:
210
211 /// \brief Moves the start of the view forward by n characters.
212 ///
213 /// The behavior is undefined if n > size().
214 ///
215 /// \param n number of characters to remove from the start of the view
216 void remove_prefix(size_type n) noexcept;
217
218 /// \brief Moves the end of the view back by n characters.
219 ///
220 /// The behavior is undefined if n > size().
221 ///
222 /// \param n number of characters to remove from the end of the view
223 void remove_suffix(size_type n) noexcept;
224
225 /// \brief Exchanges the view with that of v.
226 ///
227 /// \param v view to swap with
228 void swap(basic_string_view& v) noexcept;
229
230 //------------------------------------------------------------------------
231 // Conversions
232 //------------------------------------------------------------------------
233 public:
234
235 /// \brief Creates a basic_string with a copy of the content of the current view.
236 ///
237 /// \tparam Allocator type used to allocate internal storage
238 /// \param a Allocator instance to use for allocating the new string
239 ///
240 /// \return A basic_string containing a copy of the characters of the current view.
241 template<class Allocator = std::allocator<CharT>>
242 constexpr std::basic_string<CharT, Traits, Allocator>
243 to_string(const Allocator& a = Allocator()) const;
244
245 /// \copydoc basic_string_view::to_string
246 template<class Allocator>
247 explicit constexpr operator std::basic_string<CharT, Traits, Allocator>() const;
248
249 //------------------------------------------------------------------------
250 // Operations
251 //------------------------------------------------------------------------
252 public:
253
254 /// \brief Copies the substring [pos, pos + rcount) to the character string pointed
255 /// to by dest, where rcount is the smaller of count and size() - pos.
256 ///
257 /// \param dest pointer to the destination character string
258 /// \param count requested substring length
259 /// \param pos position of the first character
260 size_type copy( char_type* dest,
261 size_type count = npos,
262 size_type pos = 0 ) const;
263
264 /// \brief Returns a substring of this viewed string
265 ///
266 /// \param pos the position of the first character in the substring
267 /// \param len the length of the substring
268 /// \return the created substring
269 basic_string_view substr(size_t pos = 0, size_t len = npos) const;
270
271 //------------------------------------------------------------------------
272
273 /// \brief Compares two character sequences
274 ///
275 /// \param v view to compare
276 /// \return negative value if this view is less than the other character
277 /// sequence, zero if the both character sequences are equal, positive
278 /// value if this view is greater than the other character sequence.
279 int compare(basic_string_view v) const noexcept;
280
281 /// \brief Compares two character sequences
282 ///
283 /// \param pos position of the first character in this view to compare
284 /// \param count number of characters of this view to compare
285 /// \param v view to compare
286 /// \return negative value if this view is less than the other character
287 /// sequence, zero if the both character sequences are equal, positive
288 /// value if this view is greater than the other character sequence.
289 int compare(size_type pos, size_type count, basic_string_view v) const;
290
291 /// \brief Compares two character sequences
292 ///
293 /// \param pos1 position of the first character in this view to compare
294 /// \param count1 number of characters of this view to compare
295 /// \param v view to compare
296 /// \param pos2 position of the second character in this view to compare
297 /// \param count2 number of characters of the given view to compare
298 /// \return negative value if this view is less than the other character
299 /// sequence, zero if the both character sequences are equal, positive
300 /// value if this view is greater than the other character sequence.
301 int compare( size_type pos1, size_type count1, basic_string_view v,
302 size_type pos2, size_type count2 ) const;
303
304 /// \brief Compares two character sequences
305 ///
306 /// \param s pointer to the character string to compare to
307 /// \return negative value if this view is less than the other character
308 /// sequence, zero if the both character sequences are equal, positive
309 /// value if this view is greater than the other character sequence.
310 int compare(const char_type* s) const;
311
312 /// \brief Compares two character sequences
313 ///
314 /// \param pos position of the first character in this view to compare
315 /// \param count number of characters of this view to compare
316 /// \param s pointer to the character string to compare to
317 /// \return negative value if this view is less than the other character
318 /// sequence, zero if the both character sequences are equal, positive
319 /// value if this view is greater than the other character sequence.
320 int compare(size_type pos, size_type count, const char_type* s) const;
321
322 /// \brief Compares two character sequences
323 ///
324 /// \param pos position of the first character in this view to compare
325 /// \param count1 number of characters of this view to compare
326 /// \param s pointer to the character string to compare to
327 /// \param count2 number of characters of the given view to compare
328 /// \return negative value if this view is less than the other character
329 /// sequence, zero if the both character sequences are equal, positive
330 /// value if this view is greater than the other character sequence.
331 int compare( size_type pos, size_type count1, const char_type* s,
332 size_type count2 ) const;
333
334 //------------------------------------------------------------------------
335
336 size_type find(basic_string_view v, size_type pos = 0) const;
337
338 size_type find(char_type c, size_type pos = 0) const;
339
340 size_type find(const char_type* s, size_type pos, size_type count) const;
341
342 size_type find(const char_type* s, size_type pos = 0) const;
343
344 //------------------------------------------------------------------------
345
346 size_type rfind(basic_string_view v, size_type pos = npos) const;
347
348 size_type rfind(char_type c, size_type pos = npos) const;
349
350 size_type rfind(const char_type* s, size_type pos, size_type count) const;
351
352 size_type rfind(const char_type* s, size_type pos = npos) const;
353
354 //------------------------------------------------------------------------
355
356 size_type find_first_of(basic_string_view v, size_type pos = 0) const;
357
358 size_type find_first_of(char_type c, size_type pos = 0) const;
359
360 size_type find_first_of(const char_type* s, size_type pos, size_type count) const;
361
362 size_type find_first_of(const char_type* s, size_type pos = 0) const;
363
364 //------------------------------------------------------------------------
365
366 size_type find_last_of(basic_string_view v, size_type pos = npos) const;
367
368 size_type find_last_of(char_type c, size_type pos = npos) const;
369
370 size_type find_last_of(const char_type* s, size_type pos, size_type count) const;
371
372 size_type find_last_of(const char_type* s, size_type pos = npos) const;
373
374 //------------------------------------------------------------------------
375
376 size_type find_first_not_of(basic_string_view v, size_type pos = 0) const;
377
378 size_type find_first_not_of(char_type c, size_type pos = 0) const;
379
380 size_type find_first_not_of(const char_type* s, size_type pos, size_type count) const;
381
382 size_type find_first_not_of(const char_type* s, size_type pos = 0) const;
383
384 //------------------------------------------------------------------------
385
386 size_type find_last_not_of(basic_string_view v, size_type pos = npos) const;
387
388 size_type find_last_not_of(char_type c, size_type pos = npos) const;
389
390 size_type find_last_not_of(const char_type* s, size_type pos, size_type count) const;
391
392 size_type find_last_not_of(const char_type* s, size_type pos = npos) const;
393
394 //------------------------------------------------------------------------
395 // Iterators
396 //------------------------------------------------------------------------
397 public:
398
399 /// \{
400 /// \brief Retrieves the begin iterator for this basic_string_view
401 ///
402 /// \return the begin iterator
403 const_iterator begin() const noexcept;
404 const_iterator cbegin() const noexcept;
405 /// \}
406
407 /// \{
408 /// \brief Retrieves the end iterator for this basic_string_view
409 ///
410 /// \return the end iterator
411 const_iterator end() const noexcept;
412 const_iterator cend() const noexcept;
413 /// \}
414
415 /// \{
416 /// \brief Retrieves the reverse begin iterator for this basic_string_view
417 ///
418 /// \return the reverse begin iterator
419 const_reverse_iterator rbegin() const noexcept;
420 const_reverse_iterator rend() const noexcept;
421 /// \}
422
423 /// \{
424 /// \brief Retrieves the reverse end iterator for this basic_string_view
425 ///
426 /// \return the reverse end iterator
427 const_reverse_iterator crbegin() const noexcept;
428 const_reverse_iterator crend() const noexcept;
429 /// \}
430
431 //------------------------------------------------------------------------
432 // Private Member
433 //------------------------------------------------------------------------
434 private:
435
436 const char_type* m_str; ///< The internal string type
437 size_type m_size; ///< The size of this string
438
439 /// \brief Checks whether \p c is one of the characters in \p str
440 ///
441 /// \param c the character to check
442 /// \param str the characters to compare against
443 /// \return true if \p c is one of the characters in \p str
444 static bool is_one_of(CharT c, basic_string_view str);
445 };
446
447 template <typename CharT, typename Traits>
448 const typename basic_string_view<CharT,Traits>::size_type
449 basic_string_view<CharT,Traits>::npos;
450
451 //--------------------------------------------------------------------------
452 // Public Functions
453 //--------------------------------------------------------------------------
454
455 /// \brief Overload for ostream output of basic_string_view
456 ///
457 /// \param o The output stream to print to
458 /// \param str the string to print
459 /// \return reference to the output stream
460 template<typename CharT, typename Traits>
461 std::basic_ostream<CharT,Traits>& operator<<(std::basic_ostream<CharT,Traits>& o,
462 const basic_string_view<CharT,Traits>& str);
463
464 template<typename CharT, typename Traits>
465 void swap(basic_string_view<CharT,Traits>& lhs,
466 basic_string_view<CharT,Traits>& rhs) noexcept;
467
468 //--------------------------------------------------------------------------
469 // Comparison Functions
470 //--------------------------------------------------------------------------
471
472 template<typename CharT, typename Traits>
473 bool operator==(const basic_string_view<CharT,Traits>& lhs,
474 const basic_string_view<CharT,Traits>& rhs) noexcept;
475 template<typename CharT, typename Traits>
476 bool operator!=(const basic_string_view<CharT,Traits>& lhs,
477 const basic_string_view<CharT,Traits>& rhs) noexcept;
478 template<typename CharT, typename Traits>
479 bool operator<(const basic_string_view<CharT,Traits>& lhs,
480 const basic_string_view<CharT,Traits>& rhs) noexcept;
481 template<typename CharT, typename Traits>
482 bool operator>(const basic_string_view<CharT,Traits>& lhs,
483 const basic_string_view<CharT,Traits>& rhs) noexcept;
484 template<typename CharT, typename Traits>
485 bool operator<=(const basic_string_view<CharT,Traits>& lhs,
486 const basic_string_view<CharT,Traits>& rhs) noexcept;
487 template<typename CharT, typename Traits>
488 bool operator>=(const basic_string_view<CharT,Traits>& lhs,
489 const basic_string_view<CharT,Traits>& rhs) noexcept;
490
491 //--------------------------------------------------------------------------
492 // Type Aliases
493 //--------------------------------------------------------------------------
494
495 using string_view = basic_string_view<char>;
496 using wstring_view = basic_string_view<wchar_t>;
497 using u16string_view = basic_string_view<char16_t>;
498 using u32string_view = basic_string_view<char32_t>;
499
500} // namespace bpstd
501
502#ifndef BPSTD_DETAIL_STRING_VIEW_INL
503#define BPSTD_DETAIL_STRING_VIEW_INL
504
505namespace bpstd {
506
507 //--------------------------------------------------------------------------
508 // Constructor
509 //--------------------------------------------------------------------------
510
511 template<typename CharT, typename Traits>
512 inline constexpr basic_string_view<CharT,Traits>::basic_string_view()
513 noexcept
514 : m_str(nullptr),
515 m_size(0)
516 {
517
518 }
519
520 template<typename CharT, typename Traits>
521 template<typename Allocator>
522 inline basic_string_view<CharT,Traits>::basic_string_view(const std::basic_string<CharT,Traits,Allocator>& str)
523 noexcept
524 : m_str(str.c_str()),
525 m_size(str.size())
526 {
527
528 }
529
530 template<typename CharT, typename Traits>
531 inline constexpr basic_string_view<CharT,Traits>::basic_string_view(const char_type* str)
532 noexcept
533 : m_str(str),
534 m_size(traits_type::length(str))
535 {
536
537 }
538
539 template<typename CharT, typename Traits>
540 inline constexpr basic_string_view<CharT,Traits>::basic_string_view(const char_type* str, size_type count)
541 noexcept
542 : m_str(str),
543 m_size(count)
544 {
545
546 }
547
548 //--------------------------------------------------------------------------
549 // Capacity
550 //--------------------------------------------------------------------------
551
552 template<typename CharT, typename Traits>
553 inline constexpr typename basic_string_view<CharT,Traits>::size_type
554 basic_string_view<CharT,Traits>::size()
555 const noexcept
556 {
557 return m_size;
558 }
559
560 template<typename CharT, typename Traits>
561 inline constexpr typename basic_string_view<CharT,Traits>::size_type
562 basic_string_view<CharT,Traits>::length()
563 const noexcept
564 {
565 return size();
566 }
567
568 template<typename CharT, typename Traits>
569 inline constexpr typename basic_string_view<CharT,Traits>::size_type
570 basic_string_view<CharT,Traits>::max_size()
571 const noexcept
572 {
573 return npos - 1;
574 }
575
576 template<typename CharT, typename Traits>
577 inline constexpr bool basic_string_view<CharT,Traits>::empty()
578 const noexcept
579 {
580 return m_size == 0;
581 }
582
583 //--------------------------------------------------------------------------
584 // Element Access
585 //--------------------------------------------------------------------------
586
587 template<typename CharT, typename Traits>
588 inline constexpr const typename basic_string_view<CharT,Traits>::char_type*
589 basic_string_view<CharT,Traits>::c_str()
590 const noexcept
591 {
592 return m_str;
593 }
594
595 template<typename CharT, typename Traits>
596 inline constexpr const typename basic_string_view<CharT,Traits>::char_type*
597 basic_string_view<CharT,Traits>::data()
598 const noexcept
599 {
600 return m_str;
601 }
602
603 template<typename CharT, typename Traits>
604 inline constexpr typename basic_string_view<CharT,Traits>::const_reference
605 basic_string_view<CharT,Traits>::operator[](size_type pos)
606 const noexcept
607 {
608 return m_str[pos];
609 }
610
611 template<typename CharT, typename Traits>
612 inline constexpr typename basic_string_view<CharT,Traits>::const_reference
613 basic_string_view<CharT,Traits>::at(size_type pos)
614 const
615 {
616 return pos < m_size ? m_str[pos] : throw std::out_of_range("Input out of range in basic_string_view::at"), m_str[pos];
617 }
618
619 template<typename CharT, typename Traits>
620 inline constexpr typename basic_string_view<CharT,Traits>::const_reference
621 basic_string_view<CharT,Traits>::front( )
622 const noexcept
623 {
624 return *m_str;
625 }
626
627 template<typename CharT, typename Traits>
628 inline constexpr typename basic_string_view<CharT,Traits>::const_reference
629 basic_string_view<CharT,Traits>::back( )
630 const noexcept
631 {
632 return m_str[m_size-1];
633 }
634
635 //--------------------------------------------------------------------------
636 // Modifiers
637 //--------------------------------------------------------------------------
638
639 template<typename CharT, typename Traits>
640 inline void
641 basic_string_view<CharT,Traits>::remove_prefix(size_type n)
642 noexcept
643 {
644 m_str += n, m_size -= n;
645 }
646
647 template<typename CharT, typename Traits>
648 inline void
649 basic_string_view<CharT,Traits>::remove_suffix(size_type n)
650 noexcept
651 {
652 m_size -= n;
653 }
654
655 template<typename CharT, typename Traits>
656 inline void
657 basic_string_view<CharT,Traits>::swap(basic_string_view& v)
658 noexcept
659 {
660 using std::swap;
661 swap(m_size,v.m_size);
662 swap(m_str,v.m_str);
663 }
664
665 //--------------------------------------------------------------------------
666 // Conversions
667 //--------------------------------------------------------------------------
668
669 template<typename CharT, typename Traits>
670 template<class Allocator>
671 inline constexpr std::basic_string<CharT, Traits, Allocator>
672 basic_string_view<CharT,Traits>::to_string(const Allocator& a)
673 const
674 {
675 return std::basic_string<CharT,Traits,Allocator>(m_str, m_size, a);
676 }
677
678 template<typename CharT, typename Traits>
679 template<class Allocator>
680 inline constexpr basic_string_view<CharT,Traits>::operator
681 std::basic_string<CharT, Traits, Allocator>()
682 const
683 {
684 return std::basic_string<CharT,Traits,Allocator>(m_str, m_size);
685 }
686
687 //--------------------------------------------------------------------------
688 // String Operations
689 //--------------------------------------------------------------------------
690
691 template<typename CharT, typename Traits>
692 inline typename basic_string_view<CharT,Traits>::size_type
693 basic_string_view<CharT,Traits>::copy(char_type* dest,
694 size_type count,
695 size_type pos)
696 const
697 {
698 if(pos >= m_size) {
699 throw std::out_of_range("Index out of range in basic_string_view::copy");
700 }
701
702 const size_type rcount = std::min(m_size - pos,count+1);
703 std::copy( m_str + pos, m_str + pos + rcount, dest);
704 return rcount;
705 }
706
707 template<typename CharT, typename Traits>
708 inline basic_string_view<CharT,Traits>
709 basic_string_view<CharT,Traits>::substr(size_type pos,
710 size_type len)
711 const
712 {
713 const size_type max_length = pos > m_size ? 0 : m_size - pos;
714
715 if (pos > size()) {
716 throw std::out_of_range("Index out of range in basic_string_view::substr");
717 }
718
719 return basic_string_view(m_str + pos, std::min(len, max_length) );
720 }
721
722 //--------------------------------------------------------------------------
723
724 template<typename CharT, typename Traits>
725 inline int basic_string_view<CharT,Traits>::compare(basic_string_view v)
726 const noexcept
727 {
728 const size_type rlen = std::min(m_size,v.m_size);
729 const int compare = Traits::compare(m_str,v.m_str,rlen);
730
731 return (compare ? compare : (m_size < v.m_size ? -1 : (m_size > v.m_size ? 1 : 0)));
732 }
733
734 template<typename CharT, typename Traits>
735 inline int basic_string_view<CharT,Traits>::compare(size_type pos,
736 size_type count,
737 basic_string_view v)
738 const
739 {
740 return substr(pos,count).compare(v);
741 }
742
743 template<typename CharT, typename Traits>
744 inline int basic_string_view<CharT,Traits>::compare(size_type pos1,
745 size_type count1,
746 basic_string_view v,
747 size_type pos2,
748 size_type count2)
749 const
750 {
751 return substr(pos1,count1).compare(v.substr(pos2,count2));
752 }
753
754 template<typename CharT, typename Traits>
755 inline int basic_string_view<CharT,Traits>::compare(const char_type* s)
756 const
757 {
758 return compare(basic_string_view<CharT,Traits>(s));
759 }
760
761 template<typename CharT, typename Traits>
762 inline int basic_string_view<CharT,Traits>::compare(size_type pos,
763 size_type count,
764 const char_type* s)
765 const
766 {
767 return substr(pos, count).compare(basic_string_view<CharT,Traits>(s));
768 }
769
770 template<typename CharT, typename Traits>
771 inline int basic_string_view<CharT,Traits>::compare(size_type pos,
772 size_type count1,
773 const char_type* s,
774 size_type count2)
775 const
776 {
777 return substr(pos, count1).compare(basic_string_view<CharT,Traits>(s, count2));
778 }
779
780 //--------------------------------------------------------------------------
781
782 template<typename CharT, typename Traits>
783 inline typename basic_string_view<CharT,Traits>::size_type
784 basic_string_view<CharT,Traits>::find(basic_string_view v,
785 size_type pos)
786 const
787 {
788 // Can't find a substring if the substring is bigger than this
789 if (pos > size()) {
790 return npos;
791 }
792 if ((pos + v.size()) > size()) {
793 return npos;
794 }
795
796 const auto offset = pos;
797 const auto increments = size() - v.size();
798
799 for (auto i = 0u; i <= increments; ++i) {
800 const auto j = i + offset;
801 if (substr(j, v.size()) == v) {
802 return j;
803 }
804 }
805 return npos;
806 }
807
808 template<typename CharT, typename Traits>
809 inline typename basic_string_view<CharT,Traits>::size_type
810 basic_string_view<CharT,Traits>::find(char_type c,
811 size_type pos)
812 const
813 {
814 return find(basic_string_view<CharT,Traits>(&c, 1), pos);
815 }
816
817 template<typename CharT, typename Traits>
818 inline typename basic_string_view<CharT,Traits>::size_type
819 basic_string_view<CharT,Traits>::find(const char_type* s, size_type pos,
820 size_type count)
821 const
822 {
823 return find(basic_string_view<CharT,Traits>(s, count), pos);
824 }
825
826 template<typename CharT, typename Traits>
827 inline typename basic_string_view<CharT,Traits>::size_type
828 basic_string_view<CharT,Traits>::find(const char_type* s,
829 size_type pos)
830 const
831 {
832 return find(basic_string_view<CharT,Traits>(s), pos);
833 }
834
835 //--------------------------------------------------------------------------
836
837 template<typename CharT, typename Traits>
838 inline typename basic_string_view<CharT,Traits>::size_type
839 basic_string_view<CharT,Traits>::rfind(basic_string_view v,
840 size_type pos)
841 const
842 {
843 if (empty()) {
844 return v.empty() ? 0u : npos;
845 }
846 if (v.empty()) {
847 return std::min(size() - 1, pos);
848 }
849 if (v.size() > size()) {
850 return npos;
851 }
852
853 auto i = std::min(pos, (size() - v.size()));
854 while (i != npos) {
855 if (substr(i, v.size()) == v) {
856 return i;
857 }
858 --i;
859 }
860
861 return npos;
862 }
863
864 template<typename CharT, typename Traits>
865 inline typename basic_string_view<CharT,Traits>::size_type
866 basic_string_view<CharT,Traits>::rfind(char_type c,
867 size_type pos)
868 const
869 {
870 return rfind(basic_string_view<CharT,Traits>(&c, 1), pos);
871 }
872
873 template<typename CharT, typename Traits>
874 inline typename basic_string_view<CharT,Traits>::size_type
875 basic_string_view<CharT,Traits>::rfind(const char_type* s, size_type pos,
876 size_type count)
877 const
878 {
879 return rfind(basic_string_view<CharT,Traits>(s, count), pos);
880 }
881
882 template<typename CharT, typename Traits>
883 inline typename basic_string_view<CharT,Traits>::size_type
884 basic_string_view<CharT,Traits>::rfind(const char_type* s,
885 size_type pos)
886 const
887 {
888 return rfind(basic_string_view<CharT,Traits>(s), pos);
889 }
890
891 //--------------------------------------------------------------------------
892
893 template<typename CharT, typename Traits>
894 inline typename basic_string_view<CharT,Traits>::size_type
895 basic_string_view<CharT,Traits>::find_first_of(basic_string_view v,
896 size_type pos)
897 const
898 {
899 const auto max_index = size();
900 for (auto i = pos; i < max_index; ++i) {
901 if (is_one_of(m_str[i],v)) {
902 return i;
903 }
904 }
905
906 return npos;
907 }
908
909 template<typename CharT, typename Traits>
910 inline typename basic_string_view<CharT,Traits>::size_type
911 basic_string_view<CharT,Traits>::find_first_of(char_type c,
912 size_type pos)
913 const
914 {
915 return find_first_of(basic_string_view<CharT,Traits>(&c, 1), pos);
916 }
917
918 template<typename CharT, typename Traits>
919 inline typename basic_string_view<CharT,Traits>::size_type
920 basic_string_view<CharT,Traits>::find_first_of(const char_type* s, size_type pos,
921 size_type count)
922 const
923 {
924 return find_first_of(basic_string_view<CharT,Traits>(s, count), pos);
925 }
926
927 template<typename CharT, typename Traits>
928 inline typename basic_string_view<CharT,Traits>::size_type
929 basic_string_view<CharT,Traits>::find_first_of(const char_type* s,
930 size_type pos)
931 const
932 {
933 return find_first_of(basic_string_view<CharT,Traits>(s), pos);
934 }
935
936 //--------------------------------------------------------------------------
937
938 template<typename CharT, typename Traits>
939 inline typename basic_string_view<CharT,Traits>::size_type
940 basic_string_view<CharT,Traits>::find_last_of(basic_string_view v,
941 size_type pos)
942 const
943 {
944 if (empty()) {
945 return npos;
946 }
947 const auto max_index = std::min(size() - 1, pos);
948 for (auto i = 0u; i <= max_index; ++i) {
949 const auto j = max_index - i;
950
951 if (is_one_of(m_str[j],v)) {
952 return j;
953 }
954 }
955
956 return npos;
957 }
958
959 template<typename CharT, typename Traits>
960 inline typename basic_string_view<CharT,Traits>::size_type
961 basic_string_view<CharT,Traits>::find_last_of(char_type c,
962 size_type pos)
963 const
964 {
965 return find_last_of(basic_string_view<CharT,Traits>(&c, 1), pos);
966 }
967
968 template<typename CharT, typename Traits>
969 inline typename basic_string_view<CharT,Traits>::size_type
970 basic_string_view<CharT,Traits>::find_last_of(const char_type* s, size_type pos,
971 size_type count)
972 const
973 {
974 return find_last_of(basic_string_view<CharT,Traits>(s, count), pos);
975 }
976
977 template<typename CharT, typename Traits>
978 inline typename basic_string_view<CharT,Traits>::size_type
979 basic_string_view<CharT,Traits>::find_last_of(const char_type* s,
980 size_type pos)
981 const
982 {
983 return find_last_of(basic_string_view<CharT,Traits>(s), pos);
984 }
985
986 //--------------------------------------------------------------------------
987
988 template<typename CharT, typename Traits>
989 inline typename basic_string_view<CharT,Traits>::size_type
990 basic_string_view<CharT,Traits>::find_first_not_of(basic_string_view v,
991 size_type pos)
992 const
993 {
994 const auto max_index = size();
995 for (auto i = pos; i < max_index; ++i) {
996 if (!is_one_of(m_str[i],v)) {
997 return i;
998 }
999 }
1000
1001 return npos;
1002 }
1003
1004 template<typename CharT, typename Traits>
1005 inline typename basic_string_view<CharT,Traits>::size_type
1006 basic_string_view<CharT,Traits>::find_first_not_of(char_type c,
1007 size_type pos)
1008 const
1009 {
1010 return find_first_not_of(basic_string_view<CharT,Traits>(&c, 1), pos);
1011 }
1012
1013 template<typename CharT, typename Traits>
1014 inline typename basic_string_view<CharT,Traits>::size_type
1015 basic_string_view<CharT,Traits>::find_first_not_of(const char_type* s,
1016 size_type pos,
1017 size_type count)
1018 const
1019 {
1020 return find_first_not_of(basic_string_view<CharT,Traits>(s, count), pos);
1021 }
1022
1023 template<typename CharT, typename Traits>
1024 inline typename basic_string_view<CharT,Traits>::size_type
1025 basic_string_view<CharT,Traits>::find_first_not_of(const char_type* s,
1026 size_type pos)
1027 const
1028 {
1029 return find_first_not_of(basic_string_view<CharT,Traits>(s), pos);
1030 }
1031
1032 //--------------------------------------------------------------------------
1033
1034 template<typename CharT, typename Traits>
1035 inline typename basic_string_view<CharT,Traits>::size_type
1036 basic_string_view<CharT,Traits>::find_last_not_of(basic_string_view v,
1037 size_type pos)
1038 const
1039 {
1040 if (empty()) {
1041 return npos;
1042 }
1043 const auto max_index = std::min(size() - 1, pos);
1044 for (auto i = 0u; i <= max_index; ++i) {
1045 const auto j = max_index - i;
1046
1047 if (!is_one_of(m_str[j],v)) {
1048 return j;
1049 }
1050 }
1051
1052 return npos;
1053 }
1054
1055 template<typename CharT, typename Traits>
1056 inline typename basic_string_view<CharT,Traits>::size_type
1057 basic_string_view<CharT,Traits>::find_last_not_of(char_type c,
1058 size_type pos)
1059 const
1060 {
1061 return find_last_not_of(basic_string_view<CharT,Traits>(&c, 1), pos);
1062 }
1063
1064 template<typename CharT, typename Traits>
1065 inline typename basic_string_view<CharT,Traits>::size_type
1066 basic_string_view<CharT,Traits>::find_last_not_of(const char_type* s,
1067 size_type pos,
1068 size_type count)
1069 const
1070 {
1071 return find_last_not_of(basic_string_view<CharT,Traits>(s, count), pos);
1072 }
1073
1074 template<typename CharT, typename Traits>
1075 inline typename basic_string_view<CharT,Traits>::size_type
1076 basic_string_view<CharT,Traits>::find_last_not_of(const char_type* s,
1077 size_type pos)
1078 const
1079 {
1080 return find_last_not_of(basic_string_view<CharT,Traits>(s), pos);
1081 }
1082
1083 //--------------------------------------------------------------------------
1084 // Iterator
1085 //--------------------------------------------------------------------------
1086
1087 template<typename CharT, typename Traits>
1088 inline typename basic_string_view<CharT,Traits>::const_iterator
1089 basic_string_view<CharT,Traits>::begin()
1090 const noexcept
1091 {
1092 return m_str;
1093 }
1094
1095 template<typename CharT, typename Traits>
1096 inline typename basic_string_view<CharT,Traits>::const_iterator
1097 basic_string_view<CharT,Traits>::cbegin()
1098 const noexcept
1099 {
1100 return begin();
1101 }
1102
1103 template<typename CharT, typename Traits>
1104 inline typename basic_string_view<CharT,Traits>::const_iterator
1105 basic_string_view<CharT,Traits>::end()
1106 const noexcept
1107 {
1108 return m_str + m_size;
1109 }
1110
1111 template<typename CharT, typename Traits>
1112 inline typename basic_string_view<CharT,Traits>::const_iterator
1113 basic_string_view<CharT,Traits>::cend()
1114 const noexcept
1115 {
1116 return cend();
1117 }
1118
1119 template<typename CharT, typename Traits>
1120 inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
1121 basic_string_view<CharT,Traits>::rbegin()
1122 const noexcept
1123 {
1124 return const_reverse_iterator{end()};
1125 }
1126
1127 template<typename CharT, typename Traits>
1128 inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
1129 basic_string_view<CharT,Traits>::crbegin()
1130 const noexcept
1131 {
1132 return rbegin();
1133 }
1134
1135 template<typename CharT, typename Traits>
1136 inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
1137 basic_string_view<CharT,Traits>::rend()
1138 const noexcept
1139 {
1140 return const_reverse_iterator{begin()};
1141 }
1142
1143 template<typename CharT, typename Traits>
1144 inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
1145 basic_string_view<CharT,Traits>::crend()
1146 const noexcept
1147 {
1148 return crend();
1149 }
1150
1151 template <typename CharT, typename Traits>
1152 inline bool basic_string_view<CharT,Traits>::is_one_of(CharT c,
1153 basic_string_view str)
1154 {
1155 for (auto s : str) {
1156 if (c == s) {
1157 return true;
1158 }
1159 }
1160 return false;
1161 }
1162
1163 //--------------------------------------------------------------------------
1164 // Public Functions
1165 //--------------------------------------------------------------------------
1166
1167 template<typename CharT, typename Traits>
1168 std::basic_ostream<CharT,Traits>& operator<<(std::basic_ostream<CharT,Traits>& o,
1169 const basic_string_view<CharT,Traits>& str)
1170 {
1171 o.write(str.data(),str.size());
1172 return o;
1173 }
1174
1175 template<typename CharT, typename Traits>
1176 inline void swap(basic_string_view<CharT,Traits>& lhs,
1177 basic_string_view<CharT,Traits>& rhs)
1178 noexcept
1179 {
1180 lhs.swap(rhs);
1181 }
1182
1183 //--------------------------------------------------------------------------
1184 // Comparison Functions
1185 //--------------------------------------------------------------------------
1186
1187 template<typename CharT, typename Traits>
1188 inline bool operator==(const basic_string_view<CharT,Traits>& lhs,
1189 const basic_string_view<CharT,Traits>& rhs)
1190 noexcept
1191 {
1192 return lhs.compare(rhs) == 0;
1193 }
1194
1195 template<typename CharT, typename Traits>
1196 inline bool operator==(basic_string_view<CharT,Traits> lhs,
1197 const CharT* rhs)
1198 noexcept
1199 {
1200 return lhs == basic_string_view<CharT,Traits>(rhs);
1201 }
1202
1203 template<typename CharT, typename Traits>
1204 inline bool operator==(const CharT* lhs,
1205 const basic_string_view<CharT,Traits>& rhs)
1206 noexcept
1207 {
1208 return basic_string_view<CharT,Traits>(lhs) == rhs;
1209 }
1210
1211 template<typename CharT, typename Traits, typename Allocator>
1212 inline bool operator==(const std::basic_string<CharT,Traits,Allocator>& lhs,
1213 const basic_string_view<CharT,Traits>& rhs)
1214 {
1215 return basic_string_view<CharT,Traits>(lhs) == rhs;
1216 }
1217
1218 template<typename CharT, typename Traits, typename Allocator>
1219 inline bool operator==(const basic_string_view<CharT,Traits>& lhs,
1220 const std::basic_string<CharT,Traits,Allocator>& rhs)
1221 {
1222 return lhs == basic_string_view<CharT,Traits>(rhs);
1223 }
1224
1225 //--------------------------------------------------------------------------
1226
1227 template<typename CharT, typename Traits>
1228 inline bool operator!=(const basic_string_view<CharT,Traits>& lhs,
1229 const basic_string_view<CharT,Traits>& rhs)
1230 noexcept
1231 {
1232 return lhs.compare(rhs) != 0;
1233 }
1234
1235 template<typename CharT, typename Traits>
1236 inline bool operator!=(const basic_string_view<CharT,Traits>& lhs,
1237 const CharT* rhs)
1238 noexcept
1239 {
1240 return lhs != basic_string_view<CharT,Traits>(rhs);
1241 }
1242
1243 template<typename CharT, typename Traits>
1244 inline bool operator!=(const CharT* lhs,
1245 const basic_string_view<CharT,Traits>& rhs)
1246 noexcept
1247 {
1248 return basic_string_view<CharT,Traits>(lhs) != rhs;
1249 }
1250
1251 template<typename CharT, typename Traits, typename Allocator>
1252 inline bool operator!=(const std::basic_string<CharT,Traits,Allocator>& lhs,
1253 const basic_string_view<CharT,Traits>& rhs)
1254 {
1255 return basic_string_view<CharT,Traits>(lhs) != rhs;
1256 }
1257
1258 template<typename CharT, typename Traits, typename Allocator>
1259 inline bool operator!=(const basic_string_view<CharT,Traits>& lhs,
1260 const std::basic_string<CharT,Traits,Allocator>& rhs)
1261 {
1262 return lhs != basic_string_view<CharT,Traits>(rhs);
1263 }
1264 //--------------------------------------------------------------------------
1265
1266 template<typename CharT, typename Traits>
1267 inline bool operator<(const basic_string_view<CharT,Traits>& lhs,
1268 const basic_string_view<CharT,Traits>& rhs)
1269 noexcept
1270 {
1271 return lhs.compare(rhs) < 0;
1272 }
1273
1274 template<typename CharT, typename Traits>
1275 inline bool operator<(const basic_string_view<CharT,Traits>& lhs,
1276 const CharT* rhs)
1277 noexcept
1278 {
1279 return lhs < basic_string_view<CharT,Traits>(rhs);
1280 }
1281
1282 template<typename CharT, typename Traits>
1283 inline bool operator<(const CharT* lhs,
1284 const basic_string_view<CharT,Traits>& rhs)
1285 noexcept
1286 {
1287 return basic_string_view<CharT,Traits>(lhs) < rhs;
1288 }
1289
1290 template<typename CharT, typename Traits, typename Allocator>
1291 inline bool operator<(const std::basic_string<CharT,Traits,Allocator>& lhs,
1292 const basic_string_view<CharT,Traits>& rhs)
1293 {
1294 return basic_string_view<CharT,Traits>(lhs) < rhs;
1295 }
1296
1297 template<typename CharT, typename Traits, typename Allocator>
1298 inline bool operator<(const basic_string_view<CharT,Traits>& lhs,
1299 const std::basic_string<CharT,Traits,Allocator>& rhs)
1300 {
1301 return lhs < basic_string_view<CharT,Traits>(rhs);
1302 }
1303
1304 //--------------------------------------------------------------------------
1305
1306 template<typename CharT, typename Traits>
1307 inline bool operator>(const basic_string_view<CharT,Traits>& lhs,
1308 const basic_string_view<CharT,Traits>& rhs)
1309 noexcept
1310 {
1311 return lhs.compare(rhs) > 0;
1312 }
1313
1314 template<typename CharT, typename Traits>
1315 inline bool operator>(const basic_string_view<CharT,Traits>& lhs,
1316 const CharT* rhs)
1317 noexcept
1318 {
1319 return lhs > basic_string_view<CharT,Traits>(rhs);
1320 }
1321
1322 template<typename CharT, typename Traits>
1323 inline bool operator>(const CharT* lhs,
1324 const basic_string_view<CharT,Traits>& rhs)
1325 noexcept
1326 {
1327 return basic_string_view<CharT,Traits>(lhs) > rhs;
1328 }
1329
1330 template<typename CharT, typename Traits, typename Allocator>
1331 inline bool operator>(const std::basic_string<CharT,Traits,Allocator>& lhs,
1332 const basic_string_view<CharT,Traits>& rhs)
1333 {
1334 return basic_string_view<CharT,Traits>(lhs) > rhs;
1335 }
1336
1337 template<typename CharT, typename Traits, typename Allocator>
1338 inline bool operator>(const basic_string_view<CharT,Traits>& lhs,
1339 const std::basic_string<CharT,Traits,Allocator>& rhs)
1340 {
1341 return lhs > basic_string_view<CharT,Traits>(rhs);
1342 }
1343
1344 //--------------------------------------------------------------------------
1345
1346 template<typename CharT, typename Traits>
1347 inline bool operator<=(const basic_string_view<CharT,Traits>& lhs,
1348 const basic_string_view<CharT,Traits>& rhs)
1349 noexcept
1350 {
1351 return lhs.compare(rhs) <= 0;
1352 }
1353
1354 template<typename CharT, typename Traits>
1355 inline bool operator<=(const basic_string_view<CharT,Traits>& lhs,
1356 const CharT* rhs)
1357 noexcept
1358 {
1359 return lhs <= basic_string_view<CharT,Traits>(rhs);
1360 }
1361
1362 template<typename CharT, typename Traits>
1363 inline bool operator<=(const CharT* lhs,
1364 const basic_string_view<CharT,Traits>& rhs)
1365 noexcept
1366 {
1367 return basic_string_view<CharT,Traits>(lhs) <= rhs;
1368 }
1369
1370 template<typename CharT, typename Traits, typename Allocator>
1371 inline bool operator<=(const std::basic_string<CharT,Traits,Allocator>& lhs,
1372 const basic_string_view<CharT,Traits>& rhs)
1373 {
1374 return basic_string_view<CharT,Traits>(lhs) <= rhs;
1375 }
1376
1377 template<typename CharT, typename Traits, typename Allocator>
1378 inline bool operator<=(const basic_string_view<CharT,Traits>& lhs,
1379 const std::basic_string<CharT,Traits,Allocator>& rhs)
1380 {
1381 return lhs <= basic_string_view<CharT,Traits>(rhs);
1382 }
1383
1384 //--------------------------------------------------------------------------
1385
1386 template<typename CharT, typename Traits>
1387 inline bool operator>=(const basic_string_view<CharT,Traits>& lhs,
1388 const basic_string_view<CharT,Traits>& rhs)
1389 noexcept
1390 {
1391 return lhs.compare(rhs) >= 0;
1392 }
1393
1394 template<typename CharT, typename Traits>
1395 inline bool operator>=(const basic_string_view<CharT,Traits>& lhs,
1396 const CharT* rhs)
1397 noexcept
1398 {
1399 return lhs >= basic_string_view<CharT,Traits>(rhs);
1400 }
1401
1402 template<typename CharT, typename Traits>
1403 inline bool operator>=(const CharT* lhs,
1404 const basic_string_view<CharT,Traits>& rhs)
1405 noexcept
1406 {
1407 return basic_string_view<CharT,Traits>(lhs) >= rhs;
1408 }
1409
1410 template<typename CharT, typename Traits, typename Allocator>
1411 inline bool operator>=(const std::basic_string<CharT,Traits,Allocator>& lhs,
1412 const basic_string_view<CharT,Traits>& rhs)
1413 {
1414 return basic_string_view<CharT,Traits>(lhs) >= rhs;
1415 }
1416
1417 template<typename CharT, typename Traits, typename Allocator>
1418 inline bool operator>=(const basic_string_view<CharT,Traits>& lhs,
1419 const std::basic_string<CharT,Traits,Allocator>& rhs)
1420 {
1421 return lhs >= basic_string_view<CharT,Traits>(rhs);
1422 }
1423
1424} // namespace bpstd
1425
1426#endif /* BPSTD_DETAIL_STRING_VIEW_INL */
1427
1428#endif /* BPSTD_STRING_VIEW_HPP */
This page took 0.075974 seconds and 4 git commands to generate.