| 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. | |
| 51 namespace internal { | 42 namespace internal { |
| 52 | 43 |
| 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 | |
| 151 // Defines the types, methods, operators, and data members common to both | 44 // Defines the types, methods, operators, and data members common to both |
| 152 // StringPiece and StringPiece16. Do not refer to this class directly, but | 45 // StringPiece and StringPiece16. Do not refer to this class directly, but |
| 153 // rather to BasicStringPiece, StringPiece, or StringPiece16. | 46 // rather to BasicStringPiece, StringPiece, or StringPiece16. |
| 154 // | 47 template <typename STRING_TYPE> class StringPieceDetail { |
| 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: | 48 public: |
| 159 // Standard STL container boilerplate. | 49 // standard STL container boilerplate |
| 160 typedef size_t size_type; | 50 typedef size_t size_type; |
| 161 typedef typename STRING_TYPE::value_type value_type; | 51 typedef typename STRING_TYPE::value_type value_type; |
| 162 typedef const value_type* pointer; | 52 typedef const value_type* pointer; |
| 163 typedef const value_type& reference; | 53 typedef const value_type& reference; |
| 164 typedef const value_type& const_reference; | 54 typedef const value_type& const_reference; |
| 165 typedef ptrdiff_t difference_type; | 55 typedef ptrdiff_t difference_type; |
| 166 typedef const value_type* const_iterator; | 56 typedef const value_type* const_iterator; |
| 167 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | 57 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
| 168 | 58 |
| 169 static const size_type npos; | 59 static const size_type npos; |
| 170 | 60 |
| 171 public: | 61 public: |
| 172 // We provide non-explicit singleton constructors so users can pass | 62 // We provide non-explicit singleton constructors so users can pass |
| 173 // in a "const char*" or a "string" wherever a "StringPiece" is | 63 // in a "const char*" or a "string" wherever a "StringPiece" is |
| 174 // expected (likewise for char16, string16, StringPiece16). | 64 // expected (likewise for char16, string16, StringPiece16). |
| 175 BasicStringPiece() : ptr_(NULL), length_(0) {} | 65 StringPieceDetail() : ptr_(NULL), length_(0) {} |
| 176 BasicStringPiece(const value_type* str) | 66 StringPieceDetail(const value_type* str) |
| 177 : ptr_(str), | 67 : ptr_(str), |
| 178 length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {} | 68 length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {} |
| 179 BasicStringPiece(const STRING_TYPE& str) | 69 StringPieceDetail(const STRING_TYPE& str) |
| 180 : ptr_(str.data()), length_(str.size()) {} | 70 : ptr_(str.data()), length_(str.size()) {} |
| 181 BasicStringPiece(const value_type* offset, size_type len) | 71 StringPieceDetail(const value_type* offset, size_type len) |
| 182 : ptr_(offset), length_(len) {} | 72 : ptr_(offset), length_(len) {} |
| 183 BasicStringPiece(const typename STRING_TYPE::const_iterator& begin, | 73 StringPieceDetail(const typename STRING_TYPE::const_iterator& begin, |
| 184 const typename STRING_TYPE::const_iterator& end) | 74 const typename STRING_TYPE::const_iterator& end) |
| 185 : ptr_((end > begin) ? &(*begin) : NULL), | 75 : ptr_((end > begin) ? &(*begin) : NULL), |
| 186 length_((end > begin) ? (size_type)(end - begin) : 0) {} | 76 length_((end > begin) ? (size_type)(end - begin) : 0) {} |
| 187 | 77 |
| 188 // data() may return a pointer to a buffer with embedded NULs, and the | 78 // 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 | 79 // 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 | 80 // typically a mistake to pass data() to a routine that expects a NUL |
| 191 // terminated string. | 81 // terminated string. |
| 192 const value_type* data() const { return ptr_; } | 82 const value_type* data() const { return ptr_; } |
| 193 size_type size() const { return length_; } | 83 size_type size() const { return length_; } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 | 134 |
| 245 size_type max_size() const { return length_; } | 135 size_type max_size() const { return length_; } |
| 246 size_type capacity() const { return length_; } | 136 size_type capacity() const { return length_; } |
| 247 | 137 |
| 248 static int wordmemcmp(const value_type* p, | 138 static int wordmemcmp(const value_type* p, |
| 249 const value_type* p2, | 139 const value_type* p2, |
| 250 size_type N) { | 140 size_type N) { |
| 251 return STRING_TYPE::traits_type::compare(p, p2, N); | 141 return STRING_TYPE::traits_type::compare(p, p2, N); |
| 252 } | 142 } |
| 253 | 143 |
| 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 | |
| 343 protected: | 144 protected: |
| 344 const value_type* ptr_; | 145 const value_type* ptr_; |
| 345 size_type length_; | 146 size_type length_; |
| 346 }; | 147 }; |
| 347 | 148 |
| 348 template <typename STRING_TYPE> | 149 template <typename STRING_TYPE> |
| 349 const typename BasicStringPiece<STRING_TYPE>::size_type | 150 const typename StringPieceDetail<STRING_TYPE>::size_type |
| 350 BasicStringPiece<STRING_TYPE>::npos = | 151 StringPieceDetail<STRING_TYPE>::npos = |
| 351 typename BasicStringPiece<STRING_TYPE>::size_type(-1); | 152 typename StringPieceDetail<STRING_TYPE>::size_type(-1); |
| 352 | 153 |
| 353 // MSVC doesn't like complex extern templates and DLLs. | 154 // MSVC doesn't like complex extern templates and DLLs. |
| 354 #if !defined(COMPILER_MSVC) | 155 #if !defined(COMPILER_MSVC) |
| 355 extern template class BASE_EXPORT BasicStringPiece<std::string>; | 156 extern template class BASE_EXPORT StringPieceDetail<std::string>; |
| 157 extern template class BASE_EXPORT StringPieceDetail<string16>; |
| 158 #endif |
| 159 |
| 160 BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target); |
| 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). |
| 356 extern template class BASE_EXPORT BasicStringPiece<string16>; | 348 extern template class BASE_EXPORT BasicStringPiece<string16>; |
| 357 #endif | 349 #endif |
| 358 | 350 |
| 359 // StingPiece operators -------------------------------------------------------- | |
| 360 | |
| 361 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); | 351 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); |
| 362 | 352 |
| 363 inline bool operator!=(const StringPiece& x, const StringPiece& y) { | 353 inline bool operator!=(const StringPiece& x, const StringPiece& y) { |
| 364 return !(x == y); | 354 return !(x == y); |
| 365 } | 355 } |
| 366 | 356 |
| 367 inline bool operator<(const StringPiece& x, const StringPiece& y) { | 357 inline bool operator<(const StringPiece& x, const StringPiece& y) { |
| 368 const int r = StringPiece::wordmemcmp( | 358 const int r = StringPiece::wordmemcmp( |
| 369 x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); | 359 x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); |
| 370 return ((r < 0) || ((r == 0) && (x.size() < y.size()))); | 360 return ((r < 0) || ((r == 0) && (x.size() < y.size()))); |
| 371 } | 361 } |
| 372 | 362 |
| 373 inline bool operator>(const StringPiece& x, const StringPiece& y) { | 363 inline bool operator>(const StringPiece& x, const StringPiece& y) { |
| 374 return y < x; | 364 return y < x; |
| 375 } | 365 } |
| 376 | 366 |
| 377 inline bool operator<=(const StringPiece& x, const StringPiece& y) { | 367 inline bool operator<=(const StringPiece& x, const StringPiece& y) { |
| 378 return !(x > y); | 368 return !(x > y); |
| 379 } | 369 } |
| 380 | 370 |
| 381 inline bool operator>=(const StringPiece& x, const StringPiece& y) { | 371 inline bool operator>=(const StringPiece& x, const StringPiece& y) { |
| 382 return !(x < y); | 372 return !(x < y); |
| 383 } | 373 } |
| 384 | 374 |
| 385 // StringPiece16 operators ----------------------------------------------------- | |
| 386 | |
| 387 inline bool operator==(const StringPiece16& x, const StringPiece16& y) { | 375 inline bool operator==(const StringPiece16& x, const StringPiece16& y) { |
| 388 if (x.size() != y.size()) | 376 if (x.size() != y.size()) |
| 389 return false; | 377 return false; |
| 390 | 378 |
| 391 return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0; | 379 return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0; |
| 392 } | 380 } |
| 393 | 381 |
| 394 inline bool operator!=(const StringPiece16& x, const StringPiece16& y) { | 382 inline bool operator!=(const StringPiece16& x, const StringPiece16& y) { |
| 395 return !(x == y); | 383 return !(x == y); |
| 396 } | 384 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 411 | 399 |
| 412 inline bool operator>=(const StringPiece16& x, const StringPiece16& y) { | 400 inline bool operator>=(const StringPiece16& x, const StringPiece16& y) { |
| 413 return !(x < y); | 401 return !(x < y); |
| 414 } | 402 } |
| 415 | 403 |
| 416 BASE_EXPORT std::ostream& operator<<(std::ostream& o, | 404 BASE_EXPORT std::ostream& operator<<(std::ostream& o, |
| 417 const StringPiece& piece); | 405 const StringPiece& piece); |
| 418 | 406 |
| 419 } // namespace base | 407 } // namespace base |
| 420 | 408 |
| 421 // Hashing --------------------------------------------------------------------- | |
| 422 | |
| 423 // We provide appropriate hash functions so StringPiece and StringPiece16 can | 409 // We provide appropriate hash functions so StringPiece and StringPiece16 can |
| 424 // be used as keys in hash sets and maps. | 410 // be used as keys in hash sets and maps. |
| 425 | 411 |
| 426 // This hash function is copied from base/containers/hash_tables.h. We don't | 412 // 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 | 413 // 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. | 414 // would require the string constructors to be called, which we don't want. |
| 429 #define HASH_STRING_PIECE(StringPieceType, string_piece) \ | 415 #define HASH_STRING_PIECE(StringPieceType, string_piece) \ |
| 430 std::size_t result = 0; \ | 416 std::size_t result = 0; \ |
| 431 for (StringPieceType::const_iterator i = string_piece.begin(); \ | 417 for (StringPieceType::const_iterator i = string_piece.begin(); \ |
| 432 i != string_piece.end(); ++i) \ | 418 i != string_piece.end(); ++i) \ |
| (...skipping 23 matching lines...) Expand all Loading... |
| 456 } | 442 } |
| 457 inline size_t hash_value(const base::StringPiece16& sp16) { | 443 inline size_t hash_value(const base::StringPiece16& sp16) { |
| 458 HASH_STRING_PIECE(base::StringPiece16, sp16); | 444 HASH_STRING_PIECE(base::StringPiece16, sp16); |
| 459 } | 445 } |
| 460 | 446 |
| 461 #endif // COMPILER | 447 #endif // COMPILER |
| 462 | 448 |
| 463 } // namespace BASE_HASH_NAMESPACE | 449 } // namespace BASE_HASH_NAMESPACE |
| 464 | 450 |
| 465 #endif // BASE_STRINGS_STRING_PIECE_H_ | 451 #endif // BASE_STRINGS_STRING_PIECE_H_ |
| OLD | NEW |