📄 str.cpp
字号:
uint sz = size(); if (pos > sz) Throw(Out_of_range("string index error\n")); uint xlen = sz-pos; if (xlen > n) xlen = n; sz -= xlen; if (sz == 0) { if (HasCapacity()) GetStrRep()->sz = 0; else { px->Drop(); px = ASN; return *this; } } StrRep* oldp = GetStrRep(); if (HasCapacity()) { char* target = oldp->s + pos; memmove(target, target + xlen, sz-pos); oldp->sz = sz; } else { StrRep* p = new StrRepMult(sz); px = p; char* target = p->s; memcpy(target, oldp->s, pos); target += pos; memcpy(target, oldp->s+pos+xlen, sz-pos); oldp->Drop(); } return *this;}String& String::my_replace(uint pos, uint n, const StrBase& sb){ uint sz = size(); uint rlen =sb.size(); if (pos > sz) Throw(Out_of_range("string index error\n")); uint xlen = sz-pos; if (xlen > n) xlen = n; sz -= xlen; if (sz >= npos - rlen) Throw(Length_error("string length >= npos\n")); StrRep* oldp = GetStrRep(); if (rlen == xlen && refcount() == 0) // in-place replace OK { char* target = oldp->s+pos; sb.Load(target); } else if (HasCapacity() && sz + rlen <= capacity()) { // must allow for possibility that sb is part of *this char* target = oldp->s + pos; StrRep tail(target + xlen, sz-pos); sb.Load(target); tail.Load(target); oldp->sz = sz + rlen; } else if (sz + rlen == 0) { px->Drop(); px = ASN; return *this; } else { StrRep* p = new StrRepMult(sz+rlen); px = p; char* target = p->s; memcpy(target, oldp->s, pos); target += pos; sb.Load(target); memcpy(target, oldp->s+pos+xlen, sz-pos); oldp->Drop(); } return *this;}String& String::replace(uint pos1, uint n1, const String& str) { return my_replace(pos1, n1, *(str.px)); }String& String::replace(uint pos1, uint n1, const String& str, uint pos2, uint n2) { return my_replace(pos1, n1, CharSeq(str, pos2, n2)); }String& String::replace(uint pos, uint n1, const char* s, uint n2) { return my_replace(pos, n1, CharSeq((char*)s, n2)); }String& String::replace(uint pos, uint n1, uint n2, char c) { return my_replace(pos, n1, CharRepeated(n2, c)); }//************************* some odds and sods ***************************uint String::copy(char* s, uint n, uint pos) const{ StrRep* p = GetStrRep(); uint rlen = size(); if (pos > rlen) Throw(Out_of_range("string index error\n")); rlen -= pos; if (rlen > n) rlen = n; memcpy(s, p->s+pos, rlen); return rlen;}void String::swap(String& str){ StrBase* oldp = px->UnProtect(); px = str.px->UnProtect(); str.px = oldp;}const char* String::c_str() const { return px->NullTerminate(&(StrBase*&)px); }const char* String::data() const { StrRep* p = Protect(); ((String&)*this).px = p; return p->s; }//***************************** the find functions ***********************uint String::find(const CharSeq& str, uint pos) const{ uint str_sz = str.size(); uint sz = size(); if (sz < str_sz || pos > sz - str_sz) return npos; // need both checks to avoid overflows or negatives if (str_sz == 0) return pos; const char* start = GetData(); const char* newstart = start+pos; const char* str_loc = str.s; if (str_sz == 1) { newstart = (const char*)memchr(newstart, *str_loc, sz-pos); if (!newstart) return npos; else return (uint)(newstart-start); } uint sindx = s_index; // otherwise may get problems if multithreading for (;;) { if (sindx >= str_sz) sindx = 0; uint m = sz+1-str_sz-(uint)(newstart-start); if (m==0) { s_index = sindx; return npos; } newstart = (const char*)memchr(newstart+sindx, str_loc[sindx], m); if (!newstart) { s_index = sindx; return npos; } newstart -= sindx; if (memcmp(newstart, str_loc, str_sz) == 0) { s_index = sindx; return (uint)(newstart-start); } sindx++; newstart++; }}uint String::find(const String& str, uint pos) const { return find(*(str.GetStrRep()), pos); }uint String::find(const char* s, uint pos, uint n) const { return find(CharSeq((char*)s,n),pos); }uint String::find(const char* s, uint pos) const { return find(CharSeq((char*)s),pos); }uint String::find(const char c, uint pos) const{ uint sz = size(); if (pos >= sz) return npos; // also ensures sz != 0 const char* start = GetData(); const char* newstart = start+pos; newstart = (const char*)memchr(newstart, c, sz-pos); if (!newstart) return npos; else return (uint)(newstart-start);}uint String::rfind(const CharSeq& str, uint pos) const{ // can return sz if searching for a zero length string // is this what the committee wants? uint str_sz = str.size(); uint sz = size(); if (sz < str_sz) return npos; sz -= str_sz; if (pos > sz) pos = sz; if (str_sz == 0) return pos; const char* start = GetData(); const char* newstart = start+pos; const char* str_loc = str.s; uint sindx = s_index; for (;;) { if (sindx >= str_sz) sindx = 0; uint i = (uint)(newstart-start); char c = str_loc[sindx]; newstart += sindx; while (*newstart != c) { if (i-- == 0) { s_index = sindx; return npos; } newstart--; } newstart -= sindx; if (!memcmp(newstart, str_loc, str_sz)) { s_index = sindx; return (uint)(newstart-start); } if (--newstart < start) { s_index = sindx; return npos; } sindx++; }}uint String::rfind(const String& str, uint pos) const { return rfind(*(str.GetStrRep()), pos); }uint String::rfind(const char* s, uint pos, uint n) const { return rfind(CharSeq((char*)s,n),pos); }uint String::rfind(const char* s, uint pos) const { return rfind(CharSeq((char*)s),pos); }uint String::rfind(const char c, uint pos) const{ uint i = size(); if (i > pos) i = pos + 1; char* s = GetData() + i; while (i-- > 0) { if (*(--s) == c) return i; } return npos;}uint String::find_first_of(const CharSeq& str, uint pos) const{ // this should be done without memchr at least when str is long uint sz = size(); uint str_sz = str.size(); if (str_sz == 0 || pos >= sz) return npos; // also ensures sz != 0 const char* start = GetData(); const char* newstart = start+pos; const char* str_loc = str.s; sz -= pos; while (sz--) { if (memchr(str_loc, *newstart, str_sz)) return (uint)(newstart-start); newstart++; } return npos;}uint String::find_first_of(const String& str, uint pos) const { return find_first_of(*(str.GetStrRep()), pos); }uint String::find_first_of(const char* s, uint pos, uint n) const { return find_first_of(CharSeq((char*)s,n),pos); }uint String::find_first_of(const char* s, uint pos) const { return find_first_of(CharSeq((char*)s),pos); }uint String::find_first_of(const char c, uint pos) const { return find(c, pos); }uint String::find_last_of(const CharSeq& str, uint pos) const{ uint sz = size(); if (sz > pos) sz = pos + 1; uint str_sz = str.size(); if (str_sz == 0) return npos; const char* start = GetData(); const char* newstart = start+sz; const char* str_loc = str.s; while (sz--) { if (memchr(str_loc, *(--newstart), str_sz)) return (uint)(newstart-start); } return npos;}uint String::find_last_of(const String& str, uint pos) const { return find_last_of(*(str.GetStrRep()), pos); }uint String::find_last_of(const char* s, uint pos, uint n) const { return find_last_of(CharSeq((char*)s,n),pos); }uint String::find_last_of(const char* s, uint pos) const { return find_last_of(CharSeq((char*)s),pos); }uint String::find_last_of(const char c, uint pos) const { return rfind(c, pos); }uint String::find_first_not_of(const CharSeq& str, uint pos) const{ uint sz = size(); uint str_sz = str.size(); if (pos >= sz) return npos; // also ensures sz != 0 if (str_sz == 0 ) return pos; const char* start = GetData(); const char* newstart = start+pos; const char* str_loc = str.s; sz -= pos; while (sz--) { if (!memchr(str_loc, *newstart, str_sz)) return (uint)(newstart-start); newstart++; } return npos;}uint String::find_first_not_of(const String& str, uint pos) const { return find_first_not_of(*(str.GetStrRep()), pos); }uint String::find_first_not_of(const char* s, uint pos, uint n) const { return find_first_not_of(CharSeq((char*)s,n),pos); }uint String::find_first_not_of(const char* s, uint pos) const { return find_first_not_of(CharSeq((char*)s),pos); }uint String::find_first_not_of(const char c, uint pos) const{ uint sz = size(); if (pos >= sz) return npos; // also ensures sz != 0 char* s = GetData() + pos; uint i = sz - pos; while (i > 0) { if (*(s++) != c) return sz - i; i--; } return npos;}uint String::find_last_not_of(const CharSeq& str, uint pos) const{ uint sz = size(); if (sz > pos) sz = pos + 1; if (sz == 0) return npos; uint str_sz = str.size(); if (str_sz == 0) return sz - 1; const char* start = GetData(); const char* newstart = start+sz; const char* str_loc = str.s; while (sz--) { if (!memchr(str_loc, *(--newstart), str_sz)) return (uint)(newstart-start); } return npos;}uint String::find_last_not_of(const String& str, uint pos) const { return find_last_not_of(*(str.GetStrRep()), pos); }uint String::find_last_not_of(const char* s, uint pos, uint n) const { return find_last_not_of(CharSeq((char*)s,n),pos); }uint String::find_last_not_of(const char* s, uint pos) const { return find_last_not_of(CharSeq((char*)s),pos); }uint String::find_last_not_of(const char c, uint pos) const{ uint i = size(); if (i > pos) i = pos + 1; char* s = GetData() + i; while (i-- > 0) { if (*(--s) != c) return i; } return npos;}String String::substr(uint pos, uint n) const { return String(*this, pos, n); }//***************************** the booleans *****************************int String::compare(uint pos, uint n, const CharSeq& sb) const{ StrRep* p = GetStrRep(); uint sz = size(); uint str_sz = sb.size(); if (pos > sz) Throw(Out_of_range("string index error\n")); sz -= pos; if (sz > n) sz = n; else n = sz; if (n > str_sz) n = str_sz; int m = memcmp(p->s+pos, sb.s, n); if (m) return m; if (sz < str_sz) return -1; if (sz > str_sz) return 1; return 0;}int String::compare(const String& str) const { return compare(0, npos, CharSeq(str)); }int String::compare(uint pos1, uint n1, const String& str) const { return compare(pos1, n1, CharSeq(str)); }int String::compare(uint pos1, uint n1, const String& str, uint pos2, uint n2) const { return compare(pos1, n1, CharSeq(str, pos2, n2)); }int String::compare(uint pos, uint n1, const char* s, uint n2) const { return compare(pos, n1, CharSeq((char*)s, n2)); }int String::compare(const char* s) const { return compare(0, npos, CharSeq((char*)s)); }bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; }bool operator==(const char* lhs, const String& rhs) { return rhs.compare(lhs) == 0; }bool operator==(const String& lhs, const char* rhs) { return lhs.compare(rhs) == 0; }bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; }bool operator!=(const char* lhs, const String& rhs) { return rhs.compare(lhs) != 0; }bool operator!=(const String& lhs, const char* rhs) { return lhs.compare(rhs) != 0; }bool operator<(const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; }bool operator<(const char* lhs, const String& rhs) { return rhs.compare(lhs) > 0; }bool operator<(const String& lhs, const char* rhs) { return lhs.compare(rhs) < 0; }bool operator>(const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; }bool operator>(const char* lhs, const String& rhs) { return rhs.compare(lhs) < 0; }bool operator>(const String& lhs, const char* rhs) { return lhs.compare(rhs) > 0; }bool operator<=(const String& lhs, const String& rhs) { return lhs.compare(rhs) <= 0; }bool operator<=(const char* lhs, const String& rhs) { return rhs.compare(lhs) >= 0; }bool operator<=(const String& lhs, const char* rhs) { return lhs.compare(rhs) <= 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -