| 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 |
| 51 | namespace 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 | |
| 505 | namespace 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 */ |