• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    Copyright (c) Marshall Clow 2012-2015.
3    Copyright (c) Beman Dawes 2015
4    Copyright (c) Glen Joseph Fernandes 2019 (glenjofe@gmail.com)
5 
6    Distributed under the Boost Software License, Version 1.0. (See accompanying
7    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 
9     For more information, see http://www.boost.org
10 
11     Based on the StringRef implementation in LLVM (http://llvm.org) and
12     N3422 by Jeffrey Yasskin
13         http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
14     Updated July 2015 to reflect the Library Fundamentals TS
15         http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html
16 */
17 
18 #ifndef BOOST_STRING_VIEW_HPP
19 #define BOOST_STRING_VIEW_HPP
20 
21 #include <boost/config.hpp>
22 #include <boost/detail/workaround.hpp>
23 #include <boost/io/ostream_put.hpp>
24 #include <boost/utility/string_view_fwd.hpp>
25 #include <boost/throw_exception.hpp>
26 #include <boost/container_hash/hash_fwd.hpp>
27 
28 #include <cstddef>
29 #include <stdexcept>
30 #include <algorithm>
31 #include <iterator>
32 #include <string>
33 #include <cstring>
34 #include <iosfwd>
35 
36 #if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
37 // GCC 4.6 cannot handle a defaulted function with noexcept specifier
38 #define BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
39 #endif
40 
41 namespace boost {
42 
43     namespace detail {
44     //  A helper functor because sometimes we don't have lambdas
45         template <typename charT, typename traits>
46         class string_view_traits_eq {
47         public:
string_view_traits_eq(charT ch)48             string_view_traits_eq ( charT ch ) : ch_(ch) {}
operator ()(charT val) const49             bool operator()( charT val ) const { return traits::eq (ch_, val); }
50             charT ch_;
51             };
52         }
53 
54     template<typename charT, typename traits>  // traits defaulted in string_view_fwd.hpp
55     class basic_string_view {
56     public:
57       // types
58       typedef traits                                traits_type;
59       typedef charT                                 value_type;
60       typedef charT*                                pointer;
61       typedef const charT*                          const_pointer;
62       typedef charT&                                reference;
63       typedef const charT&                          const_reference;
64       typedef const_pointer                         const_iterator; // impl-defined
65       typedef const_iterator                        iterator;
66       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
67       typedef const_reverse_iterator                reverse_iterator;
68       typedef std::size_t                           size_type;
69       typedef std::ptrdiff_t                        difference_type;
70       static BOOST_CONSTEXPR_OR_CONST size_type     npos = size_type(-1);
71 
72       // construct/copy
basic_string_view()73       BOOST_CONSTEXPR basic_string_view() BOOST_NOEXCEPT
74         : ptr_(NULL), len_(0) {}
75 
76       // by defaulting these functions, basic_string_ref becomes
77       //  trivially copy/move constructible.
78       BOOST_CONSTEXPR basic_string_view(const basic_string_view &rhs) BOOST_NOEXCEPT
79 #ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
80         = default;
81 #else
82         : ptr_(rhs.ptr_), len_(rhs.len_) {}
83 #endif
84 
85       basic_string_view& operator=(const basic_string_view &rhs) BOOST_NOEXCEPT
86 #ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
87             = default;
88 #else
89         {
90         ptr_ = rhs.ptr_;
91         len_ = rhs.len_;
92         return *this;
93         }
94 #endif
95 
96       template<typename Allocator>
basic_string_view(const std::basic_string<charT,traits,Allocator> & str)97         basic_string_view(const std::basic_string<charT, traits, Allocator>& str) BOOST_NOEXCEPT
98           : ptr_(str.data()), len_(str.length()) {}
99 
100 // #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
101 //       // Constructing a string_view from a temporary string is a bad idea
102 //       template<typename Allocator>
103 //         basic_string_view(      std::basic_string<charT, traits, Allocator>&&)
104 //           = delete;
105 // #endif
106 
basic_string_view(const charT * str)107       BOOST_CONSTEXPR basic_string_view(const charT* str)
108         : ptr_(str), len_(traits::length(str)) {}
109 
basic_string_view(const charT * str,size_type len)110       BOOST_CONSTEXPR basic_string_view(const charT* str, size_type len)
111         : ptr_(str), len_(len) {}
112 
113         // iterators
begin() const114         BOOST_CONSTEXPR const_iterator   begin() const BOOST_NOEXCEPT { return ptr_; }
cbegin() const115         BOOST_CONSTEXPR const_iterator  cbegin() const BOOST_NOEXCEPT { return ptr_; }
end() const116         BOOST_CONSTEXPR const_iterator     end() const BOOST_NOEXCEPT { return ptr_ + len_; }
cend() const117         BOOST_CONSTEXPR const_iterator    cend() const BOOST_NOEXCEPT { return ptr_ + len_; }
rbegin() const118                 const_reverse_iterator  rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
crbegin() const119                 const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
rend() const120                 const_reverse_iterator    rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
crend() const121                 const_reverse_iterator   crend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
122 
123         // capacity
size() const124         BOOST_CONSTEXPR size_type size()     const BOOST_NOEXCEPT { return len_; }
length() const125         BOOST_CONSTEXPR size_type length()   const BOOST_NOEXCEPT { return len_; }
max_size() const126         BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { return len_; }
empty() const127         BOOST_CONSTEXPR bool empty()         const BOOST_NOEXCEPT { return len_ == 0; }
128 
129         // element access
operator [](size_type pos) const130         BOOST_CONSTEXPR const_reference operator[](size_type pos) const BOOST_NOEXCEPT { return ptr_[pos]; }
131 
at(size_t pos) const132         BOOST_CONSTEXPR const_reference at(size_t pos) const {
133             return pos >= len_ ? BOOST_THROW_EXCEPTION(std::out_of_range("boost::string_view::at")), ptr_[0] : ptr_[pos];
134             }
135 
front() const136         BOOST_CONSTEXPR const_reference front() const                { return ptr_[0]; }
back() const137         BOOST_CONSTEXPR const_reference back()  const                { return ptr_[len_-1]; }
data() const138         BOOST_CONSTEXPR const_pointer data()    const BOOST_NOEXCEPT { return ptr_; }
139 
140         // modifiers
clear()141         void clear() BOOST_NOEXCEPT { len_ = 0; }          // Boost extension
142 
remove_prefix(size_type n)143         BOOST_CXX14_CONSTEXPR void remove_prefix(size_type n) {
144             if ( n > len_ )
145                 n = len_;
146             ptr_ += n;
147             len_ -= n;
148             }
149 
remove_suffix(size_type n)150         BOOST_CXX14_CONSTEXPR void remove_suffix(size_type n) {
151             if ( n > len_ )
152                 n = len_;
153             len_ -= n;
154             }
155 
swap(basic_string_view & s)156         BOOST_CXX14_CONSTEXPR void swap(basic_string_view& s) BOOST_NOEXCEPT {
157             std::swap(ptr_, s.ptr_);
158             std::swap(len_, s.len_);
159             }
160 
161         // basic_string_view string operations
162 #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
163         template<typename Allocator>
operator std::basic_string<charT,traits,Allocator>() const164         explicit operator std::basic_string<charT, traits, Allocator>() const {
165             return std::basic_string<charT, traits, Allocator>(begin(), end());
166             }
167 #endif
168 
169 #ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
170         template<typename Allocator = std::allocator<charT> >
to_string(const Allocator & a=Allocator ()) const171         std::basic_string<charT, traits, Allocator> to_string(const Allocator& a = Allocator()) const {
172             return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
173             }
174 #else
to_string() const175         std::basic_string<charT, traits> to_string() const {
176             return std::basic_string<charT, traits>(begin(), end());
177             }
178 
179         template<typename Allocator>
to_string(const Allocator & a) const180         std::basic_string<charT, traits, Allocator> to_string(const Allocator& a) const {
181             return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
182             }
183 #endif
184 
copy(charT * s,size_type n,size_type pos=0) const185         size_type copy(charT* s, size_type n, size_type pos=0) const {
186             if (pos > size())
187                 BOOST_THROW_EXCEPTION(std::out_of_range("string_view::copy" ));
188             size_type rlen = (std::min)(n, len_ - pos);
189             traits_type::copy(s, data() + pos, rlen);
190             return rlen;
191             }
192 
substr(size_type pos,size_type n=npos) const193         BOOST_CXX14_CONSTEXPR basic_string_view substr(size_type pos, size_type n=npos) const {
194             if ( pos > size())
195                 BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::substr" ) );
196             return basic_string_view(data() + pos, (std::min)(size() - pos, n));
197             }
198 
compare(basic_string_view x) const199         BOOST_CXX14_CONSTEXPR int compare(basic_string_view x) const BOOST_NOEXCEPT {
200             const int cmp = traits::compare(ptr_, x.ptr_, (std::min)(len_, x.len_));
201             return cmp != 0 ? cmp : (len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1);
202             }
203 
compare(size_type pos1,size_type n1,basic_string_view x) const204         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string_view x)
205           const BOOST_NOEXCEPT {
206             return substr(pos1, n1).compare(x);
207             }
208 
compare(size_type pos1,size_type n1,basic_string_view x,size_type pos2,size_type n2) const209         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
210           basic_string_view x, size_type pos2, size_type n2) const {
211             return substr(pos1, n1).compare(x.substr(pos2, n2));
212             }
213 
compare(const charT * x) const214         BOOST_CXX14_CONSTEXPR int compare(const charT* x) const {
215             return compare(basic_string_view(x));
216             }
217 
compare(size_type pos1,size_type n1,const charT * x) const218         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, const charT* x) const {
219             return substr(pos1, n1).compare(basic_string_view(x));
220             }
221 
compare(size_type pos1,size_type n1,const charT * x,size_type n2) const222         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
223           const charT* x, size_type n2) const {
224             return substr(pos1, n1).compare(basic_string_view(x, n2));
225             }
226 
227         //  Searches
starts_with(charT c) const228         BOOST_CONSTEXPR bool starts_with(charT c) const BOOST_NOEXCEPT {              // Boost extension
229             return !empty() && traits::eq(c, front());
230             }
231 
starts_with(basic_string_view x) const232         BOOST_CONSTEXPR bool starts_with(basic_string_view x) const BOOST_NOEXCEPT {  // Boost extension
233             return len_ >= x.len_ && traits::compare(ptr_, x.ptr_, x.len_) == 0;
234             }
235 
ends_with(charT c) const236         BOOST_CONSTEXPR bool ends_with(charT c) const BOOST_NOEXCEPT {                // Boost extension
237             return !empty() && traits::eq(c, back());
238             }
239 
ends_with(basic_string_view x) const240         BOOST_CONSTEXPR bool ends_with(basic_string_view x) const BOOST_NOEXCEPT {    // Boost extension
241             return len_ >= x.len_ &&
242                traits::compare(ptr_ + len_ - x.len_, x.ptr_, x.len_) == 0;
243             }
244 
245         //  find
find(basic_string_view s,size_type pos=0) const246         BOOST_CXX14_CONSTEXPR size_type find(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
247             if (pos > size())
248               return npos;
249             if (s.empty())
250               return pos;
251             if (s.size() > size() - pos)
252                 return npos;
253             const charT* cur = ptr_ + pos;
254             const charT* last = cend() - s.size() + 1;
255             for (; cur != last ; ++cur) {
256                 cur = traits::find(cur, last - cur, s[0]);
257                 if (!cur)
258                     return npos;
259                 if (traits::compare(cur, s.cbegin(), s.size()) == 0)
260                     return cur - ptr_;
261             }
262             return npos;
263             }
find(charT c,size_type pos=0) const264         BOOST_CXX14_CONSTEXPR size_type find(charT c, size_type pos = 0) const BOOST_NOEXCEPT {
265             if (pos > size())
266               return npos;
267             const charT* ret_ptr = traits::find(ptr_ + pos, len_ - pos, c);
268             if (ret_ptr)
269               return ret_ptr - ptr_;
270             return npos;
271             }
find(const charT * s,size_type pos,size_type n) const272         BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
273             { return find(basic_string_view(s, n), pos); }
find(const charT * s,size_type pos=0) const274         BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
275             { return find(basic_string_view(s), pos); }
276 
277         //  rfind
rfind(basic_string_view s,size_type pos=npos) const278         BOOST_CXX14_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
279             if (len_ < s.len_)
280               return npos;
281             if (pos > len_ - s.len_)
282               pos = len_ - s.len_;
283             if (s.len_ == 0u)     // an empty string is always found
284               return pos;
285             for (const charT* cur = ptr_ + pos; ; --cur) {
286                 if (traits::compare(cur, s.ptr_, s.len_) == 0)
287                   return cur - ptr_;
288                 if (cur == ptr_)
289                   return npos;
290                 };
291             }
rfind(charT c,size_type pos=npos) const292         BOOST_CXX14_CONSTEXPR size_type rfind(charT c, size_type pos = npos) const BOOST_NOEXCEPT
293             { return rfind(basic_string_view(&c, 1), pos); }
rfind(const charT * s,size_type pos,size_type n) const294         BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
295             { return rfind(basic_string_view(s, n), pos); }
rfind(const charT * s,size_type pos=npos) const296         BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
297             { return rfind(basic_string_view(s), pos); }
298 
299         //  find_first_of
find_first_of(basic_string_view s,size_type pos=0) const300         BOOST_CXX14_CONSTEXPR size_type find_first_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
301             if (pos >= len_ || s.len_ == 0)
302               return npos;
303             const_iterator iter = std::find_first_of
304                 (this->cbegin () + pos, this->cend (), s.cbegin (), s.cend (), traits::eq);
305             return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
306             }
find_first_of(charT c,size_type pos=0) const307         BOOST_CXX14_CONSTEXPR size_type find_first_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
308             { return find(c, pos); }
find_first_of(const charT * s,size_type pos,size_type n) const309         BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
310             { return find_first_of(basic_string_view(s, n), pos); }
find_first_of(const charT * s,size_type pos=0) const311         BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
312             { return find_first_of(basic_string_view(s), pos); }
313 
314         //  find_last_of
find_last_of(basic_string_view s,size_type pos=npos) const315         BOOST_CXX14_CONSTEXPR size_type find_last_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
316             if (s.len_ == 0u)
317               return npos;
318             if (pos >= len_)
319               pos = 0;
320             else
321               pos = len_ - (pos+1);
322             const_reverse_iterator iter = std::find_first_of
323                 ( this->crbegin () + pos, this->crend (), s.cbegin (), s.cend (), traits::eq );
324             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
325             }
find_last_of(charT c,size_type pos=npos) const326         BOOST_CXX14_CONSTEXPR size_type find_last_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
327             { return find_last_of(basic_string_view(&c, 1), pos); }
find_last_of(const charT * s,size_type pos,size_type n) const328         BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
329             { return find_last_of(basic_string_view(s, n), pos); }
find_last_of(const charT * s,size_type pos=npos) const330         BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
331             { return find_last_of(basic_string_view(s), pos); }
332 
333         //  find_first_not_of
find_first_not_of(basic_string_view s,size_type pos=0) const334         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
335             if (pos >= len_)
336               return npos;
337             if (s.len_ == 0)
338               return pos;
339             const_iterator iter = find_not_of ( this->cbegin () + pos, this->cend (), s );
340             return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
341             }
find_first_not_of(charT c,size_type pos=0) const342         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
343             { return find_first_not_of(basic_string_view(&c, 1), pos); }
find_first_not_of(const charT * s,size_type pos,size_type n) const344         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
345             { return find_first_not_of(basic_string_view(s, n), pos); }
find_first_not_of(const charT * s,size_type pos=0) const346         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
347             { return find_first_not_of(basic_string_view(s), pos); }
348 
349         //  find_last_not_of
find_last_not_of(basic_string_view s,size_type pos=npos) const350         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
351             if (pos >= len_)
352               pos = len_ - 1;
353             if (s.len_ == 0u)
354               return pos;
355             pos = len_ - (pos+1);
356             const_reverse_iterator iter = find_not_of ( this->crbegin () + pos, this->crend (), s );
357             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
358             }
find_last_not_of(charT c,size_type pos=npos) const359         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
360             { return find_last_not_of(basic_string_view(&c, 1), pos); }
find_last_not_of(const charT * s,size_type pos,size_type n) const361         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
362             { return find_last_not_of(basic_string_view(s, n), pos); }
find_last_not_of(const charT * s,size_type pos=npos) const363         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
364             { return find_last_not_of(basic_string_view(s), pos); }
365 
366     private:
367         template <typename r_iter>
reverse_distance(r_iter first,r_iter last) const368         size_type reverse_distance(r_iter first, r_iter last) const BOOST_NOEXCEPT {
369         // Portability note here: std::distance is not NOEXCEPT, but calling it with a string_view::reverse_iterator will not throw.
370             return len_ - 1 - std::distance ( first, last );
371             }
372 
373         template <typename Iterator>
find_not_of(Iterator first,Iterator last,basic_string_view s) const374         Iterator find_not_of(Iterator first, Iterator last, basic_string_view s) const BOOST_NOEXCEPT {
375             for (; first != last ; ++first)
376                 if ( 0 == traits::find(s.ptr_, s.len_, *first))
377                     return first;
378             return last;
379             }
380 
381         const charT *ptr_;
382         std::size_t len_;
383         };
384 
385 
386 //  Comparison operators
387 //  Equality
388     template<typename charT, typename traits>
operator ==(basic_string_view<charT,traits> x,basic_string_view<charT,traits> y)389     inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
390                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
391         if (x.size () != y.size ()) return false;
392         return x.compare(y) == 0;
393         }
394 
395 //  Inequality
396     template<typename charT, typename traits>
operator !=(basic_string_view<charT,traits> x,basic_string_view<charT,traits> y)397     inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
398                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
399         if ( x.size () != y.size ()) return true;
400         return x.compare(y) != 0;
401         }
402 
403 //  Less than
404     template<typename charT, typename traits>
operator <(basic_string_view<charT,traits> x,basic_string_view<charT,traits> y)405     inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
406                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
407         return x.compare(y) < 0;
408         }
409 
410 //  Greater than
411     template<typename charT, typename traits>
operator >(basic_string_view<charT,traits> x,basic_string_view<charT,traits> y)412     inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
413                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
414         return x.compare(y) > 0;
415         }
416 
417 //  Less than or equal to
418     template<typename charT, typename traits>
operator <=(basic_string_view<charT,traits> x,basic_string_view<charT,traits> y)419     inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
420                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
421         return x.compare(y) <= 0;
422         }
423 
424 //  Greater than or equal to
425     template<typename charT, typename traits>
operator >=(basic_string_view<charT,traits> x,basic_string_view<charT,traits> y)426     inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
427                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
428         return x.compare(y) >= 0;
429         }
430 
431 // "sufficient additional overloads of comparison functions"
432     template<typename charT, typename traits, typename Allocator>
operator ==(basic_string_view<charT,traits> x,const std::basic_string<charT,traits,Allocator> & y)433     inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
434                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
435         return x == basic_string_view<charT, traits>(y);
436         }
437 
438     template<typename charT, typename traits, typename Allocator>
operator ==(const std::basic_string<charT,traits,Allocator> & x,basic_string_view<charT,traits> y)439     inline BOOST_CXX14_CONSTEXPR bool operator==(const std::basic_string<charT, traits, Allocator> & x,
440                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
441         return basic_string_view<charT, traits>(x) == y;
442         }
443 
444     template<typename charT, typename traits>
operator ==(basic_string_view<charT,traits> x,const charT * y)445     inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
446                                               const charT * y) BOOST_NOEXCEPT {
447         return x == basic_string_view<charT, traits>(y);
448         }
449 
450     template<typename charT, typename traits>
operator ==(const charT * x,basic_string_view<charT,traits> y)451     inline BOOST_CXX14_CONSTEXPR bool operator==(const charT * x,
452                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
453         return basic_string_view<charT, traits>(x) == y;
454         }
455 
456     template<typename charT, typename traits, typename Allocator>
operator !=(basic_string_view<charT,traits> x,const std::basic_string<charT,traits,Allocator> & y)457     inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
458                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
459         return x != basic_string_view<charT, traits>(y);
460         }
461 
462     template<typename charT, typename traits, typename Allocator>
operator !=(const std::basic_string<charT,traits,Allocator> & x,basic_string_view<charT,traits> y)463     inline BOOST_CXX14_CONSTEXPR bool operator!=(const std::basic_string<charT, traits, Allocator> & x,
464                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
465         return basic_string_view<charT, traits>(x) != y;
466         }
467 
468     template<typename charT, typename traits>
operator !=(basic_string_view<charT,traits> x,const charT * y)469     inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
470                            const charT * y) BOOST_NOEXCEPT {
471         return x != basic_string_view<charT, traits>(y);
472         }
473 
474     template<typename charT, typename traits>
operator !=(const charT * x,basic_string_view<charT,traits> y)475     inline BOOST_CXX14_CONSTEXPR bool operator!=(const charT * x,
476                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
477         return basic_string_view<charT, traits>(x) != y;
478         }
479 
480     template<typename charT, typename traits, typename Allocator>
operator <(basic_string_view<charT,traits> x,const std::basic_string<charT,traits,Allocator> & y)481     inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
482                     const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
483         return x < basic_string_view<charT, traits>(y);
484         }
485 
486     template<typename charT, typename traits, typename Allocator>
operator <(const std::basic_string<charT,traits,Allocator> & x,basic_string_view<charT,traits> y)487     inline BOOST_CXX14_CONSTEXPR bool operator<(const std::basic_string<charT, traits, Allocator> & x,
488                                 basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
489         return basic_string_view<charT, traits>(x) < y;
490         }
491 
492     template<typename charT, typename traits>
operator <(basic_string_view<charT,traits> x,const charT * y)493     inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
494                           const charT * y) BOOST_NOEXCEPT {
495         return x < basic_string_view<charT, traits>(y);
496         }
497 
498     template<typename charT, typename traits>
operator <(const charT * x,basic_string_view<charT,traits> y)499     inline BOOST_CXX14_CONSTEXPR bool operator<(const charT * x,
500                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
501         return basic_string_view<charT, traits>(x) < y;
502         }
503 
504     template<typename charT, typename traits, typename Allocator>
operator >(basic_string_view<charT,traits> x,const std::basic_string<charT,traits,Allocator> & y)505     inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
506                     const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
507         return x > basic_string_view<charT, traits>(y);
508         }
509 
510     template<typename charT, typename traits, typename Allocator>
operator >(const std::basic_string<charT,traits,Allocator> & x,basic_string_view<charT,traits> y)511     inline BOOST_CXX14_CONSTEXPR bool operator>(const std::basic_string<charT, traits, Allocator> & x,
512                                 basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
513         return basic_string_view<charT, traits>(x) > y;
514         }
515 
516     template<typename charT, typename traits>
operator >(basic_string_view<charT,traits> x,const charT * y)517     inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
518                           const charT * y) BOOST_NOEXCEPT {
519         return x > basic_string_view<charT, traits>(y);
520         }
521 
522     template<typename charT, typename traits>
operator >(const charT * x,basic_string_view<charT,traits> y)523     inline BOOST_CXX14_CONSTEXPR bool operator>(const charT * x,
524                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
525         return basic_string_view<charT, traits>(x) > y;
526         }
527 
528     template<typename charT, typename traits, typename Allocator>
operator <=(basic_string_view<charT,traits> x,const std::basic_string<charT,traits,Allocator> & y)529     inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
530                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
531         return x <= basic_string_view<charT, traits>(y);
532         }
533 
534     template<typename charT, typename traits, typename Allocator>
operator <=(const std::basic_string<charT,traits,Allocator> & x,basic_string_view<charT,traits> y)535     inline BOOST_CXX14_CONSTEXPR bool operator<=(const std::basic_string<charT, traits, Allocator> & x,
536                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
537         return basic_string_view<charT, traits>(x) <= y;
538         }
539 
540     template<typename charT, typename traits>
operator <=(basic_string_view<charT,traits> x,const charT * y)541     inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
542                            const charT * y) BOOST_NOEXCEPT {
543         return x <= basic_string_view<charT, traits>(y);
544         }
545 
546     template<typename charT, typename traits>
operator <=(const charT * x,basic_string_view<charT,traits> y)547     inline BOOST_CXX14_CONSTEXPR bool operator<=(const charT * x,
548                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
549         return basic_string_view<charT, traits>(x) <= y;
550         }
551 
552     template<typename charT, typename traits, typename Allocator>
operator >=(basic_string_view<charT,traits> x,const std::basic_string<charT,traits,Allocator> & y)553     inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
554                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
555         return x >= basic_string_view<charT, traits>(y);
556         }
557 
558     template<typename charT, typename traits, typename Allocator>
operator >=(const std::basic_string<charT,traits,Allocator> & x,basic_string_view<charT,traits> y)559     inline BOOST_CXX14_CONSTEXPR bool operator>=(const std::basic_string<charT, traits, Allocator> & x,
560                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
561         return basic_string_view<charT, traits>(x) >= y;
562         }
563 
564     template<typename charT, typename traits>
operator >=(basic_string_view<charT,traits> x,const charT * y)565     inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
566                            const charT * y) BOOST_NOEXCEPT {
567         return x >= basic_string_view<charT, traits>(y);
568         }
569 
570     template<typename charT, typename traits>
operator >=(const charT * x,basic_string_view<charT,traits> y)571     inline BOOST_CXX14_CONSTEXPR bool operator>=(const charT * x,
572                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
573         return basic_string_view<charT, traits>(x) >= y;
574         }
575 
576     // Inserter
577     template<class charT, class traits>
578     inline std::basic_ostream<charT, traits>&
operator <<(std::basic_ostream<charT,traits> & os,const basic_string_view<charT,traits> & str)579     operator<<(std::basic_ostream<charT, traits>& os,
580       const basic_string_view<charT,traits>& str) {
581         return boost::io::ostream_put(os, str.data(), str.size());
582         }
583 
584 #if 0
585     // numeric conversions
586     //
587     //  These are short-term implementations.
588     //  In a production environment, I would rather avoid the copying.
589     //
590     inline int stoi (string_view str, size_t* idx=0, int base=10) {
591         return std::stoi ( std::string(str), idx, base );
592         }
593 
594     inline long stol (string_view str, size_t* idx=0, int base=10) {
595         return std::stol ( std::string(str), idx, base );
596         }
597 
598     inline unsigned long stoul (string_view str, size_t* idx=0, int base=10) {
599         return std::stoul ( std::string(str), idx, base );
600         }
601 
602     inline long long stoll (string_view str, size_t* idx=0, int base=10) {
603         return std::stoll ( std::string(str), idx, base );
604         }
605 
606     inline unsigned long long stoull (string_view str, size_t* idx=0, int base=10) {
607         return std::stoull ( std::string(str), idx, base );
608         }
609 
610     inline float stof (string_view str, size_t* idx=0) {
611         return std::stof ( std::string(str), idx );
612         }
613 
614     inline double stod (string_view str, size_t* idx=0) {
615         return std::stod ( std::string(str), idx );
616         }
617 
618     inline long double stold (string_view str, size_t* idx=0)  {
619         return std::stold ( std::string(str), idx );
620         }
621 
622     inline int  stoi (wstring_view str, size_t* idx=0, int base=10) {
623         return std::stoi ( std::wstring(str), idx, base );
624         }
625 
626     inline long stol (wstring_view str, size_t* idx=0, int base=10) {
627         return std::stol ( std::wstring(str), idx, base );
628         }
629 
630     inline unsigned long stoul (wstring_view str, size_t* idx=0, int base=10) {
631         return std::stoul ( std::wstring(str), idx, base );
632         }
633 
634     inline long long stoll (wstring_view str, size_t* idx=0, int base=10) {
635         return std::stoll ( std::wstring(str), idx, base );
636         }
637 
638     inline unsigned long long stoull (wstring_view str, size_t* idx=0, int base=10) {
639         return std::stoull ( std::wstring(str), idx, base );
640         }
641 
642     inline float  stof (wstring_view str, size_t* idx=0) {
643         return std::stof ( std::wstring(str), idx );
644         }
645 
646     inline double stod (wstring_view str, size_t* idx=0) {
647         return std::stod ( std::wstring(str), idx );
648         }
649 
650     inline long double stold (wstring_view str, size_t* idx=0) {
651         return std::stold ( std::wstring(str), idx );
652         }
653 #endif
654 
655     template <class charT, class traits>
hash_value(basic_string_view<charT,traits> s)656     std::size_t hash_value(basic_string_view<charT, traits> s) {
657         return boost::hash_range(s.begin(), s.end());
658         }
659 }
660 
661 #if 0
662 namespace std {
663     // Hashing
664     template<> struct hash<boost::string_view>;
665     template<> struct hash<boost::u16string_view>;
666     template<> struct hash<boost::u32string_view>;
667     template<> struct hash<boost::wstring_view>;
668 }
669 #endif
670 
671 #endif
672