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