4
4
5
5
namespace WTF {
6
6
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
+
7
93
template <typename T>
8
94
class HashSet {
9
95
public:
@@ -89,6 +175,9 @@ namespace WTF {
89
175
90
176
}
91
177
178
+ using WTF::StringView;
179
+ using WTF::StringImpl;
180
+ using WTF::String;
92
181
using WTF::HashSet;
93
182
using WTF::HashMap;
94
183
using WTF::WeakHashSet;
@@ -101,8 +190,37 @@ class RefCounted {
101
190
};
102
191
103
192
RefCounted* object ();
193
+ StringImpl* strImpl ();
194
+ String* str ();
195
+ StringView strView ();
104
196
105
197
void 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
+
106
224
HashSet<RefPtr<RefCounted>> set;
107
225
set.find (*object ());
108
226
set.contains (*object ());
0 commit comments