44
55namespace WTF {
66
7+ constexpr unsigned long notFound = static_cast <unsigned long >(-1 );
8+
9+ class String ;
10+ class StringImpl ;
11+
12+ class StringView {
13+ public:
14+ StringView (const String&);
15+ private:
16+ RefPtr<StringImpl> m_impl;
17+ };
18+
19+ class StringImpl {
20+ public:
21+ void ref () const { ++m_refCount; }
22+ void deref () const {
23+ if (!--m_refCount)
24+ delete this ;
25+ }
26+
27+ static constexpr unsigned s_flagIs8Bit = 1u << 0 ;
28+ bool is8Bit () const { return m_hashAndFlags & s_flagIs8Bit; }
29+ const char * characters8 () const { return m_char8; }
30+ const short * characters16 () const { return m_char16; }
31+ unsigned length () const { return m_length; }
32+ Ref<StringImpl> substring (unsigned position, unsigned length) const ;
33+
34+ unsigned long find (char ) const ;
35+ unsigned long find (StringView) const ;
36+ unsigned long contains (StringView) const ;
37+ unsigned long findIgnoringASCIICase (StringView) const ;
38+
39+ bool startsWith (StringView) const ;
40+ bool startsWithIgnoringASCIICase (StringView) const ;
41+ bool endsWith (StringView) const ;
42+ bool endsWithIgnoringASCIICase (StringView) const ;
43+
44+ private:
45+ mutable unsigned m_refCount { 0 };
46+ unsigned m_length { 0 };
47+ union {
48+ const char * m_char8;
49+ const short * m_char16;
50+ };
51+ unsigned m_hashAndFlags { 0 };
52+ };
53+
54+ class String {
55+ public:
56+ String () = default ;
57+ String (StringImpl& impl) : m_impl(&impl) { }
58+ String (StringImpl* impl) : m_impl(impl) { }
59+ String (Ref<StringImpl>&& impl) : m_impl(impl.get()) { }
60+ StringImpl* impl () { return m_impl.get (); }
61+ unsigned length () const { return m_impl ? m_impl->length () : 0 ; }
62+ const char * characters8 () const { return m_impl ? m_impl->characters8 () : nullptr ; }
63+ const short * characters16 () const { return m_impl ? m_impl->characters16 () : nullptr ; }
64+
65+ bool is8Bit () const { return !m_impl || m_impl->is8Bit (); }
66+
67+ unsigned long find (char character) const { return m_impl ? m_impl->find (character) : notFound; }
68+ unsigned long find (StringView str) const { return m_impl ? m_impl->find (str) : notFound; }
69+ unsigned long findIgnoringASCIICase (StringView) const ;
70+
71+ bool contains (char character) const { return find (character) != notFound; }
72+ bool contains (StringView) const ;
73+ bool containsIgnoringASCIICase (StringView) const ;
74+
75+ bool startsWith (StringView) const ;
76+ bool startsWithIgnoringASCIICase (StringView) const ;
77+ bool endsWith (StringView) const ;
78+ bool endsWithIgnoringASCIICase (StringView) const ;
79+
80+ String substring (unsigned position, unsigned length) const
81+ {
82+ if (!m_impl)
83+ return { };
84+ if (!position && length >= m_impl->length ())
85+ return *this ;
86+ return m_impl->substring (position, length);
87+ }
88+
89+ private:
90+ RefPtr<StringImpl> m_impl;
91+ };
92+
793 template <typename T>
894 class HashSet {
995 public:
@@ -89,6 +175,9 @@ namespace WTF {
89175
90176}
91177
178+ using WTF::StringView;
179+ using WTF::StringImpl;
180+ using WTF::String;
92181using WTF::HashSet;
93182using WTF::HashMap;
94183using WTF::WeakHashSet;
@@ -101,8 +190,37 @@ class RefCounted {
101190};
102191
103192RefCounted* object ();
193+ StringImpl* strImpl ();
194+ String* str ();
195+ StringView strView ();
104196
105197void test () {
198+ strImpl ()->is8Bit ();
199+ strImpl ()->characters8 ();
200+ strImpl ()->characters16 ();
201+ strImpl ()->length ();
202+ strImpl ()->substring (2 , 4 );
203+ strImpl ()->find (strView ());
204+ strImpl ()->contains (strView ());
205+ strImpl ()->findIgnoringASCIICase (strView ());
206+ strImpl ()->startsWith (strView ());
207+ strImpl ()->startsWithIgnoringASCIICase (strView ());
208+ strImpl ()->endsWith (strView ());
209+ strImpl ()->endsWithIgnoringASCIICase (strView ());
210+
211+ str ()->is8Bit ();
212+ str ()->characters8 ();
213+ str ()->characters16 ();
214+ str ()->length ();
215+ str ()->substring (2 , 4 );
216+ str ()->find (strView ());
217+ str ()->contains (strView ());
218+ str ()->findIgnoringASCIICase (strView ());
219+ str ()->startsWith (strView ());
220+ str ()->startsWithIgnoringASCIICase (strView ());
221+ str ()->endsWith (strView ());
222+ str ()->endsWithIgnoringASCIICase (strView ());
223+
106224 HashSet<RefPtr<RefCounted>> set;
107225 set.find (*object ());
108226 set.contains (*object ());
0 commit comments