/*********************************************************************** Class 'String' is intended to be similar to 'char*', but to keep all memory operations hidden. ***********************************************************************/ /*********************************************************************** This is copied from THE C++ PROGRAMMING LANGUAGE by B. Stroustrup ***********************************************************************/ #ifndef _cppstring_h_ #define _cppstring_h_ #include "assert.h" #include "string.h" typedef unsigned char BOOLEAN; #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif /*====================================================================== class String : ======================================================================*/ class String { struct srep { char *s; int n; srep() { n=1; } }; srep *p; public : String(const char *); // String x = "abc" String(); // String x; String(const String &); // String x = str_var; ~String(); String& operator=(const char*); String& operator=(const String &); char& operator[](unsigned i); const char& operator[](unsigned i) const; const char* string() const; char * string(); friend BOOLEAN operator==(const String &, const String&); friend BOOLEAN operator!=(const String &, const String &); friend BOOLEAN operator==(const String &, const char *); friend BOOLEAN operator!=(const String &, const char *); String& operator+(const String&); String& operator+(const char *); }; // inline definition inline String::String() { p = new srep; p->s = NULL; } inline String::String(const char* s) { p = new srep; p->s = new char[strlen(s)+1]; strcpy(p->s,s); } inline String::String(const String& x) { p = x.p; p->n++; } inline String::~String() { if (--p->n == 0) { delete[] p->s; delete p; } } inline String& String::operator=(const char *s) { if (p->n > 1) { p->n--; p = new srep; } else delete[] p->s; p->s = new char[strlen(s)+1]; strcpy(p->s,s); return *this; } inline String& String::operator=(const String& x) { x.p->n++; // protect against "st == st" if (--p->n == 0) { delete[] p->s; delete p; } p = x.p; return *this; } inline char& String::operator[](unsigned i) { assert((i>=0) && (i<=strlen(p->s))); if (p->n>1) // clone to maintain value semantics { srep *np = new srep; np->s = new char[strlen(p->s)+1]; strcpy(np->s,p->s); p->n--; p = np; } return p->s[i]; }; inline const char& String::operator[](unsigned i) const { assert((i>=0) && (i<=strlen(p->s))); return p->s[i]; } inline const char* String::string() const { return p->s; } inline char* String::string() { return p->s; } inline BOOLEAN operator==(const String &x, const String&y) { if (strcmp(x.p->s,y.p->s)==0) return TRUE; else return FALSE; } inline BOOLEAN operator!=(const String &x, const String &y) { if (strcmp(x.p->s,y.p->s)==0) return FALSE; else return TRUE; } inline BOOLEAN operator==(const String &x, const char *s) { if (strcmp(x.p->s,s)==0) return TRUE; else return FALSE; } inline BOOLEAN operator!=(const String &x, const char *s) { if (strcmp(x.p->s,s)==0) return FALSE; else return TRUE; } inline String& String::operator+(const String &x) { char *str = new char[strlen(p->s)+strlen(x.p->s)+1]; strcpy(str,p->s); strcat(str,x.p->s); if (p->n > 1) { p->n--; p = new srep; } else delete [] p->s; p->s = str; return *this; } inline String& String::operator+(const char* x) { char *str = new char[strlen(p->s)+strlen(x)+1]; strcpy(str,p->s); strcat(str,x); if (p->n > 1) { p->n--; p = new srep; } else delete [] p->s; p->s = str; return *this; } #endif