string_view.hpp 30 KB

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