OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // Copied from strings/stringpiece.h with modifications | 4 // Copied from strings/stringpiece.h with modifications |
5 // | 5 // |
6 // A string-like object that points to a sized piece of memory. | 6 // A string-like object that points to a sized piece of memory. |
7 // | 7 // |
8 // Functions or methods may use const StringPiece& parameters to accept either | 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 | 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 | 10 // a StringPiece. The implicit conversion means that it is often appropriate |
(...skipping 21 matching lines...) Expand all Loading... |
32 #include "base/basictypes.h" | 32 #include "base/basictypes.h" |
33 #include "base/containers/hash_tables.h" | 33 #include "base/containers/hash_tables.h" |
34 #include "base/strings/string16.h" | 34 #include "base/strings/string16.h" |
35 | 35 |
36 namespace base { | 36 namespace base { |
37 | 37 |
38 template <typename STRING_TYPE> class BasicStringPiece; | 38 template <typename STRING_TYPE> class BasicStringPiece; |
39 typedef BasicStringPiece<std::string> StringPiece; | 39 typedef BasicStringPiece<std::string> StringPiece; |
40 typedef BasicStringPiece<string16> StringPiece16; | 40 typedef BasicStringPiece<string16> StringPiece16; |
41 | 41 |
| 42 // internal -------------------------------------------------------------------- |
| 43 |
| 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. |
| 47 // |
| 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. |
42 namespace internal { | 51 namespace internal { |
43 | 52 |
| 53 BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target); |
| 54 BASE_EXPORT void CopyToString(const StringPiece16& self, string16* target); |
| 55 |
| 56 BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target); |
| 57 BASE_EXPORT void AppendToString(const StringPiece16& self, string16* target); |
| 58 |
| 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); |
| 67 |
| 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); |
| 80 |
| 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); |
| 93 |
| 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); |
| 100 |
| 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); |
| 113 |
| 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); |
| 126 |
| 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); |
| 139 |
| 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); |
| 146 |
| 147 } // namespace internal |
| 148 |
| 149 // BasicStringPiece ------------------------------------------------------------ |
| 150 |
44 // Defines the types, methods, operators, and data members common to both | 151 // Defines the types, methods, operators, and data members common to both |
45 // StringPiece and StringPiece16. Do not refer to this class directly, but | 152 // StringPiece and StringPiece16. Do not refer to this class directly, but |
46 // rather to BasicStringPiece, StringPiece, or StringPiece16. | 153 // rather to BasicStringPiece, StringPiece, or StringPiece16. |
47 template <typename STRING_TYPE> class StringPieceDetail { | 154 // |
| 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 { |
48 public: | 158 public: |
49 // standard STL container boilerplate | 159 // Standard STL container boilerplate. |
50 typedef size_t size_type; | 160 typedef size_t size_type; |
51 typedef typename STRING_TYPE::value_type value_type; | 161 typedef typename STRING_TYPE::value_type value_type; |
52 typedef const value_type* pointer; | 162 typedef const value_type* pointer; |
53 typedef const value_type& reference; | 163 typedef const value_type& reference; |
54 typedef const value_type& const_reference; | 164 typedef const value_type& const_reference; |
55 typedef ptrdiff_t difference_type; | 165 typedef ptrdiff_t difference_type; |
56 typedef const value_type* const_iterator; | 166 typedef const value_type* const_iterator; |
57 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | 167 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
58 | 168 |
59 static const size_type npos; | 169 static const size_type npos; |
60 | 170 |
61 public: | 171 public: |
62 // We provide non-explicit singleton constructors so users can pass | 172 // We provide non-explicit singleton constructors so users can pass |
63 // in a "const char*" or a "string" wherever a "StringPiece" is | 173 // in a "const char*" or a "string" wherever a "StringPiece" is |
64 // expected (likewise for char16, string16, StringPiece16). | 174 // expected (likewise for char16, string16, StringPiece16). |
65 StringPieceDetail() : ptr_(NULL), length_(0) {} | 175 BasicStringPiece() : ptr_(NULL), length_(0) {} |
66 StringPieceDetail(const value_type* str) | 176 BasicStringPiece(const value_type* str) |
67 : ptr_(str), | 177 : ptr_(str), |
68 length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {} | 178 length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {} |
69 StringPieceDetail(const STRING_TYPE& str) | 179 BasicStringPiece(const STRING_TYPE& str) |
70 : ptr_(str.data()), length_(str.size()) {} | 180 : ptr_(str.data()), length_(str.size()) {} |
71 StringPieceDetail(const value_type* offset, size_type len) | 181 BasicStringPiece(const value_type* offset, size_type len) |
72 : ptr_(offset), length_(len) {} | 182 : ptr_(offset), length_(len) {} |
73 StringPieceDetail(const typename STRING_TYPE::const_iterator& begin, | 183 BasicStringPiece(const typename STRING_TYPE::const_iterator& begin, |
74 const typename STRING_TYPE::const_iterator& end) | 184 const typename STRING_TYPE::const_iterator& end) |
75 : ptr_((end > begin) ? &(*begin) : NULL), | 185 : ptr_((end > begin) ? &(*begin) : NULL), |
76 length_((end > begin) ? (size_type)(end - begin) : 0) {} | 186 length_((end > begin) ? (size_type)(end - begin) : 0) {} |
77 | 187 |
78 // data() may return a pointer to a buffer with embedded NULs, and the | 188 // data() may return a pointer to a buffer with embedded NULs, and the |
79 // returned buffer may or may not be null terminated. Therefore it is | 189 // returned buffer may or may not be null terminated. Therefore it is |
80 // typically a mistake to pass data() to a routine that expects a NUL | 190 // typically a mistake to pass data() to a routine that expects a NUL |
81 // terminated string. | 191 // terminated string. |
82 const value_type* data() const { return ptr_; } | 192 const value_type* data() const { return ptr_; } |
83 size_type size() const { return length_; } | 193 size_type size() const { return length_; } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 | 244 |
135 size_type max_size() const { return length_; } | 245 size_type max_size() const { return length_; } |
136 size_type capacity() const { return length_; } | 246 size_type capacity() const { return length_; } |
137 | 247 |
138 static int wordmemcmp(const value_type* p, | 248 static int wordmemcmp(const value_type* p, |
139 const value_type* p2, | 249 const value_type* p2, |
140 size_type N) { | 250 size_type N) { |
141 return STRING_TYPE::traits_type::compare(p, p2, N); | 251 return STRING_TYPE::traits_type::compare(p, p2, N); |
142 } | 252 } |
143 | 253 |
| 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); |
| 258 } |
| 259 |
| 260 void AppendToString(STRING_TYPE* target) const { |
| 261 internal::AppendToString(*this, target); |
| 262 } |
| 263 |
| 264 size_type copy(value_type* buf, size_type n, size_type pos = 0) const { |
| 265 return internal::copy(*this, buf, n, pos); |
| 266 } |
| 267 |
| 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)); |
| 272 } |
| 273 |
| 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)); |
| 279 } |
| 280 |
| 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); |
| 285 } |
| 286 size_type find(value_type c, size_type pos = 0) const { |
| 287 return internal::find(*this, c, pos); |
| 288 } |
| 289 |
| 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); |
| 294 } |
| 295 size_type rfind(value_type c, size_type pos = BasicStringPiece::npos) const { |
| 296 return internal::rfind(*this, c, pos); |
| 297 } |
| 298 |
| 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); |
| 303 } |
| 304 size_type find_first_of(value_type c, size_type pos = 0) const { |
| 305 return find(c, pos); |
| 306 } |
| 307 |
| 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); |
| 312 } |
| 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); |
| 315 } |
| 316 |
| 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); |
| 321 } |
| 322 size_type find_last_of(value_type c, |
| 323 size_type pos = BasicStringPiece::npos) const { |
| 324 return rfind(c, pos); |
| 325 } |
| 326 |
| 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); |
| 331 } |
| 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); |
| 335 } |
| 336 |
| 337 // substr. |
| 338 BasicStringPiece substr(size_type pos, |
| 339 size_type n = BasicStringPiece::npos) const { |
| 340 return internal::substr(*this, pos, n); |
| 341 } |
| 342 |
144 protected: | 343 protected: |
145 const value_type* ptr_; | 344 const value_type* ptr_; |
146 size_type length_; | 345 size_type length_; |
147 }; | 346 }; |
148 | 347 |
149 template <typename STRING_TYPE> | 348 template <typename STRING_TYPE> |
150 const typename StringPieceDetail<STRING_TYPE>::size_type | 349 const typename BasicStringPiece<STRING_TYPE>::size_type |
151 StringPieceDetail<STRING_TYPE>::npos = | 350 BasicStringPiece<STRING_TYPE>::npos = |
152 typename StringPieceDetail<STRING_TYPE>::size_type(-1); | 351 typename BasicStringPiece<STRING_TYPE>::size_type(-1); |
153 | 352 |
154 // MSVC doesn't like complex extern templates and DLLs. | 353 // MSVC doesn't like complex extern templates and DLLs. |
155 #if !defined(COMPILER_MSVC) | 354 #if !defined(COMPILER_MSVC) |
156 extern template class BASE_EXPORT StringPieceDetail<std::string>; | 355 extern template class BASE_EXPORT BasicStringPiece<std::string>; |
157 extern template class BASE_EXPORT StringPieceDetail<string16>; | 356 extern template class BASE_EXPORT BasicStringPiece<string16>; |
158 #endif | 357 #endif |
159 | 358 |
160 BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target); | 359 // StingPiece operators -------------------------------------------------------- |
161 BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target); | |
162 BASE_EXPORT StringPieceDetail<std::string>::size_type copy( | |
163 const StringPiece& self, | |
164 char* buf, | |
165 StringPieceDetail<std::string>::size_type n, | |
166 StringPieceDetail<std::string>::size_type pos); | |
167 BASE_EXPORT StringPieceDetail<std::string>::size_type find( | |
168 const StringPiece& self, | |
169 const StringPiece& s, | |
170 StringPieceDetail<std::string>::size_type pos); | |
171 BASE_EXPORT StringPieceDetail<std::string>::size_type find( | |
172 const StringPiece& self, | |
173 char c, | |
174 StringPieceDetail<std::string>::size_type pos); | |
175 BASE_EXPORT StringPieceDetail<std::string>::size_type rfind( | |
176 const StringPiece& self, | |
177 const StringPiece& s, | |
178 StringPieceDetail<std::string>::size_type pos); | |
179 BASE_EXPORT StringPieceDetail<std::string>::size_type rfind( | |
180 const StringPiece& self, | |
181 char c, | |
182 StringPieceDetail<std::string>::size_type pos); | |
183 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_of( | |
184 const StringPiece& self, | |
185 const StringPiece& s, | |
186 StringPieceDetail<std::string>::size_type pos); | |
187 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of( | |
188 const StringPiece& self, | |
189 const StringPiece& s, | |
190 StringPieceDetail<std::string>::size_type pos); | |
191 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of( | |
192 const StringPiece& self, | |
193 char c, | |
194 StringPieceDetail<std::string>::size_type pos); | |
195 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of( | |
196 const StringPiece& self, | |
197 const StringPiece& s, | |
198 StringPieceDetail<std::string>::size_type pos); | |
199 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of( | |
200 const StringPiece& self, | |
201 char c, | |
202 StringPieceDetail<std::string>::size_type pos); | |
203 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of( | |
204 const StringPiece& self, | |
205 const StringPiece& s, | |
206 StringPieceDetail<std::string>::size_type pos); | |
207 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of( | |
208 const StringPiece& self, | |
209 char c, | |
210 StringPieceDetail<std::string>::size_type pos); | |
211 BASE_EXPORT StringPiece substr(const StringPiece& self, | |
212 StringPieceDetail<std::string>::size_type pos, | |
213 StringPieceDetail<std::string>::size_type n); | |
214 } // namespace internal | |
215 | |
216 // Defines the template type that is instantiated as either StringPiece or | |
217 // StringPiece16. | |
218 template <typename STRING_TYPE> class BasicStringPiece : | |
219 public internal::StringPieceDetail<STRING_TYPE> { | |
220 public: | |
221 typedef typename internal::StringPieceDetail<STRING_TYPE>::value_type | |
222 value_type; | |
223 typedef typename internal::StringPieceDetail<STRING_TYPE>::size_type | |
224 size_type; | |
225 | |
226 BasicStringPiece() {} | |
227 BasicStringPiece(const value_type*str) | |
228 : internal::StringPieceDetail<STRING_TYPE>(str) {} | |
229 BasicStringPiece(const STRING_TYPE& str) | |
230 : internal::StringPieceDetail<STRING_TYPE>(str) {} | |
231 BasicStringPiece(const value_type* offset, size_type len) | |
232 : internal::StringPieceDetail<STRING_TYPE>(offset, len) {} | |
233 BasicStringPiece(const typename STRING_TYPE::const_iterator& begin, | |
234 const typename STRING_TYPE::const_iterator& end) | |
235 : internal::StringPieceDetail<STRING_TYPE>(begin, end) {} | |
236 }; | |
237 | |
238 // Specializes BasicStringPiece for std::string to add a few operations that | |
239 // are not needed for string16. | |
240 template <> class BasicStringPiece<std::string> : | |
241 public internal::StringPieceDetail<std::string> { | |
242 public: | |
243 BasicStringPiece() {} | |
244 BasicStringPiece(const char* str) | |
245 : internal::StringPieceDetail<std::string>(str) {} | |
246 BasicStringPiece(const std::string& str) | |
247 : internal::StringPieceDetail<std::string>(str) {} | |
248 BasicStringPiece(const char* offset, size_type len) | |
249 : internal::StringPieceDetail<std::string>(offset, len) {} | |
250 BasicStringPiece(const std::string::const_iterator& begin, | |
251 const std::string::const_iterator& end) | |
252 : internal::StringPieceDetail<std::string>(begin, end) {} | |
253 | |
254 // Prevent the following overload of set() from hiding the definitions in the | |
255 // base class. | |
256 using internal::StringPieceDetail<std::string>::set; | |
257 | |
258 void set(const void* data, size_type len) { | |
259 ptr_ = reinterpret_cast<const value_type*>(data); | |
260 length_ = len; | |
261 } | |
262 | |
263 void CopyToString(std::string* target) const { | |
264 internal::CopyToString(*this, target); | |
265 } | |
266 | |
267 void AppendToString(std::string* target) const { | |
268 internal::AppendToString(*this, target); | |
269 } | |
270 | |
271 // Does "this" start with "x" | |
272 bool starts_with(const BasicStringPiece& x) const { | |
273 return ((length_ >= x.length_) && | |
274 (wordmemcmp(ptr_, x.ptr_, x.length_) == 0)); | |
275 } | |
276 | |
277 // Does "this" end with "x" | |
278 bool ends_with(const BasicStringPiece& x) const { | |
279 return ((length_ >= x.length_) && | |
280 (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0)); | |
281 } | |
282 | |
283 size_type copy(char* buf, size_type n, size_type pos = 0) const { | |
284 return internal::copy(*this, buf, n, pos); | |
285 } | |
286 | |
287 size_type find(const BasicStringPiece& s, size_type pos = 0) const { | |
288 return internal::find(*this, s, pos); | |
289 } | |
290 | |
291 size_type find(char c, size_type pos = 0) const { | |
292 return internal::find(*this, c, pos); | |
293 } | |
294 | |
295 size_type rfind(const BasicStringPiece& s, size_type pos = npos) const { | |
296 return internal::rfind(*this, s, pos); | |
297 } | |
298 | |
299 size_type rfind(char c, size_type pos = npos) const { | |
300 return internal::rfind(*this, c, pos); | |
301 } | |
302 | |
303 size_type find_first_of(const BasicStringPiece& s, size_type pos = 0) const { | |
304 return internal::find_first_of(*this, s, pos); | |
305 } | |
306 | |
307 size_type find_first_of(char c, size_type pos = 0) const { | |
308 return find(c, pos); | |
309 } | |
310 | |
311 size_type find_first_not_of(const BasicStringPiece& s, | |
312 size_type pos = 0) const { | |
313 return internal::find_first_not_of(*this, s, pos); | |
314 } | |
315 | |
316 size_type find_first_not_of(char c, size_type pos = 0) const { | |
317 return internal::find_first_not_of(*this, c, pos); | |
318 } | |
319 | |
320 size_type find_last_of(const BasicStringPiece& s, | |
321 size_type pos = npos) const { | |
322 return internal::find_last_of(*this, s, pos); | |
323 } | |
324 | |
325 size_type find_last_of(char c, size_type pos = npos) const { | |
326 return rfind(c, pos); | |
327 } | |
328 | |
329 size_type find_last_not_of(const BasicStringPiece& s, | |
330 size_type pos = npos) const { | |
331 return internal::find_last_not_of(*this, s, pos); | |
332 } | |
333 | |
334 size_type find_last_not_of(char c, size_type pos = npos) const { | |
335 return internal::find_last_not_of(*this, c, pos); | |
336 } | |
337 | |
338 BasicStringPiece substr(size_type pos, size_type n = npos) const { | |
339 return internal::substr(*this, pos, n); | |
340 } | |
341 }; | |
342 | |
343 // MSVC doesn't like complex extern templates and DLLs. | |
344 #if !defined(COMPILER_MSVC) | |
345 // We can't explicitly declare the std::string instantiation here because it was | |
346 // already instantiated when specialized, above. Not only is it a no-op, but | |
347 // currently it also crashes Clang (see http://crbug.com/107412). | |
348 extern template class BASE_EXPORT BasicStringPiece<string16>; | |
349 #endif | |
350 | 360 |
351 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); | 361 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); |
352 | 362 |
353 inline bool operator!=(const StringPiece& x, const StringPiece& y) { | 363 inline bool operator!=(const StringPiece& x, const StringPiece& y) { |
354 return !(x == y); | 364 return !(x == y); |
355 } | 365 } |
356 | 366 |
357 inline bool operator<(const StringPiece& x, const StringPiece& y) { | 367 inline bool operator<(const StringPiece& x, const StringPiece& y) { |
358 const int r = StringPiece::wordmemcmp( | 368 const int r = StringPiece::wordmemcmp( |
359 x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); | 369 x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); |
360 return ((r < 0) || ((r == 0) && (x.size() < y.size()))); | 370 return ((r < 0) || ((r == 0) && (x.size() < y.size()))); |
361 } | 371 } |
362 | 372 |
363 inline bool operator>(const StringPiece& x, const StringPiece& y) { | 373 inline bool operator>(const StringPiece& x, const StringPiece& y) { |
364 return y < x; | 374 return y < x; |
365 } | 375 } |
366 | 376 |
367 inline bool operator<=(const StringPiece& x, const StringPiece& y) { | 377 inline bool operator<=(const StringPiece& x, const StringPiece& y) { |
368 return !(x > y); | 378 return !(x > y); |
369 } | 379 } |
370 | 380 |
371 inline bool operator>=(const StringPiece& x, const StringPiece& y) { | 381 inline bool operator>=(const StringPiece& x, const StringPiece& y) { |
372 return !(x < y); | 382 return !(x < y); |
373 } | 383 } |
374 | 384 |
| 385 // StringPiece16 operators ----------------------------------------------------- |
| 386 |
375 inline bool operator==(const StringPiece16& x, const StringPiece16& y) { | 387 inline bool operator==(const StringPiece16& x, const StringPiece16& y) { |
376 if (x.size() != y.size()) | 388 if (x.size() != y.size()) |
377 return false; | 389 return false; |
378 | 390 |
379 return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0; | 391 return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0; |
380 } | 392 } |
381 | 393 |
382 inline bool operator!=(const StringPiece16& x, const StringPiece16& y) { | 394 inline bool operator!=(const StringPiece16& x, const StringPiece16& y) { |
383 return !(x == y); | 395 return !(x == y); |
384 } | 396 } |
(...skipping 14 matching lines...) Expand all Loading... |
399 | 411 |
400 inline bool operator>=(const StringPiece16& x, const StringPiece16& y) { | 412 inline bool operator>=(const StringPiece16& x, const StringPiece16& y) { |
401 return !(x < y); | 413 return !(x < y); |
402 } | 414 } |
403 | 415 |
404 BASE_EXPORT std::ostream& operator<<(std::ostream& o, | 416 BASE_EXPORT std::ostream& operator<<(std::ostream& o, |
405 const StringPiece& piece); | 417 const StringPiece& piece); |
406 | 418 |
407 } // namespace base | 419 } // namespace base |
408 | 420 |
| 421 // Hashing --------------------------------------------------------------------- |
| 422 |
409 // We provide appropriate hash functions so StringPiece and StringPiece16 can | 423 // We provide appropriate hash functions so StringPiece and StringPiece16 can |
410 // be used as keys in hash sets and maps. | 424 // be used as keys in hash sets and maps. |
411 | 425 |
412 // This hash function is copied from base/containers/hash_tables.h. We don't | 426 // This hash function is copied from base/containers/hash_tables.h. We don't |
413 // use the ones already defined for string and string16 directly because it | 427 // use the ones already defined for string and string16 directly because it |
414 // would require the string constructors to be called, which we don't want. | 428 // would require the string constructors to be called, which we don't want. |
415 #define HASH_STRING_PIECE(StringPieceType, string_piece) \ | 429 #define HASH_STRING_PIECE(StringPieceType, string_piece) \ |
416 std::size_t result = 0; \ | 430 std::size_t result = 0; \ |
417 for (StringPieceType::const_iterator i = string_piece.begin(); \ | 431 for (StringPieceType::const_iterator i = string_piece.begin(); \ |
418 i != string_piece.end(); ++i) \ | 432 i != string_piece.end(); ++i) \ |
(...skipping 23 matching lines...) Expand all Loading... |
442 } | 456 } |
443 inline size_t hash_value(const base::StringPiece16& sp16) { | 457 inline size_t hash_value(const base::StringPiece16& sp16) { |
444 HASH_STRING_PIECE(base::StringPiece16, sp16); | 458 HASH_STRING_PIECE(base::StringPiece16, sp16); |
445 } | 459 } |
446 | 460 |
447 #endif // COMPILER | 461 #endif // COMPILER |
448 | 462 |
449 } // namespace BASE_HASH_NAMESPACE | 463 } // namespace BASE_HASH_NAMESPACE |
450 | 464 |
451 #endif // BASE_STRINGS_STRING_PIECE_H_ | 465 #endif // BASE_STRINGS_STRING_PIECE_H_ |
OLD | NEW |