1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be 3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file. 4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copied from strings/stringpiece.h with modifications 5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// A string-like object that points to a sized piece of memory. 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 8b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// You can use StringPiece as a function or method parameter. A StringPiece 9b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// parameter can receive a double-quoted string literal argument, a "const 10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// char*" argument, a string argument, or a StringPiece argument with no data 11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// copying. Systematic use of StringPiece for arguments reduces data 12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// copies and strlen() calls. 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Prefer passing StringPieces by value: 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// void MyFunction(StringPiece arg); 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// If circumstances require, you may also pass by const reference: 17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// void MyFunction(const StringPiece& arg); // not preferred 18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Both of these have the same lifetime semantics. Passing by value 19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// generates slightly smaller code. For more discussion, Googlers can see 20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// the thread go/stringpiecebyvalue on c-users. 21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifndef BASE_STRINGS_STRING_PIECE_H_ 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define BASE_STRINGS_STRING_PIECE_H_ 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <stddef.h> 26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <iosfwd> 28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <string> 29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/base_export.h" 31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/containers/hash_tables.h" 32cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/logging.h" 33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/strings/string16.h" 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base { 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate <typename STRING_TYPE> class BasicStringPiece; 38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattypedef BasicStringPiece<std::string> StringPiece; 39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattypedef BasicStringPiece<string16> StringPiece16; 40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// internal -------------------------------------------------------------------- 42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Many of the StringPiece functions use different implementations for the 44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 8-bit and 16-bit versions, and we don't want lots of template expansions in 45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// this (very common) header that will slow down compilation. 46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// So here we define overloaded functions called by the StringPiece template. 48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// For those that share an implementation, the two versions will expand to a 49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// template internal to the .cc file. 50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace internal { 51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT void CopyToString(const StringPiece& self, std::string* target); 53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT void CopyToString(const StringPiece16& self, string16* target); 54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT void AppendToString(const StringPiece& self, std::string* target); 56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT void AppendToString(const StringPiece16& self, string16* target); 57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t copy(const StringPiece& self, 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char* buf, 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t n, 61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 62b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t copy(const StringPiece16& self, 63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char16* buf, 64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t n, 65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find(const StringPiece& self, 68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece& s, 69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find(const StringPiece16& self, 71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece16& s, 72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 73b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find(const StringPiece& self, 74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char c, 75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 76b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find(const StringPiece16& self, 77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char16 c, 78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t rfind(const StringPiece& self, 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece& s, 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t rfind(const StringPiece16& self, 84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece16& s, 85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t rfind(const StringPiece& self, 87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char c, 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t rfind(const StringPiece16& self, 90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char16 c, 91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_first_of(const StringPiece& self, 94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece& s, 95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_first_of(const StringPiece16& self, 97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece16& s, 98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 100b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_first_not_of(const StringPiece& self, 101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece& s, 102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_first_not_of(const StringPiece16& self, 104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece16& s, 105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_first_not_of(const StringPiece& self, 107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char c, 108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_first_not_of(const StringPiece16& self, 110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char16 c, 111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_last_of(const StringPiece& self, 114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece& s, 115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_last_of(const StringPiece16& self, 117b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece16& s, 118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_last_of(const StringPiece& self, 120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char c, 121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_last_of(const StringPiece16& self, 123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char16 c, 124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 125b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 126b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_last_not_of(const StringPiece& self, 127b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece& s, 128b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 129b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_last_not_of(const StringPiece16& self, 130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece16& s, 131b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 132b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_last_not_of(const StringPiece16& self, 133b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char16 c, 134b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 135b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT size_t find_last_not_of(const StringPiece& self, 136b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char c, 137b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos); 138b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 139b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT StringPiece substr(const StringPiece& self, 140b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos, 141b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t n); 142b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT StringPiece16 substr(const StringPiece16& self, 143b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t pos, 144b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t n); 145b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 146cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#if DCHECK_IS_ON() 147cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Asserts that begin <= end to catch some errors with iterator usage. 148cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoBASE_EXPORT void AssertIteratorsInOrder(std::string::const_iterator begin, 149cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko std::string::const_iterator end); 150cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoBASE_EXPORT void AssertIteratorsInOrder(string16::const_iterator begin, 151cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko string16::const_iterator end); 152cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#endif 153cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko 154b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace internal 155b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 156b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// BasicStringPiece ------------------------------------------------------------ 157b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 158b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Defines the types, methods, operators, and data members common to both 159b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// StringPiece and StringPiece16. Do not refer to this class directly, but 160b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// rather to BasicStringPiece, StringPiece, or StringPiece16. 161b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 162b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// This is templatized by string class type rather than character type, so 163b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// BasicStringPiece<std::string> or BasicStringPiece<base::string16>. 164b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate <typename STRING_TYPE> class BasicStringPiece { 165b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public: 166b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Standard STL container boilerplate. 167b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat typedef size_t size_type; 168b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat typedef typename STRING_TYPE::value_type value_type; 169b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat typedef const value_type* pointer; 170b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat typedef const value_type& reference; 171b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat typedef const value_type& const_reference; 172b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat typedef ptrdiff_t difference_type; 173b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat typedef const value_type* const_iterator; 174b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 175b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 176b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat static const size_type npos; 177b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 178b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public: 179b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // We provide non-explicit singleton constructors so users can pass 180b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // in a "const char*" or a "string" wherever a "StringPiece" is 181b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // expected (likewise for char16, string16, StringPiece16). 182b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat BasicStringPiece() : ptr_(NULL), length_(0) {} 183b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat BasicStringPiece(const value_type* str) 184b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : ptr_(str), 185b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {} 186b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat BasicStringPiece(const STRING_TYPE& str) 187b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : ptr_(str.data()), length_(str.size()) {} 188b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat BasicStringPiece(const value_type* offset, size_type len) 189b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : ptr_(offset), length_(len) {} 190b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat BasicStringPiece(const typename STRING_TYPE::const_iterator& begin, 191cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko const typename STRING_TYPE::const_iterator& end) { 192cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#if DCHECK_IS_ON() 193cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // This assertion is done out-of-line to avoid bringing in logging.h and 194cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // instantiating logging macros for every instantiation. 195cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko internal::AssertIteratorsInOrder(begin, end); 196cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#endif 197cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko length_ = static_cast<size_t>(std::distance(begin, end)); 198cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko 199cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // The length test before assignment is to avoid dereferencing an iterator 200cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // that may point to the end() of a string. 201cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko ptr_ = length_ > 0 ? &*begin : nullptr; 202cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko } 203b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 204b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // data() may return a pointer to a buffer with embedded NULs, and the 205b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // returned buffer may or may not be null terminated. Therefore it is 206b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // typically a mistake to pass data() to a routine that expects a NUL 207b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // terminated string. 208b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const value_type* data() const { return ptr_; } 209b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type size() const { return length_; } 210b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type length() const { return length_; } 211b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool empty() const { return length_ == 0; } 212b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 213b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void clear() { 214b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ptr_ = NULL; 215b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat length_ = 0; 216b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 217b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void set(const value_type* data, size_type len) { 218b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ptr_ = data; 219b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat length_ = len; 220b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 221b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void set(const value_type* str) { 222b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ptr_ = str; 223b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat length_ = str ? STRING_TYPE::traits_type::length(str) : 0; 224b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 225b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 226b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat value_type operator[](size_type i) const { return ptr_[i]; } 227b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 228b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void remove_prefix(size_type n) { 229b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ptr_ += n; 230b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat length_ -= n; 231b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 232b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 233b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void remove_suffix(size_type n) { 234b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat length_ -= n; 235b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 236b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 237b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int compare(const BasicStringPiece<STRING_TYPE>& x) const { 238b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int r = wordmemcmp( 239b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_)); 240b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (r == 0) { 241b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (length_ < x.length_) r = -1; 242b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat else if (length_ > x.length_) r = +1; 243b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 244b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return r; 245b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 246b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 247b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat STRING_TYPE as_string() const { 248b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // std::string doesn't like to take a NULL pointer even with a 0 size. 249b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return empty() ? STRING_TYPE() : STRING_TYPE(data(), size()); 250b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 251b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 252b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const_iterator begin() const { return ptr_; } 253b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const_iterator end() const { return ptr_ + length_; } 254b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const_reverse_iterator rbegin() const { 255b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return const_reverse_iterator(ptr_ + length_); 256b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 257b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const_reverse_iterator rend() const { 258b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return const_reverse_iterator(ptr_); 259b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 260b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 261b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type max_size() const { return length_; } 262b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type capacity() const { return length_; } 263b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 264b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat static int wordmemcmp(const value_type* p, 265b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const value_type* p2, 266b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type N) { 267b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return STRING_TYPE::traits_type::compare(p, p2, N); 268b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 269b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 270b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Sets the value of the given string target type to be the current string. 271b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // This saves a temporary over doing |a = b.as_string()| 272b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void CopyToString(STRING_TYPE* target) const { 273b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat internal::CopyToString(*this, target); 274b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 275b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 276b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void AppendToString(STRING_TYPE* target) const { 277b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat internal::AppendToString(*this, target); 278b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 279b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 280b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type copy(value_type* buf, size_type n, size_type pos = 0) const { 281b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::copy(*this, buf, n, pos); 282b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 283b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 284b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Does "this" start with "x" 285b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool starts_with(const BasicStringPiece& x) const { 286b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ((this->length_ >= x.length_) && 287b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat (wordmemcmp(this->ptr_, x.ptr_, x.length_) == 0)); 288b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 289b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 290b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Does "this" end with "x" 291b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool ends_with(const BasicStringPiece& x) const { 292b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ((this->length_ >= x.length_) && 293b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat (wordmemcmp(this->ptr_ + (this->length_-x.length_), 294b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat x.ptr_, x.length_) == 0)); 295b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 296b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 297b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // find: Search for a character or substring at a given offset. 298b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type find(const BasicStringPiece<STRING_TYPE>& s, 299b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type pos = 0) const { 300b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::find(*this, s, pos); 301b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 302b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type find(value_type c, size_type pos = 0) const { 303b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::find(*this, c, pos); 304b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 305b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 306b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // rfind: Reverse find. 307b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type rfind(const BasicStringPiece& s, 308b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type pos = BasicStringPiece::npos) const { 309b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::rfind(*this, s, pos); 310b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 311b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type rfind(value_type c, size_type pos = BasicStringPiece::npos) const { 312b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::rfind(*this, c, pos); 313b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 314b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 315b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // find_first_of: Find the first occurence of one of a set of characters. 316b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type find_first_of(const BasicStringPiece& s, 317b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type pos = 0) const { 318b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::find_first_of(*this, s, pos); 319b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 320b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type find_first_of(value_type c, size_type pos = 0) const { 321b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return find(c, pos); 322b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 323b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 324b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // find_first_not_of: Find the first occurence not of a set of characters. 325b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type find_first_not_of(const BasicStringPiece& s, 326b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type pos = 0) const { 327b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::find_first_not_of(*this, s, pos); 328b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 329b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type find_first_not_of(value_type c, size_type pos = 0) const { 330b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::find_first_not_of(*this, c, pos); 331b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 332b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 333b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // find_last_of: Find the last occurence of one of a set of characters. 334b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type find_last_of(const BasicStringPiece& s, 335b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type pos = BasicStringPiece::npos) const { 336b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::find_last_of(*this, s, pos); 337b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 338b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type find_last_of(value_type c, 339b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type pos = BasicStringPiece::npos) const { 340b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return rfind(c, pos); 341b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 342b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 343b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // find_last_not_of: Find the last occurence not of a set of characters. 344b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type find_last_not_of(const BasicStringPiece& s, 345b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type pos = BasicStringPiece::npos) const { 346b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::find_last_not_of(*this, s, pos); 347b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 348b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type find_last_not_of(value_type c, 349b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type pos = BasicStringPiece::npos) const { 350b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::find_last_not_of(*this, c, pos); 351b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 352b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 353b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // substr. 354b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat BasicStringPiece substr(size_type pos, 355b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type n = BasicStringPiece::npos) const { 356b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return internal::substr(*this, pos, n); 357b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 358b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 359b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat protected: 360b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const value_type* ptr_; 361b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_type length_; 362b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 363b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 364b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate <typename STRING_TYPE> 365b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst typename BasicStringPiece<STRING_TYPE>::size_type 366b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBasicStringPiece<STRING_TYPE>::npos = 367b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat typename BasicStringPiece<STRING_TYPE>::size_type(-1); 368b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 369b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// MSVC doesn't like complex extern templates and DLLs. 370b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if !defined(COMPILER_MSVC) 371b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratextern template class BASE_EXPORT BasicStringPiece<std::string>; 372b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratextern template class BASE_EXPORT BasicStringPiece<string16>; 373b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 374b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 375b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// StingPiece operators -------------------------------------------------------- 376b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 377b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); 378b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 379b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool operator!=(const StringPiece& x, const StringPiece& y) { 380b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return !(x == y); 381b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 382b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 383b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool operator<(const StringPiece& x, const StringPiece& y) { 384b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const int r = StringPiece::wordmemcmp( 385b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); 386b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ((r < 0) || ((r == 0) && (x.size() < y.size()))); 387b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 388b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 389b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool operator>(const StringPiece& x, const StringPiece& y) { 390b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return y < x; 391b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 392b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 393b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool operator<=(const StringPiece& x, const StringPiece& y) { 394b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return !(x > y); 395b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 396b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 397b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool operator>=(const StringPiece& x, const StringPiece& y) { 398b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return !(x < y); 399b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 400b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 401b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// StringPiece16 operators ----------------------------------------------------- 402b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 403b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool operator==(const StringPiece16& x, const StringPiece16& y) { 404b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (x.size() != y.size()) 405b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 406b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 407b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0; 408b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 409b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 410b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool operator!=(const StringPiece16& x, const StringPiece16& y) { 411b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return !(x == y); 412b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 413b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 414b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool operator<(const StringPiece16& x, const StringPiece16& y) { 415b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const int r = StringPiece16::wordmemcmp( 416b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); 417b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ((r < 0) || ((r == 0) && (x.size() < y.size()))); 418b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 419b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 420b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool operator>(const StringPiece16& x, const StringPiece16& y) { 421b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return y < x; 422b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 423b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 424b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool operator<=(const StringPiece16& x, const StringPiece16& y) { 425b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return !(x > y); 426b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 427b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 428b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool operator>=(const StringPiece16& x, const StringPiece16& y) { 429b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return !(x < y); 430b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 431b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 432b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratBASE_EXPORT std::ostream& operator<<(std::ostream& o, 433b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const StringPiece& piece); 434b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 435b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace base 436b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 437b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Hashing --------------------------------------------------------------------- 438b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 439b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// We provide appropriate hash functions so StringPiece and StringPiece16 can 440b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// be used as keys in hash sets and maps. 441b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 442b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// This hash function is copied from base/containers/hash_tables.h. We don't 443b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// use the ones already defined for string and string16 directly because it 444b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// would require the string constructors to be called, which we don't want. 445b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define HASH_STRING_PIECE(StringPieceType, string_piece) \ 446b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::size_t result = 0; \ 447b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat for (StringPieceType::const_iterator i = string_piece.begin(); \ 448b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat i != string_piece.end(); ++i) \ 449b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat result = (result * 131) + *i; \ 450b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return result; \ 451b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 452b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace BASE_HASH_NAMESPACE { 453b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 454b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate<> 455b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstruct hash<base::StringPiece> { 456b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::size_t operator()(const base::StringPiece& sp) const { 457b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat HASH_STRING_PIECE(base::StringPiece, sp); 458b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 459b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 460b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate<> 461b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstruct hash<base::StringPiece16> { 462b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::size_t operator()(const base::StringPiece16& sp16) const { 463b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat HASH_STRING_PIECE(base::StringPiece16, sp16); 464b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 465b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 466b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 467b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace BASE_HASH_NAMESPACE 468b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 469b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif // BASE_STRINGS_STRING_PIECE_H_ 470