Coverage Report

Created: 2023-09-25 06:17

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