Changeset 681e12f
- Timestamp:
- Jan 4, 2024, 11:58:49 AM (12 months ago)
- Branches:
- master
- Children:
- be10079
- Parents:
- 8b4faf6
- Location:
- libcfa/src/collections
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/collections/string.cfa
r8b4faf6 r681e12f 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Oct 18 21:52:09 202313 // Update Count : 2 0812 // Last Modified On : Thu Jan 4 11:27:37 2024 13 // Update Count : 233 14 14 // 15 15 … … 30 30 31 31 32 void ?{}( string & this ) {33 ( this.inner) { malloc() };34 ?{}( * this.inner );32 void ?{}( string & s ) { 33 (s.inner) { malloc() }; 34 ?{}( *s.inner ); 35 35 } 36 36 37 37 // private (not in header) 38 static void ?{}( string & this, string_res & src, size_t start, size_t end ) {39 ( this.inner) { malloc() };40 ?{}( * this.inner, src, SHARE_EDITS, start, end );41 } 42 43 void ?{}( string & this, const string & other) {44 ( this.inner) { malloc() };45 ?{}( * this.inner, *other.inner, COPY_VALUE );46 } 47 48 void ?{}( string & this, string & other) {49 ?{}( this, (const string &) other);50 } 51 52 void ?{}( string & this, const char * val ) {53 ( this.inner) { malloc() };54 ?{}( * this.inner, val );55 } 56 57 void ?{}( string & this, const char * buffer, size_t bsize) {58 ( this.inner) { malloc() };59 ?{}( * this.inner, buffer, bsize );60 } 61 62 void ^?{}( string & this ) {63 ^(* this.inner){};64 free( this.inner );65 this.inner = 0p;38 static void ?{}( string & s, string_res & src, size_t start, size_t end ) { 39 (s.inner) { malloc() }; 40 ?{}( *s.inner, src, SHARE_EDITS, start, end ); 41 } 42 43 void ?{}( string & s, const string & c ) { 44 (s.inner) { malloc() }; 45 ?{}( *s.inner, *c.inner, COPY_VALUE ); 46 } 47 48 void ?{}( string & s, string & c ) { 49 ?{}( s, (const string &) c ); 50 } 51 52 void ?{}( string & s, const char * val ) { 53 (s.inner) { malloc() }; 54 ?{}( *s.inner, val ); 55 } 56 57 void ?{}( string & s, const char * buffer, size_t bsize) { 58 (s.inner) { malloc() }; 59 ?{}( *s.inner, buffer, bsize ); 60 } 61 62 void ^?{}( string & s ) { 63 ^(*s.inner){}; 64 free( s.inner ); 65 s.inner = 0p; 66 66 } 67 67 … … 69 69 // Alternate construction: request shared edits 70 70 71 string_WithSharedEdits ?`shareEdits( string & this ) {72 string_WithSharedEdits ret = { & this };73 return ret; 74 } 75 76 void ?{}( string & this, string_WithSharedEdits src ) {77 ?{}( this, *src.s->inner, 0, src.s->inner->Handle.lnth);71 string_WithSharedEdits ?`shareEdits( string & s ) { 72 string_WithSharedEdits ret = { &s }; 73 return ret; 74 } 75 76 void ?{}( string & s, string_WithSharedEdits src ) { 77 ?{}( s, *src.s->inner, 0, src.s->inner->Handle.lnth); 78 78 } 79 79 … … 81 81 // Assignment 82 82 83 void ?=?( string & this, const char * val ) {84 (* this.inner) = val;85 } 86 87 void ?=?(string & this, const string & other) {88 (* this.inner) = (*other.inner);89 } 90 91 void ?=?( string & this, char val ) {92 (* this.inner) = val;93 } 94 95 string & ?=?(string & this, string & other) { //// <---- straw man change96 (* this.inner) = (*other.inner);97 return this;83 void ?=?( string & s, const char * val ) { 84 (*s.inner) = val; 85 } 86 87 void ?=?(string & s, const string & c) { 88 (*s.inner) = (*c.inner); 89 } 90 91 void ?=?( string & s, char val ) { 92 (*s.inner) = val; 93 } 94 95 string & ?=?(string & s, string & c) { //// <---- straw man change 96 (*s.inner) = (*c.inner); 97 return s; 98 98 } 99 99 … … 102 102 // Input-Output 103 103 104 ofstream & ?|?( ofstream & out, const string & this ) {105 return out | (* this.inner); // print internal string_res106 } 107 108 void ?|?( ofstream & out, const string & this ) {109 (ofstream &)(out | (* this.inner)); ends( out );104 ofstream & ?|?( ofstream & out, const string & s ) { 105 return out | (*s.inner); // print internal string_res 106 } 107 108 void ?|?( ofstream & out, const string & s ) { 109 (ofstream &)(out | (*s.inner)); ends( out ); 110 110 } 111 111 … … 124 124 } 125 125 126 ifstream & ?|?(ifstream & in, string & this) {127 return in | (* this.inner); // read to internal string_res128 } 129 130 void ?|?( ifstream & in, string & this ) {131 in | (* this.inner);126 ifstream & ?|?(ifstream & in, string & s) { 127 return in | (*s.inner); // read to internal string_res 128 } 129 130 void ?|?( ifstream & in, string & s ) { 131 in | (*s.inner); 132 132 } 133 133 … … 144 144 // Slicing 145 145 146 string ?()( string & this, size_t start, size_t end ) {147 string ret = { * this.inner, start, end };146 string ?()( string & s, size_t start, size_t end ) { 147 string ret = { *s.inner, start, end }; 148 148 return ret`shareEdits; 149 149 } 150 150 151 string ?()( string & this, size_t start ) {152 string ret = { * this.inner, start, size( this ) };151 string ?()( string & s, size_t start ) { 152 string ret = { *s.inner, start, size( s ) }; 153 153 return ret`shareEdits; 154 154 } … … 157 157 // Comparison 158 158 159 int cmp (const string &s1, const string &s2) { return cmp(*s1.inner ,*s2.inner); }160 bool ?==?(const string & s1, const string &s2) { return *s1.inner == *s2.inner; }161 bool ?!=?(const string & s1, const string &s2) { return *s1.inner != *s2.inner; }162 bool ?>? (const string & s1, const string &s2) { return *s1.inner > *s2.inner; }163 bool ?>=?(const string & s1, const string &s2) { return *s1.inner >= *s2.inner; }164 bool ?<=?(const string & s1, const string &s2) { return *s1.inner <= *s2.inner; }165 bool ?<? (const string & s1, const string &s2) { return *s1.inner < *s2.inner; }166 167 int cmp (const string &s1, const char* s2) { return cmp(*s1.inner , s2); }168 bool ?==?(const string & s1, const char* s2) { return *s1.inner == s2; }169 bool ?!=?(const string & s1, const char* s2) { return *s1.inner != s2; }170 bool ?>? (const string & s1, const char* s2) { return *s1.inner > s2; }171 bool ?>=?(const string & s1, const char* s2) { return *s1.inner >= s2; }172 bool ?<=?(const string & s1, const char* s2) { return *s1.inner <= s2; }173 bool ?<? (const string & s1, const char* s2) { return *s1.inner < s2; }174 175 int cmp (const char* s1, const string &s2) { return cmp( s1 ,*s2.inner); }176 bool ?==?(const char * s1, const string &s2) { return s1 == *s2.inner; }177 bool ?!=?(const char * s1, const string &s2) { return s1 != *s2.inner; }178 bool ?>? (const char * s1, const string &s2) { return s1 > *s2.inner; }179 bool ?>=?(const char * s1, const string &s2) { return s1 >= *s2.inner; }180 bool ?<=?(const char * s1, const string &s2) { return s1 <= *s2.inner; }181 bool ?<? (const char * s1, const string &s2) { return s1 < *s2.inner; }159 int strcmp(const string & s1, const string & s2) { return strcmp(*s1.inner, *s2.inner); } 160 bool ?==?(const string & s1, const string & s2) { return *s1.inner == *s2.inner; } 161 bool ?!=?(const string & s1, const string & s2) { return *s1.inner != *s2.inner; } 162 bool ?>? (const string & s1, const string & s2) { return *s1.inner > *s2.inner; } 163 bool ?>=?(const string & s1, const string & s2) { return *s1.inner >= *s2.inner; } 164 bool ?<=?(const string & s1, const string & s2) { return *s1.inner <= *s2.inner; } 165 bool ?<? (const string & s1, const string & s2) { return *s1.inner < *s2.inner; } 166 167 int strcmp(const string & s1, const char * s2) { return strcmp(*s1.inner, s2 ); } 168 bool ?==?(const string & s1, const char * s2) { return *s1.inner == s2; } 169 bool ?!=?(const string & s1, const char * s2) { return *s1.inner != s2; } 170 bool ?>? (const string & s1, const char * s2) { return *s1.inner > s2; } 171 bool ?>=?(const string & s1, const char * s2) { return *s1.inner >= s2; } 172 bool ?<=?(const string & s1, const char * s2) { return *s1.inner <= s2; } 173 bool ?<? (const string & s1, const char * s2) { return *s1.inner < s2; } 174 175 int strcmp(const char * s1, const string & s2) { return strcmp( s1, *s2.inner); } 176 bool ?==?(const char * s1, const string & s2) { return s1 == *s2.inner; } 177 bool ?!=?(const char * s1, const string & s2) { return s1 != *s2.inner; } 178 bool ?>? (const char * s1, const string & s2) { return s1 > *s2.inner; } 179 bool ?>=?(const char * s1, const string & s2) { return s1 >= *s2.inner; } 180 bool ?<=?(const char * s1, const string & s2) { return s1 <= *s2.inner; } 181 bool ?<? (const char * s1, const string & s2) { return s1 < *s2.inner; } 182 182 183 183 … … 186 186 187 187 size_t size(const string & s) { 188 return size( * 188 return size( *s.inner ); 189 189 } 190 190 … … 192 192 // Concatenation 193 193 194 void ?+=?(string & s, char other) {195 (*s.inner) += other;194 void ?+=?(string & s, char c) { 195 (*s.inner) += c; 196 196 } 197 197 … … 200 200 } 201 201 202 void ?+=?(string & s, const char * other) {203 (*s.inner) += other;204 } 205 206 string ?+?(const string & s, char other) {202 void ?+=?(string & s, const char * c) { 203 (*s.inner) += c; 204 } 205 206 string ?+?(const string & s, char c) { 207 207 string ret = s; 208 ret += other;208 ret += c; 209 209 return ret; 210 210 } … … 222 222 } 223 223 224 string ?+?(const string & s, const char * other) {224 string ?+?(const string & s, const char * c) { 225 225 string ret = s; 226 ret += other;226 ret += c; 227 227 return ret; 228 228 } … … 339 339 // charclass, include, exclude 340 340 341 void ?{}( charclass & this, const string & chars) {342 ( this.inner) { malloc() };343 ?{}( * this.inner, *(const string_res *)chars.inner );344 } 345 346 void ?{}( charclass & this, const char * chars ) {347 ( this.inner) { malloc() };348 ?{}( * this.inner, chars );349 } 350 351 void ?{}( charclass & this, const char * chars, size_t charssize ) {352 ( this.inner) { malloc() };353 ?{}( * this.inner, chars, charssize );354 } 355 356 void ^?{}( charclass & this ) {357 ^(* this.inner){};358 free( this.inner );359 this.inner = 0p;341 void ?{}( charclass & s, const string & chars) { 342 (s.inner) { malloc() }; 343 ?{}( *s.inner, *(const string_res *)chars.inner ); 344 } 345 346 void ?{}( charclass & s, const char * chars ) { 347 (s.inner) { malloc() }; 348 ?{}( *s.inner, chars ); 349 } 350 351 void ?{}( charclass & s, const char * chars, size_t charssize ) { 352 (s.inner) { malloc() }; 353 ?{}( *s.inner, chars, charssize ); 354 } 355 356 void ^?{}( charclass & s ) { 357 ^(*s.inner){}; 358 free( s.inner ); 359 s.inner = 0p; 360 360 } 361 361 -
libcfa/src/collections/string.hfa
r8b4faf6 r681e12f 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Sep 2 11:26:28 202313 // Update Count : 5512 // Last Modified On : Thu Jan 4 11:27:35 2024 13 // Update Count : 75 14 14 // 15 15 … … 29 29 // Getters 30 30 size_t size(const string & s); 31 static inline size_t strlen(const string & s) { return size( s ); } 31 32 32 33 // RAII, assignment 33 void ?{}(string & this); // empty string34 void ?{}(string & s); // empty string 34 35 void ?{}(string & s, const char * initial); // copy from string literal (NULL-terminated) 35 36 void ?{}(string & s, const char * buffer, size_t bsize); // copy specific length from buffer … … 38 39 void ?{}(string & s, string & s2); 39 40 40 void ?=?(string & s, const char * other); // copy assignment from literal 41 void ?=?(string & s, const string & other); 42 void ?=?(string & s, char other); 43 string & ?=?(string & s, string & other); // surprising ret seems to help avoid calls to autogen 41 void ?=?(string & s, const char * c); // copy assignment from literal 42 static inline string & strcpy(string & s, const char * c) { s = c; return s; } 43 void ?=?(string & s, const string & c); 44 static inline string & strcpy(string & s, const string c) { s = c; return s; } 45 void ?=?(string & s, char c); 46 string & ?=?(string & s, string & c); // surprising ret seems to help avoid calls to autogen 44 47 //string ?=?( string &, string ) = void; 45 48 void ^?{}(string & s); … … 49 52 string * s; 50 53 }; 51 string_WithSharedEdits ?`shareEdits( string & this );52 void ?{}( string & this, string_WithSharedEdits src );54 string_WithSharedEdits ?`shareEdits( string & s ); 55 void ?{}( string & s, string_WithSharedEdits src ); 53 56 54 57 // IO Operator … … 56 59 void ?|?(ofstream & out, const string & s); 57 60 ifstream & ?|?(ifstream & in, string & s); 58 void ?|?( ifstream & in, string & this );61 void ?|?( ifstream & in, string & s ); 59 62 60 63 static inline { … … 81 84 _Istream_Sstr wdi( unsigned int rwd, string & s ) { return (_Istream_Sstr)@{ s, {{0p}, rwd, {.flags.rwd : true}} }; } 82 85 _Istream_Sstr getline( string & s, const char delimiter = '\n' ) { 83 return (_Istream_Sstr)@{ s, {{.delimiter : { delimiter, '\0' } }, -1, {.flags.delimiter : true, .flags.inex : true}} };86 return (_Istream_Sstr)@{ s, {{.delimiters : { delimiter, '\0' } }, -1, {.flags.delimiter : true, .flags.inex : true}} }; 84 87 } 85 88 _Istream_Sstr & getline( _Istream_Sstr & fmt, const char delimiter = '\n' ) { 86 fmt.delimiter [0] = delimiter; fmt.delimiter[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt;89 fmt.delimiters[0] = delimiter; fmt.delimiters[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt; 87 90 } 88 91 _Istream_Sstr incl( const char scanset[], string & s ) { return (_Istream_Sstr)@{ s, {{scanset}, -1, {.flags.inex : false}} }; } … … 97 100 98 101 // Concatenation 99 void ?+=?(string & s, char other); // append a character102 void ?+=?(string & s, char c); // append a character 100 103 void ?+=?(string & s, const string & s2); // append-concatenate to first string 101 void ?+=?(string & s, const char * other); // append-concatenate to first string 102 string ?+?(const string & s, char other); // add a character to a copy of the string 104 static inline string & strcat(string & s, const string & s2) { s += s2; return s; } 105 void ?+=?(string & s, const char * s2); // append-concatenate to first string 106 static inline string & strcat(string & s, const char * c) { s += c; return s; } 107 string ?+?(const string & s, char c); // add a character to a copy of the string 103 108 string ?+?(const string & s, const string & s2); // copy and concatenate both strings 104 109 string ?+?(const char * s1, const char * s2); // concatenate both strings 105 string ?+?(const string & s, const char * other); // copy and concatenate with NULL-terminated string110 string ?+?(const string & s, const char * c); // copy and concatenate with NULL-terminated string 106 111 107 112 // Repetition … … 116 121 117 122 // Comparisons 118 int cmp (const string &, const string &);123 int strcmp (const string &, const string &); 119 124 bool ?==?(const string &, const string &); 120 125 bool ?!=?(const string &, const string &); … … 124 129 bool ?<? (const string &, const string &); 125 130 126 int cmp (const string &, const char*);127 bool ?==?(const string &, const char *);128 bool ?!=?(const string &, const char *);129 bool ?>? (const string &, const char *);130 bool ?>=?(const string &, const char *);131 bool ?<=?(const string &, const char *);132 bool ?<? (const string &, const char *);133 134 int cmp (const char*, const string &);135 bool ?==?(const char *, const string &);136 bool ?!=?(const char *, const string &);137 bool ?>? (const char *, const string &);138 bool ?>=?(const char *, const string &);139 bool ?<=?(const char *, const string &);140 bool ?<? (const char *, const string &);131 int strcmp (const string &, const char *); 132 bool ?==?(const string &, const char *); 133 bool ?!=?(const string &, const char *); 134 bool ?>? (const string &, const char *); 135 bool ?>=?(const string &, const char *); 136 bool ?<=?(const string &, const char *); 137 bool ?<? (const string &, const char *); 138 139 int strcmp (const char *, const string &); 140 bool ?==?(const char *, const string &); 141 bool ?!=?(const char *, const string &); 142 bool ?>? (const char *, const string &); 143 bool ?>=?(const char *, const string &); 144 bool ?<=?(const char *, const string &); 145 bool ?<? (const char *, const string &); 141 146 142 147 143 148 // Slicing 144 string ?()( string & this, size_t start, size_t end ); // TODO const?145 string ?()( string & this, size_t start);149 string ?()( string & s, size_t start, size_t end ); // TODO const? 150 string ?()( string & s, size_t start); 146 151 147 152 // String search … … 177 182 178 183 179 180 184 struct charclass { 181 185 charclass_res * inner; -
libcfa/src/collections/string_res.cfa
r8b4faf6 r681e12f 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Oct 18 21:54:54 202313 // Update Count : 1512 // Last Modified On : Tue Jan 2 13:20:27 2024 13 // Update Count : 34 14 14 // 15 15 … … 22 22 // Workaround is: EndVbyte = TEMP_ALLOC(char, CurrSize) 23 23 // Should be: EndVbyte = alloc(CurrSize) 24 #define TEMP_ALLOC(T, n) (( T * ) malloc( n * sizeof( T ) ))24 #define TEMP_ALLOC(T, n) (( T * ) malloc( n * sizeof( T ) )) 25 25 26 26 #include <assert.h> … … 33 33 34 34 struct VbyteHeap { 35 36 int NoOfCompactions; // number of compactions of the byte area 37 int NoOfExtensions; // number of extensions in the size of the byte area 38 int NoOfReductions; // number of reductions in the size of the byte area 35 int NoOfCompactions; // number of compactions of the byte area 36 int NoOfExtensions; // number of extensions in the size of the byte area 37 int NoOfReductions; // number of reductions in the size of the byte area 39 38 40 int InitSize; // initial number of bytes in the byte-string area41 int CurrSize; // current number of bytes in the byte-string area42 char *StartVbyte; // pointer to the `st byte of the start of the byte-string area43 char *EndVbyte; // pointer to the next byte after the end of the currently used portion of byte-string area44 void *ExtVbyte; // pointer to the next byte after the end of the byte-string area45 46 HandleNode Header; // header node for handle list39 int InitSize; // initial number of bytes in the byte-string area 40 int CurrSize; // current number of bytes in the byte-string area 41 char *StartVbyte; // pointer to the `st byte of the start of the byte-string area 42 char *EndVbyte; // pointer to the next byte after the end of the currently used portion of byte-string area 43 void *ExtVbyte; // pointer to the next byte after the end of the byte-string area 44 45 HandleNode Header; // header node for handle list 47 46 }; // VbyteHeap 48 47 49 48 50 static void compaction( VbyteHeap & ); 51 static void garbage( VbyteHeap &, int ); 49 static void compaction( VbyteHeap & ); // compaction of the byte area 50 static void garbage( VbyteHeap &, int ); // garbage collect the byte area 52 51 static void extend( VbyteHeap &, int ); // extend the size of the byte area 53 52 static void reduce( VbyteHeap &, int ); // reduce the size of the byte area … … 67 66 // Allocate the storage for the variable sized area and intialize the heap variables. 68 67 69 static void ?{}( VbyteHeap & this, size_t Size ) with(this) {70 #ifdef VbyteDebug 71 serr | "enter:VbyteHeap::VbyteHeap, this:" | &this | " Size:" | Size;68 static void ?{}( VbyteHeap & s, size_t Size ) with(s) { 69 #ifdef VbyteDebug 70 serr | "enter:VbyteHeap::VbyteHeap, s:" | &s | " Size:" | Size; 72 71 #endif // VbyteDebug 73 72 NoOfCompactions = NoOfExtensions = NoOfReductions = 0; … … 76 75 ExtVbyte = (void *)( StartVbyte + CurrSize ); 77 76 Header.flink = Header.blink = &Header; 78 Header.ulink = & this;77 Header.ulink = &s; 79 78 #ifdef VbyteDebug 80 79 HeaderPtr = &Header; 81 serr | "exit:VbyteHeap::VbyteHeap, this:" | &this;80 serr | "exit:VbyteHeap::VbyteHeap, s:" | &s; 82 81 #endif // VbyteDebug 83 82 } // VbyteHeap … … 86 85 // Release the dynamically allocated storage for the byte area. 87 86 88 static void ^?{}( VbyteHeap & this ) with(this) {87 static void ^?{}( VbyteHeap & s ) with(s) { 89 88 free( StartVbyte ); 90 89 } // ~VbyteHeap … … 97 96 // creator. 98 97 99 static void ?{}( HandleNode & this ) with(this) {100 #ifdef VbyteDebug 101 serr | "enter:HandleNode::HandleNode, this:" | &this;98 static void ?{}( HandleNode & s ) with(s) { 99 #ifdef VbyteDebug 100 serr | "enter:HandleNode::HandleNode, s:" | &s; 102 101 #endif // VbyteDebug 103 102 s = 0; 104 103 lnth = 0; 105 104 #ifdef VbyteDebug 106 serr | "exit:HandleNode::HandleNode, this:" | &this;105 serr | "exit:HandleNode::HandleNode, s:" | &s; 107 106 #endif // VbyteDebug 108 107 } // HandleNode … … 112 111 // collection. 113 112 114 static void ?{}( HandleNode & this, VbyteHeap & vh ) with(this) {115 #ifdef VbyteDebug 116 serr | "enter:HandleNode::HandleNode, this:" | &this;113 static void ?{}( HandleNode & s, VbyteHeap & vh ) with(s) { 114 #ifdef VbyteDebug 115 serr | "enter:HandleNode::HandleNode, s:" | &s; 117 116 #endif // VbyteDebug 118 117 s = 0; 119 118 lnth = 0; 120 119 ulink = &vh; 121 AddThisAfter( this, *vh.Header.blink );122 #ifdef VbyteDebug 123 serr | "exit:HandleNode::HandleNode, this:" | &this;120 AddThisAfter( s, *vh.Header.blink ); 121 #ifdef VbyteDebug 122 serr | "exit:HandleNode::HandleNode, s:" | &s; 124 123 #endif // VbyteDebug 125 124 } // HandleNode … … 129 128 // is the responsibility of the creator to destroy it. 130 129 131 static void ^?{}( HandleNode & this ) with(this) {132 #ifdef VbyteDebug 133 serr | "enter:HandleNode::~HandleNode, this:" | & this;130 static void ^?{}( HandleNode & s ) with(s) { 131 #ifdef VbyteDebug 132 serr | "enter:HandleNode::~HandleNode, s:" | & s; 134 133 { 135 134 serr | nlOff; … … 142 141 } 143 142 #endif // VbyteDebug 144 DeleteNode( this );143 DeleteNode( s ); 145 144 } // ~HandleNode 146 145 … … 151 150 static string_sharectx default_string_sharectx = {NEW_SHARING}; // stable bottom of stack 152 151 153 void ?{}( string_sharectx & this, StringSharectx_Mode mode ) with( this ) {152 void ?{}( string_sharectx & s, StringSharectx_Mode mode ) with( s ) { 154 153 (older){ ambient_string_sharectx }; 155 154 if ( mode == NEW_SHARING ) { … … 159 158 (activeHeap){ 0p }; 160 159 } 161 ambient_string_sharectx = & this;162 } 163 164 void ^?{}( string_sharectx & this ) with( this ) {160 ambient_string_sharectx = & s; 161 } 162 163 void ^?{}( string_sharectx & s ) with( s ) { 165 164 if ( activeHeap ) delete( activeHeap ); 166 165 167 // unlink this from older-list starting from ambient_string_sharectx168 // usually, this==ambient_string_sharectx and the loop runs zero times166 // unlink s from older-list starting from ambient_string_sharectx 167 // usually, s==ambient_string_sharectx and the loop runs zero times 169 168 string_sharectx *& c = ambient_string_sharectx; 170 while ( c != & this ) &c = &c->older; // find this171 c = this.older; // unlink169 while ( c != &s ) &c = &c->older; // find s 170 c = s.older; // unlink 172 171 } 173 172 … … 193 192 194 193 // Returns the size of the string in bytes 195 size_t size(const string_res & s) with(s) {194 size_t size(const string_res & s) with(s) { 196 195 return Handle.lnth; 197 196 } 198 197 199 198 // Output operator 200 ofstream & ?|?(ofstream & out, const string_res &s) {199 ofstream & ?|?(ofstream & out, const string_res & s) { 201 200 // CFA string is NOT null terminated, so print exactly lnth characters in a minimum width of 0. 202 201 out | wd( 0, s.Handle.lnth, s.Handle.s ) | nonl; … … 204 203 } 205 204 206 void ?|?(ofstream & out, const string_res &s) {205 void ?|?(ofstream & out, const string_res & s) { 207 206 (ofstream &)(out | s); ends( out ); 208 207 } 209 208 210 209 // Input operator 211 ifstream & ?|?(ifstream &in, string_res &s) { 212 210 ifstream & ?|?(ifstream & in, string_res & s) { 213 211 // Reading into a temp before assigning to s is near zero overhead in typical cases because of sharing. 214 212 // If s is a substring of something larger, simple assignment takes care of that case correctly. … … 238 236 *(temp.Handle.ulink->EndVbyte) = '\0'; // pre-assign empty cstring 239 237 in | wdi( lenReadable, temp.Handle.ulink->EndVbyte ); 240 } catch (cstring_length *) {238 } catch (cstring_length *) { 241 239 cont = true; 242 240 } … … 252 250 } 253 251 254 void ?|?( ifstream & in, string_res & this ) {255 (ifstream &)(in | this);252 void ?|?( ifstream & in, string_res & s ) { 253 (ifstream &)(in | s); 256 254 } 257 255 … … 274 272 cont = true; 275 273 } finally { 276 if ( ! cf.flags.ignore && // ok to initialize string 277 cstr[0] != '\0' ) { // something was read 274 if ( ! cf.flags.ignore // ok to initialize string 275 // && cstr[0] != '\0' // something was read 276 ) { 278 277 *(f.s) = cstr; 279 278 } … … 287 286 cont = true; // continue not allowed 288 287 } finally { 289 if ( ! cf.flags.ignore && 290 cstr[0] != '\0' ) { // something was read 288 if ( ! cf.flags.ignore && cstr[0] != '\0' ) { // something was read 291 289 *(f.s) += cstr; // build string chunk at a time 292 290 } … … 302 300 303 301 // Empty constructor 304 void ?{}(string_res & s) with(s) {302 void ?{}(string_res & s) with(s) { 305 303 if( ambient_string_sharectx->activeHeap ) { 306 304 (Handle){ * ambient_string_sharectx->activeHeap }; … … 317 315 } 318 316 319 static void eagerCopyCtorHelper(string_res & s, const char* rhs, size_t rhslnth) with(s) {317 static void eagerCopyCtorHelper(string_res & s, const char* rhs, size_t rhslnth) with(s) { 320 318 if( ambient_string_sharectx->activeHeap ) { 321 319 (Handle){ * ambient_string_sharectx->activeHeap }; … … 333 331 334 332 // Constructor from a raw buffer and size 335 void ?{}(string_res & s, const char* rhs, size_t rhslnth) with(s) {333 void ?{}(string_res & s, const char* rhs, size_t rhslnth) with(s) { 336 334 eagerCopyCtorHelper(s, rhs, rhslnth); 337 335 } 338 336 339 337 // private ctor (not in header): use specified heap (ignore ambient) and copy chars in 340 void ?{}( string_res & s, VbyteHeap & heap, const char* rhs, size_t rhslnth ) with(s) {338 void ?{}( string_res & s, VbyteHeap & heap, const char* rhs, size_t rhslnth ) with(s) { 341 339 (Handle){ heap }; 342 340 Handle.s = VbyteAlloc(*Handle.ulink, rhslnth); … … 349 347 350 348 // General copy constructor 351 void ?{}(string_res & s, const string_res & s2, StrResInitMode mode, size_t start, size_t end ) {349 void ?{}(string_res & s, const string_res & s2, StrResInitMode mode, size_t start, size_t end ) { 352 350 353 351 verify( start <= end && end <= s2.Handle.lnth ); … … 394 392 } 395 393 396 static void assignEditSet(string_res & this, string_res * shareEditSetStartPeer, string_res * shareEditSetEndPeer,394 static void assignEditSet(string_res & s, string_res * shareEditSetStartPeer, string_res * shareEditSetEndPeer, 397 395 char * resultSesStart, 398 396 size_t resultSesLnth, … … 400 398 401 399 char * beforeBegin = shareEditSetStartPeer->Handle.s; 402 size_t beforeLen = this.Handle.s - beforeBegin;403 404 char * afterBegin = this.Handle.s + this.Handle.lnth;400 size_t beforeLen = s.Handle.s - beforeBegin; 401 402 char * afterBegin = s.Handle.s + s.Handle.lnth; 405 403 size_t afterLen = shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - afterBegin; 406 404 407 size_t oldLnth = this.Handle.lnth;408 409 this.Handle.s = resultSesStart + beforeLen;410 this.Handle.lnth = bsize;405 size_t oldLnth = s.Handle.lnth; 406 407 s.Handle.s = resultSesStart + beforeLen; 408 s.Handle.lnth = bsize; 411 409 if (resultPadPosition) 412 MoveThisAfter( this.Handle, *resultPadPosition );410 MoveThisAfter( s.Handle, *resultPadPosition ); 413 411 414 412 // adjust all substring string and handle locations, and check if any substring strings are outside the new base string 415 413 char *limit = resultSesStart + resultSesLnth; 416 for ( string_res * p = this.shareEditSet_next; p != &this; p = p->shareEditSet_next ) {414 for ( string_res * p = s.shareEditSet_next; p != &s; p = p->shareEditSet_next ) { 417 415 verify (p->Handle.s >= beforeBegin); 418 416 if ( p->Handle.s >= afterBegin ) { … … 439 437 // take end as end-anchored 440 438 // stretch-shrink p according to the edit 441 p->Handle.lnth += this.Handle.lnth;439 p->Handle.lnth += s.Handle.lnth; 442 440 p->Handle.lnth -= oldLnth; 443 441 } … … 452 450 // p ends during the edit; p does not include the last character replaced 453 451 // set p to empty string at start of edit 454 p->Handle.s = this.Handle.s;452 p->Handle.s = s.Handle.s; 455 453 p->Handle.lnth = 0; 456 454 } else { … … 458 456 // clip start of p to start at end of edit 459 457 int charsToClip = afterBegin - p->Handle.s; 460 p->Handle.s = this.Handle.s + this.Handle.lnth;458 p->Handle.s = s.Handle.s + s.Handle.lnth; 461 459 p->Handle.lnth -= charsToClip; 462 460 } … … 467 465 } 468 466 469 // traverse the share-edit set (SES) to recover the range of a base string to which ` this` belongs470 static void locateInShareEditSet( string_res & this, string_res *&shareEditSetStartPeer, string_res *&shareEditSetEndPeer ) {471 shareEditSetStartPeer = & this;472 shareEditSetEndPeer = & this;473 for (string_res * editPeer = this.shareEditSet_next; editPeer != &this; editPeer = editPeer->shareEditSet_next) {467 // traverse the share-edit set (SES) to recover the range of a base string to which `s` belongs 468 static void locateInShareEditSet( string_res & s, string_res *& shareEditSetStartPeer, string_res *& shareEditSetEndPeer ) { 469 shareEditSetStartPeer = & s; 470 shareEditSetEndPeer = & s; 471 for (string_res * editPeer = s.shareEditSet_next; editPeer != &s; editPeer = editPeer->shareEditSet_next) { 474 472 if ( editPeer->Handle.s < shareEditSetStartPeer->Handle.s ) { 475 473 shareEditSetStartPeer = editPeer; … … 481 479 } 482 480 483 static string_res & assign_(string_res & this, const char* buffer, size_t bsize, const string_res & valSrc) {481 static string_res & assign_(string_res & s, const char* buffer, size_t bsize, const string_res & valSrc) { 484 482 485 483 string_res * shareEditSetStartPeer; 486 484 string_res * shareEditSetEndPeer; 487 locateInShareEditSet( this, shareEditSetStartPeer, shareEditSetEndPeer );485 locateInShareEditSet( s, shareEditSetStartPeer, shareEditSetEndPeer ); 488 486 489 487 verify( shareEditSetEndPeer->Handle.s >= shareEditSetStartPeer->Handle.s ); 490 488 size_t origEditSetLength = shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - shareEditSetStartPeer->Handle.s; 491 verify( origEditSetLength >= this.Handle.lnth );492 493 if ( this.shareEditSet_owns_ulink ) { // assigning to private context489 verify( origEditSetLength >= s.Handle.lnth ); 490 491 if ( s.shareEditSet_owns_ulink ) { // assigning to private context 494 492 // ok to overwrite old value within LHS 495 493 char * prefixStartOrig = shareEditSetStartPeer->Handle.s; 496 int prefixLen = this.Handle.s - prefixStartOrig;497 char * suffixStartOrig = this.Handle.s + this.Handle.lnth;494 int prefixLen = s.Handle.s - prefixStartOrig; 495 char * suffixStartOrig = s.Handle.s + s.Handle.lnth; 498 496 int suffixLen = shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - suffixStartOrig; 499 497 500 int delta = bsize - this.Handle.lnth;501 if ( char * oldBytes = VbyteTryAdjustLast( * this.Handle.ulink, delta ) ) {498 int delta = bsize - s.Handle.lnth; 499 if ( char * oldBytes = VbyteTryAdjustLast( *s.Handle.ulink, delta ) ) { 502 500 // growing: copy from old to new 503 char * dest = VbyteAlloc( * this.Handle.ulink, origEditSetLength + delta );501 char * dest = VbyteAlloc( *s.Handle.ulink, origEditSetLength + delta ); 504 502 char *destCursor = dest; memcpy(destCursor, prefixStartOrig, prefixLen); 505 503 destCursor += prefixLen; memcpy(destCursor, buffer , bsize ); 506 504 destCursor += bsize; memcpy(destCursor, suffixStartOrig, suffixLen); 507 assignEditSet( this, shareEditSetStartPeer, shareEditSetEndPeer,505 assignEditSet(s, shareEditSetStartPeer, shareEditSetEndPeer, 508 506 dest, 509 507 origEditSetLength + delta, … … 513 511 // room is already allocated in-place: bubble suffix and overwite middle 514 512 memmove( suffixStartOrig + delta, suffixStartOrig, suffixLen ); 515 memcpy( this.Handle.s, buffer, bsize );516 517 assignEditSet( this, shareEditSetStartPeer, shareEditSetEndPeer,513 memcpy( s.Handle.s, buffer, bsize ); 514 515 assignEditSet(s, shareEditSetStartPeer, shareEditSetEndPeer, 518 516 shareEditSetStartPeer->Handle.s, 519 517 origEditSetLength + delta, … … 522 520 523 521 } else if ( // assigning to shared context 524 this.Handle.lnth == origEditSetLength && // overwriting entire run of SES522 s.Handle.lnth == origEditSetLength && // overwriting entire run of SES 525 523 & valSrc && // sourcing from a managed string 526 valSrc.Handle.ulink == this.Handle.ulink ) { // sourcing from same heap524 valSrc.Handle.ulink == s.Handle.ulink ) { // sourcing from same heap 527 525 528 526 // SES's result will only use characters from the source string => reuse source 529 assignEditSet( this, shareEditSetStartPeer, shareEditSetEndPeer,527 assignEditSet(s, shareEditSetStartPeer, shareEditSetEndPeer, 530 528 valSrc.Handle.s, 531 529 valSrc.Handle.lnth, … … 537 535 538 536 // full string is from start of shareEditSetStartPeer thru end of shareEditSetEndPeer 539 // ` this` occurs in the middle of it, to be replaced537 // `s` occurs in the middle of it, to be replaced 540 538 // build up the new text in `pasting` 541 539 542 540 string_res pasting = { 543 * this.Handle.ulink, // maintain same heap, regardless of context541 * s.Handle.ulink, // maintain same heap, regardless of context 544 542 shareEditSetStartPeer->Handle.s, // start of SES 545 this.Handle.s - shareEditSetStartPeer->Handle.s }; // length of SES, before this543 s.Handle.s - shareEditSetStartPeer->Handle.s }; // length of SES, before s 546 544 append( pasting, 547 buffer, // start of replacement for this548 bsize ); // length of replacement for this545 buffer, // start of replacement for s 546 bsize ); // length of replacement for s 549 547 append( pasting, 550 this.Handle.s + this.Handle.lnth, // start of SES after this548 s.Handle.s + s.Handle.lnth, // start of SES after s 551 549 shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - 552 ( this.Handle.s + this.Handle.lnth) ); // length of SES, after this550 (s.Handle.s + s.Handle.lnth) ); // length of SES, after s 553 551 554 552 // The above string building can trigger compaction. 555 553 // The reference points (that are arguments of the string building) may move during that building. 556 // From this point on, they are stable.557 558 assignEditSet( this, shareEditSetStartPeer, shareEditSetEndPeer,554 // From s point on, they are stable. 555 556 assignEditSet(s, shareEditSetStartPeer, shareEditSetEndPeer, 559 557 pasting.Handle.s, 560 558 pasting.Handle.lnth, … … 562 560 } 563 561 564 return this;565 } 566 567 string_res & assign(string_res & this, const char* buffer, size_t bsize) {568 return assign_( this, buffer, bsize, *0p);569 } 570 571 string_res & ?=?(string_res & s, char other) {572 return assign(s, & other, 1);562 return s; 563 } 564 565 string_res & assign(string_res & s, const char* buffer, size_t bsize) { 566 return assign_(s, buffer, bsize, *0p); 567 } 568 569 string_res & ?=?(string_res & s, char c) { 570 return assign(s, &c, 1); 573 571 } 574 572 575 573 // Copy assignment operator 576 string_res & ?=?(string_res & this, const string_res & rhs) with( this ) {577 return assign_( this, rhs.Handle.s, rhs.Handle.lnth, rhs);578 } 579 580 string_res & ?=?(string_res & this, string_res & rhs) with( this ) {574 string_res & ?=?(string_res & s, const string_res & rhs) with( s ) { 575 return assign_(s, rhs.Handle.s, rhs.Handle.lnth, rhs); 576 } 577 578 string_res & ?=?(string_res & s, string_res & rhs) with( s ) { 581 579 const string_res & rhs2 = rhs; 582 return this = rhs2;580 return s = rhs2; 583 581 } 584 582 585 583 586 584 // Destructor 587 void ^?{}(string_res & s) with(s) {585 void ^?{}(string_res & s) with(s) { 588 586 // much delegated to implied ^VbyteSM 589 587 … … 603 601 // With unicode support, this may be different from just the byte at the given 604 602 // offset from the start of the string. 605 char ?[?](const string_res & s, size_t index) with(s) {603 char ?[?](const string_res & s, size_t index) with(s) { 606 604 //TODO: Check if index is valid (no exceptions yet) 607 605 return Handle.s[index]; 608 606 } 609 607 610 void assignAt(const string_res & s, size_t index, char val) {608 void assignAt(const string_res & s, size_t index, char val) { 611 609 string_res editZone = { s, SHARE_EDITS, index, index+1 }; 612 610 assign(editZone, &val, 1); … … 617 615 // Concatenation 618 616 619 void append(string_res & str1, const char * buffer, size_t bsize) {617 void append(string_res & str1, const char * buffer, size_t bsize) { 620 618 size_t clnth = str1.Handle.lnth + bsize; 621 619 if ( str1.Handle.s + str1.Handle.lnth == buffer ) { // already juxtapose ? … … 635 633 } 636 634 637 void ?+=?(string_res & str1, const string_res &str2) {635 void ?+=?(string_res & str1, const string_res & str2) { 638 636 append( str1, str2.Handle.s, str2.Handle.lnth ); 639 637 } 640 638 641 void ?+=?(string_res &s, char other) { 642 append( s, &other, 1 ); 643 } 644 645 646 639 void ?+=?(string_res & s, char c) { 640 append( s, & c, 1 ); 641 } 647 642 648 643 … … 650 645 // Comparisons 651 646 652 int cmp(const string_res &s1, const string_res &s2) {647 int strcmp(const string_res & s1, const string_res & s2) { 653 648 // return 0; 654 649 int ans1 = memcmp(s1.Handle.s, s2.Handle.s, min(s1.Handle.lnth, s2.Handle.lnth)); … … 657 652 } 658 653 659 bool ?==?(const string_res & s1, const string_res &s2) { returncmp(s1, s2) == 0; }660 bool ?!=?(const string_res & s1, const string_res &s2) { returncmp(s1, s2) != 0; }661 bool ?>? (const string_res & s1, const string_res &s2) { returncmp(s1, s2) > 0; }662 bool ?>=?(const string_res & s1, const string_res &s2) { returncmp(s1, s2) >= 0; }663 bool ?<=?(const string_res & s1, const string_res &s2) { returncmp(s1, s2) <= 0; }664 bool ?<? (const string_res & s1, const string_res &s2) { returncmp(s1, s2) < 0; }665 666 int cmp (const string_res &s1, const char* s2) {654 bool ?==?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) == 0; } 655 bool ?!=?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) != 0; } 656 bool ?>? (const string_res & s1, const string_res & s2) { return strcmp(s1, s2) > 0; } 657 bool ?>=?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) >= 0; } 658 bool ?<=?(const string_res & s1, const string_res & s2) { return strcmp(s1, s2) <= 0; } 659 bool ?<? (const string_res & s1, const string_res & s2) { return strcmp(s1, s2) < 0; } 660 661 int strcmp (const string_res & s1, const char* s2) { 667 662 string_res s2x = s2; 668 return cmp(s1, s2x);669 } 670 671 bool ?==?(const string_res & s1, const char* s2) { returncmp(s1, s2) == 0; }672 bool ?!=?(const string_res & s1, const char* s2) { returncmp(s1, s2) != 0; }673 bool ?>? (const string_res & s1, const char* s2) { returncmp(s1, s2) > 0; }674 bool ?>=?(const string_res & s1, const char* s2) { returncmp(s1, s2) >= 0; }675 bool ?<=?(const string_res & s1, const char* s2) { returncmp(s1, s2) <= 0; }676 bool ?<? (const string_res & s1, const char* s2) { returncmp(s1, s2) < 0; }677 678 int cmp (const char* s1, const string_res & s2) {663 return strcmp(s1, s2x); 664 } 665 666 bool ?==?(const string_res & s1, const char* s2) { return strcmp(s1, s2) == 0; } 667 bool ?!=?(const string_res & s1, const char* s2) { return strcmp(s1, s2) != 0; } 668 bool ?>? (const string_res & s1, const char* s2) { return strcmp(s1, s2) > 0; } 669 bool ?>=?(const string_res & s1, const char* s2) { return strcmp(s1, s2) >= 0; } 670 bool ?<=?(const string_res & s1, const char* s2) { return strcmp(s1, s2) <= 0; } 671 bool ?<? (const string_res & s1, const char* s2) { return strcmp(s1, s2) < 0; } 672 673 int strcmp (const char* s1, const string_res & s2) { 679 674 string_res s1x = s1; 680 return cmp(s1x, s2);681 } 682 683 bool ?==?(const char* s1, const string_res & s2) { returncmp(s1, s2) == 0; }684 bool ?!=?(const char* s1, const string_res & s2) { returncmp(s1, s2) != 0; }685 bool ?>? (const char* s1, const string_res & s2) { returncmp(s1, s2) > 0; }686 bool ?>=?(const char* s1, const string_res & s2) { returncmp(s1, s2) >= 0; }687 bool ?<=?(const char* s1, const string_res & s2) { returncmp(s1, s2) <= 0; }688 bool ?<? (const char* s1, const string_res & s2) { returncmp(s1, s2) < 0; }675 return strcmp(s1x, s2); 676 } 677 678 bool ?==?(const char* s1, const string_res & s2) { return strcmp(s1, s2) == 0; } 679 bool ?!=?(const char* s1, const string_res & s2) { return strcmp(s1, s2) != 0; } 680 bool ?>? (const char* s1, const string_res & s2) { return strcmp(s1, s2) > 0; } 681 bool ?>=?(const char* s1, const string_res & s2) { return strcmp(s1, s2) >= 0; } 682 bool ?<=?(const char* s1, const string_res & s2) { return strcmp(s1, s2) <= 0; } 683 bool ?<? (const char* s1, const string_res & s2) { return strcmp(s1, s2) < 0; } 689 684 690 685 … … 693 688 // Search 694 689 695 bool contains(const string_res & s, char ch) {690 bool contains(const string_res & s, char ch) { 696 691 for ( i; size(s) ) { 697 692 if (s[i] == ch) return true; … … 700 695 } 701 696 702 int find(const string_res & s, char search) {697 int find(const string_res & s, char search) { 703 698 return findFrom(s, 0, search); 704 699 } 705 700 706 int findFrom(const string_res & s, size_t fromPos, char search) {701 int findFrom(const string_res & s, size_t fromPos, char search) { 707 702 // FIXME: This paricular overload (find of single char) is optimized to use memchr. 708 703 // The general overload (find of string, memchr applying to its first character) and `contains` should be adjusted to match. … … 715 710 } 716 711 717 int find(const string_res & s, const string_res &search) {712 int find(const string_res & s, const string_res & search) { 718 713 return findFrom(s, 0, search); 719 714 } 720 715 721 int findFrom(const string_res & s, size_t fromPos, const string_res &search) {716 int findFrom(const string_res & s, size_t fromPos, const string_res & search) { 722 717 return findFrom(s, fromPos, search.Handle.s, search.Handle.lnth); 723 718 } 724 719 725 int find(const string_res & s, const char* search) {720 int find(const string_res & s, const char* search) { 726 721 return findFrom(s, 0, search); 727 722 } 728 int findFrom(const string_res & s, size_t fromPos, const char* search) {723 int findFrom(const string_res & s, size_t fromPos, const char* search) { 729 724 return findFrom(s, fromPos, search, strlen(search)); 730 725 } 731 726 732 int find(const string_res & s, const char* search, size_t searchsize) {727 int find(const string_res & s, const char* search, size_t searchsize) { 733 728 return findFrom(s, 0, search, searchsize); 734 729 } 735 730 736 int findFrom(const string_res & s, size_t fromPos, const char* search, size_t searchsize) {731 int findFrom(const string_res & s, size_t fromPos, const char* search, size_t searchsize) { 737 732 738 733 /* Remaining implementations essentially ported from Sunjay's work */ … … 771 766 } 772 767 773 bool includes(const string_res & s, const string_res &search) {768 bool includes(const string_res & s, const string_res & search) { 774 769 return includes(s, search.Handle.s, search.Handle.lnth); 775 770 } 776 771 777 bool includes(const string_res & s, const char* search) {772 bool includes(const string_res & s, const char* search) { 778 773 return includes(s, search, strlen(search)); 779 774 } 780 775 781 bool includes(const string_res & s, const char* search, size_t searchsize) {776 bool includes(const string_res & s, const char* search, size_t searchsize) { 782 777 return find(s, search, searchsize) < s.Handle.lnth; 783 778 } 784 779 785 bool startsWith(const string_res & s, const string_res &prefix) {780 bool startsWith(const string_res & s, const string_res & prefix) { 786 781 return startsWith(s, prefix.Handle.s, prefix.Handle.lnth); 787 782 } 788 783 789 bool startsWith(const string_res & s, const char* prefix) {784 bool startsWith(const string_res & s, const char* prefix) { 790 785 return startsWith(s, prefix, strlen(prefix)); 791 786 } 792 787 793 bool startsWith(const string_res & s, const char* prefix, size_t prefixsize) {788 bool startsWith(const string_res & s, const char* prefix, size_t prefixsize) { 794 789 if (s.Handle.lnth < prefixsize) { 795 790 return false; … … 798 793 } 799 794 800 bool endsWith(const string_res & s, const string_res &suffix) {795 bool endsWith(const string_res & s, const string_res & suffix) { 801 796 return endsWith(s, suffix.Handle.s, suffix.Handle.lnth); 802 797 } 803 798 804 bool endsWith(const string_res & s, const char* suffix) {799 bool endsWith(const string_res & s, const char* suffix) { 805 800 return endsWith(s, suffix, strlen(suffix)); 806 801 } 807 802 808 bool endsWith(const string_res & s, const char* suffix, size_t suffixsize) {803 bool endsWith(const string_res & s, const char* suffix, size_t suffixsize) { 809 804 if (s.Handle.lnth < suffixsize) { 810 805 return false; … … 822 817 // charclass, include, exclude 823 818 824 void ?{}( charclass_res & this, const string_res & chars) {825 ( this){ chars.Handle.s, chars.Handle.lnth };826 } 827 828 void ?{}( charclass_res & this, const char * chars ) {829 ( this){ chars, strlen(chars) };830 } 831 832 void ?{}( charclass_res & this, const char * chars, size_t charssize ) {833 ( this.chars){ chars, charssize };819 void ?{}( charclass_res & s, const string_res & chars) { 820 (s){ chars.Handle.s, chars.Handle.lnth }; 821 } 822 823 void ?{}( charclass_res & s, const char * chars ) { 824 (s){ chars, strlen(chars) }; 825 } 826 827 void ?{}( charclass_res & s, const char * chars, size_t charssize ) { 828 (s.chars){ chars, charssize }; 834 829 // now sort it ? 835 830 } 836 831 837 void ^?{}( charclass_res & this ) {838 ^( this.chars){};832 void ^?{}( charclass_res & s ) { 833 ^(s.chars){}; 839 834 } 840 835 … … 844 839 } 845 840 846 int exclude(const string_res & s, const charclass_res &mask) {841 int exclude(const string_res & s, const charclass_res & mask) { 847 842 for ( i; size(s) ) { 848 843 if ( test(mask, s[i]) ) return i; … … 851 846 } 852 847 853 int include(const string_res & s, const charclass_res &mask) {848 int include(const string_res & s, const charclass_res & mask) { 854 849 for ( i; size(s) ) { 855 850 if ( ! test(mask, s[i]) ) return i; … … 863 858 // Add a new HandleNode node n after the current HandleNode node. 864 859 865 static void AddThisAfter( HandleNode & this, HandleNode & n ) with(this) {866 #ifdef VbyteDebug 867 serr | "enter:AddThisAfter, this:" | &this | " n:" | &n;860 static void AddThisAfter( HandleNode & s, HandleNode & n ) with(s) { 861 #ifdef VbyteDebug 862 serr | "enter:AddThisAfter, s:" | &s | " n:" | &n; 868 863 #endif // VbyteDebug 869 864 // Performance note: we are on the critical path here. MB has ensured that the verifies don't contribute to runtime (are compiled away, like they're supposed to be). 870 865 verify( n.ulink != 0p ); 871 verify( this.ulink == n.ulink );866 verify( s.ulink == n.ulink ); 872 867 flink = n.flink; 873 868 blink = &n; 874 n.flink->blink = & this;875 n.flink = & this;869 n.flink->blink = &s; 870 n.flink = &s; 876 871 #ifdef VbyteDebug 877 872 { … … 894 889 // Delete the current HandleNode node. 895 890 896 static void DeleteNode( HandleNode & this ) with(this) {897 #ifdef VbyteDebug 898 serr | "enter:DeleteNode, this:" | &this;891 static void DeleteNode( HandleNode & s ) with(s) { 892 #ifdef VbyteDebug 893 serr | "enter:DeleteNode, s:" | &s; 899 894 #endif // VbyteDebug 900 895 flink->blink = blink; … … 906 901 907 902 908 909 903 // Allocates specified storage for a string from byte-string area. If not enough space remains to perform the 910 904 // allocation, the garbage collection routine is called. 911 905 912 static char * VbyteAlloc( VbyteHeap & this, int size ) with(this) {906 static char * VbyteAlloc( VbyteHeap & s, int size ) with(s) { 913 907 #ifdef VbyteDebug 914 908 serr | "enter:VbyteAlloc, size:" | size; … … 918 912 919 913 NoBytes = ( uintptr_t )EndVbyte + size; 920 if ( NoBytes > ( uintptr_t )ExtVbyte ) { // enough room for new byte-string ?921 garbage( this, size );// firer up the garbage collector914 if ( NoBytes > ( uintptr_t )ExtVbyte ) { // enough room for new byte-string ? 915 garbage( s, size ); // firer up the garbage collector 922 916 verify( (( uintptr_t )EndVbyte + size) <= ( uintptr_t )ExtVbyte && "garbage run did not free up required space" ); 923 917 } // if … … 939 933 // VbyteAlloc to claim the new space, while doing optimal copying from old to new, then free old. 940 934 941 static char * VbyteTryAdjustLast( VbyteHeap & this, int delta ) with(this) { 942 935 static char * VbyteTryAdjustLast( VbyteHeap & s, int delta ) with(s) { 943 936 if ( ( uintptr_t )EndVbyte + delta <= ( uintptr_t )ExtVbyte ) { 944 937 // room available … … 961 954 // the address in the byte string area. 962 955 963 static void MoveThisAfter( HandleNode & this, const HandleNode & h ) with(this) {964 #ifdef VbyteDebug 965 serr | "enter:MoveThisAfter, this:" | & this | " h:" | & h;956 static void MoveThisAfter( HandleNode & s, const HandleNode & h ) with(s) { 957 #ifdef VbyteDebug 958 serr | "enter:MoveThisAfter, s:" | & s | " h:" | & h; 966 959 #endif // VbyteDebug 967 960 verify( h.ulink != 0p ); 968 verify( this.ulink == h.ulink );961 verify( s.ulink == h.ulink ); 969 962 if ( s < h.s ) { // check argument values 970 963 // serr | "VbyteSM: Error - Cannot move byte string starting at:" | s | " after byte string starting at:" … … 976 969 HandleNode *i; 977 970 for ( i = h.flink; i->s != 0 && s > ( i->s ); i = i->flink ); // find the position for this node after h 978 if ( & this != i->blink ) {979 DeleteNode( this );980 AddThisAfter( this, *i->blink );971 if ( & s != i->blink ) { 972 DeleteNode( s ); 973 AddThisAfter( s, *i->blink ); 981 974 } // if 982 975 #ifdef VbyteDebug … … 1058 1051 // the containing string has been moved. Hence, they only require that their string pointers be adjusted. 1059 1052 1060 void compaction(VbyteHeap & this) with(this) {1053 void compaction(VbyteHeap & s) with(s) { 1061 1054 HandleNode *h; 1062 1055 char *obase, *nbase, *limit; … … 1098 1091 // the heap. The heap is then compacted in the existing heap or into the newly allocated heap. 1099 1092 1100 void garbage(VbyteHeap & this, int minreq ) with(this) {1093 void garbage(VbyteHeap & s, int minreq ) with(s) { 1101 1094 #ifdef VbyteDebug 1102 1095 serr | "enter:garbage"; … … 1124 1117 if ( ( double ) AmountFree < ( CurrSize * heap_expansion_freespace_threshold ) || AmountFree < minreq ) { // free space less than threshold or not enough to serve cur request 1125 1118 1126 extend( this, max( CurrSize, minreq ) ); // extend the heap1119 extend( s, max( CurrSize, minreq ) ); // extend the heap 1127 1120 1128 1121 // Peter says, "This needs work before it should be used." … … 1133 1126 1134 1127 } else { 1135 compaction( this); // in-place1128 compaction(s); // in-place 1136 1129 }// if 1137 1130 #ifdef VbyteDebug … … 1159 1152 // area is deleted. 1160 1153 1161 void extend( VbyteHeap & this, int size ) with (this) {1154 void extend( VbyteHeap & s, int size ) with (s) { 1162 1155 #ifdef VbyteDebug 1163 1156 serr | "enter:extend, size:" | size; … … 1171 1164 StartVbyte = EndVbyte = TEMP_ALLOC(char, CurrSize); 1172 1165 ExtVbyte = (void *)( StartVbyte + CurrSize ); 1173 compaction( this); // copy from old heap to new & adjust pointers to new heap1166 compaction(s); // copy from old heap to new & adjust pointers to new heap 1174 1167 free( OldStartVbyte ); // release old heap 1175 1168 #ifdef VbyteDebug -
libcfa/src/collections/string_res.hfa
r8b4faf6 r681e12f 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 12 15:45:47 202313 // Update Count : 2 12 // Last Modified On : Thu Jan 4 11:28:06 2024 13 // Update Count : 27 14 14 // 15 15 … … 70 70 71 71 // Getters 72 size_t size(const string_res & s);72 size_t size(const string_res & s); 73 73 74 74 // Constructors, Assignment Operators, Destructor 75 void ?{}(string_res & s); // empty string76 void ?{}(string_res & s, const char* buffer, size_t bsize); // copy specific length from buffer77 static inline void ?{}(string_res & s, const char* rhs) { // copy from string literal (NULL-terminated)75 void ?{}(string_res & s); // empty string 76 void ?{}(string_res & s, const char * buffer, size_t bsize); // copy specific length from buffer 77 static inline void ?{}(string_res & s, const char * rhs) { // copy from string literal (NULL-terminated) 78 78 (s){ rhs, strlen(rhs) }; 79 79 } 80 80 81 void ?{}(string_res & s, const string_res & s2) = void;82 void ?{}(string_res & s, string_res & s2) = void;81 void ?{}(string_res & s, const string_res & s2) = void; 82 void ?{}(string_res & s, string_res & s2) = void; 83 83 84 84 enum StrResInitMode { COPY_VALUE, SHARE_EDITS }; 85 void ?{}(string_res & s, const string_res & src, StrResInitMode, size_t start, size_t end );86 static inline void ?{}(string_res & s, const string_res & src, StrResInitMode mode ) {85 void ?{}(string_res & s, const string_res & src, StrResInitMode, size_t start, size_t end ); 86 static inline void ?{}(string_res & s, const string_res & src, StrResInitMode mode ) { 87 87 ?{}( s, src, mode, 0, size(src)); 88 88 } 89 89 90 string_res & assign(string_res & s, const char* buffer, size_t bsize); // copy specific length from buffer91 static inline string_res & ?=?(string_res & s, const char* other) { // copy from string literal (NULL-terminated)92 return assign(s, other, strlen(other));93 } 94 string_res & ?=?(string_res & s, const string_res &other);95 string_res & ?=?(string_res & s, string_res &other);96 string_res & ?=?(string_res & s, char other);97 98 void ^?{}(string_res & s);90 string_res & assign(string_res & s, const char * buffer, size_t bsize); // copy specific length from buffer 91 static inline string_res & ?=?(string_res & s, const char * c) { // copy from string literal (NULL-terminated) 92 return assign(s, c, strlen(c)); 93 } 94 string_res & ?=?(string_res & s, const string_res & c); 95 string_res & ?=?(string_res & s, string_res & c); 96 string_res & ?=?(string_res & s, char c); 97 98 void ^?{}(string_res & s); 99 99 100 100 // IO Operator 101 ofstream & ?|?(ofstream & out, const string_res &s);102 void ?|?(ofstream & out, const string_res &s);103 ifstream & ?|?(ifstream & in, string_res &s);104 void ?|?( ifstream & in, string_res & this );101 ofstream & ?|?(ofstream & out, const string_res & s); 102 void ?|?(ofstream & out, const string_res & s); 103 ifstream & ?|?(ifstream & in, string_res & s); 104 void ?|?( ifstream & in, string_res & s ); 105 105 106 106 struct _Istream_Rstr { … … 113 113 _Istream_Rstr wdi( unsigned int rwd, string_res & s ) { return (_Istream_Rstr)@{ &s, {{0p}, rwd, {.flags.rwd : true}} }; } 114 114 _Istream_Rstr getline( string_res & s, const char delimiter = '\n' ) { 115 return (_Istream_Rstr)@{ &s, {{.delimiter : { delimiter, '\0' } }, -1, {.flags.delimiter : true, .flags.inex : true}} };115 return (_Istream_Rstr)@{ &s, {{.delimiters : { delimiter, '\0' } }, -1, {.flags.delimiter : true, .flags.inex : true}} }; 116 116 } 117 117 _Istream_Rstr & getline( _Istream_Rstr & fmt, const char delimiter = '\n' ) { 118 fmt.delimiter [0] = delimiter; fmt.delimiter[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt;118 fmt.delimiters[0] = delimiter; fmt.delimiters[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt; 119 119 } 120 120 _Istream_Rstr incl( const char scanset[], string_res & s ) { return (_Istream_Rstr)@{ &s, {{scanset}, -1, {.flags.inex : false}} }; } … … 129 129 130 130 // Concatenation 131 void append(string_res & s, const char* buffer, size_t bsize);132 void ?+=?(string_res & s, char other); // append a character133 void ?+=?(string_res & s, const string_res &s2); // append-concatenate to first string134 static inline void ?+=?(string_res & s, const char* other) {135 append( s, other, strlen(other) );131 void append(string_res & s, const char * buffer, size_t bsize); 132 void ?+=?(string_res & s, char c); // append a character 133 void ?+=?(string_res & s, const string_res & s2); // append-concatenate to first string 134 static inline void ?+=?(string_res & s, const char * c) { 135 append( s, c, strlen(c) ); 136 136 } 137 137 138 138 // Character access 139 void assignAt(const string_res & s, size_t index, char val);140 char ?[?](const string_res & s, size_t index); // Mike changed to ret by val from Sunjay's ref, to match Peter's141 //char codePointAt(const string_res & s, size_t index); // revisit under Unicode139 void assignAt(const string_res & s, size_t index, char val); 140 char ?[?](const string_res & s, size_t index); // Mike changed to ret by val from Sunjay's ref, to match Peter's 141 //char codePointAt(const string_res & s, size_t index); // revisit under Unicode 142 142 143 143 // Comparisons 144 int cmp (const string_res &, const string_res &);144 int strcmp (const string_res &, const string_res &); 145 145 bool ?==?(const string_res &, const string_res &); 146 146 bool ?!=?(const string_res &, const string_res &); … … 150 150 bool ?<? (const string_res &, const string_res &); 151 151 152 int cmp (const string_res &, const char*);153 bool ?==?(const string_res &, const char *);154 bool ?!=?(const string_res &, const char *);155 bool ?>? (const string_res &, const char *);156 bool ?>=?(const string_res &, const char *);157 bool ?<=?(const string_res &, const char *);158 bool ?<? (const string_res &, const char *);159 160 int cmp (const char*, const string_res &);161 bool ?==?(const char *, const string_res &);162 bool ?!=?(const char *, const string_res &);163 bool ?>? (const char *, const string_res &);164 bool ?>=?(const char *, const string_res &);165 bool ?<=?(const char *, const string_res &);166 bool ?<? (const char *, const string_res &);152 int strcmp(const string_res &, const char *); 153 bool ?==?(const string_res &, const char *); 154 bool ?!=?(const string_res &, const char *); 155 bool ?>? (const string_res &, const char *); 156 bool ?>=?(const string_res &, const char *); 157 bool ?<=?(const string_res &, const char *); 158 bool ?<? (const string_res &, const char *); 159 160 int strcmp(const char *, const string_res &); 161 bool ?==?(const char *, const string_res &); 162 bool ?!=?(const char *, const string_res &); 163 bool ?>? (const char *, const string_res &); 164 bool ?>=?(const char *, const string_res &); 165 bool ?<=?(const char *, const string_res &); 166 bool ?<? (const char *, const string_res &); 167 167 168 168 // String search 169 bool contains(const string_res & s, char ch); // single character170 171 int find(const string_res & s, char search);172 int find(const string_res & s, const string_res &search);173 int find(const string_res & s, const char* search);174 int find(const string_res & s, const char* search, size_t searchsize);175 176 int findFrom(const string_res & s, size_t fromPos, char search);177 int findFrom(const string_res & s, size_t fromPos, const string_res &search);178 int findFrom(const string_res & s, size_t fromPos, const char* search);179 int findFrom(const string_res & s, size_t fromPos, const char* search, size_t searchsize);180 181 bool includes(const string_res & s, const string_res &search);182 bool includes(const string_res & s, const char* search);183 bool includes(const string_res & s, const char* search, size_t searchsize);184 185 bool startsWith(const string_res & s, const string_res &prefix);186 bool startsWith(const string_res & s, const char* prefix);187 bool startsWith(const string_res & s, const char* prefix, size_t prefixsize);188 189 bool endsWith(const string_res & s, const string_res &suffix);190 bool endsWith(const string_res & s, const char* suffix);191 bool endsWith(const string_res & s, const char* suffix, size_t suffixsize);192 193 int include(const string_res & s, const charclass_res &mask);194 int exclude(const string_res & s, const charclass_res &mask);169 bool contains(const string_res & s, char ch); // single character 170 171 int find(const string_res & s, char search); 172 int find(const string_res & s, const string_res & search); 173 int find(const string_res & s, const char * search); 174 int find(const string_res & s, const char * search, size_t searchsize); 175 176 int findFrom(const string_res & s, size_t fromPos, char search); 177 int findFrom(const string_res & s, size_t fromPos, const string_res & search); 178 int findFrom(const string_res & s, size_t fromPos, const char * search); 179 int findFrom(const string_res & s, size_t fromPos, const char * search, size_t searchsize); 180 181 bool includes(const string_res & s, const string_res & search); 182 bool includes(const string_res & s, const char * search); 183 bool includes(const string_res & s, const char * search, size_t searchsize); 184 185 bool startsWith(const string_res & s, const string_res & prefix); 186 bool startsWith(const string_res & s, const char * prefix); 187 bool startsWith(const string_res & s, const char * prefix, size_t prefixsize); 188 189 bool endsWith(const string_res & s, const string_res & suffix); 190 bool endsWith(const string_res & s, const char * suffix); 191 bool endsWith(const string_res & s, const char * suffix, size_t suffixsize); 192 193 int include(const string_res & s, const charclass_res & mask); 194 int exclude(const string_res & s, const charclass_res & mask); 195 195 196 196 // Modifiers 197 void padStart(string_res & s, size_t n);198 void padStart(string_res & s, size_t n, char padding);199 void padEnd(string_res & s, size_t n);197 void padStart(string_res & s, size_t n); 198 void padStart(string_res & s, size_t n, char padding); 199 void padEnd(string_res & s, size_t n); 200 200 void padEnd(string_res &s, size_t n, char padding); 201 201
Note: See TracChangeset
for help on using the changeset viewer.