📄 str.cpp
字号:
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; }//****************** the io routines (need more work) ********************istream& operator>>(istream& is, String& str){ char buf[1024]; is.width(1024); is >> buf; str = buf; is.width(0); return is;}ostream& operator<<(ostream& os, const String& str){ return os << str.c_str(); }// from Alain Decampsistream& getline(istream& is, String& str, char delim){ int token; str.reserve(2048); str.erase(); // with current implementation no reallocation here while (((token = is.get()) != EOF) && (token != delim)) { str += char(token); } if (token == EOF) { is.clear(ios::eofbit|is.rdstate()); } // str.reserve(0); // waste of time if used in a "while not EOF" return is;};//******************** bodies of the helper classes **********************// the virtual functions - do not inlineuint StrSum::size() const { return lhs->size() + rhs->size(); }uint StrSumLC::size() const { return 1 + rhs->size(); }uint StrSumRC::size() const { return lhs->size() + 1; }uint CharSeq::size() const { return sz; }uint CharSingle::size() const { return 1; }uint CharRepeated::size() const { return n; }uint StrNull::size() const { return 0; }uint StrBase::capacity() const { return size(); }uint CharSeq::capacity() const { return sz; }uint StrRepCap::capacity() const { return cpx; }void StrSum::Load(char*& ps) const { lhs->Load(ps); rhs->Load(ps); }void StrSumLC::Load(char*& ps) const { *ps++ = lhs; rhs->Load(ps); }void StrSumRC::Load(char*& ps) const { lhs->Load(ps); *ps++ = rhs; }void CharSeq::Load(char*& ps) const { memmove(ps, s, sz); ps += sz; }void CharSingle::Load(char*& ps) const { *ps++ = c; }void CharRepeated::Load(char*& ps) const { memset(ps, c, n); ps += n; }void StrNull::Load(char*&) const {}StrRep* StrBase::GetStrRep(StrBase** px){ StrRep* p = new StrRepMult(size()); char* target = p->s; Load(target); (*px)->Drop(); *px = p; return p;}StrRep* StrRep::GetStrRep(StrBase**) { return this; }StrRep* StrBase::GetStrRepW(StrBase** px){ StrRep* p = new StrRepMult(size()); char* target = p->s; Load(target); (*px)->Drop(); *px = p; return p;}StrRep* StrRep::GetStrRepW(StrBase**) { return this; }StrRep* StrRepMult::GetStrRepW(StrBase** px){ if (refcnt == 0) return this; StrRep* p = new StrRepMult(s, sz); (*px)->Drop(); *px = p; return p;}StrRep* StrBase::Protect(StrBase** px){ StrRep* p = new StrRep(size()); char* target = p->s; Load(target); (*px)->Drop(); *px = p; return p;}StrRep* StrRep::Protect(StrBase**) { return this; }StrRep* StrRepMult::Protect(StrBase** px){ StrRep* p; if (refcnt == 0) { p = new StrRep(); p->sz = sz; sz = 0; char* s1 = p->s; p->s = s; s = s1; } else { p = new StrRep(s, sz); } (*px)->Drop(); *px = p; return p;}StrBase* StrBase::UnProtect() { return this; }StrBase* StrRep::UnProtect(){ StrRepMult* p = new StrRepMult(); p->sz = sz; sz = 0; char* s1 = p->s; p->s = s; s = s1; p->refcnt = 0; delete this; return p;}StrBase* StrRepMult::UnProtect() { return this; }StrBase* StrRepCap::UnProtect(){ StrRepMult* p = new StrRepMult(s, sz); delete this; return p;}StrBase* StrRepNullTerm::UnProtect(){ StrRepMult* p = new StrRepMult(s, sz); delete this; return p;}StrBase* StrNull::UnProtect() { return this; }void StrBase::WithCapacity(StrBase** px){ uint sz1 = size(); StrRepCap* p = new StrRepCap(sz1,sz1); char* target = p->s; Load(target); (*px)->Drop(); *px = p;}void StrRepCap::WithCapacity(StrBase**) {}void StrRep::WithCapacity(StrBase** px){ StrRepCap* p = new StrRepCap(); p->cpx = p->sz = sz; sz = 0; char* s1 = p->s; p->s = s; s = s1; (*px)->Drop(); *px = p;}void StrRepMult::WithCapacity(StrBase** px){ StrRepCap* p; if (refcnt == 0) { p = new StrRepCap(); p->cpx = p->sz = sz; sz = 0; char* s1 = p->s; p->s = s; s = s1; } else { p = new StrRepCap(s, sz); } (*px)->Drop(); *px = p;}void StrRepNullTerm::WithCapacity(StrBase** px){ StrRepCap* p = new StrRepCap(s, sz); (*px)->Drop(); *px = p;}const char* StrBase::NullTerminate(StrBase** px){ StrRep* p = new StrRepNullTerm(size()); char* target = p->s; char* t = target; Load(target); *target = 0; (*px)->Drop(); *px = p; return t;}const char* StrRepNullTerm::NullTerminate(StrBase**) { return s; }const char* StrRepCap::NullTerminate(StrBase** px){ if (cpx > sz) { s[sz] = 0; return s; } else return StrBase::NullTerminate(px);}void StrSum::Drop() { if (ref) ref = false; else { lhs->Drop(); rhs->Drop(); delete this; } }void StrSumLC::Drop() { if (ref) ref = false; else { rhs->Drop(); delete this; } }void StrSumRC::Drop() { if (ref) ref = false; else { lhs->Drop(); delete this; } }void StrBase::Drop() { delete this; }void StrRepMult::Drop() { if (refcnt-- == 0) delete this; }void StrNull::Drop() {}StrBase* StrSumBase::Clone(StrBase** px){ if (ref) { StrRepMult* p = new StrRepMult(size()); p->refcnt++; char* target = p->s; Load(target); (*px)->Drop(); *px = p; return p; } else { ref = true; return this; }}StrBase* CharSeq::Clone(StrBase**){ StrBase* sb = new StrRep(s,sz); return sb;}StrBase* StrRep::Clone(StrBase**){ StrRepMult* p = new StrRepMult(s, size()); return p;}StrBase* StrRepMult::Clone(StrBase**) { refcnt++; return this; }StrBase* CharSingle::Clone(StrBase**){ StrBase* sb = new CharSingle(c); return sb;}StrBase* CharRepeated::Clone(StrBase**){ StrBase* sb = new CharRepeated(n,c); return sb;}StrBase* StrNull::Clone(StrBase**) { return this; }bool StrBase::HasCapacity() const { return false; }bool StrRepCap::HasCapacity() const { return true; }unsigned int StrBase::refcount() const { return 0; }unsigned int StrRepMult::refcount() const { return refcnt; }unsigned int StrSumBase::refcount() const { return (ref) ? 1 : 0; }//***************************** constructors *****************************StrRep::StrRep(uint SZ) : CharSeq(SZ){ s = new char[sz];}StrRep::StrRep(uint n, char c) : CharSeq(n){ s = new char[sz]; memset(s, c, sz);}StrRep::StrRep(const char* x){ sz = strlen(x); s = new char[sz]; memcpy(s, x, sz);}StrRep::StrRep(const char* x, uint len) : CharSeq(len){ s = new char[sz]; memcpy(s, x, sz);}StrRep::StrRep(const char* x, uint len, uint n, char c) : CharSeq(n){ s = new char[sz]; memcpy(s, x, len); memset(s+len, c, n-len);}StrRep::~StrRep() { if (s) delete [] s; }StrRepMult::StrRepMult(uint SZ) : StrRep(SZ), refcnt(0) {}StrRepMult::StrRepMult(uint n, char c) : StrRep(n, c), refcnt(0) {}StrRepMult::StrRepMult(const char* x) : StrRep(x), refcnt(0) {}StrRepMult::StrRepMult(const char* x, uint len) : StrRep(x, len), refcnt(0) {}StrRepMult::StrRepMult(const char* x, uint len, uint n, char c) : StrRep(x, len, n, c), refcnt(0) {}StrRepCap::StrRepCap(uint len, uint cp) : StrRep(cp), cpx(cp) { sz = len; }StrRepCap::StrRepCap(const char* x, uint len) : StrRep(x, len), cpx(len) {}StrRepNullTerm::StrRepNullTerm(uint len) : StrRep(len + 1) { sz = len; }StrNull::StrNull() : StrRepNullTerm(0) { *s = 0; }CharSeq::CharSeq(char* S) : sz(strlen(S)), s(S) {}CharSeq::CharSeq(char* S, uint n) : s(S){ uint i = 0; while (*S++) { if (i >= n) break; i++; } sz = i; }CharSeq::CharSeq(const String& str) : sz(str.size()), s(str.GetData()) {}CharSeq::CharSeq(const String& str, uint pos, uint n){ sz =str.size(); if (pos > sz) Throw(Out_of_range("string index error\n")); sz -= pos; if (sz > n) sz = n; s = str.GetData()+pos;}CharRepeated::CharRepeated(int N, char C) : CharSingle(C), n(N) { if (n==String::npos) Throw(Length_error("string length = npos\n")); }StrSum::StrSum(StrBase* L, StrBase* R) : lhs(L), rhs(R) {}StrSumLC::StrSumLC(char L, StrBase* R) : lhs(L), rhs(R) {}StrSumRC::StrSumRC(StrBase* L, char R) : lhs(L), rhs(R) {}StrSumBase::StrSumBase() : ref(false) {}//******************************** operator+ *****************************String operator+(const String& lhs, const String& rhs){ StrSum* sos = new StrSum(lhs.Clone(), rhs.Clone()); return String(sos);}String operator+(const char* lhs, const String& rhs){ StrRep* lhscs = new StrRep((char*)lhs); StrSum* sos = new StrSum(lhscs, rhs.Clone()); return String(sos);}String operator+(char lhs, const String& rhs){ StrSumLC* sos = new StrSumLC(lhs, rhs.Clone()); return String(sos);}String operator+(const String& lhs, const char* rhs){ StrRep* rhscs = new StrRep((char*)rhs); StrSum* sos = new StrSum(lhs.Clone(), rhscs); return String(sos);}String operator+(const String& lhs, char rhs){ StrSumRC* sos = new StrSumRC(lhs.Clone(), rhs); return String(sos);}//******************** initialise string package **********************// this is called whenever str.h is loaded; this ensures that npos is set to// -1 and ASN is initialised before any globals involving strings get// initialised.StringPackageInitialise::StringPackageInitialise(){ if (!String::ASN) { String::ASN = new StrNull; String::npos = (uint)(-1); }}//*********************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -