Blink roll 174234:174238
[chromium-blink-merge.git] / base / strings / string_piece.h
blob38e2277e98c874c9db56d5b9cc454f24c972249f
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 // Functions or methods may use const StringPiece& parameters to accept either
9 // a "const char*" or a "string" value that will be implicitly converted to
10 // a StringPiece. The implicit conversion means that it is often appropriate
11 // to include this .h file in other files rather than forward-declaring
12 // StringPiece as would be appropriate for most other Google classes.
14 // Systematic usage of StringPiece is encouraged as it will reduce unnecessary
15 // conversions from "const char*" to "string" and back again.
17 // StringPiece16 is similar to StringPiece but for base::string16 instead of
18 // std::string. We do not define as large of a subset of the STL functions
19 // from basic_string as in StringPiece, but this can be changed if these
20 // functions (find, find_first_of, etc.) are found to be useful in this context.
23 #ifndef BASE_STRINGS_STRING_PIECE_H_
24 #define BASE_STRINGS_STRING_PIECE_H_
26 #include <stddef.h>
28 #include <iosfwd>
29 #include <string>
31 #include "base/base_export.h"
32 #include "base/basictypes.h"
33 #include "base/containers/hash_tables.h"
34 #include "base/strings/string16.h"
36 namespace base {
38 template <typename STRING_TYPE> class BasicStringPiece;
39 typedef BasicStringPiece<std::string> StringPiece;
40 typedef BasicStringPiece<string16> StringPiece16;
42 // internal --------------------------------------------------------------------
44 // Many of the StringPiece functions use different implementations for the
45 // 8-bit and 16-bit versions, and we don't want lots of template expansions in
46 // this (very common) header that will slow down compilation.
48 // So here we define overloaded functions called by the StringPiece template.
49 // For those that share an implementation, the two versions will expand to a
50 // template internal to the .cc file.
51 namespace internal {
53 BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target);
54 BASE_EXPORT void CopyToString(const StringPiece16& self, string16* target);
56 BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target);
57 BASE_EXPORT void AppendToString(const StringPiece16& self, string16* target);
59 BASE_EXPORT size_t copy(const StringPiece& self,
60 char* buf,
61 size_t n,
62 size_t pos);
63 BASE_EXPORT size_t copy(const StringPiece16& self,
64 char16* buf,
65 size_t n,
66 size_t pos);
68 BASE_EXPORT size_t find(const StringPiece& self,
69 const StringPiece& s,
70 size_t pos);
71 BASE_EXPORT size_t find(const StringPiece16& self,
72 const StringPiece16& s,
73 size_t pos);
74 BASE_EXPORT size_t find(const StringPiece& self,
75 char c,
76 size_t pos);
77 BASE_EXPORT size_t find(const StringPiece16& self,
78 char16 c,
79 size_t pos);
81 BASE_EXPORT size_t rfind(const StringPiece& self,
82 const StringPiece& s,
83 size_t pos);
84 BASE_EXPORT size_t rfind(const StringPiece16& self,
85 const StringPiece16& s,
86 size_t pos);
87 BASE_EXPORT size_t rfind(const StringPiece& self,
88 char c,
89 size_t pos);
90 BASE_EXPORT size_t rfind(const StringPiece16& self,
91 char16 c,
92 size_t pos);
94 BASE_EXPORT size_t find_first_of(const StringPiece& self,
95 const StringPiece& s,
96 size_t pos);
97 BASE_EXPORT size_t find_first_of(const StringPiece16& self,
98 const StringPiece16& s,
99 size_t pos);
101 BASE_EXPORT size_t find_first_not_of(const StringPiece& self,
102 const StringPiece& s,
103 size_t pos);
104 BASE_EXPORT size_t find_first_not_of(const StringPiece16& self,
105 const StringPiece16& s,
106 size_t pos);
107 BASE_EXPORT size_t find_first_not_of(const StringPiece& self,
108 char c,
109 size_t pos);
110 BASE_EXPORT size_t find_first_not_of(const StringPiece16& self,
111 char16 c,
112 size_t pos);
114 BASE_EXPORT size_t find_last_of(const StringPiece& self,
115 const StringPiece& s,
116 size_t pos);
117 BASE_EXPORT size_t find_last_of(const StringPiece16& self,
118 const StringPiece16& s,
119 size_t pos);
120 BASE_EXPORT size_t find_last_of(const StringPiece& self,
121 char c,
122 size_t pos);
123 BASE_EXPORT size_t find_last_of(const StringPiece16& self,
124 char16 c,
125 size_t pos);
127 BASE_EXPORT size_t find_last_not_of(const StringPiece& self,
128 const StringPiece& s,
129 size_t pos);
130 BASE_EXPORT size_t find_last_not_of(const StringPiece16& self,
131 const StringPiece16& s,
132 size_t pos);
133 BASE_EXPORT size_t find_last_not_of(const StringPiece16& self,
134 char16 c,
135 size_t pos);
136 BASE_EXPORT size_t find_last_not_of(const StringPiece& self,
137 char c,
138 size_t pos);
140 BASE_EXPORT StringPiece substr(const StringPiece& self,
141 size_t pos,
142 size_t n);
143 BASE_EXPORT StringPiece16 substr(const StringPiece16& self,
144 size_t pos,
145 size_t n);
147 } // namespace internal
149 // BasicStringPiece ------------------------------------------------------------
151 // Defines the types, methods, operators, and data members common to both
152 // StringPiece and StringPiece16. Do not refer to this class directly, but
153 // rather to BasicStringPiece, StringPiece, or StringPiece16.
155 // This is templatized by string class type rather than character type, so
156 // BasicStringPiece<std::string> or BasicStringPiece<base::string16>.
157 template <typename STRING_TYPE> class BasicStringPiece {
158 public:
159 // Standard STL container boilerplate.
160 typedef size_t size_type;
161 typedef typename STRING_TYPE::value_type value_type;
162 typedef const value_type* pointer;
163 typedef const value_type& reference;
164 typedef const value_type& const_reference;
165 typedef ptrdiff_t difference_type;
166 typedef const value_type* const_iterator;
167 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
169 static const size_type npos;
171 public:
172 // We provide non-explicit singleton constructors so users can pass
173 // in a "const char*" or a "string" wherever a "StringPiece" is
174 // expected (likewise for char16, string16, StringPiece16).
175 BasicStringPiece() : ptr_(NULL), length_(0) {}
176 BasicStringPiece(const value_type* str)
177 : ptr_(str),
178 length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {}
179 BasicStringPiece(const STRING_TYPE& str)
180 : ptr_(str.data()), length_(str.size()) {}
181 BasicStringPiece(const value_type* offset, size_type len)
182 : ptr_(offset), length_(len) {}
183 BasicStringPiece(const typename STRING_TYPE::const_iterator& begin,
184 const typename STRING_TYPE::const_iterator& end)
185 : ptr_((end > begin) ? &(*begin) : NULL),
186 length_((end > begin) ? (size_type)(end - begin) : 0) {}
188 // data() may return a pointer to a buffer with embedded NULs, and the
189 // returned buffer may or may not be null terminated. Therefore it is
190 // typically a mistake to pass data() to a routine that expects a NUL
191 // terminated string.
192 const value_type* data() const { return ptr_; }
193 size_type size() const { return length_; }
194 size_type length() const { return length_; }
195 bool empty() const { return length_ == 0; }
197 void clear() {
198 ptr_ = NULL;
199 length_ = 0;
201 void set(const value_type* data, size_type len) {
202 ptr_ = data;
203 length_ = len;
205 void set(const value_type* str) {
206 ptr_ = str;
207 length_ = str ? STRING_TYPE::traits_type::length(str) : 0;
210 value_type operator[](size_type i) const { return ptr_[i]; }
212 void remove_prefix(size_type n) {
213 ptr_ += n;
214 length_ -= n;
217 void remove_suffix(size_type n) {
218 length_ -= n;
221 int compare(const BasicStringPiece<STRING_TYPE>& x) const {
222 int r = wordmemcmp(
223 ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_));
224 if (r == 0) {
225 if (length_ < x.length_) r = -1;
226 else if (length_ > x.length_) r = +1;
228 return r;
231 STRING_TYPE as_string() const {
232 // std::string doesn't like to take a NULL pointer even with a 0 size.
233 return empty() ? STRING_TYPE() : STRING_TYPE(data(), size());
236 const_iterator begin() const { return ptr_; }
237 const_iterator end() const { return ptr_ + length_; }
238 const_reverse_iterator rbegin() const {
239 return const_reverse_iterator(ptr_ + length_);
241 const_reverse_iterator rend() const {
242 return const_reverse_iterator(ptr_);
245 size_type max_size() const { return length_; }
246 size_type capacity() const { return length_; }
248 static int wordmemcmp(const value_type* p,
249 const value_type* p2,
250 size_type N) {
251 return STRING_TYPE::traits_type::compare(p, p2, N);
254 // Sets the value of the given string target type to be the current string.
255 // This saves a temporary over doing |a = b.as_string()|
256 void CopyToString(STRING_TYPE* target) const {
257 internal::CopyToString(*this, target);
260 void AppendToString(STRING_TYPE* target) const {
261 internal::AppendToString(*this, target);
264 size_type copy(value_type* buf, size_type n, size_type pos = 0) const {
265 return internal::copy(*this, buf, n, pos);
268 // Does "this" start with "x"
269 bool starts_with(const BasicStringPiece& x) const {
270 return ((this->length_ >= x.length_) &&
271 (wordmemcmp(this->ptr_, x.ptr_, x.length_) == 0));
274 // Does "this" end with "x"
275 bool ends_with(const BasicStringPiece& x) const {
276 return ((this->length_ >= x.length_) &&
277 (wordmemcmp(this->ptr_ + (this->length_-x.length_),
278 x.ptr_, x.length_) == 0));
281 // find: Search for a character or substring at a given offset.
282 size_type find(const BasicStringPiece<STRING_TYPE>& s,
283 size_type pos = 0) const {
284 return internal::find(*this, s, pos);
286 size_type find(value_type c, size_type pos = 0) const {
287 return internal::find(*this, c, pos);
290 // rfind: Reverse find.
291 size_type rfind(const BasicStringPiece& s,
292 size_type pos = BasicStringPiece::npos) const {
293 return internal::rfind(*this, s, pos);
295 size_type rfind(value_type c, size_type pos = BasicStringPiece::npos) const {
296 return internal::rfind(*this, c, pos);
299 // find_first_of: Find the first occurence of one of a set of characters.
300 size_type find_first_of(const BasicStringPiece& s,
301 size_type pos = 0) const {
302 return internal::find_first_of(*this, s, pos);
304 size_type find_first_of(value_type c, size_type pos = 0) const {
305 return find(c, pos);
308 // find_first_not_of: Find the first occurence not of a set of characters.
309 size_type find_first_not_of(const BasicStringPiece& s,
310 size_type pos = 0) const {
311 return internal::find_first_not_of(*this, s, pos);
313 size_type find_first_not_of(value_type c, size_type pos = 0) const {
314 return internal::find_first_not_of(*this, c, pos);
317 // find_last_of: Find the last occurence of one of a set of characters.
318 size_type find_last_of(const BasicStringPiece& s,
319 size_type pos = BasicStringPiece::npos) const {
320 return internal::find_last_of(*this, s, pos);
322 size_type find_last_of(value_type c,
323 size_type pos = BasicStringPiece::npos) const {
324 return rfind(c, pos);
327 // find_last_not_of: Find the last occurence not of a set of characters.
328 size_type find_last_not_of(const BasicStringPiece& s,
329 size_type pos = BasicStringPiece::npos) const {
330 return internal::find_last_not_of(*this, s, pos);
332 size_type find_last_not_of(value_type c,
333 size_type pos = BasicStringPiece::npos) const {
334 return internal::find_last_not_of(*this, c, pos);
337 // substr.
338 BasicStringPiece substr(size_type pos,
339 size_type n = BasicStringPiece::npos) const {
340 return internal::substr(*this, pos, n);
343 protected:
344 const value_type* ptr_;
345 size_type length_;
348 template <typename STRING_TYPE>
349 const typename BasicStringPiece<STRING_TYPE>::size_type
350 BasicStringPiece<STRING_TYPE>::npos =
351 typename BasicStringPiece<STRING_TYPE>::size_type(-1);
353 // MSVC doesn't like complex extern templates and DLLs.
354 #if !defined(COMPILER_MSVC)
355 extern template class BASE_EXPORT BasicStringPiece<std::string>;
356 extern template class BASE_EXPORT BasicStringPiece<string16>;
357 #endif
359 // StingPiece operators --------------------------------------------------------
361 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y);
363 inline bool operator!=(const StringPiece& x, const StringPiece& y) {
364 return !(x == y);
367 inline bool operator<(const StringPiece& x, const StringPiece& y) {
368 const int r = StringPiece::wordmemcmp(
369 x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
370 return ((r < 0) || ((r == 0) && (x.size() < y.size())));
373 inline bool operator>(const StringPiece& x, const StringPiece& y) {
374 return y < x;
377 inline bool operator<=(const StringPiece& x, const StringPiece& y) {
378 return !(x > y);
381 inline bool operator>=(const StringPiece& x, const StringPiece& y) {
382 return !(x < y);
385 // StringPiece16 operators -----------------------------------------------------
387 inline bool operator==(const StringPiece16& x, const StringPiece16& y) {
388 if (x.size() != y.size())
389 return false;
391 return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0;
394 inline bool operator!=(const StringPiece16& x, const StringPiece16& y) {
395 return !(x == y);
398 inline bool operator<(const StringPiece16& x, const StringPiece16& y) {
399 const int r = StringPiece16::wordmemcmp(
400 x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
401 return ((r < 0) || ((r == 0) && (x.size() < y.size())));
404 inline bool operator>(const StringPiece16& x, const StringPiece16& y) {
405 return y < x;
408 inline bool operator<=(const StringPiece16& x, const StringPiece16& y) {
409 return !(x > y);
412 inline bool operator>=(const StringPiece16& x, const StringPiece16& y) {
413 return !(x < y);
416 BASE_EXPORT std::ostream& operator<<(std::ostream& o,
417 const StringPiece& piece);
419 } // namespace base
421 // Hashing ---------------------------------------------------------------------
423 // We provide appropriate hash functions so StringPiece and StringPiece16 can
424 // be used as keys in hash sets and maps.
426 // This hash function is copied from base/containers/hash_tables.h. We don't
427 // use the ones already defined for string and string16 directly because it
428 // would require the string constructors to be called, which we don't want.
429 #define HASH_STRING_PIECE(StringPieceType, string_piece) \
430 std::size_t result = 0; \
431 for (StringPieceType::const_iterator i = string_piece.begin(); \
432 i != string_piece.end(); ++i) \
433 result = (result * 131) + *i; \
434 return result; \
436 namespace BASE_HASH_NAMESPACE {
437 #if defined(COMPILER_GCC)
439 template<>
440 struct hash<base::StringPiece> {
441 std::size_t operator()(const base::StringPiece& sp) const {
442 HASH_STRING_PIECE(base::StringPiece, sp);
445 template<>
446 struct hash<base::StringPiece16> {
447 std::size_t operator()(const base::StringPiece16& sp16) const {
448 HASH_STRING_PIECE(base::StringPiece16, sp16);
452 #elif defined(COMPILER_MSVC)
454 inline size_t hash_value(const base::StringPiece& sp) {
455 HASH_STRING_PIECE(base::StringPiece, sp);
457 inline size_t hash_value(const base::StringPiece16& sp16) {
458 HASH_STRING_PIECE(base::StringPiece16, sp16);
461 #endif // COMPILER
463 } // namespace BASE_HASH_NAMESPACE
465 #endif // BASE_STRINGS_STRING_PIECE_H_