mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
Core: String::Find(String) optimizations, refactoring
git-svn-id: svn://ultimatepp.org/upp/trunk@6977 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
2d902f2fa1
commit
51ff437d49
4 changed files with 115 additions and 58 deletions
|
|
@ -121,56 +121,6 @@ int AString<B>::ReverseFind(int chr) const
|
|||
return B::GetCount() ? ReverseFind(chr, B::GetCount() - 1) : -1;
|
||||
}
|
||||
|
||||
template <class B>
|
||||
int AString<B>::Find(int len, const tchar *s, int from) const
|
||||
{
|
||||
ASSERT(from >= 0 && from <= GetLength());
|
||||
int l = GetLength() - len - from;
|
||||
if(l < 0)
|
||||
return -1;
|
||||
if(len == 0)
|
||||
return from;
|
||||
const tchar *ptr = B::Begin();
|
||||
const tchar *p = ptr + from;
|
||||
const tchar *e = p + l;
|
||||
if(len > 4) {
|
||||
len -= 4;
|
||||
while(p <= e) {
|
||||
if(s[0] == p[0] && s[1] == p[1] && s[2] == p[2] && s[3] == p[3] && memcmp(s + 4, p + 4, len * sizeof(tchar)) == 0)
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 4)
|
||||
while(p <= e) {
|
||||
if(s[0] == p[0] && s[1] == p[1] && s[2] == p[2] && s[3] == p[3])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
else
|
||||
if(len == 3)
|
||||
while(p <= e) {
|
||||
if(s[0] == p[0] && s[1] == p[1] && s[2] == p[2])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
else
|
||||
if(len == 2)
|
||||
while(p <= e) {
|
||||
if(s[0] == p[0] && s[1] == p[1])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
else
|
||||
while(p <= e) {
|
||||
if(*s == *p)
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <class B>
|
||||
void AString<B>::Replace(const String& find, const String& replace)
|
||||
{
|
||||
|
|
@ -227,12 +177,6 @@ bool AString<B>::EndsWith(const tchar *s) const
|
|||
return EndsWith(s, strlen__(s));
|
||||
}
|
||||
|
||||
template <class B>
|
||||
int AString<B>::Find(const tchar *s, int from) const
|
||||
{
|
||||
return Find(strlen__(s), s, from);
|
||||
}
|
||||
|
||||
template <class B>
|
||||
int AString<B>::FindFirstOf(int len, const tchar *s, int from) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -712,6 +712,38 @@ do { \
|
|||
} \
|
||||
} while(false)
|
||||
|
||||
template <class tchar>
|
||||
force_inline bool svo_memeq(const tchar *a, const tchar *b, int len)
|
||||
{
|
||||
if(len > 11)
|
||||
return memcmp(a, b, len) == 0;
|
||||
switch(len) {
|
||||
case 11:
|
||||
if(a[10] != b[10]) return false;
|
||||
case 10:
|
||||
if(a[9] != b[9]) return false;
|
||||
case 9:
|
||||
if(a[8] != b[8]) return false;
|
||||
case 8:
|
||||
if(a[7] != b[7]) return false;
|
||||
case 7:
|
||||
if(a[6] != b[6]) return false;
|
||||
case 6:
|
||||
if(a[5] != b[5]) return false;
|
||||
case 5:
|
||||
if(a[4] != b[4]) return false;
|
||||
case 4:
|
||||
if(a[3] != b[3]) return false;
|
||||
case 3:
|
||||
if(a[2] != b[2]) return false;
|
||||
case 2:
|
||||
if(a[1] != b[1]) return false;
|
||||
case 1:
|
||||
if(a[0] != b[0]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//Quick fix....
|
||||
#ifdef PLATFORM_WINCE
|
||||
const char *FromSysChrSet(const wchar *s);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,84 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
template <class tchar>
|
||||
int t_find(const tchar *ptr, int plen, const tchar *s, int len, int from)
|
||||
{
|
||||
ASSERT(from >= 0 && from <= plen);
|
||||
int l = plen - len - from;
|
||||
if(l < 0)
|
||||
return -1;
|
||||
if(len == 0)
|
||||
return from;
|
||||
const tchar *p = ptr + from;
|
||||
const tchar *e = p + l;
|
||||
if(len > 4) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
tchar s2 = s[2];
|
||||
tchar sl = s[len - 1];
|
||||
int l_1 = len - 1;
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && sl == p[l_1] && s1 == p[1] && s2 == p[2] &&
|
||||
svo_memeq(s + 4, p + 4, len - 5))
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 4) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
tchar s2 = s[2];
|
||||
tchar s3 = s[3];
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && s3 == p[3] && s1 == p[1] && s2 == p[2])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 3) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
tchar s2 = s[2];
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && s2 == p[2] && s1 == p[1])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(len == 2) {
|
||||
tchar s0 = s[0];
|
||||
tchar s1 = s[1];
|
||||
while(p <= e) {
|
||||
if(s0 == p[0] && s1 == p[1])
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tchar s0 = s[0];
|
||||
while(p <= e) {
|
||||
if(s0 == *p)
|
||||
return (int)(p - ptr);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int find(const char *text, int len, const char *needle, int nlen, int from)
|
||||
{
|
||||
return t_find(text, len, needle, nlen, from);
|
||||
}
|
||||
|
||||
int find(const wchar *text, int len, const wchar *needle, int nlen, int from)
|
||||
{
|
||||
return t_find(text, len, needle, nlen, from);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
void String0::Dsyn()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ inline int strlen__(const wchar *s) { return s ? (int)wstrlen(s) : 0; }
|
|||
inline int cmpval__(char x) { return (byte)x; }
|
||||
inline int cmpval__(wchar x) { return (word)x; }
|
||||
|
||||
int find(const char *text, int len, const char *needle, int nlen, int from);
|
||||
int find(const wchar *text, int len, const wchar *needle, int nlen, int from);
|
||||
|
||||
class String;
|
||||
class WString;
|
||||
class StringBuffer;
|
||||
|
|
@ -85,8 +88,8 @@ public:
|
|||
int ReverseFind(int chr, int from) const;
|
||||
int ReverseFind(int chr) const;
|
||||
|
||||
int Find(int len, const tchar *s, int from) const;
|
||||
int Find(const tchar *s, int from = 0) const;
|
||||
int Find(int len, const tchar *s, int from) const { return find(B::Begin(), B::GetCount(), s, len, from); }
|
||||
int Find(const tchar *s, int from = 0) const { return Find(strlen__(s), s, from); }
|
||||
int Find(const String& s, int from = 0) const { return Find(s.GetCount(), ~s, from); }
|
||||
|
||||
int ReverseFind(int len, const tchar *s, int from) const;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue