| [f450f2f] | 1 | //
 | 
|---|
 | 2 | // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
 | 
|---|
 | 3 | //
 | 
|---|
 | 4 | // The contents of this file are covered under the licence agreement in the
 | 
|---|
 | 5 | // file "LICENCE" distributed with Cforall.
 | 
|---|
 | 6 | //
 | 
|---|
 | 7 | // string -- variable-length, mutable run of text, with value semantics
 | 
|---|
 | 8 | //
 | 
|---|
 | 9 | // Author           : Michael L. Brooks
 | 
|---|
 | 10 | // Created On       : Fri Sep 03 11:00:00 2021
 | 
|---|
 | 11 | // Last Modified By : Michael L. Brooks
 | 
|---|
 | 12 | // Last Modified On : Fri Sep 03 11:00:00 2021
 | 
|---|
 | 13 | // Update Count     : 1
 | 
|---|
 | 14 | //
 | 
|---|
 | 15 | 
 | 
|---|
 | 16 | #include "string.hfa"
 | 
|---|
 | 17 | #include "string_res.hfa"
 | 
|---|
 | 18 | #include <stdlib.hfa>
 | 
|---|
 | 19 | 
 | 
|---|
| [accc9df9] | 20 | #pragma GCC visibility push(default)
 | 
|---|
| [f450f2f] | 21 | 
 | 
|---|
 | 22 | /*
 | 
|---|
 | 23 | Implementation Principle: typical operation translates to the equivalent
 | 
|---|
 | 24 | operation on `inner`.  Exceptions are implementing new RAII pattern for value
 | 
|---|
 | 25 | semantics and some const-hell handling.
 | 
|---|
 | 26 | */
 | 
|---|
 | 27 | 
 | 
|---|
 | 28 | ////////////////////////////////////////////////////////
 | 
|---|
 | 29 | // string RAII
 | 
|---|
 | 30 | 
 | 
|---|
 | 31 | 
 | 
|---|
 | 32 | void ?{}( string & this ) {
 | 
|---|
 | 33 |     (this.inner) { malloc() };
 | 
|---|
 | 34 |     ?{}( *this.inner );
 | 
|---|
 | 35 | }
 | 
|---|
 | 36 | 
 | 
|---|
 | 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;
 | 
|---|
 | 66 | }
 | 
|---|
 | 67 | 
 | 
|---|
 | 68 | ////////////////////////////////////////////////////////
 | 
|---|
 | 69 | // Alternate construction: request shared edits
 | 
|---|
 | 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);
 | 
|---|
 | 78 | }
 | 
|---|
 | 79 | 
 | 
|---|
 | 80 | ////////////////////////////////////////////////////////
 | 
|---|
 | 81 | // Assignment
 | 
|---|
 | 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 | 
 | 
|---|
| [4b3b352] | 95 | string & ?=?(string & this, string & other) { //// <---- straw man change
 | 
|---|
| [f450f2f] | 96 |     (*this.inner) = (*other.inner);
 | 
|---|
 | 97 |     return this;
 | 
|---|
 | 98 | }
 | 
|---|
 | 99 | 
 | 
|---|
 | 100 | 
 | 
|---|
 | 101 | ////////////////////////////////////////////////////////
 | 
|---|
 | 102 | // Output
 | 
|---|
 | 103 | 
 | 
|---|
 | 104 | ofstream & ?|?( ofstream & fs, const string & this ) {
 | 
|---|
 | 105 |     return fs | (*this.inner);
 | 
|---|
 | 106 | }
 | 
|---|
 | 107 | 
 | 
|---|
 | 108 | void ?|?( ofstream & fs, const string & this ) {
 | 
|---|
 | 109 |     fs | (*this.inner);
 | 
|---|
 | 110 | }
 | 
|---|
 | 111 | 
 | 
|---|
 | 112 | ////////////////////////////////////////////////////////
 | 
|---|
 | 113 | // Slicing
 | 
|---|
 | 114 | 
 | 
|---|
 | 115 | string ?()( string & this, size_t start, size_t end ) {
 | 
|---|
 | 116 |     string ret = { *this.inner, start, end };
 | 
|---|
 | 117 |     return ret`shareEdits;
 | 
|---|
 | 118 | }
 | 
|---|
 | 119 | 
 | 
|---|
 | 120 | ////////////////////////////////////////////////////////
 | 
|---|
 | 121 | // Comparison
 | 
|---|
 | 122 | 
 | 
|---|
 | 123 | bool ?==?(const string &s, const string &other) {
 | 
|---|
 | 124 |     return *s.inner == *other.inner;
 | 
|---|
 | 125 | }
 | 
|---|
 | 126 | 
 | 
|---|
 | 127 | bool ?!=?(const string &s, const string &other) {
 | 
|---|
 | 128 |     return *s.inner != *other.inner;
 | 
|---|
 | 129 | }
 | 
|---|
 | 130 | 
 | 
|---|
 | 131 | bool ?==?(const string &s, const char* other) {
 | 
|---|
 | 132 |     return *s.inner == other;
 | 
|---|
 | 133 | }
 | 
|---|
 | 134 | 
 | 
|---|
 | 135 | bool ?!=?(const string &s, const char* other) {
 | 
|---|
 | 136 |     return *s.inner != other;
 | 
|---|
 | 137 | }
 | 
|---|
 | 138 | 
 | 
|---|
 | 139 | ////////////////////////////////////////////////////////
 | 
|---|
 | 140 | // Getter
 | 
|---|
 | 141 | 
 | 
|---|
 | 142 | size_t size(const string &s) {
 | 
|---|
 | 143 |     return size( * s.inner );
 | 
|---|
 | 144 | }
 | 
|---|
 | 145 | 
 | 
|---|
 | 146 | ////////////////////////////////////////////////////////
 | 
|---|
 | 147 | // Concatenation
 | 
|---|
 | 148 | 
 | 
|---|
 | 149 | void ?+=?(string &s, char other) {
 | 
|---|
 | 150 |     (*s.inner) += other;
 | 
|---|
 | 151 | }
 | 
|---|
 | 152 | 
 | 
|---|
 | 153 | void ?+=?(string &s, const string &s2) {
 | 
|---|
 | 154 |     (*s.inner) += (*s2.inner);
 | 
|---|
 | 155 | }
 | 
|---|
 | 156 | 
 | 
|---|
 | 157 | void ?+=?(string &s, const char* other) {
 | 
|---|
 | 158 |     (*s.inner) += other;
 | 
|---|
 | 159 | }
 | 
|---|
 | 160 | 
 | 
|---|
 | 161 | string ?+?(const string &s, char other) {
 | 
|---|
 | 162 |     string ret = s;
 | 
|---|
 | 163 |     ret += other;
 | 
|---|
 | 164 |     return ret;
 | 
|---|
 | 165 | }
 | 
|---|
 | 166 | 
 | 
|---|
 | 167 | string ?+?(const string &s, const string &s2) {
 | 
|---|
 | 168 |     string ret = s;
 | 
|---|
 | 169 |     ret += s2;
 | 
|---|
 | 170 |     return ret;
 | 
|---|
 | 171 | }
 | 
|---|
 | 172 | 
 | 
|---|
 | 173 | string ?+?(const char* s1, const char* s2) {
 | 
|---|
 | 174 |     string ret = s1;
 | 
|---|
 | 175 |     ret += s2;
 | 
|---|
 | 176 |     return ret;
 | 
|---|
 | 177 | }
 | 
|---|
 | 178 | 
 | 
|---|
 | 179 | string ?+?(const string &s, const char* other) {
 | 
|---|
 | 180 |     string ret = s;
 | 
|---|
 | 181 |     ret += other;
 | 
|---|
 | 182 |     return ret;
 | 
|---|
 | 183 | }
 | 
|---|
 | 184 | 
 | 
|---|
 | 185 | ////////////////////////////////////////////////////////
 | 
|---|
 | 186 | // Repetition
 | 
|---|
 | 187 | 
 | 
|---|
 | 188 | string ?*?(const string &s, size_t factor) {
 | 
|---|
 | 189 |     string ret = "";
 | 
|---|
 | 190 |     for (factor) ret += s;
 | 
|---|
 | 191 |     return ret;
 | 
|---|
 | 192 | }
 | 
|---|
 | 193 | 
 | 
|---|
 | 194 | string ?*?(char c, size_t size) {
 | 
|---|
 | 195 |     string ret = "";
 | 
|---|
 | 196 |     for ((size_t)size) ret += c;
 | 
|---|
 | 197 |     return ret;
 | 
|---|
 | 198 | }
 | 
|---|
 | 199 | 
 | 
|---|
 | 200 | string ?*?(const char *s, size_t factor) {
 | 
|---|
 | 201 |     string ss = s;
 | 
|---|
 | 202 |     return ss * factor;
 | 
|---|
 | 203 | }
 | 
|---|
 | 204 | 
 | 
|---|
 | 205 | ////////////////////////////////////////////////////////
 | 
|---|
 | 206 | // Character access
 | 
|---|
 | 207 | 
 | 
|---|
 | 208 | char ?[?](const string &s, size_t index) {
 | 
|---|
 | 209 |     return (*s.inner)[index];
 | 
|---|
 | 210 | }
 | 
|---|
 | 211 | 
 | 
|---|
 | 212 | string ?[?](string &s, size_t index) {
 | 
|---|
 | 213 |     string ret = { *s.inner, index, index + 1 };
 | 
|---|
 | 214 |     return ret`shareEdits;
 | 
|---|
 | 215 | }
 | 
|---|
 | 216 | 
 | 
|---|
 | 217 | ////////////////////////////////////////////////////////
 | 
|---|
 | 218 | // Search
 | 
|---|
 | 219 | 
 | 
|---|
 | 220 | bool contains(const string &s, char ch) {
 | 
|---|
 | 221 |     return contains( *s.inner, ch );
 | 
|---|
 | 222 | }
 | 
|---|
 | 223 | 
 | 
|---|
 | 224 | int find(const string &s, char search) {
 | 
|---|
 | 225 |     return find( *s.inner, search );
 | 
|---|
 | 226 | }
 | 
|---|
 | 227 | 
 | 
|---|
 | 228 | int find(const string &s, const string &search) {
 | 
|---|
 | 229 |     return find( *s.inner, *search.inner );
 | 
|---|
 | 230 | }
 | 
|---|
 | 231 | 
 | 
|---|
 | 232 | int find(const string &s, const char* search) {
 | 
|---|
 | 233 |     return find( *s.inner, search);
 | 
|---|
 | 234 | }
 | 
|---|
 | 235 | 
 | 
|---|
 | 236 | int find(const string &s, const char* search, size_t searchsize) {
 | 
|---|
 | 237 |     return find( *s.inner, search, searchsize);
 | 
|---|
 | 238 | }
 | 
|---|
 | 239 | 
 | 
|---|
| [08ed947] | 240 | int findFrom(const string &s, size_t fromPos, char search) {
 | 
|---|
 | 241 |     return findFrom( *s.inner, fromPos, search );
 | 
|---|
 | 242 | }
 | 
|---|
 | 243 | 
 | 
|---|
 | 244 | int findFrom(const string &s, size_t fromPos, const string &search) {
 | 
|---|
 | 245 |     return findFrom( *s.inner, fromPos, *search.inner );
 | 
|---|
 | 246 | }
 | 
|---|
 | 247 | 
 | 
|---|
 | 248 | int findFrom(const string &s, size_t fromPos, const char* search) {
 | 
|---|
 | 249 |     return findFrom( *s.inner, fromPos, search );
 | 
|---|
 | 250 | }
 | 
|---|
 | 251 | 
 | 
|---|
 | 252 | int findFrom(const string &s, size_t fromPos, const char* search, size_t searchsize) {
 | 
|---|
 | 253 |     return findFrom( *s.inner, fromPos, search, searchsize );
 | 
|---|
 | 254 | }
 | 
|---|
 | 255 | 
 | 
|---|
| [f450f2f] | 256 | bool includes(const string &s, const string &search) {
 | 
|---|
 | 257 |     return includes( *s.inner, *search.inner );
 | 
|---|
 | 258 | }
 | 
|---|
 | 259 | 
 | 
|---|
 | 260 | bool includes(const string &s, const char* search) {
 | 
|---|
 | 261 |     return includes( *s.inner, search );
 | 
|---|
 | 262 | }
 | 
|---|
 | 263 | 
 | 
|---|
 | 264 | bool includes(const string &s, const char* search, size_t searchsize) {
 | 
|---|
 | 265 |     return includes( *s.inner, search, searchsize );
 | 
|---|
 | 266 | }
 | 
