7 // switching into "blonde" mode
8 // i trust stringclass nowadays.
12 /// Internal String struct
14 // GNU malloc: storage overhead is 8 bytes anyway.
15 const int INITIALMAX
= 8;
17 friend class String_handle
;
18 int maxlen
; // maxlen is arraysize-1
28 string
= new char[maxlen
+ 1];
33 /// init from src. Conservative allocation.
34 StringData(StringData
const &src
) {
36 maxlen
= length
= src
.length
;
37 string
= new char[maxlen
+1]; // should calc GNU 8byte overhead.
38 strcpy(string
, src
.string
);
42 assert(references
== 0);
52 string
= new char[maxlen
+ 1];
58 /** POST: maxlen >= j.
59 IN: j, maximum stringlength.
67 char *p
= new char[maxlen
+ 1];
71 // length = strlen(string);
74 /** POST: maxlen >= j.
75 IN: j, maximum stringlength.
76 contents are kept if it grows.
78 /// check if writeable.
81 assert (references
== 1);
87 assert(strlen(string
) == size_t(length
));
88 assert(maxlen
>= length
);
90 assert(references
>= 1);
95 length
= strlen (string
);
98 /// reduce memory usage.
99 void tighten() { // should be dec'd const
101 char *p
= new char[maxlen
+ 1];
108 void set(const char *s
) {
119 void operator += (const char *s
) {
126 strcpy(string
+ old
, s
);
130 operator const char *() const { return string
; }
133 char *array_for_modify() {
139 assert(j
>= 0 && j
<= length
);
144 /** not really safe. Can alter length without StringData knowing it.
146 char &operator [](int j
) {
147 assert(j
>= 0 && j
<= length
);
151 char operator [](int j
) const {
152 assert(j
>= 0 && j
<= length
);
158 the data itself. Handles simple tasks (resizing, resetting)
160 /****************************************************************/
161 /// ref. counting for strings
162 class String_handle
{
165 /// decrease ref count. Named kind of like a Tanenbaum semafore
166 void down() { if (!(--data
->references
)) delete data
; data
= 0; }
168 /// increase ref count
169 void up(StringData
*d
) { data
=d
; data
->references
++; }
171 /** make sure data has only one reference.
172 POST: data->references == 1
175 if (data
->references
!=1){
176 StringData
*newdata
= new StringData(*data
);
190 String_handle(String_handle
const & src
) {
194 /// retrieve the actual array.
195 operator const char *() const { return *data
; }
196 char *array_for_modify() {
198 return data
->array_for_modify();
201 void operator =(String_handle
const &src
) {
208 void operator += (const char *s
) {
214 char operator[](int j
) const { return (*data
)[j
]; }
217 // don't use this for loops. Use array_for_modify()
218 char &operator[](int j
) {
219 copy(); // hmm. Not efficient
220 return data
->array_for_modify()[j
];
223 void operator = (char const *p
) {
228 void trunc(int j
) { copy(); data
->trunc(j
); }
229 int len() const { return data
->length
; }
232 handles ref. counting, and provides a very thin
233 interface using char *
238 #if (NDEBUG == BLONDE)
245 #endif // STRINGUTIL_HH