string_view.hpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  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. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. For more information, see http://www.boost.org
  8. Based on the StringRef implementation in LLVM (http://llvm.org) and
  9. N3422 by Jeffrey Yasskin
  10. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
  11. Updated July 2015 to reflect the Library Fundamentals TS
  12. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html
  13. */
  14. #ifndef BOOST_STRING_VIEW_HPP
  15. #define BOOST_STRING_VIEW_HPP
  16. #include <boost/config.hpp>
  17. #include <boost/detail/workaround.hpp>
  18. #include <boost/io/ostream_put.hpp>
  19. #include <boost/utility/string_view_fwd.hpp>
  20. #include <boost/throw_exception.hpp>
  21. #include <boost/assert.hpp>
  22. #include <cstddef>
  23. #include <stdexcept>
  24. #include <algorithm>
  25. #include <iterator>
  26. #include <string>
  27. #include <cstring>
  28. #include <iosfwd>
  29. #if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
  30. // GCC 4.6 cannot handle a defaulted function with noexcept specifier
  31. #define BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
  32. #endif
  33. namespace boost {
  34. namespace detail {
  35. // A helper functor because sometimes we don't have lambdas
  36. template <typename charT, typename traits>
  37. class string_view_traits_eq {
  38. public:
  39. string_view_traits_eq ( charT ch ) : ch_(ch) {}
  40. bool operator()( charT val ) const { return traits::eq (ch_, val); }
  41. charT ch_;
  42. };
  43. }
  44. template<typename charT, typename traits> // traits defaulted in string_view_fwd.hpp
  45. class basic_string_view {
  46. public:
  47. // types
  48. typedef traits traits_type;
  49. typedef charT value_type;
  50. typedef charT* pointer;
  51. typedef const charT* const_pointer;
  52. typedef charT& reference;
  53. typedef const charT& const_reference;
  54. typedef const_pointer const_iterator; // impl-defined
  55. typedef const_iterator iterator;
  56. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  57. typedef const_reverse_iterator reverse_iterator;
  58. typedef std::size_t size_type;
  59. typedef std::ptrdiff_t difference_type;
  60. static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
  61. // construct/copy
  62. BOOST_CONSTEXPR basic_string_view() BOOST_NOEXCEPT
  63. : ptr_(NULL), len_(0) {}
  64. // by defaulting these functions, basic_string_ref becomes
  65. // trivially copy/move constructible.
  66. BOOST_CONSTEXPR basic_string_view(const basic_string_view &rhs) BOOST_NOEXCEPT
  67. #ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
  68. = default;
  69. #else
  70. : ptr_(rhs.ptr_), len_(rhs.len_) {}
  71. #endif
  72. basic_string_view& operator=(const basic_string_view &rhs) BOOST_NOEXCEPT
  73. #ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
  74. = default;
  75. #else
  76. {
  77. ptr_ = rhs.ptr_;
  78. len_ = rhs.len_;
  79. return *this;
  80. }
  81. #endif
  82. template<typename Allocator>
  83. basic_string_view(const std::basic_string<charT, traits, Allocator>& str) BOOST_NOEXCEPT
  84. : ptr_(str.data()), len_(str.length()) {}
  85. // #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
  86. // // Constructing a string_view from a temporary string is a bad idea
  87. // template<typename Allocator>
  88. // basic_string_view( std::basic_string<charT, traits, Allocator>&&)
  89. // = delete;
  90. // #endif
  91. BOOST_CONSTEXPR basic_string_view(const charT* str)
  92. : ptr_(str), len_(traits::length(str)) {}
  93. BOOST_CONSTEXPR basic_string_view(const charT* str, size_type len)
  94. : ptr_(str), len_(len) {}
  95. // iterators
  96. BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return ptr_; }
  97. BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT { return ptr_; }
  98. BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return ptr_ + len_; }
  99. BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return ptr_ + len_; }
  100. const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
  101. const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
  102. const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
  103. const_reverse_iterator crend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
  104. // capacity
  105. BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return len_; }
  106. BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT { return len_; }
  107. BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { return ~static_cast<size_type>(0) / (sizeof(value_type) * 2u); }
  108. BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT { return len_ == 0; }
  109. // element access
  110. BOOST_CONSTEXPR const_reference operator[](size_type pos) const BOOST_NOEXCEPT { return ptr_[pos]; }
  111. BOOST_CONSTEXPR const_reference at(size_type pos) const {
  112. return pos >= len_ ? BOOST_THROW_EXCEPTION(std::out_of_range("boost::string_view::at")), ptr_[0] : ptr_[pos];
  113. }
  114. BOOST_CONSTEXPR const_reference front() const { return ptr_[0]; }
  115. BOOST_CONSTEXPR const_reference back() const { return ptr_[len_-1]; }
  116. BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT { return ptr_; }
  117. // modifiers
  118. void clear() BOOST_NOEXCEPT { len_ = 0; } // Boost extension
  119. BOOST_CXX14_CONSTEXPR void remove_prefix(size_type n) {
  120. BOOST_ASSERT(n <= size());
  121. // This check is deprecated and is left for backward compatibility. It will be removed in the future.
  122. if ( n > len_ )
  123. n = len_;
  124. ptr_ += n;
  125. len_ -= n;
  126. }
  127. BOOST_CXX14_CONSTEXPR void remove_suffix(size_type n) {
  128. BOOST_ASSERT(n <= size());
  129. // This check is deprecated and is left for backward compatibility. It will be removed in the future.
  130. if ( n > len_ )
  131. n = len_;
  132. len_ -= n;
  133. }
  134. BOOST_CXX14_CONSTEXPR void swap(basic_string_view& s) BOOST_NOEXCEPT {
  135. std::swap(ptr_, s.ptr_);
  136. std::swap(len_, s.len_);
  137. }
  138. // basic_string_view string operations
  139. #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
  140. template<typename Allocator>
  141. explicit operator std::basic_string<charT, traits, Allocator>() const {
  142. return std::basic_string<charT, traits, Allocator>(begin(), end());
  143. }
  144. #endif
  145. #ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
  146. template<typename Allocator = std::allocator<charT> >
  147. std::basic_string<charT, traits, Allocator> to_string(const Allocator& a = Allocator()) const {
  148. return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
  149. }
  150. #else
  151. std::basic_string<charT, traits> to_string() const {
  152. return std::basic_string<charT, traits>(begin(), end());
  153. }
  154. template<typename Allocator>
  155. std::basic_string<charT, traits, Allocator> to_string(const Allocator& a) const {
  156. return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
  157. }
  158. #endif
  159. size_type copy(charT* s, size_type n, size_type pos=0) const {
  160. if (pos > size())
  161. BOOST_THROW_EXCEPTION(std::out_of_range("string_view::copy" ));
  162. size_type rlen = (std::min)(n, len_ - pos);
  163. traits_type::copy(s, data() + pos, rlen);
  164. return rlen;
  165. }
  166. BOOST_CXX14_CONSTEXPR basic_string_view substr() const {
  167. return basic_string_view(data(), size());
  168. }
  169. BOOST_CXX14_CONSTEXPR basic_string_view substr(size_type pos, size_type n=npos) const {
  170. if ( pos > size())
  171. BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::substr" ) );
  172. return basic_string_view(data() + pos, (std::min)(size() - pos, n));
  173. }
  174. BOOST_CXX14_CONSTEXPR int compare(basic_string_view x) const BOOST_NOEXCEPT {
  175. const int cmp = traits::compare(ptr_, x.ptr_, (std::min)(len_, x.len_));
  176. return cmp != 0 ? cmp : (len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1);
  177. }
  178. BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string_view x)
  179. const {
  180. return substr(pos1, n1).compare(x);
  181. }
  182. BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
  183. basic_string_view x, size_type pos2, size_type n2) const {
  184. return substr(pos1, n1).compare(x.substr(pos2, n2));
  185. }
  186. BOOST_CXX14_CONSTEXPR int compare(const charT* x) const {
  187. return compare(basic_string_view(x));
  188. }
  189. BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, const charT* x) const {
  190. return substr(pos1, n1).compare(basic_string_view(x));
  191. }
  192. BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
  193. const charT* x, size_type n2) const {
  194. return substr(pos1, n1).compare(basic_string_view(x, n2));
  195. }
  196. // Searches
  197. BOOST_CONSTEXPR bool starts_with(charT c) const BOOST_NOEXCEPT { // Boost extension
  198. return !empty() && traits::eq(c, front());
  199. }
  200. BOOST_CONSTEXPR bool starts_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension
  201. return len_ >= x.len_ && traits::compare(ptr_, x.ptr_, x.len_) == 0;
  202. }
  203. BOOST_CONSTEXPR bool ends_with(charT c) const BOOST_NOEXCEPT { // Boost extension
  204. return !empty() && traits::eq(c, back());
  205. }
  206. BOOST_CONSTEXPR bool ends_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension
  207. return len_ >= x.len_ &&
  208. traits::compare(ptr_ + len_ - x.len_, x.ptr_, x.len_) == 0;
  209. }
  210. BOOST_CXX14_CONSTEXPR bool contains(basic_string_view s) const BOOST_NOEXCEPT {
  211. return find(s) != npos;
  212. }
  213. BOOST_CXX14_CONSTEXPR bool contains(charT c) const BOOST_NOEXCEPT {
  214. return find(c) != npos;
  215. }
  216. BOOST_CXX14_CONSTEXPR bool contains(const charT* s) const BOOST_NOEXCEPT {
  217. return find(s) != npos;
  218. }
  219. // find
  220. BOOST_CXX14_CONSTEXPR size_type find(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
  221. if (pos > size())
  222. return npos;
  223. if (s.empty())
  224. return pos;
  225. if (s.size() > size() - pos)
  226. return npos;
  227. const charT* cur = ptr_ + pos;
  228. const charT* last = cend() - s.size() + 1;
  229. for (; cur != last ; ++cur) {
  230. cur = traits::find(cur, last - cur, s[0]);
  231. if (!cur)
  232. return npos;
  233. if (traits::compare(cur, s.cbegin(), s.size()) == 0)
  234. return cur - ptr_;
  235. }
  236. return npos;
  237. }
  238. BOOST_CXX14_CONSTEXPR size_type find(charT c, size_type pos = 0) const BOOST_NOEXCEPT {
  239. if (pos > size())
  240. return npos;
  241. const charT* ret_ptr = traits::find(ptr_ + pos, len_ - pos, c);
  242. if (ret_ptr)
  243. return ret_ptr - ptr_;
  244. return npos;
  245. }
  246. BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
  247. { return find(basic_string_view(s, n), pos); }
  248. BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
  249. { return find(basic_string_view(s), pos); }
  250. // rfind
  251. BOOST_CXX14_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
  252. if (len_ < s.len_)
  253. return npos;
  254. if (pos > len_ - s.len_)
  255. pos = len_ - s.len_;
  256. if (s.len_ == 0u) // an empty string is always found
  257. return pos;
  258. for (const charT* cur = ptr_ + pos; ; --cur) {
  259. if (traits::compare(cur, s.ptr_, s.len_) == 0)
  260. return cur - ptr_;
  261. if (cur == ptr_)
  262. return npos;
  263. };
  264. }
  265. BOOST_CXX14_CONSTEXPR size_type rfind(charT c, size_type pos = npos) const BOOST_NOEXCEPT
  266. { return rfind(basic_string_view(&c, 1), pos); }
  267. BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
  268. { return rfind(basic_string_view(s, n), pos); }
  269. BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
  270. { return rfind(basic_string_view(s), pos); }
  271. // find_first_of
  272. BOOST_CXX14_CONSTEXPR size_type find_first_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
  273. if (pos >= len_ || s.len_ == 0)
  274. return npos;
  275. const_iterator iter = std::find_first_of
  276. (this->cbegin () + pos, this->cend (), s.cbegin (), s.cend (), traits::eq);
  277. return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
  278. }
  279. BOOST_CXX14_CONSTEXPR size_type find_first_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
  280. { return find(c, pos); }
  281. BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
  282. { return find_first_of(basic_string_view(s, n), pos); }
  283. BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
  284. { return find_first_of(basic_string_view(s), pos); }
  285. // find_last_of
  286. BOOST_CXX14_CONSTEXPR size_type find_last_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
  287. if (s.len_ == 0u)
  288. return npos;
  289. if (pos >= len_)
  290. pos = 0;
  291. else
  292. pos = len_ - (pos+1);
  293. const_reverse_iterator iter = std::find_first_of
  294. ( this->crbegin () + pos, this->crend (), s.cbegin (), s.cend (), traits::eq );
  295. return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
  296. }
  297. BOOST_CXX14_CONSTEXPR size_type find_last_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
  298. { return find_last_of(basic_string_view(&c, 1), pos); }
  299. BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
  300. { return find_last_of(basic_string_view(s, n), pos); }
  301. BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
  302. { return find_last_of(basic_string_view(s), pos); }
  303. // find_first_not_of
  304. BOOST_CXX14_CONSTEXPR size_type find_first_not_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
  305. if (pos >= len_)
  306. return npos;
  307. if (s.len_ == 0)
  308. return pos;
  309. const_iterator iter = find_not_of ( this->cbegin () + pos, this->cend (), s );
  310. return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
  311. }
  312. BOOST_CXX14_CONSTEXPR size_type find_first_not_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
  313. { return find_first_not_of(basic_string_view(&c, 1), pos); }
  314. BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
  315. { return find_first_not_of(basic_string_view(s, n), pos); }
  316. BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
  317. { return find_first_not_of(basic_string_view(s), pos); }
  318. // find_last_not_of
  319. BOOST_CXX14_CONSTEXPR size_type find_last_not_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
  320. if (pos >= len_)
  321. pos = len_ - 1;
  322. if (s.len_ == 0u)
  323. return pos;
  324. pos = len_ - (pos+1);
  325. const_reverse_iterator iter = find_not_of ( this->crbegin () + pos, this->crend (), s );
  326. return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
  327. }
  328. BOOST_CXX14_CONSTEXPR size_type find_last_not_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
  329. { return find_last_not_of(basic_string_view(&c, 1), pos); }
  330. BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
  331. { return find_last_not_of(basic_string_view(s, n), pos); }
  332. BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
  333. { return find_last_not_of(basic_string_view(s), pos); }
  334. private:
  335. template <typename r_iter>
  336. size_type reverse_distance(r_iter first, r_iter last) const BOOST_NOEXCEPT {
  337. // Portability note here: std::distance is not NOEXCEPT, but calling it with a string_view::reverse_iterator will not throw.
  338. return len_ - 1 - std::distance ( first, last );
  339. }
  340. template <typename Iterator>
  341. Iterator find_not_of(Iterator first, Iterator last, basic_string_view s) const BOOST_NOEXCEPT {
  342. for (; first != last ; ++first)
  343. if ( 0 == traits::find(s.ptr_, s.len_, *first))
  344. return first;
  345. return last;
  346. }
  347. const charT *ptr_;
  348. std::size_t len_;
  349. };
  350. // Comparison operators
  351. // Equality
  352. template<typename charT, typename traits>
  353. inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
  354. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  355. if (x.size () != y.size ()) return false;
  356. return x.compare(y) == 0;
  357. }
  358. // Inequality
  359. template<typename charT, typename traits>
  360. inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
  361. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  362. if ( x.size () != y.size ()) return true;
  363. return x.compare(y) != 0;
  364. }
  365. // Less than
  366. template<typename charT, typename traits>
  367. inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
  368. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  369. return x.compare(y) < 0;
  370. }
  371. // Greater than
  372. template<typename charT, typename traits>
  373. inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
  374. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  375. return x.compare(y) > 0;
  376. }
  377. // Less than or equal to
  378. template<typename charT, typename traits>
  379. inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
  380. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  381. return x.compare(y) <= 0;
  382. }
  383. // Greater than or equal to
  384. template<typename charT, typename traits>
  385. inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
  386. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  387. return x.compare(y) >= 0;
  388. }
  389. // "sufficient additional overloads of comparison functions"
  390. template<typename charT, typename traits, typename Allocator>
  391. inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
  392. const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
  393. return x == basic_string_view<charT, traits>(y);
  394. }
  395. template<typename charT, typename traits, typename Allocator>
  396. inline BOOST_CXX14_CONSTEXPR bool operator==(const std::basic_string<charT, traits, Allocator> & x,
  397. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  398. return basic_string_view<charT, traits>(x) == y;
  399. }
  400. template<typename charT, typename traits>
  401. inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
  402. const charT * y) BOOST_NOEXCEPT {
  403. return x == basic_string_view<charT, traits>(y);
  404. }
  405. template<typename charT, typename traits>
  406. inline BOOST_CXX14_CONSTEXPR bool operator==(const charT * x,
  407. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  408. return basic_string_view<charT, traits>(x) == y;
  409. }
  410. template<typename charT, typename traits, typename Allocator>
  411. inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
  412. const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
  413. return x != basic_string_view<charT, traits>(y);
  414. }
  415. template<typename charT, typename traits, typename Allocator>
  416. inline BOOST_CXX14_CONSTEXPR bool operator!=(const std::basic_string<charT, traits, Allocator> & x,
  417. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  418. return basic_string_view<charT, traits>(x) != y;
  419. }
  420. template<typename charT, typename traits>
  421. inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
  422. const charT * y) BOOST_NOEXCEPT {
  423. return x != basic_string_view<charT, traits>(y);
  424. }
  425. template<typename charT, typename traits>
  426. inline BOOST_CXX14_CONSTEXPR bool operator!=(const charT * x,
  427. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  428. return basic_string_view<charT, traits>(x) != y;
  429. }
  430. template<typename charT, typename traits, typename Allocator>
  431. inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
  432. const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
  433. return x < basic_string_view<charT, traits>(y);
  434. }
  435. template<typename charT, typename traits, typename Allocator>
  436. inline BOOST_CXX14_CONSTEXPR bool operator<(const std::basic_string<charT, traits, Allocator> & x,
  437. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  438. return basic_string_view<charT, traits>(x) < y;
  439. }
  440. template<typename charT, typename traits>
  441. inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
  442. const charT * y) BOOST_NOEXCEPT {
  443. return x < basic_string_view<charT, traits>(y);
  444. }
  445. template<typename charT, typename traits>
  446. inline BOOST_CXX14_CONSTEXPR bool operator<(const charT * x,
  447. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  448. return basic_string_view<charT, traits>(x) < y;
  449. }
  450. template<typename charT, typename traits, typename Allocator>
  451. inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
  452. const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
  453. return x > basic_string_view<charT, traits>(y);
  454. }
  455. template<typename charT, typename traits, typename Allocator>
  456. inline BOOST_CXX14_CONSTEXPR bool operator>(const std::basic_string<charT, traits, Allocator> & x,
  457. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  458. return basic_string_view<charT, traits>(x) > y;
  459. }
  460. template<typename charT, typename traits>
  461. inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
  462. const charT * y) BOOST_NOEXCEPT {
  463. return x > basic_string_view<charT, traits>(y);
  464. }
  465. template<typename charT, typename traits>
  466. inline BOOST_CXX14_CONSTEXPR bool operator>(const charT * x,
  467. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  468. return basic_string_view<charT, traits>(x) > y;
  469. }
  470. template<typename charT, typename traits, typename Allocator>
  471. inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
  472. const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
  473. return x <= basic_string_view<charT, traits>(y);
  474. }
  475. template<typename charT, typename traits, typename Allocator>
  476. inline BOOST_CXX14_CONSTEXPR bool operator<=(const std::basic_string<charT, traits, Allocator> & x,
  477. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  478. return basic_string_view<charT, traits>(x) <= y;
  479. }
  480. template<typename charT, typename traits>
  481. inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
  482. const charT * y) BOOST_NOEXCEPT {
  483. return x <= basic_string_view<charT, traits>(y);
  484. }
  485. template<typename charT, typename traits>
  486. inline BOOST_CXX14_CONSTEXPR bool operator<=(const charT * x,
  487. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  488. return basic_string_view<charT, traits>(x) <= y;
  489. }
  490. template<typename charT, typename traits, typename Allocator>
  491. inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
  492. const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
  493. return x >= basic_string_view<charT, traits>(y);
  494. }
  495. template<typename charT, typename traits, typename Allocator>
  496. inline BOOST_CXX14_CONSTEXPR bool operator>=(const std::basic_string<charT, traits, Allocator> & x,
  497. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  498. return basic_string_view<charT, traits>(x) >= y;
  499. }
  500. template<typename charT, typename traits>
  501. inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
  502. const charT * y) BOOST_NOEXCEPT {
  503. return x >= basic_string_view<charT, traits>(y);
  504. }
  505. template<typename charT, typename traits>
  506. inline BOOST_CXX14_CONSTEXPR bool operator>=(const charT * x,
  507. basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
  508. return basic_string_view<charT, traits>(x) >= y;
  509. }
  510. // Inserter
  511. template<class charT, class traits>
  512. inline std::basic_ostream<charT, traits>&
  513. operator<<(std::basic_ostream<charT, traits>& os,
  514. const basic_string_view<charT,traits>& str) {
  515. return boost::io::ostream_put(os, str.data(), str.size());
  516. }
  517. #if 0
  518. // numeric conversions
  519. //
  520. // These are short-term implementations.
  521. // In a production environment, I would rather avoid the copying.
  522. //
  523. inline int stoi (string_view str, size_t* idx=0, int base=10) {
  524. return std::stoi ( std::string(str), idx, base );
  525. }
  526. inline long stol (string_view str, size_t* idx=0, int base=10) {
  527. return std::stol ( std::string(str), idx, base );
  528. }
  529. inline unsigned long stoul (string_view str, size_t* idx=0, int base=10) {
  530. return std::stoul ( std::string(str), idx, base );
  531. }
  532. inline long long stoll (string_view str, size_t* idx=0, int base=10) {
  533. return std::stoll ( std::string(str), idx, base );
  534. }
  535. inline unsigned long long stoull (string_view str, size_t* idx=0, int base=10) {
  536. return std::stoull ( std::string(str), idx, base );
  537. }
  538. inline float stof (string_view str, size_t* idx=0) {
  539. return std::stof ( std::string(str), idx );
  540. }
  541. inline double stod (string_view str, size_t* idx=0) {
  542. return std::stod ( std::string(str), idx );
  543. }
  544. inline long double stold (string_view str, size_t* idx=0) {
  545. return std::stold ( std::string(str), idx );
  546. }
  547. inline int stoi (wstring_view str, size_t* idx=0, int base=10) {
  548. return std::stoi ( std::wstring(str), idx, base );
  549. }
  550. inline long stol (wstring_view str, size_t* idx=0, int base=10) {
  551. return std::stol ( std::wstring(str), idx, base );
  552. }
  553. inline unsigned long stoul (wstring_view str, size_t* idx=0, int base=10) {
  554. return std::stoul ( std::wstring(str), idx, base );
  555. }
  556. inline long long stoll (wstring_view str, size_t* idx=0, int base=10) {
  557. return std::stoll ( std::wstring(str), idx, base );
  558. }
  559. inline unsigned long long stoull (wstring_view str, size_t* idx=0, int base=10) {
  560. return std::stoull ( std::wstring(str), idx, base );
  561. }
  562. inline float stof (wstring_view str, size_t* idx=0) {
  563. return std::stof ( std::wstring(str), idx );
  564. }
  565. inline double stod (wstring_view str, size_t* idx=0) {
  566. return std::stod ( std::wstring(str), idx );
  567. }
  568. inline long double stold (wstring_view str, size_t* idx=0) {
  569. return std::stold ( std::wstring(str), idx );
  570. }
  571. #endif
  572. // Forward declaration of Boost.ContainerHash function
  573. template <class It> std::size_t hash_range(It, It);
  574. template <class charT, class traits>
  575. std::size_t hash_value(basic_string_view<charT, traits> s) {
  576. return boost::hash_range(s.begin(), s.end());
  577. }
  578. }
  579. #if 0
  580. namespace std {
  581. // Hashing
  582. template<> struct hash<boost::string_view>;
  583. template<> struct hash<boost::u16string_view>;
  584. template<> struct hash<boost::u32string_view>;
  585. template<> struct hash<boost::wstring_view>;
  586. }
  587. #endif
  588. #endif