2 * Copyright (c) 2016 Matthew Rodusek <http://rodusek.me>
4 * SPDX-License-Identifier: MIT
8 * \file string_view.hpp
10 * \brief This header contains the definition of the string_view type, as
11 * described by the C++17 standard.
13 * \author Matthew Rodusek (matthew.rodusek@gmail.com)
14 * \copyright Matthew Rodusek
18 * The MIT License (MIT)
20 * Licensed under the MIT License <http://opensource.org/licenses/MIT>.
21 * Copyright (c) 2016 Matthew Rodusek <http://rodusek.me>
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:
30 * The above copyright notice and this permission notice shall be included in all
31 * copies or substantial portions of the Software.
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
41 #ifndef BPSTD_STRING_VIEW_HPP
42 #define BPSTD_STRING_VIEW_HPP
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
51 namespace bpstd { // back-port std
53 ////////////////////////////////////////////////////////////////////////////
54 /// \brief A wrapper around non-owned strings.
56 /// This is an implementation of the C++17 string_view proposal
59 ////////////////////////////////////////////////////////////////////////////
62 typename Traits = std::char_traits<CharT>
64 class basic_string_view final
66 //------------------------------------------------------------------------
67 // Public Member Types
68 //------------------------------------------------------------------------
71 using char_type = CharT;
72 using traits_type = Traits;
73 using size_type = std::size_t;
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*;
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>;
86 //------------------------------------------------------------------------
88 //------------------------------------------------------------------------
91 static constexpr size_type npos = size_type(-1);
93 //------------------------------------------------------------------------
95 //------------------------------------------------------------------------
98 /// \brief Default constructs a basic_string_view without any content
99 constexpr basic_string_view() noexcept;
101 /// \brief Constructs a basic_string_view by copying another one
103 /// \param other the string view being copied
104 constexpr basic_string_view(const basic_string_view& other) noexcept = default;
106 /// \brief Constructs a basic_string_view by moving anothe rone
108 /// \param other the string view being moved
109 constexpr basic_string_view(basic_string_view&& other) noexcept = default;
111 /// \brief Constructs a basic_string_view from a std::basic_string
113 /// \param str the string to view
114 template<typename Allocator>
115 basic_string_view(const std::basic_string<CharT,Traits,Allocator>& str) noexcept;
117 /// \brief Constructs a basic_string_view from an ansi-string
119 /// \param str the string to view
120 constexpr basic_string_view(const char_type* str) noexcept;
122 /// \brief Constructs a basic_string_view from an ansi string of a given size
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;
128 //------------------------------------------------------------------------
130 //------------------------------------------------------------------------
133 /// \brief Assigns a basic_string_view from an ansi-string
135 /// \param view the string to view
136 /// \return reference to \c (*this)
137 basic_string_view& operator=(const basic_string_view& view) = default;
139 //------------------------------------------------------------------------
141 //------------------------------------------------------------------------
144 /// \brief Returns the length of the string, in terms of bytes
146 /// \return the length of the string, in terms of bytes
147 constexpr size_type size() const noexcept;
149 /// \copydoc basic_string_view::size
150 constexpr size_type length() const noexcept;
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;
157 /// \brief Returns whether the basic_string_view is empty
158 /// (i.e. whether its length is 0).
160 /// \return whether the basic_string_view is empty
161 constexpr bool empty() const noexcept;
163 //------------------------------------------------------------------------
165 //------------------------------------------------------------------------
168 /// \brief Gets the ansi-string of the current basic_string_view
170 /// \return the ansi-string pointer
171 constexpr const char_type* c_str() const noexcept;
173 /// \brief Gets the data of the current basic_string_view
175 /// \note This is an alias of #c_str
177 /// \return the data this basic_string_view contains
178 constexpr const char_type* data() const noexcept;
180 /// \brief Accesses the element at index \p pos
182 /// \param pos the index to access
183 /// \return const reference to the character
184 constexpr const_reference operator[](size_type pos) const noexcept;
186 /// \brief Accesses the element at index \p pos
188 /// \param pos the index to access
189 /// \return const reference to the character
190 constexpr const_reference at(size_type pos) const;
192 /// \brief Access the first character of the string
194 /// \note Undefined behavior if basic_string_view is empty
196 /// \return reference to the first character of the string
197 constexpr const_reference front() const noexcept;
199 /// \brief References the last character of the string
201 /// \note Undefined behavior if basic_string_view is empty
203 /// \return reference to the last character of the string
204 constexpr const_reference back() const noexcept;
206 //------------------------------------------------------------------------
208 //------------------------------------------------------------------------
211 /// \brief Moves the start of the view forward by n characters.
213 /// The behavior is undefined if n > size().
215 /// \param n number of characters to remove from the start of the view
216 void remove_prefix(size_type n) noexcept;
218 /// \brief Moves the end of the view back by n characters.
220 /// The behavior is undefined if n > size().
222 /// \param n number of characters to remove from the end of the view
223 void remove_suffix(size_type n) noexcept;
225 /// \brief Exchanges the view with that of v.
227 /// \param v view to swap with
228 void swap(basic_string_view& v) noexcept;
230 //------------------------------------------------------------------------
232 //------------------------------------------------------------------------
235 /// \brief Creates a basic_string with a copy of the content of the current view.
237 /// \tparam Allocator type used to allocate internal storage
238 /// \param a Allocator instance to use for allocating the new string
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;
245 /// \copydoc basic_string_view::to_string
246 template<class Allocator>
247 explicit constexpr operator std::basic_string<CharT, Traits, Allocator>() const;
249 //------------------------------------------------------------------------
251 //------------------------------------------------------------------------
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.
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;
264 /// \brief Returns a substring of this viewed string
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;
271 //------------------------------------------------------------------------
273 /// \brief Compares two character sequences
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;
281 /// \brief Compares two character sequences
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;
291 /// \brief Compares two character sequences
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;
304 /// \brief Compares two character sequences
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;
312 /// \brief Compares two character sequences
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;
322 /// \brief Compares two character sequences
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;
334 //------------------------------------------------------------------------
336 size_type find(basic_string_view v, size_type pos = 0) const;
338 size_type find(char_type c, size_type pos = 0) const;
340 size_type find(const char_type* s, size_type pos, size_type count) const;
342 size_type find(const char_type* s, size_type pos = 0) const;
344 //------------------------------------------------------------------------
346 size_type rfind(basic_string_view v, size_type pos = npos) const;
348 size_type rfind(char_type c, size_type pos = npos) const;
350 size_type rfind(const char_type* s, size_type pos, size_type count) const;
352 size_type rfind(const char_type* s, size_type pos = npos) const;
354 //------------------------------------------------------------------------
356 size_type find_first_of(basic_string_view v, size_type pos = 0) const;
358 size_type find_first_of(char_type c, size_type pos = 0) const;
360 size_type find_first_of(const char_type* s, size_type pos, size_type count) const;
362 size_type find_first_of(const char_type* s, size_type pos = 0) const;
364 //------------------------------------------------------------------------
366 size_type find_last_of(basic_string_view v, size_type pos = npos) const;
368 size_type find_last_of(char_type c, size_type pos = npos) const;
370 size_type find_last_of(const char_type* s, size_type pos, size_type count) const;
372 size_type find_last_of(const char_type* s, size_type pos = npos) const;
374 //------------------------------------------------------------------------
376 size_type find_first_not_of(basic_string_view v, size_type pos = 0) const;
378 size_type find_first_not_of(char_type c, size_type pos = 0) const;
380 size_type find_first_not_of(const char_type* s, size_type pos, size_type count) const;
382 size_type find_first_not_of(const char_type* s, size_type pos = 0) const;
384 //------------------------------------------------------------------------
386 size_type find_last_not_of(basic_string_view v, size_type pos = npos) const;
388 size_type find_last_not_of(char_type c, size_type pos = npos) const;
390 size_type find_last_not_of(const char_type* s, size_type pos, size_type count) const;
392 size_type find_last_not_of(const char_type* s, size_type pos = npos) const;
394 //------------------------------------------------------------------------
396 //------------------------------------------------------------------------
400 /// \brief Retrieves the begin iterator for this basic_string_view
402 /// \return the begin iterator
403 const_iterator begin() const noexcept;
404 const_iterator cbegin() const noexcept;
408 /// \brief Retrieves the end iterator for this basic_string_view
410 /// \return the end iterator
411 const_iterator end() const noexcept;
412 const_iterator cend() const noexcept;
416 /// \brief Retrieves the reverse begin iterator for this basic_string_view
418 /// \return the reverse begin iterator
419 const_reverse_iterator rbegin() const noexcept;
420 const_reverse_iterator rend() const noexcept;
424 /// \brief Retrieves the reverse end iterator for this basic_string_view
426 /// \return the reverse end iterator
427 const_reverse_iterator crbegin() const noexcept;
428 const_reverse_iterator crend() const noexcept;
431 //------------------------------------------------------------------------
433 //------------------------------------------------------------------------
436 const char_type* m_str; ///< The internal string type
437 size_type m_size; ///< The size of this string
439 /// \brief Checks whether \p c is one of the characters in \p str
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);
447 template <typename CharT, typename Traits>
448 const typename basic_string_view<CharT,Traits>::size_type
449 basic_string_view<CharT,Traits>::npos;
451 //--------------------------------------------------------------------------
453 //--------------------------------------------------------------------------
455 /// \brief Overload for ostream output of basic_string_view
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);
464 template<typename CharT, typename Traits>
465 void swap(basic_string_view<CharT,Traits>& lhs,
466 basic_string_view<CharT,Traits>& rhs) noexcept;
468 //--------------------------------------------------------------------------
469 // Comparison Functions
470 //--------------------------------------------------------------------------
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;
491 //--------------------------------------------------------------------------
493 //--------------------------------------------------------------------------
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>;
502 #ifndef BPSTD_DETAIL_STRING_VIEW_INL
503 #define BPSTD_DETAIL_STRING_VIEW_INL
507 //--------------------------------------------------------------------------
509 //--------------------------------------------------------------------------
511 template<typename CharT, typename Traits>
512 inline constexpr basic_string_view<CharT,Traits>::basic_string_view()
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)
524 : m_str(str.c_str()),
530 template<typename CharT, typename Traits>
531 inline constexpr basic_string_view<CharT,Traits>::basic_string_view(const char_type* str)
534 m_size(traits_type::length(str))
539 template<typename CharT, typename Traits>
540 inline constexpr basic_string_view<CharT,Traits>::basic_string_view(const char_type* str, size_type count)
548 //--------------------------------------------------------------------------
550 //--------------------------------------------------------------------------
552 template<typename CharT, typename Traits>
553 inline constexpr typename basic_string_view<CharT,Traits>::size_type
554 basic_string_view<CharT,Traits>::size()
560 template<typename CharT, typename Traits>
561 inline constexpr typename basic_string_view<CharT,Traits>::size_type
562 basic_string_view<CharT,Traits>::length()
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()
576 template<typename CharT, typename Traits>
577 inline constexpr bool basic_string_view<CharT,Traits>::empty()
583 //--------------------------------------------------------------------------
585 //--------------------------------------------------------------------------
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()
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()
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)
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)
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];
619 template<typename CharT, typename Traits>
620 inline constexpr typename basic_string_view<CharT,Traits>::const_reference
621 basic_string_view<CharT,Traits>::front( )
627 template<typename CharT, typename Traits>
628 inline constexpr typename basic_string_view<CharT,Traits>::const_reference
629 basic_string_view<CharT,Traits>::back( )
632 return m_str[m_size-1];
635 //--------------------------------------------------------------------------
637 //--------------------------------------------------------------------------
639 template<typename CharT, typename Traits>
641 basic_string_view<CharT,Traits>::remove_prefix(size_type n)
644 m_str += n, m_size -= n;
647 template<typename CharT, typename Traits>
649 basic_string_view<CharT,Traits>::remove_suffix(size_type n)
655 template<typename CharT, typename Traits>
657 basic_string_view<CharT,Traits>::swap(basic_string_view& v)
661 swap(m_size,v.m_size);
665 //--------------------------------------------------------------------------
667 //--------------------------------------------------------------------------
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)
675 return std::basic_string<CharT,Traits,Allocator>(m_str, m_size, a);
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>()
684 return std::basic_string<CharT,Traits,Allocator>(m_str, m_size);
687 //--------------------------------------------------------------------------
689 //--------------------------------------------------------------------------
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,
699 throw std::out_of_range("Index out of range in basic_string_view::copy");
702 const size_type rcount = std::min(m_size - pos,count+1);
703 std::copy( m_str + pos, m_str + pos + rcount, dest);
707 template<typename CharT, typename Traits>
708 inline basic_string_view<CharT,Traits>
709 basic_string_view<CharT,Traits>::substr(size_type pos,
713 const size_type max_length = pos > m_size ? 0 : m_size - pos;
716 throw std::out_of_range("Index out of range in basic_string_view::substr");
719 return basic_string_view(m_str + pos, std::min(len, max_length) );
722 //--------------------------------------------------------------------------
724 template<typename CharT, typename Traits>
725 inline int basic_string_view<CharT,Traits>::compare(basic_string_view v)
728 const size_type rlen = std::min(m_size,v.m_size);
729 const int compare = Traits::compare(m_str,v.m_str,rlen);
731 return (compare ? compare : (m_size < v.m_size ? -1 : (m_size > v.m_size ? 1 : 0)));
734 template<typename CharT, typename Traits>
735 inline int basic_string_view<CharT,Traits>::compare(size_type pos,
740 return substr(pos,count).compare(v);
743 template<typename CharT, typename Traits>
744 inline int basic_string_view<CharT,Traits>::compare(size_type pos1,
751 return substr(pos1,count1).compare(v.substr(pos2,count2));
754 template<typename CharT, typename Traits>
755 inline int basic_string_view<CharT,Traits>::compare(const char_type* s)
758 return compare(basic_string_view<CharT,Traits>(s));
761 template<typename CharT, typename Traits>
762 inline int basic_string_view<CharT,Traits>::compare(size_type pos,
767 return substr(pos, count).compare(basic_string_view<CharT,Traits>(s));
770 template<typename CharT, typename Traits>
771 inline int basic_string_view<CharT,Traits>::compare(size_type pos,
777 return substr(pos, count1).compare(basic_string_view<CharT,Traits>(s, count2));
780 //--------------------------------------------------------------------------
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,
788 // Can't find a substring if the substring is bigger than this
792 if ((pos + v.size()) > size()) {
796 const auto offset = pos;
797 const auto increments = size() - v.size();
799 for (auto i = 0u; i <= increments; ++i) {
800 const auto j = i + offset;
801 if (substr(j, v.size()) == v) {
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,
814 return find(basic_string_view<CharT,Traits>(&c, 1), pos);
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,
823 return find(basic_string_view<CharT,Traits>(s, count), pos);
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,
832 return find(basic_string_view<CharT,Traits>(s), pos);
835 //--------------------------------------------------------------------------
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,
844 return v.empty() ? 0u : npos;
847 return std::min(size() - 1, pos);
849 if (v.size() > size()) {
853 auto i = std::min(pos, (size() - v.size()));
855 if (substr(i, v.size()) == v) {
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,
870 return rfind(basic_string_view<CharT,Traits>(&c, 1), pos);
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,
879 return rfind(basic_string_view<CharT,Traits>(s, count), pos);
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,
888 return rfind(basic_string_view<CharT,Traits>(s), pos);
891 //--------------------------------------------------------------------------
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,
899 const auto max_index = size();
900 for (auto i = pos; i < max_index; ++i) {
901 if (is_one_of(m_str[i],v)) {
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,
915 return find_first_of(basic_string_view<CharT,Traits>(&c, 1), pos);
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,
924 return find_first_of(basic_string_view<CharT,Traits>(s, count), pos);
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,
933 return find_first_of(basic_string_view<CharT,Traits>(s), pos);
936 //--------------------------------------------------------------------------
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,
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;
951 if (is_one_of(m_str[j],v)) {
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,
965 return find_last_of(basic_string_view<CharT,Traits>(&c, 1), pos);
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,
974 return find_last_of(basic_string_view<CharT,Traits>(s, count), pos);
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,
983 return find_last_of(basic_string_view<CharT,Traits>(s), pos);
986 //--------------------------------------------------------------------------
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,
994 const auto max_index = size();
995 for (auto i = pos; i < max_index; ++i) {
996 if (!is_one_of(m_str[i],v)) {
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,
1010 return find_first_not_of(basic_string_view<CharT,Traits>(&c, 1), pos);
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,
1020 return find_first_not_of(basic_string_view<CharT,Traits>(s, count), pos);
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,
1029 return find_first_not_of(basic_string_view<CharT,Traits>(s), pos);
1032 //--------------------------------------------------------------------------
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,
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;
1047 if (!is_one_of(m_str[j],v)) {
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,
1061 return find_last_not_of(basic_string_view<CharT,Traits>(&c, 1), pos);
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,
1071 return find_last_not_of(basic_string_view<CharT,Traits>(s, count), pos);
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,
1080 return find_last_not_of(basic_string_view<CharT,Traits>(s), pos);
1083 //--------------------------------------------------------------------------
1085 //--------------------------------------------------------------------------
1087 template<typename CharT, typename Traits>
1088 inline typename basic_string_view<CharT,Traits>::const_iterator
1089 basic_string_view<CharT,Traits>::begin()
1095 template<typename CharT, typename Traits>
1096 inline typename basic_string_view<CharT,Traits>::const_iterator
1097 basic_string_view<CharT,Traits>::cbegin()
1103 template<typename CharT, typename Traits>
1104 inline typename basic_string_view<CharT,Traits>::const_iterator
1105 basic_string_view<CharT,Traits>::end()
1108 return m_str + m_size;
1111 template<typename CharT, typename Traits>
1112 inline typename basic_string_view<CharT,Traits>::const_iterator
1113 basic_string_view<CharT,Traits>::cend()
1119 template<typename CharT, typename Traits>
1120 inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
1121 basic_string_view<CharT,Traits>::rbegin()
1124 return const_reverse_iterator{end()};
1127 template<typename CharT, typename Traits>
1128 inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
1129 basic_string_view<CharT,Traits>::crbegin()
1135 template<typename CharT, typename Traits>
1136 inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
1137 basic_string_view<CharT,Traits>::rend()
1140 return const_reverse_iterator{begin()};
1143 template<typename CharT, typename Traits>
1144 inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
1145 basic_string_view<CharT,Traits>::crend()
1151 template <typename CharT, typename Traits>
1152 inline bool basic_string_view<CharT,Traits>::is_one_of(CharT c,
1153 basic_string_view str)
1155 for (auto s : str) {
1163 //--------------------------------------------------------------------------
1165 //--------------------------------------------------------------------------
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)
1171 o.write(str.data(),str.size());
1175 template<typename CharT, typename Traits>
1176 inline void swap(basic_string_view<CharT,Traits>& lhs,
1177 basic_string_view<CharT,Traits>& rhs)
1183 //--------------------------------------------------------------------------
1184 // Comparison Functions
1185 //--------------------------------------------------------------------------
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)
1192 return lhs.compare(rhs) == 0;
1195 template<typename CharT, typename Traits>
1196 inline bool operator==(basic_string_view<CharT,Traits> lhs,
1200 return lhs == basic_string_view<CharT,Traits>(rhs);
1203 template<typename CharT, typename Traits>
1204 inline bool operator==(const CharT* lhs,
1205 const basic_string_view<CharT,Traits>& rhs)
1208 return basic_string_view<CharT,Traits>(lhs) == rhs;
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)
1215 return basic_string_view<CharT,Traits>(lhs) == rhs;
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)
1222 return lhs == basic_string_view<CharT,Traits>(rhs);
1225 //--------------------------------------------------------------------------
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)
1232 return lhs.compare(rhs) != 0;
1235 template<typename CharT, typename Traits>
1236 inline bool operator!=(const basic_string_view<CharT,Traits>& lhs,
1240 return lhs != basic_string_view<CharT,Traits>(rhs);
1243 template<typename CharT, typename Traits>
1244 inline bool operator!=(const CharT* lhs,
1245 const basic_string_view<CharT,Traits>& rhs)
1248 return basic_string_view<CharT,Traits>(lhs) != rhs;
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)
1255 return basic_string_view<CharT,Traits>(lhs) != rhs;
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)
1262 return lhs != basic_string_view<CharT,Traits>(rhs);
1264 //--------------------------------------------------------------------------
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)
1271 return lhs.compare(rhs) < 0;
1274 template<typename CharT, typename Traits>
1275 inline bool operator<(const basic_string_view<CharT,Traits>& lhs,
1279 return lhs < basic_string_view<CharT,Traits>(rhs);
1282 template<typename CharT, typename Traits>
1283 inline bool operator<(const CharT* lhs,
1284 const basic_string_view<CharT,Traits>& rhs)
1287 return basic_string_view<CharT,Traits>(lhs) < rhs;
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)
1294 return basic_string_view<CharT,Traits>(lhs) < rhs;
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)
1301 return lhs < basic_string_view<CharT,Traits>(rhs);
1304 //--------------------------------------------------------------------------
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)
1311 return lhs.compare(rhs) > 0;
1314 template<typename CharT, typename Traits>
1315 inline bool operator>(const basic_string_view<CharT,Traits>& lhs,
1319 return lhs > basic_string_view<CharT,Traits>(rhs);
1322 template<typename CharT, typename Traits>
1323 inline bool operator>(const CharT* lhs,
1324 const basic_string_view<CharT,Traits>& rhs)
1327 return basic_string_view<CharT,Traits>(lhs) > rhs;
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)
1334 return basic_string_view<CharT,Traits>(lhs) > rhs;
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)
1341 return lhs > basic_string_view<CharT,Traits>(rhs);
1344 //--------------------------------------------------------------------------
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)
1351 return lhs.compare(rhs) <= 0;
1354 template<typename CharT, typename Traits>
1355 inline bool operator<=(const basic_string_view<CharT,Traits>& lhs,
1359 return lhs <= basic_string_view<CharT,Traits>(rhs);
1362 template<typename CharT, typename Traits>
1363 inline bool operator<=(const CharT* lhs,
1364 const basic_string_view<CharT,Traits>& rhs)
1367 return basic_string_view<CharT,Traits>(lhs) <= rhs;
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)
1374 return basic_string_view<CharT,Traits>(lhs) <= rhs;
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)
1381 return lhs <= basic_string_view<CharT,Traits>(rhs);
1384 //--------------------------------------------------------------------------
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)
1391 return lhs.compare(rhs) >= 0;
1394 template<typename CharT, typename Traits>
1395 inline bool operator>=(const basic_string_view<CharT,Traits>& lhs,
1399 return lhs >= basic_string_view<CharT,Traits>(rhs);
1402 template<typename CharT, typename Traits>
1403 inline bool operator>=(const CharT* lhs,
1404 const basic_string_view<CharT,Traits>& rhs)
1407 return basic_string_view<CharT,Traits>(lhs) >= rhs;
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)
1414 return basic_string_view<CharT,Traits>(lhs) >= rhs;
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)
1421 return lhs >= basic_string_view<CharT,Traits>(rhs);
1424 } // namespace bpstd
1426 #endif /* BPSTD_DETAIL_STRING_VIEW_INL */
1428 #endif /* BPSTD_STRING_VIEW_HPP */