|---|
 | 267 | 
 | 
|---|
 | 268 | bool startsWith(const string &s, const string &prefix) {
 | 
|---|
 | 269 |     return startsWith( *s.inner, *prefix.inner );
 | 
|---|
 | 270 | }
 | 
|---|
 | 271 | 
 | 
|---|
 | 272 | bool startsWith(const string &s, const char* prefix) {
 | 
|---|
 | 273 |     return startsWith( *s.inner, prefix );
 | 
|---|
 | 274 | }
 | 
|---|
 | 275 | 
 | 
|---|
 | 276 | bool startsWith(const string &s, const char* prefix, size_t prefixsize) {
 | 
|---|
 | 277 |     return startsWith( *s.inner, prefix, prefixsize );
 | 
|---|
 | 278 | }
 | 
|---|
 | 279 | 
 | 
|---|
 | 280 | bool endsWith(const string &s, const string &suffix) {
 | 
|---|
 | 281 |     return endsWith( *s.inner, *suffix.inner );
 | 
|---|
 | 282 | }
 | 
|---|
 | 283 | 
 | 
|---|
 | 284 | bool endsWith(const string &s, const char* suffix) {
 | 
|---|
 | 285 |     return endsWith( *s.inner, suffix );
 | 
|---|
 | 286 | }
 | 
|---|
 | 287 | 
 | 
|---|
 | 288 | bool endsWith(const string &s, const char* suffix, size_t suffixsize) {
 | 
|---|
 | 289 |     return endsWith( *s.inner, suffix, suffixsize );
 | 
|---|
 | 290 | }
 | 
|---|
 | 291 | 
 | 
|---|
 | 292 | 
 | 
|---|
 | 293 | ///////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 294 | // charclass, include, exclude
 | 
|---|
 | 295 | 
 | 
|---|
 | 296 | void ?{}( charclass & this, const string & chars) {
 | 
|---|
 | 297 |     (this.inner) { malloc() };
 | 
|---|
 | 298 |     ?{}( *this.inner, *(const string_res *)chars.inner );
 | 
|---|
 | 299 | }
 | 
|---|
 | 300 | 
 | 
|---|
 | 301 | void ?{}( charclass & this, const char * chars ) {
 | 
|---|
 | 302 |     (this.inner) { malloc() };
 | 
|---|
 | 303 |     ?{}( *this.inner, chars );
 | 
|---|
 | 304 | }
 | 
|---|
 | 305 | 
 | 
|---|
 | 306 | void ?{}( charclass & this, const char * chars, size_t charssize ) {
 | 
|---|
 | 307 |     (this.inner) { malloc() };
 | 
|---|
 | 308 |     ?{}( *this.inner, chars, charssize );
 | 
|---|
 | 309 | }
 | 
|---|
 | 310 | 
 | 
|---|
 | 311 | void ^?{}( charclass & this ) {
 | 
|---|
 | 312 |     ^(*this.inner){};
 | 
|---|
 | 313 |     free( this.inner );
 | 
|---|
 | 314 |     this.inner = 0p;
 | 
|---|
 | 315 | }
 | 
|---|
 | 316 | 
 | 
|---|
 | 317 | 
 | 
|---|
 | 318 | int exclude(const string &s, const charclass &mask) {
 | 
|---|
 | 319 |     return exclude( *s.inner, *mask.inner );
 | 
|---|
 | 320 | }
 | 
|---|
 | 321 | /*
 | 
|---|
 | 322 | StrSlice exclude(string &s, const charclass &mask) {
 | 
|---|
 | 323 | }
 | 
|---|
 | 324 | */
 | 
|---|
 | 325 | 
 | 
|---|
 | 326 | int include(const string &s, const charclass &mask) {
 | 
|---|
 | 327 |     return include( *s.inner, *mask.inner );
 | 
|---|
 | 328 | }
 | 
|---|
 | 329 | 
 | 
|---|
 | 330 | /*
 | 
|---|
 | 331 | StrSlice include(string &s, const charclass &mask) {
 | 
|---|
 | 332 | }
 | 
|---|
 | 333 | */
 | 
|---|
 | 334 | 
 | 
|---|