initial
[prop.git] / include / AD / strings / str.h
blob003cea8e6704533c23e599042c5197c424c42d86
1 //////////////////////////////////////////////////////////////////////////////
2 // NOTICE:
3 //
4 // ADLib, Prop and their related set of tools and documentation are in the
5 // public domain. The author(s) of this software reserve no copyrights on
6 // the source code and any code generated using the tools. You are encouraged
7 // to use ADLib and Prop to develop software, in both academic and commercial
8 // settings, and are free to incorporate any part of ADLib and Prop into
9 // your programs.
11 // Although you are under no obligation to do so, we strongly recommend that
12 // you give away all software developed using our tools.
14 // We also ask that credit be given to us when ADLib and/or Prop are used in
15 // your programs, and that this notice be preserved intact in all the source
16 // code.
18 // This software is still under development and we welcome any suggestions
19 // and help from the users.
21 // Allen Leung
22 // 1994
23 //////////////////////////////////////////////////////////////////////////////
25 #ifndef variable_sized_string_h
26 #define variable_sized_string_h
28 /////////////////////////////////////////////////////////////////////////////
29 // Class |String|
31 // Class |String| behaves very much like C's `char *' and can be
32 // used as such in most situations. It handles its own storage management.
33 // For compatibility with C style strings, class String keeps an extra
34 // nul character at the end. However, nul characters *are* allowed in
35 // class String.
36 /////////////////////////////////////////////////////////////////////////////
38 #include <stdlib.h>
39 #include <iostream.h>
40 #include <AD/generic/generic.h> // Generic definitions
42 ////////////////////////////////////////////////////////////////////////////
43 // The GNU C++ class library already has classes String and SubString.
44 // Xlib already has typedef String.
45 ////////////////////////////////////////////////////////////////////////////
46 #if defined(__GNUG__) || defined(X11)
47 # define String String_
48 # define SubString SubString_
49 # define StringImpl StringImpl_
50 #endif
52 ////////////////////////////////////////////////////////////////////////////
53 // Forward declarations.
54 ////////////////////////////////////////////////////////////////////////////
55 class String;
56 class SubString;
57 class StringImpl;
58 class RegExp;
59 class ostream;
60 class istream;
62 ////////////////////////////////////////////////////////////////////////////
63 // Class StringImpl, the actual implementation of a string.
64 // We use a simple reference counted, copy on write implementation.
65 ////////////////////////////////////////////////////////////////////////////
66 class StringImpl {
67 friend class String;
68 friend class SubString;
69 unsigned long ref; // reference count
70 size_t len; // logical length
71 size_t capacity; // actual capacity
72 char string[1]; // actual data
73 void * operator new (size_t, size_t, size_t);
74 void operator delete (void *);
75 inline void dec_ref() { if (--ref == 0) delete this; }
76 inline void inc_ref() { ++ref; }
77 static StringImpl * empty_string;
78 static StringImpl * make_empty_string();
79 public:
82 ////////////////////////////////////////////////////////////////////////////
83 // Class SubString
84 ////////////////////////////////////////////////////////////////////////////
85 class SubString
86 { friend class String;
87 StringImpl * impl; // the actual string implementation
88 size_t start; // starting index
89 size_t len; // logical length
91 SubString(StringImpl *, size_t, size_t);
92 public:
93 inline ~SubString() { if (--impl->ref == 0) delete impl; }
95 ///////////////////////////////////////////////////////////////////////
96 // Conversions
97 ///////////////////////////////////////////////////////////////////////
98 operator String () const;
100 ///////////////////////////////////////////////////////////////////////
101 // Selectors
102 ///////////////////////////////////////////////////////////////////////
103 inline size_t length() const { return len; }
104 inline size_t size() const { return len; }
105 inline size_t capacity() const { return impl->capacity; }
106 inline Bool is_empty() const { return len == 0; }
107 inline Bool is_full() const { return false; }
108 inline char operator [] (int i) const { return impl->string[start+i]; }
109 inline char& operator [] (int i) { return impl->string[start+i]; }
112 ////////////////////////////////////////////////////////////////////////////
113 // Class String
114 ////////////////////////////////////////////////////////////////////////////
115 class String {
116 StringImpl * impl; // the actual string implementation
117 inline String(StringImpl * s) : impl(s) {}
118 void copy_on_write(size_t extra);
119 public:
120 ///////////////////////////////////////////////////////////////////////
121 // Constructors and destructor
122 ///////////////////////////////////////////////////////////////////////
123 String(); // Make empty String
124 String(size_t initial_capacity); // Make an uninitialized String
125 String(char c, size_t times = 1); // Make String initialized with c's
126 String(const char * s, int l = -1); // e.g. String = "abcde";
127 inline String(const String& s) // e.g. String s1 = s2;
128 : impl(s.impl) { impl->inc_ref(); }
129 inline ~String() { impl->dec_ref(); }
131 ///////////////////////////////////////////////////////////////////////
132 // Conversion
133 ///////////////////////////////////////////////////////////////////////
134 inline operator const char * () const { return impl->string; }
135 inline const char * str() const { return impl->string; }
137 ///////////////////////////////////////////////////////////////////////
138 // Assignment
139 ///////////////////////////////////////////////////////////////////////
140 inline String& operator = (const String& s)
141 { if (this != &s) { s.impl->inc_ref(); dec_ref(); impl = s.impl; }
142 return *this;
144 String& operator = (const char *);
146 ///////////////////////////////////////////////////////////////////////
147 // Splice a new (sub)string into location:
148 // e.g. String S = "The quick brown fox";
149 // S.splice(4,5,"slow");
151 // S now becomes "The slow brown fox";
152 ///////////////////////////////////////////////////////////////////////
153 String& splice(int location, int len, const char *, int size = -1);
154 String& splice(int location, int len, char c, int size = 1);
155 String& splice(int location, int len, const String& s);
157 ///////////////////////////////////////////////////////////////////////
158 // Selectors
159 ///////////////////////////////////////////////////////////////////////
160 inline size_t length() const { return impl->len; }
161 inline size_t size() const { return impl->len; }
162 inline size_t capacity() const { return impl->capacity; }
163 inline Bool is_empty() const { return impl->len == 0; }
164 inline Bool is_full() const { return false; }
165 inline char operator [] (int i) const { return impl->string[i]; }
166 inline char& operator [] (int i) { return impl->string[i]; }
168 ///////////////////////////////////////////////////////////////////////
169 // Substring extraction
170 ///////////////////////////////////////////////////////////////////////
171 SubString at (int left, int length) const;
172 SubString left (int length) const;
173 SubString right (int length) const;
175 ///////////////////////////////////////////////////////////////////////
176 // Concatenation
177 ///////////////////////////////////////////////////////////////////////
178 friend String operator + (const String&, const String&);
179 friend String operator + (const String&, const char *);
180 friend String operator + (const char *, const String&);
182 ///////////////////////////////////////////////////////////////////////
183 // Multiplication
184 ///////////////////////////////////////////////////////////////////////
185 String operator * (int times);
187 ///////////////////////////////////////////////////////////////////////
188 // Append to end
189 ///////////////////////////////////////////////////////////////////////
190 String& operator += (const String&);
191 String& operator += (const char *);
192 String& operator += (char);
194 ///////////////////////////////////////////////////////////////////////
195 // Comparisons
196 ///////////////////////////////////////////////////////////////////////
197 inline friend Bool operator == (const String& a, const String& b) { return a.compare(b) == 0; }
198 inline friend Bool operator == (const String& a, const char * b) { return a.compare(b) == 0; }
199 inline friend Bool operator == (const char * a, const String& b) { return b.compare(a) == 0; }
200 inline friend Bool operator != (const String& a, const String& b) { return a.compare(b) != 0; }
201 inline friend Bool operator != (const String& a, const char * b) { return a.compare(b) != 0; }
202 inline friend Bool operator != (const char * a, const String& b) { return b.compare(a) != 0; }
203 inline friend Bool operator > (const String& a, const String& b) { return a.compare(b) > 0; }
204 inline friend Bool operator > (const String& a, const char * b) { return a.compare(b) > 0; }
205 inline friend Bool operator > (const char * a, const String& b) { return b.compare(a) < 0; }
206 inline friend Bool operator < (const String& a, const String& b) { return a.compare(b) < 0; }
207 inline friend Bool operator < (const String& a, const char * b) { return a.compare(b) < 0; }
208 inline friend Bool operator < (const char * a, const String& b) { return b.compare(a) > 0; }
209 inline friend Bool operator >= (const String& a, const String& b) { return a.compare(b) >= 0; }
210 inline friend Bool operator >= (const String& a, const char * b) { return a.compare(b) >= 0; }
211 inline friend Bool operator >= (const char * a, const String& b) { return b.compare(a) <= 0; }
212 inline friend Bool operator <= (const String& a, const String& b) { return a.compare(b) <= 0; }
213 inline friend Bool operator <= (const String& a, const char * b) { return a.compare(b) <= 0; }
214 inline friend Bool operator <= (const char * a, const String& b) { return b.compare(a) >= 0; }
216 ///////////////////////////////////////////////////////////////////////
217 // More Comparisons
218 ///////////////////////////////////////////////////////////////////////
219 int compare (const String&) const;
220 int compare (const char *, int len = -1) const;
221 int case_insensitive_compare (const String&) const;
222 int case_insensitive_compare (const char *, int len = -1) const;
223 int collate (const String&) const;
224 int collate (const char *, int len = -1) const;
226 ///////////////////////////////////////////////////////////////////////
227 // In place operations
228 ///////////////////////////////////////////////////////////////////////
229 String& toupper(); // make all upper case
230 String& tolower(); // make all lower case
231 String& trunc(int len); // truncate the length to `len'
233 ///////////////////////////////////////////////////////////////////////
234 // Searching: returns a non-negative index if found
235 ///////////////////////////////////////////////////////////////////////
236 int contains (RegExp&) const;
237 int contains (char) const;
238 int contains (const char *, int len = -1) const;
239 int contains (const String&) const;
241 ///////////////////////////////////////////////////////////////////////
242 // Input and Output
243 ///////////////////////////////////////////////////////////////////////
244 friend ostream& operator << (ostream& out, const String& s);
245 friend istream& operator >> (istream&, String&);
248 #endif