Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(726)

Unified Diff: third_party/WebKit/Source/wtf/text/StringConcatenate.h

Issue 2315853002: Massively simplify WTF's StringConcatenate (Closed)
Patch Set: missing inlines. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/wtf/BUILD.gn ('k') | third_party/WebKit/Source/wtf/text/StringConcatenate.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/wtf/text/StringConcatenate.h
diff --git a/third_party/WebKit/Source/wtf/text/StringConcatenate.h b/third_party/WebKit/Source/wtf/text/StringConcatenate.h
index b9c6d948a08e6e23d2ef7e9f5f4fb1e90adab565..a6d5e408a6f770eb834cd00caf2886269bb9a7e3 100644
--- a/third_party/WebKit/Source/wtf/text/StringConcatenate.h
+++ b/third_party/WebKit/Source/wtf/text/StringConcatenate.h
@@ -27,331 +27,251 @@
#define StringConcatenate_h
#include "wtf/Allocator.h"
+#include "wtf/text/StringBuffer.h"
#include <string.h>
#ifndef WTFString_h
#include "wtf/text/AtomicString.h"
#endif
-// This macro is helpful for testing how many intermediate Strings are created while evaluating an
-// expression containing operator+.
-#ifndef WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING
-#define WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING() ((void)0)
-#endif
-
namespace WTF {
template<typename StringType>
class StringTypeAdapter {
- DISALLOW_NEW();
+ STACK_ALLOCATED();
};
template<>
-class StringTypeAdapter<char> {
- DISALLOW_NEW();
+class StringTypeAdapter<LChar> {
+ STACK_ALLOCATED();
public:
- StringTypeAdapter<char>(char buffer)
- : m_buffer(buffer)
- {
- }
-
- unsigned length() { return 1; }
+ explicit StringTypeAdapter<LChar>(LChar buffer)
+ : m_buffer(buffer) {}
- bool is8Bit() { return true; }
+ unsigned length() const { return 1; }
+ bool is8Bit() const { return true; }
- void writeTo(LChar* destination)
- {
- *destination = m_buffer;
- }
-
- void writeTo(UChar* destination) { *destination = m_buffer; }
+ void writeTo(LChar* destination) const { *destination = m_buffer; }
+ void writeTo(UChar* destination) const { *destination = m_buffer; }
private:
- unsigned char m_buffer;
+ const LChar m_buffer;
};
template<>
-class StringTypeAdapter<LChar> {
- DISALLOW_NEW();
+class StringTypeAdapter<char> : public StringTypeAdapter<LChar> {
+ STACK_ALLOCATED();
public:
- StringTypeAdapter<LChar>(LChar buffer)
- : m_buffer(buffer)
- {
- }
-
- unsigned length() { return 1; }
-
- bool is8Bit() { return true; }
-
- void writeTo(LChar* destination)
- {
- *destination = m_buffer;
- }
-
- void writeTo(UChar* destination) { *destination = m_buffer; }
-
-private:
- LChar m_buffer;
+ explicit StringTypeAdapter<char>(char buffer)
+ : StringTypeAdapter<LChar>(buffer) {}
};
template<>
class StringTypeAdapter<UChar> {
- DISALLOW_NEW();
+ STACK_ALLOCATED();
public:
- StringTypeAdapter<UChar>(UChar buffer)
- : m_buffer(buffer)
- {
- }
-
- unsigned length() { return 1; }
+ explicit StringTypeAdapter<UChar>(UChar buffer)
+ : m_buffer(buffer) {}
- bool is8Bit() { return m_buffer <= 0xff; }
+ unsigned length() const { return 1; }
+ bool is8Bit() const { return m_buffer <= 0xff; }
- void writeTo(LChar* destination)
+ void writeTo(LChar* destination) const
{
- ASSERT(is8Bit());
+ DCHECK(is8Bit());
*destination = static_cast<LChar>(m_buffer);
}
- void writeTo(UChar* destination) { *destination = m_buffer; }
+ void writeTo(UChar* destination) const { *destination = m_buffer; }
private:
- UChar m_buffer;
+ const UChar m_buffer;
};
template<>
-class WTF_EXPORT StringTypeAdapter<char*> {
- DISALLOW_NEW();
+class WTF_EXPORT StringTypeAdapter<const UChar*> {
+ STACK_ALLOCATED();
public:
- StringTypeAdapter<char*>(char* buffer)
- : m_buffer(buffer)
- , m_length(strlen(buffer))
- {
- }
-
- unsigned length() { return m_length; }
+ explicit StringTypeAdapter(const UChar* buffer);
- bool is8Bit() { return true; }
+ unsigned length() const { return m_length; }
- void writeTo(LChar* destination);
+ bool is8Bit() const { return false; }
- void writeTo(UChar* destination);
+ void writeTo(LChar*) const { RELEASE_NOTREACHED(); }
+ void writeTo(UChar* destination) const;
private:
- const char* m_buffer;
- unsigned m_length;
+ const UChar* m_buffer;
+ const unsigned m_length;
};
template<>
-class WTF_EXPORT StringTypeAdapter<LChar*> {
- DISALLOW_NEW();
+class WTF_EXPORT StringTypeAdapter<const LChar*> {
+ STACK_ALLOCATED();
public:
- StringTypeAdapter<LChar*>(LChar* buffer);
-
- unsigned length() { return m_length; }
+ explicit StringTypeAdapter(const LChar* buffer)
+ : m_buffer(buffer)
+ , m_length(strlen(reinterpret_cast<const char*>(buffer))) {}
- bool is8Bit() { return true; }
+ explicit StringTypeAdapter(const char* buffer)
+ : StringTypeAdapter(reinterpret_cast<const LChar*>(buffer)) {}
- void writeTo(LChar* destination);
+ unsigned length() const { return m_length; }
+ bool is8Bit() const { return true; }
- void writeTo(UChar* destination);
+ void writeTo(LChar* destination) const;
+ void writeTo(UChar* destination) const;
private:
const LChar* m_buffer;
- unsigned m_length;
+ const unsigned m_length;
};
template<>
-class WTF_EXPORT StringTypeAdapter<const UChar*> {
- DISALLOW_NEW();
+class WTF_EXPORT StringTypeAdapter<String> {
+ STACK_ALLOCATED();
public:
- StringTypeAdapter(const UChar* buffer);
-
- unsigned length() { return m_length; }
+ explicit StringTypeAdapter(const String& string)
+ : m_buffer(string) {}
- bool is8Bit() { return false; }
-
- void writeTo(LChar*)
- {
- RELEASE_ASSERT(false);
- }
+ unsigned length() const { return m_buffer.length(); }
+ bool is8Bit() const { return m_buffer.isNull() || m_buffer.is8Bit(); }
- void writeTo(UChar* destination);
+ void writeTo(LChar* destination) const;
+ void writeTo(UChar* destination) const;
private:
- const UChar* m_buffer;
- unsigned m_length;
+ const String m_buffer;
Yuta Kitamura 2016/09/07 10:25:39 I don't think store-as-value is an improvement, un
esprehn 2016/09/07 16:21:26 Note that the StringAppend class has always stored
Jeffrey Yasskin 2016/09/07 18:53:01 LLVM has a type called "Twine" that stores referen
Yuta Kitamura 2016/09/08 05:09:31 Ah sorry, I wasn't aware the tests were disabled a
};
template<>
-class WTF_EXPORT StringTypeAdapter<const char*> {
- DISALLOW_NEW();
+class StringTypeAdapter<AtomicString> : public StringTypeAdapter<String> {
+ STACK_ALLOCATED();
public:
- StringTypeAdapter<const char*>(const char* buffer);
-
- unsigned length() { return m_length; }
-
- bool is8Bit() { return true; }
-
- void writeTo(LChar* destination);
-
- void writeTo(UChar* destination);
+ explicit StringTypeAdapter(const AtomicString& string)
+ : StringTypeAdapter<String>(string) {}
+};
-private:
- const char* m_buffer;
- unsigned m_length;
+namespace internal {
+WTF_EXPORT unsigned checkedAddLength(unsigned length1, unsigned length2);
};
-template<>
-class WTF_EXPORT StringTypeAdapter<const LChar*> {
- DISALLOW_NEW();
+template<typename StringType1, typename StringType2>
+class StringAppend final {
+ STACK_ALLOCATED();
public:
- StringTypeAdapter<const LChar*>(const LChar* buffer);
+ StringAppend(StringType1 string1, StringType2 string2)
+ : m_adapter1(string1)
+ , m_adapter2(string2) {}
- unsigned length() { return m_length; }
+ operator String() const { return toString(); }
+ operator AtomicString() const { return AtomicString(toString()); }
- bool is8Bit() { return true; }
+ unsigned length() const { return internal::checkedAddLength(m_adapter1.length(), m_adapter2.length()); }
+ bool is8Bit() const { return m_adapter1.is8Bit() && m_adapter2.is8Bit(); }
- void writeTo(LChar* destination);
-
- void writeTo(UChar* destination);
-
-private:
- const LChar* m_buffer;
- unsigned m_length;
-};
-
-template<>
-class WTF_EXPORT StringTypeAdapter<Vector<char>> {
- DISALLOW_NEW();
-public:
- StringTypeAdapter<Vector<char>>(const Vector<char>& buffer)
- : m_buffer(buffer)
+ void writeTo(LChar* destination) const
{
+ DCHECK(is8Bit());
+ m_adapter1.writeTo(destination);
+ m_adapter2.writeTo(destination + m_adapter1.length());
}
- size_t length() { return m_buffer.size(); }
-
- bool is8Bit() { return true; }
-
- void writeTo(LChar* destination);
-
- void writeTo(UChar* destination);
-
-private:
- const Vector<char>& m_buffer;
-};
-
-template<>
-class StringTypeAdapter<Vector<LChar>> {
- DISALLOW_NEW();
-public:
- StringTypeAdapter<Vector<LChar>>(const Vector<LChar>& buffer)
- : m_buffer(buffer)
+ void writeTo(UChar* destination) const
{
+ m_adapter1.writeTo(destination);
+ m_adapter2.writeTo(destination + m_adapter1.length());
}
- size_t length() { return m_buffer.size(); }
-
- bool is8Bit() { return true; }
-
- void writeTo(LChar* destination);
-
- void writeTo(UChar* destination);
-
private:
- const Vector<LChar>& m_buffer;
-};
-
-template<>
-class WTF_EXPORT StringTypeAdapter<String> {
- DISALLOW_NEW();
-public:
- StringTypeAdapter<String>(const String& string)
- : m_buffer(string)
+ PassRefPtr<StringImpl> toString() const
{
+ if (is8Bit()) {
+ StringBuffer<LChar> buffer(length());
+ writeTo(buffer.characters());
+ return buffer.release();
+ }
+ StringBuffer<UChar> buffer(length());
+ writeTo(buffer.characters());
+ return buffer.release();
}
- unsigned length() { return m_buffer.length(); }
+ StringTypeAdapter<StringType1> m_adapter1;
+ StringTypeAdapter<StringType2> m_adapter2;
+};
- bool is8Bit() { return m_buffer.isNull() || m_buffer.is8Bit(); }
+template<typename StringType1, typename StringType2>
+class StringTypeAdapter<StringAppend<StringType1, StringType2>> {
+ STACK_ALLOCATED();
+public:
+ explicit StringTypeAdapter(const StringAppend<StringType1, StringType2>& buffer)
+ : m_buffer(buffer) {}
- void writeTo(LChar* destination);
+ unsigned length() const { return m_buffer.length(); }
+ bool is8Bit() const { return m_buffer.is8Bit(); }
- void writeTo(UChar* destination);
+ void writeTo(LChar* destination) const { m_buffer.writeTo(destination); }
+ void writeTo(UChar* destination) const { m_buffer.writeTo(destination); }
private:
- const String& m_buffer;
+ const StringAppend<StringType1, StringType2> m_buffer;
};
-template<>
-class StringTypeAdapter<AtomicString> {
- DISALLOW_NEW();
-public:
- StringTypeAdapter<AtomicString>(const AtomicString& string)
- : m_adapter(string.getString())
- {
- }
+inline StringAppend<const LChar*, String> operator+(const char* string1, const String& string2)
+{
+ return StringAppend<const LChar*, String>(reinterpret_cast<const LChar*>(string1), string2);
+}
- unsigned length() { return m_adapter.length(); }
+inline StringAppend<const LChar*, AtomicString> operator+(const char* string1, const AtomicString& string2)
+{
+ return StringAppend<const LChar*, AtomicString>(reinterpret_cast<const LChar*>(string1), string2);
+}
- bool is8Bit() { return m_adapter.is8Bit(); }
+template<typename U, typename V>
+inline StringAppend<const LChar*, StringAppend<U, V>> operator+(const char* string1, const StringAppend<U, V>& string2)
+{
+ return StringAppend<const LChar*, StringAppend<U, V>>(reinterpret_cast<const LChar*>(string1), string2);
+}
- void writeTo(LChar* destination) { m_adapter.writeTo(destination); }
- void writeTo(UChar* destination) { m_adapter.writeTo(destination); }
+inline StringAppend<const UChar*, String> operator+(const UChar* string1, const String& string2)
+{
+ return StringAppend<const UChar*, String>(string1, string2);
+}
-private:
- StringTypeAdapter<String> m_adapter;
-};
+inline StringAppend<const UChar*, AtomicString> operator+(const UChar* string1, const AtomicString& string2)
+{
+ return StringAppend<const UChar*, AtomicString>(string1, string2);
+}
-inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow)
+template<typename U, typename V>
+inline StringAppend<const UChar*, StringAppend<U, V>> operator+(const UChar* string1, const StringAppend<U, V>& string2)
{
- unsigned oldTotal = total;
- total = oldTotal + addend;
- if (total < oldTotal)
- overflow = true;
+ return StringAppend<const UChar*, StringAppend<U, V>>(string1, string2);
}
-template<typename StringType1, typename StringType2>
-PassRefPtr<StringImpl> makeString(StringType1 string1, StringType2 string2)
+inline StringAppend<String, const LChar*> operator+(const String& string1, const char* string2)
{
- StringTypeAdapter<StringType1> adapter1(string1);
- StringTypeAdapter<StringType2> adapter2(string2);
-
- bool overflow = false;
- unsigned length = adapter1.length();
- sumWithOverflow(length, adapter2.length(), overflow);
- if (overflow)
- return nullptr;
-
- if (adapter1.is8Bit() && adapter2.is8Bit()) {
- LChar* buffer;
- RefPtr<StringImpl> resultImpl = StringImpl::createUninitialized(length, buffer);
- if (!resultImpl)
- return nullptr;
-
- LChar* result = buffer;
- adapter1.writeTo(result);
- result += adapter1.length();
- adapter2.writeTo(result);
-
- return resultImpl.release();
- }
+ return StringAppend<String, const LChar*>(string1, reinterpret_cast<const LChar*>(string2));
+}
- UChar* buffer;
- RefPtr<StringImpl> resultImpl = StringImpl::createUninitialized(length, buffer);
- if (!resultImpl)
- return nullptr;
+template<typename T>
+inline StringAppend<String, T> operator+(const String& string1, T string2)
+{
+ return StringAppend<String, T>(string1, string2);
+}
- UChar* result = buffer;
- adapter1.writeTo(result);
- result += adapter1.length();
- adapter2.writeTo(result);
+template<typename U, typename V>
+inline StringAppend<StringAppend<U, V>, const LChar*> operator+(const StringAppend<U, V>& string1, const char* string2)
+{
+ return StringAppend<StringAppend<U, V>, const LChar*>(string1, reinterpret_cast<const LChar*>(string2));
+}
- return resultImpl.release();
+template<typename U, typename V, typename W>
+inline StringAppend<StringAppend<U, V>, W> operator+(const StringAppend<U, V>& string1, W string2)
+{
+ return StringAppend<StringAppend<U, V>, W>(string1, string2);
}
} // namespace WTF
-
-#include "wtf/text/StringOperators.h"
#endif
« no previous file with comments | « third_party/WebKit/Source/wtf/BUILD.gn ('k') | third_party/WebKit/Source/wtf/text/StringConcatenate.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698