Index: src/inspector/string-16.h |
diff --git a/src/inspector/string-16.h b/src/inspector/string-16.h |
index 6dc7759de059e1151731da35177c05a47826540f..360ec93864346fcf2ef0dce9fc58bb8fcfe88242 100644 |
--- a/src/inspector/string-16.h |
+++ b/src/inspector/string-16.h |
@@ -21,7 +21,10 @@ class String16 { |
static const size_t kNotFound = static_cast<size_t>(-1); |
String16() {} |
- String16(const String16& other) : m_impl(other.m_impl) {} |
+ String16(const String16& other) |
+ : m_impl(other.m_impl), hash_code(other.hash_code) {} |
+ String16(const String16&& other) |
+ : m_impl(std::move(other.m_impl)), hash_code(other.hash_code) {} |
String16(const UChar* characters, size_t size) : m_impl(characters, size) {} |
String16(const UChar* characters) // NOLINT(runtime/explicit) |
: m_impl(characters) {} |
@@ -31,6 +34,18 @@ class String16 { |
m_impl.resize(size); |
for (size_t i = 0; i < size; ++i) m_impl[i] = characters[i]; |
} |
+ explicit String16(const std::basic_string<UChar>& impl) : m_impl(impl) {} |
+ |
+ String16& operator=(const String16& other) { |
+ m_impl = other.m_impl; |
+ hash_code = other.hash_code; |
+ return *this; |
+ } |
+ String16& operator=(String16&& other) { |
+ m_impl = std::move(other.m_impl); |
+ hash_code = other.hash_code; |
+ return *this; |
+ } |
static String16 fromInteger(int); |
static String16 fromInteger(size_t); |
@@ -52,51 +67,53 @@ class String16 { |
size_t reverseFind(const String16& str, size_t start = UINT_MAX) const { |
return m_impl.rfind(str.m_impl, start); |
} |
- void swap(String16& other) { m_impl.swap(other.m_impl); } |
+ size_t find(UChar c, size_t start = 0) const { return m_impl.find(c, start); } |
+ size_t reverseFind(UChar c, size_t start = UINT_MAX) const { |
+ return m_impl.rfind(c, start); |
+ } |
+ void swap(String16& other) { |
+ m_impl.swap(other.m_impl); |
+ std::swap(hash_code, other.hash_code); |
+ } |
// Convenience methods. |
std::string utf8() const; |
static String16 fromUTF8(const char* stringStart, size_t length); |
- const std::basic_string<UChar>& impl() const { return m_impl; } |
- explicit String16(const std::basic_string<UChar>& impl) : m_impl(impl) {} |
- |
std::size_t hash() const { |
- if (!has_hash) { |
- size_t hash = 0; |
- for (size_t i = 0; i < length(); ++i) hash = 31 * hash + m_impl[i]; |
- hash_code = hash; |
- has_hash = true; |
+ if (!hash_code) { |
+ for (char c : m_impl) hash_code = 31 * hash_code + c; |
+ // Map hash code 0 to 1. This double the number of hash collisions for 1, |
+ // but avoids recomputing the hash code. |
+ if (!hash_code) ++hash_code; |
} |
return hash_code; |
} |
+ inline bool operator==(const String16& other) const { |
+ return m_impl == other.m_impl; |
+ } |
+ inline bool operator<(const String16& other) const { |
+ return m_impl < other.m_impl; |
+ } |
+ inline bool operator!=(const String16& other) const { |
+ return m_impl != other.m_impl; |
+ } |
+ inline String16 operator+(const String16& other) const { |
+ return String16(m_impl + other.m_impl); |
+ } |
+ |
+ // Defined later, since it uses the String16Builder. |
+ template <typename... T> |
+ static String16 concat(T... args); |
+ |
private: |
std::basic_string<UChar> m_impl; |
- mutable bool has_hash = false; |
mutable std::size_t hash_code = 0; |
}; |
-inline bool operator==(const String16& a, const String16& b) { |
- return a.impl() == b.impl(); |
-} |
-inline bool operator<(const String16& a, const String16& b) { |
- return a.impl() < b.impl(); |
-} |
-inline bool operator!=(const String16& a, const String16& b) { |
- return a.impl() != b.impl(); |
-} |
-inline bool operator==(const String16& a, const char* b) { |
- return a.impl() == String16(b).impl(); |
-} |
-inline String16 operator+(const String16& a, const char* b) { |
- return String16(a.impl() + String16(b).impl()); |
-} |
inline String16 operator+(const char* a, const String16& b) { |
- return String16(String16(a).impl() + b.impl()); |
-} |
-inline String16 operator+(const String16& a, const String16& b) { |
- return String16(a.impl() + b.impl()); |
+ return String16(a) + b; |
} |
class String16Builder { |
@@ -107,13 +124,29 @@ class String16Builder { |
void append(char); |
void append(const UChar*, size_t); |
void append(const char*, size_t); |
+ void appendNumber(int); |
+ void appendNumber(size_t); |
String16 toString(); |
void reserveCapacity(size_t); |
+ template <typename T, typename... R> |
+ void appendAll(T first, R... rest) { |
+ append(first); |
+ appendAll(rest...); |
+ } |
+ void appendAll() {} |
+ |
private: |
std::vector<UChar> m_buffer; |
}; |
+template <typename... T> |
+String16 String16::concat(T... args) { |
+ String16Builder builder; |
+ builder.appendAll(args...); |
+ return builder.toString(); |
+} |
+ |
} // namespace v8_inspector |
#if !defined(__APPLE__) || defined(_LIBCPP_VERSION) |