string_piece.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. // Copied from strings/stringpiece.h with modifications
  5. //
  6. // A string-like object that points to a sized piece of memory.
  7. //
  8. // You can use StringPiece as a function or method parameter. A StringPiece
  9. // parameter can receive a double-quoted string literal argument, a "const
  10. // char*" argument, a string argument, or a StringPiece argument with no data
  11. // copying. Systematic use of StringPiece for arguments reduces data
  12. // copies and strlen() calls.
  13. //
  14. // Prefer passing StringPieces by value:
  15. // void MyFunction(StringPiece arg);
  16. // If circumstances require, you may also pass by const reference:
  17. // void MyFunction(const StringPiece& arg); // not preferred
  18. // Both of these have the same lifetime semantics. Passing by value
  19. // generates slightly smaller code. For more discussion, Googlers can see
  20. // the thread go/stringpiecebyvalue on c-users.
  21. #ifndef BASE_STRINGS_STRING_PIECE_H_
  22. #define BASE_STRINGS_STRING_PIECE_H_
  23. #include <stddef.h>
  24. #include <iosfwd>
  25. #include <ostream>
  26. #include <string>
  27. #include <type_traits>
  28. #include "base/base_export.h"
  29. #include "base/check_op.h"
  30. #include "base/strings/char_traits.h"
  31. #include "base/strings/string16.h"
  32. #include "base/strings/string_piece_forward.h"
  33. namespace base {
  34. // internal --------------------------------------------------------------------
  35. // Many of the StringPiece functions use different implementations for the
  36. // 8-bit and 16-bit versions, and we don't want lots of template expansions in
  37. // this (very common) header that will slow down compilation.
  38. //
  39. // So here we define overloaded functions called by the StringPiece template.
  40. // For those that share an implementation, the two versions will expand to a
  41. // template internal to the .cc file.
  42. namespace internal {
  43. BASE_EXPORT size_t copy(const StringPiece& self,
  44. char* buf,
  45. size_t n,
  46. size_t pos);
  47. BASE_EXPORT size_t copy(const StringPiece16& self,
  48. char16* buf,
  49. size_t n,
  50. size_t pos);
  51. BASE_EXPORT size_t find(const StringPiece& self,
  52. const StringPiece& s,
  53. size_t pos);
  54. BASE_EXPORT size_t find(const StringPiece16& self,
  55. const StringPiece16& s,
  56. size_t pos);
  57. BASE_EXPORT size_t find(const StringPiece& self,
  58. char c,
  59. size_t pos);
  60. BASE_EXPORT size_t find(const StringPiece16& self,
  61. char16 c,
  62. size_t pos);
  63. BASE_EXPORT size_t rfind(const StringPiece& self,
  64. const StringPiece& s,
  65. size_t pos);
  66. BASE_EXPORT size_t rfind(const StringPiece16& self,
  67. const StringPiece16& s,
  68. size_t pos);
  69. BASE_EXPORT size_t rfind(const StringPiece& self,
  70. char c,
  71. size_t pos);
  72. BASE_EXPORT size_t rfind(const StringPiece16& self,
  73. char16 c,
  74. size_t pos);
  75. BASE_EXPORT size_t find_first_of(const StringPiece& self,
  76. const StringPiece& s,
  77. size_t pos);
  78. BASE_EXPORT size_t find_first_of(const StringPiece16& self,
  79. const StringPiece16& s,
  80. size_t pos);
  81. BASE_EXPORT size_t find_first_not_of(const StringPiece& self,
  82. const StringPiece& s,
  83. size_t pos);
  84. BASE_EXPORT size_t find_first_not_of(const StringPiece16& self,
  85. const StringPiece16& s,
  86. size_t pos);
  87. BASE_EXPORT size_t find_first_not_of(const StringPiece& self,
  88. char c,
  89. size_t pos);
  90. BASE_EXPORT size_t find_first_not_of(const StringPiece16& self,
  91. char16 c,
  92. size_t pos);
  93. BASE_EXPORT size_t find_last_of(const StringPiece& self,
  94. const StringPiece& s,
  95. size_t pos);
  96. BASE_EXPORT size_t find_last_of(const StringPiece16& self,
  97. const StringPiece16& s,
  98. size_t pos);
  99. BASE_EXPORT size_t find_last_of(const StringPiece& self,
  100. char c,
  101. size_t pos);
  102. BASE_EXPORT size_t find_last_of(const StringPiece16& self,
  103. char16 c,
  104. size_t pos);
  105. BASE_EXPORT size_t find_last_not_of(const StringPiece& self,
  106. const StringPiece& s,
  107. size_t pos);
  108. BASE_EXPORT size_t find_last_not_of(const StringPiece16& self,
  109. const StringPiece16& s,
  110. size_t pos);
  111. BASE_EXPORT size_t find_last_not_of(const StringPiece16& self,
  112. char16 c,
  113. size_t pos);
  114. BASE_EXPORT size_t find_last_not_of(const StringPiece& self,
  115. char c,
  116. size_t pos);
  117. } // namespace internal
  118. // BasicStringPiece ------------------------------------------------------------
  119. // Defines the types, methods, operators, and data members common to both
  120. // StringPiece and StringPiece16.
  121. //
  122. // This is templatized by string class type rather than character type, so
  123. // BasicStringPiece<std::string> or BasicStringPiece<base::string16>.
  124. template <typename STRING_TYPE> class BasicStringPiece {
  125. public:
  126. // Standard STL container boilerplate.
  127. typedef size_t size_type;
  128. typedef typename STRING_TYPE::traits_type traits_type;
  129. typedef typename STRING_TYPE::value_type value_type;
  130. typedef const value_type* pointer;
  131. typedef const value_type& reference;
  132. typedef const value_type& const_reference;
  133. typedef ptrdiff_t difference_type;
  134. typedef const value_type* const_iterator;
  135. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  136. static const size_type npos;
  137. public:
  138. // We provide non-explicit singleton constructors so users can pass
  139. // in a "const char*" or a "string" wherever a "StringPiece" is
  140. // expected (likewise for char16, string16, StringPiece16).
  141. constexpr BasicStringPiece() : ptr_(nullptr), length_(0) {}
  142. // TODO(crbug.com/1049498): Construction from nullptr is not allowed for
  143. // std::basic_string_view, so remove the special handling for it.
  144. // Note: This doesn't just use STRING_TYPE::traits_type::length(), since that
  145. // isn't constexpr until C++17.
  146. constexpr BasicStringPiece(const value_type* str)
  147. : ptr_(str), length_(!str ? 0 : CharTraits<value_type>::length(str)) {}
  148. // Explicitly disallow construction from nullptr. Note that this does not
  149. // catch construction from runtime strings that might be null.
  150. // Note: The following is just a more elaborate way of spelling
  151. // `BasicStringPiece(nullptr_t) = delete`, but unfortunately the terse form is
  152. // not supported by the PNaCl toolchain.
  153. // TODO(crbug.com/1049498): Remove once we CHECK(str) in the constructor
  154. // above.
  155. template <class T, class = std::enable_if_t<std::is_null_pointer<T>::value>>
  156. BasicStringPiece(T) {
  157. static_assert(sizeof(T) == 0, // Always false.
  158. "StringPiece does not support construction from nullptr, use "
  159. "the default constructor instead.");
  160. }
  161. BasicStringPiece(const STRING_TYPE& str)
  162. : ptr_(str.data()), length_(str.size()) {}
  163. constexpr BasicStringPiece(const value_type* offset, size_type len)
  164. : ptr_(offset), length_(len) {}
  165. BasicStringPiece(const typename STRING_TYPE::const_iterator& begin,
  166. const typename STRING_TYPE::const_iterator& end) {
  167. DCHECK(begin <= end) << "StringPiece iterators swapped or invalid.";
  168. length_ = static_cast<size_t>(std::distance(begin, end));
  169. // The length test before assignment is to avoid dereferencing an iterator
  170. // that may point to the end() of a string.
  171. ptr_ = length_ > 0 ? &*begin : nullptr;
  172. }
  173. // data() may return a pointer to a buffer with embedded NULs, and the
  174. // returned buffer may or may not be null terminated. Therefore it is
  175. // typically a mistake to pass data() to a routine that expects a NUL
  176. // terminated string.
  177. constexpr const value_type* data() const { return ptr_; }
  178. constexpr size_type size() const noexcept { return length_; }
  179. constexpr size_type length() const noexcept { return length_; }
  180. constexpr bool empty() const noexcept { return length_ == 0; }
  181. constexpr value_type operator[](size_type i) const {
  182. CHECK(i < length_);
  183. return ptr_[i];
  184. }
  185. constexpr value_type front() const {
  186. CHECK_NE(0UL, length_);
  187. return ptr_[0];
  188. }
  189. constexpr value_type back() const {
  190. CHECK_NE(0UL, length_);
  191. return ptr_[length_ - 1];
  192. }
  193. constexpr void remove_prefix(size_type n) {
  194. CHECK(n <= length_);
  195. ptr_ += n;
  196. length_ -= n;
  197. }
  198. constexpr void remove_suffix(size_type n) {
  199. CHECK(n <= length_);
  200. length_ -= n;
  201. }
  202. constexpr int compare(BasicStringPiece x) const noexcept {
  203. int r = CharTraits<value_type>::compare(
  204. ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_));
  205. if (r == 0) {
  206. if (length_ < x.length_) r = -1;
  207. else if (length_ > x.length_) r = +1;
  208. }
  209. return r;
  210. }
  211. // This is the style of conversion preferred by std::string_view in C++17.
  212. explicit operator STRING_TYPE() const {
  213. return empty() ? STRING_TYPE() : STRING_TYPE(data(), size());
  214. }
  215. // Deprecated, use operator STRING_TYPE() instead.
  216. // TODO(crbug.com/1049498): Remove for all STRING_TYPEs.
  217. template <typename StrT = STRING_TYPE,
  218. typename = std::enable_if_t<std::is_same<StrT, std::string>::value>>
  219. STRING_TYPE as_string() const {
  220. return STRING_TYPE(*this);
  221. }
  222. constexpr const_iterator begin() const noexcept { return ptr_; }
  223. constexpr const_iterator end() const noexcept { return ptr_ + length_; }
  224. constexpr const_reverse_iterator rbegin() const noexcept {
  225. return const_reverse_iterator(ptr_ + length_);
  226. }
  227. constexpr const_reverse_iterator rend() const noexcept {
  228. return const_reverse_iterator(ptr_);
  229. }
  230. size_type max_size() const { return length_; }
  231. size_type capacity() const { return length_; }
  232. size_type copy(value_type* buf, size_type n, size_type pos = 0) const {
  233. return internal::copy(*this, buf, n, pos);
  234. }
  235. // find: Search for a character or substring at a given offset.
  236. size_type find(const BasicStringPiece<STRING_TYPE>& s,
  237. size_type pos = 0) const {
  238. return internal::find(*this, s, pos);
  239. }
  240. size_type find(value_type c, size_type pos = 0) const {
  241. return internal::find(*this, c, pos);
  242. }
  243. // rfind: Reverse find.
  244. size_type rfind(const BasicStringPiece& s,
  245. size_type pos = BasicStringPiece::npos) const {
  246. return internal::rfind(*this, s, pos);
  247. }
  248. size_type rfind(value_type c, size_type pos = BasicStringPiece::npos) const {
  249. return internal::rfind(*this, c, pos);
  250. }
  251. // find_first_of: Find the first occurence of one of a set of characters.
  252. size_type find_first_of(const BasicStringPiece& s,
  253. size_type pos = 0) const {
  254. return internal::find_first_of(*this, s, pos);
  255. }
  256. size_type find_first_of(value_type c, size_type pos = 0) const {
  257. return find(c, pos);
  258. }
  259. // find_first_not_of: Find the first occurence not of a set of characters.
  260. size_type find_first_not_of(const BasicStringPiece& s,
  261. size_type pos = 0) const {
  262. return internal::find_first_not_of(*this, s, pos);
  263. }
  264. size_type find_first_not_of(value_type c, size_type pos = 0) const {
  265. return internal::find_first_not_of(*this, c, pos);
  266. }
  267. // find_last_of: Find the last occurence of one of a set of characters.
  268. size_type find_last_of(const BasicStringPiece& s,
  269. size_type pos = BasicStringPiece::npos) const {
  270. return internal::find_last_of(*this, s, pos);
  271. }
  272. size_type find_last_of(value_type c,
  273. size_type pos = BasicStringPiece::npos) const {
  274. return rfind(c, pos);
  275. }
  276. // find_last_not_of: Find the last occurence not of a set of characters.
  277. size_type find_last_not_of(const BasicStringPiece& s,
  278. size_type pos = BasicStringPiece::npos) const {
  279. return internal::find_last_not_of(*this, s, pos);
  280. }
  281. size_type find_last_not_of(value_type c,
  282. size_type pos = BasicStringPiece::npos) const {
  283. return internal::find_last_not_of(*this, c, pos);
  284. }
  285. // substr.
  286. constexpr BasicStringPiece substr(
  287. size_type pos,
  288. size_type n = BasicStringPiece::npos) const {
  289. CHECK_LE(pos, size());
  290. return {data() + pos, std::min(n, size() - pos)};
  291. }
  292. protected:
  293. const value_type* ptr_;
  294. size_type length_;
  295. };
  296. template <typename STRING_TYPE>
  297. const typename BasicStringPiece<STRING_TYPE>::size_type
  298. BasicStringPiece<STRING_TYPE>::npos =
  299. typename BasicStringPiece<STRING_TYPE>::size_type(-1);
  300. // MSVC doesn't like complex extern templates and DLLs.
  301. #if !defined(COMPILER_MSVC)
  302. extern template class BASE_EXPORT BasicStringPiece<std::string>;
  303. extern template class BASE_EXPORT BasicStringPiece<string16>;
  304. #endif
  305. // Comparison operators --------------------------------------------------------
  306. // operator ==
  307. template <typename StringT>
  308. constexpr bool operator==(BasicStringPiece<StringT> lhs,
  309. BasicStringPiece<StringT> rhs) noexcept {
  310. return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
  311. }
  312. // Here and below we make use of std::common_type_t to emulate an identity type
  313. // transformation. This creates a non-deduced context, so that we can compare
  314. // StringPieces with types that implicitly convert to StringPieces. See
  315. // https://wg21.link/n3766 for details.
  316. // Furthermore, we require dummy template parameters for these overloads to work
  317. // around a name mangling issue on Windows.
  318. template <typename StringT, int = 1>
  319. constexpr bool operator==(
  320. BasicStringPiece<StringT> lhs,
  321. std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept {
  322. return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
  323. }
  324. template <typename StringT, int = 2>
  325. constexpr bool operator==(std::common_type_t<BasicStringPiece<StringT>> lhs,
  326. BasicStringPiece<StringT> rhs) noexcept {
  327. return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
  328. }
  329. // operator !=
  330. template <typename StringT>
  331. constexpr bool operator!=(BasicStringPiece<StringT> lhs,
  332. BasicStringPiece<StringT> rhs) noexcept {
  333. return !(lhs == rhs);
  334. }
  335. template <typename StringT, int = 1>
  336. constexpr bool operator!=(
  337. BasicStringPiece<StringT> lhs,
  338. std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept {
  339. return !(lhs == rhs);
  340. }
  341. template <typename StringT, int = 2>
  342. constexpr bool operator!=(std::common_type_t<BasicStringPiece<StringT>> lhs,
  343. BasicStringPiece<StringT> rhs) noexcept {
  344. return !(lhs == rhs);
  345. }
  346. // operator <
  347. template <typename StringT>
  348. constexpr bool operator<(BasicStringPiece<StringT> lhs,
  349. BasicStringPiece<StringT> rhs) noexcept {
  350. return lhs.compare(rhs) < 0;
  351. }
  352. template <typename StringT, int = 1>
  353. constexpr bool operator<(
  354. BasicStringPiece<StringT> lhs,
  355. std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept {
  356. return lhs.compare(rhs) < 0;
  357. }
  358. template <typename StringT, int = 2>
  359. constexpr bool operator<(std::common_type_t<BasicStringPiece<StringT>> lhs,
  360. BasicStringPiece<StringT> rhs) noexcept {
  361. return lhs.compare(rhs) < 0;
  362. }
  363. // operator >
  364. template <typename StringT>
  365. constexpr bool operator>(BasicStringPiece<StringT> lhs,
  366. BasicStringPiece<StringT> rhs) noexcept {
  367. return rhs < lhs;
  368. }
  369. template <typename StringT, int = 1>
  370. constexpr bool operator>(
  371. BasicStringPiece<StringT> lhs,
  372. std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept {
  373. return rhs < lhs;
  374. }
  375. template <typename StringT, int = 2>
  376. constexpr bool operator>(std::common_type_t<BasicStringPiece<StringT>> lhs,
  377. BasicStringPiece<StringT> rhs) noexcept {
  378. return rhs < lhs;
  379. }
  380. // operator <=
  381. template <typename StringT>
  382. constexpr bool operator<=(BasicStringPiece<StringT> lhs,
  383. BasicStringPiece<StringT> rhs) noexcept {
  384. return !(rhs < lhs);
  385. }
  386. template <typename StringT, int = 1>
  387. constexpr bool operator<=(
  388. BasicStringPiece<StringT> lhs,
  389. std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept {
  390. return !(rhs < lhs);
  391. }
  392. template <typename StringT, int = 2>
  393. constexpr bool operator<=(std::common_type_t<BasicStringPiece<StringT>> lhs,
  394. BasicStringPiece<StringT> rhs) noexcept {
  395. return !(rhs < lhs);
  396. }
  397. // operator >=
  398. template <typename StringT>
  399. constexpr bool operator>=(BasicStringPiece<StringT> lhs,
  400. BasicStringPiece<StringT> rhs) noexcept {
  401. return !(lhs < rhs);
  402. }
  403. template <typename StringT, int = 1>
  404. constexpr bool operator>=(
  405. BasicStringPiece<StringT> lhs,
  406. std::common_type_t<BasicStringPiece<StringT>> rhs) noexcept {
  407. return !(lhs < rhs);
  408. }
  409. template <typename StringT, int = 2>
  410. constexpr bool operator>=(std::common_type_t<BasicStringPiece<StringT>> lhs,
  411. BasicStringPiece<StringT> rhs) noexcept {
  412. return !(lhs < rhs);
  413. }
  414. BASE_EXPORT std::ostream& operator<<(std::ostream& o,
  415. const StringPiece& piece);
  416. BASE_EXPORT std::ostream& operator<<(std::ostream& o,
  417. const StringPiece16& piece);
  418. // Hashing ---------------------------------------------------------------------
  419. // We provide appropriate hash functions so StringPiece and StringPiece16 can
  420. // be used as keys in hash sets and maps.
  421. // This hash function is copied from base/strings/string16.h. We don't use the
  422. // ones already defined for string and string16 directly because it would
  423. // require the string constructors to be called, which we don't want.
  424. template <typename StringPieceType>
  425. struct StringPieceHashImpl {
  426. std::size_t operator()(StringPieceType sp) const {
  427. std::size_t result = 0;
  428. for (auto c : sp)
  429. result = (result * 131) + c;
  430. return result;
  431. }
  432. };
  433. using StringPieceHash = StringPieceHashImpl<StringPiece>;
  434. using StringPiece16Hash = StringPieceHashImpl<StringPiece16>;
  435. using WStringPieceHash = StringPieceHashImpl<WStringPiece>;
  436. } // namespace base
  437. #endif // BASE_STRINGS_STRING_PIECE_H_