source: libcfa/src/collections/string.cfa@ 6d9aa79

Last change on this file since 6d9aa79 was fbe3f03, checked in by Peter A. Buhr <pabuhr@…>, 18 months ago

formatting

  • Property mode set to 100644
File size: 11.6 KB
RevLine 
[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
[bc9f84a]11// Last Modified By : Peter A. Buhr
[fbe3f03]12// Last Modified On : Mon Apr 15 21:56:28 2024
13// Update Count : 260
[f450f2f]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/*
23Implementation Principle: typical operation translates to the equivalent
24operation on `inner`. Exceptions are implementing new RAII pattern for value
25semantics and some const-hell handling.
26*/
27
28////////////////////////////////////////////////////////
29// string RAII
30
31// private (not in header)
[e8b3717]32static void ?{}( string & s, string_res & src, size_t start, size_t len ) {
[681e12f]33 (s.inner) { malloc() };
[e8b3717]34 ?{}( *s.inner, src, SHARE_EDITS, start, len );
[f450f2f]35}
36
[479fbe3]37void ?{}( string & s ) {
38 (s.inner) { malloc() };
39 ?{}( *s.inner );
40}
41
[681e12f]42void ?{}( string & s, const string & c ) {
43 (s.inner) { malloc() };
44 ?{}( *s.inner, *c.inner, COPY_VALUE );
[f450f2f]45}
46
[7abc3de]47void ?{}( string & s, const string & s2, size_t maxlen) {
48 (s.inner) { malloc() };
49 ?{}( *s.inner, *s2.inner, COPY_VALUE, maxlen );
50}
51
52
[681e12f]53void ?{}( string & s, string & c ) {
54 ?{}( s, (const string &) c );
[f450f2f]55}
56
[479fbe3]57void ?{}( string & s, const char c ) {
[681e12f]58 (s.inner) { malloc() };
[7abc3de]59 ?{}( *s.inner, c );
[f450f2f]60}
61
[479fbe3]62void ?{}( string & s, const char * c ) {
[681e12f]63 (s.inner) { malloc() };
[479fbe3]64 ?{}( *s.inner, c );
65}
66
67void ?{}( string & s, const char * c, size_t size) {
68 (s.inner) { malloc() };
69 ?{}( *s.inner, c, size );
[f450f2f]70}
71
[f2898df]72void ?{}( string & s, ssize_t rhs ) {
73 (s.inner) { malloc() };
74 ?{}( *s.inner, rhs );
75}
76
77void ?{}( string & s, size_t rhs ) {
78 (s.inner) { malloc() };
79 ?{}( *s.inner, rhs );
80}
81
82void ?{}( string & s, double rhs ) {
83 (s.inner) { malloc() };
84 ?{}( *s.inner, rhs );
85}
86
87void ?{}( string & s, long double rhs ) {
88 (s.inner) { malloc() };
89 ?{}( *s.inner, rhs );
90}
91
92void ?{}( string & s, double _Complex rhs ) {
93 (s.inner) { malloc() };
94 ?{}( *s.inner, rhs );
95}
96
97void ?{}( string & s, long double _Complex rhs ) {
98 (s.inner) { malloc() };
99 ?{}( *s.inner, rhs );
100}
101
[681e12f]102void ^?{}( string & s ) {
103 ^(*s.inner){};
104 free( s.inner );
105 s.inner = 0p;
[f450f2f]106}
107
108////////////////////////////////////////////////////////
109// Alternate construction: request shared edits
110
[681e12f]111string_WithSharedEdits ?`shareEdits( string & s ) {
112 string_WithSharedEdits ret = { &s };
[f450f2f]113 return ret;
114}
115
[681e12f]116void ?{}( string & s, string_WithSharedEdits src ) {
117 ?{}( s, *src.s->inner, 0, src.s->inner->Handle.lnth);
[f450f2f]118}
119
120////////////////////////////////////////////////////////
121// Assignment
122
[b1eefe50]123string & ?=?(string & s, const string & c) {
[681e12f]124 (*s.inner) = (*c.inner);
[b1eefe50]125 return s;
[f450f2f]126}
[b1eefe50]127
[906d8fa]128string & ?=?(string & s, string & c) {
129 (*s.inner) = (*c.inner);
130 return s;
131}
[f450f2f]132
[b1eefe50]133string & ?=?( string & s, const char * val ) {
[681e12f]134 (*s.inner) = val;
[b1eefe50]135 return s;
[f450f2f]136}
137
[b1eefe50]138string & ?=?( string & s, char val ) {
139 (*s.inner) = val;
140 return s;
141}
142
143string & assign(string & s, const string & c, size_t n) {
[e891349]144 assign(*s.inner, *c.inner, n);
[b1eefe50]145 return s;
[e891349]146}
[b1eefe50]147
148string & assign(string & s, const char * c, size_t n) {
[e891349]149 assign(*s.inner, c, n);
[b1eefe50]150 return s;
[e891349]151}
152
[f2898df]153string & ?=?( string & s, ssize_t rhs ) {
154 (*s.inner) = rhs;
155 return s;
156}
157
158string & ?=?( string & s, size_t rhs ) {
159 (*s.inner) = rhs;
160 return s;
161}
162
163string & ?=?( string & s, double rhs ) {
164 (*s.inner) = rhs;
165 return s;
166}
167
168string & ?=?( string & s, long double rhs ) {
169 (*s.inner) = rhs;
170 return s;
171}
172
173string & ?=?( string & s, double _Complex rhs ) {
174 (*s.inner) = rhs;
175 return s;
176}
177
178string & ?=?( string & s, long double _Complex rhs ) {
179 (*s.inner) = rhs;
180 return s;
181}
[f450f2f]182
183////////////////////////////////////////////////////////
[d32679d5]184// Input-Output
[f450f2f]185
[681e12f]186ofstream & ?|?( ofstream & out, const string & s ) {
187 return out | (*s.inner); // print internal string_res
[f450f2f]188}
189
[681e12f]190void ?|?( ofstream & out, const string & s ) {
191 (ofstream &)(out | (*s.inner)); ends( out );
[f450f2f]192}
193
[34c6e1e6]194ofstream & ?|?( ofstream & os, _Ostream_Manip(string) f ) {
195 size_t len = size( f.val );
196 char cstr[len + 1]; // room for null terminator
197 for ( i; len ) cstr[i] = f.val[i]; // copy string
198 cstr[len] = '\0'; // terminate
199 _Ostream_Manip(const char *) cf @= { cstr, f.wd, f.pc, f.base, {f.all} };
[fbe3f03]200 return os | cf | nonl;
[34c6e1e6]201} // ?|?
202
203void ?|?( ofstream & os, _Ostream_Manip(string) f ) {
204 (ofstream &)(os | f); ends( os );
205}
206
[681e12f]207ifstream & ?|?(ifstream & in, string & s) {
208 return in | (*s.inner); // read to internal string_res
[d32679d5]209}
210
[211def2]211ifstream & ?|?( ifstream & is, _Istream_Squoted f ) {
212 _Istream_Rquoted f2 = { { f.sstr.s.inner, (_Istream_str_base)f.sstr } };
213 return is | f2;
214} // ?|?
[d32679d5]215
[34c6e1e6]216ifstream & ?|?( ifstream & is, _Istream_Sstr f ) {
[211def2]217// _Istream_Rstr f2 = {f.sstr.s.inner, (_Istream_str_base)f.sstr};
[737988b]218 _Istream_Rstr f2 = {f.s.inner, (_Istream_str_base)f};
219 return is | f2;
[7e1dbd7]220} // ?|?
221
[f450f2f]222////////////////////////////////////////////////////////
223// Slicing
224
[e8b3717]225string ?()( string & s, size_t start, size_t len ) {
226 string ret = { *s.inner, start, len };
[f450f2f]227 return ret`shareEdits;
228}
229
[681e12f]230string ?()( string & s, size_t start ) {
[e8b3717]231 string ret = { *s.inner, start, size( s ) - start };
[bc9f84a]232 return ret`shareEdits;
233}
234
[f450f2f]235////////////////////////////////////////////////////////
236// Comparison
237
[681e12f]238int strcmp(const string & s1, const string & s2) { return strcmp(*s1.inner, *s2.inner); }
239bool ?==?(const string & s1, const string & s2) { return *s1.inner == *s2.inner; }
240bool ?!=?(const string & s1, const string & s2) { return *s1.inner != *s2.inner; }
241bool ?>? (const string & s1, const string & s2) { return *s1.inner > *s2.inner; }
242bool ?>=?(const string & s1, const string & s2) { return *s1.inner >= *s2.inner; }
243bool ?<=?(const string & s1, const string & s2) { return *s1.inner <= *s2.inner; }
244bool ?<? (const string & s1, const string & s2) { return *s1.inner < *s2.inner; }
245
246int strcmp(const string & s1, const char * s2) { return strcmp(*s1.inner, s2 ); }
247bool ?==?(const string & s1, const char * s2) { return *s1.inner == s2; }
248bool ?!=?(const string & s1, const char * s2) { return *s1.inner != s2; }
249bool ?>? (const string & s1, const char * s2) { return *s1.inner > s2; }
250bool ?>=?(const string & s1, const char * s2) { return *s1.inner >= s2; }
251bool ?<=?(const string & s1, const char * s2) { return *s1.inner <= s2; }
252bool ?<? (const string & s1, const char * s2) { return *s1.inner < s2; }
253
254int strcmp(const char * s1, const string & s2) { return strcmp( s1, *s2.inner); }
255bool ?==?(const char * s1, const string & s2) { return s1 == *s2.inner; }
256bool ?!=?(const char * s1, const string & s2) { return s1 != *s2.inner; }
257bool ?>? (const char * s1, const string & s2) { return s1 > *s2.inner; }
258bool ?>=?(const char * s1, const string & s2) { return s1 >= *s2.inner; }
259bool ?<=?(const char * s1, const string & s2) { return s1 <= *s2.inner; }
260bool ?<? (const char * s1, const string & s2) { return s1 < *s2.inner; }
[f450f2f]261
262
263////////////////////////////////////////////////////////
264// Getter
265
[6264087]266size_t size(const string & s) {
[681e12f]267 return size( *s.inner );
[f450f2f]268}
269
270////////////////////////////////////////////////////////
271// Concatenation
272
[681e12f]273void ?+=?(string & s, char c) {
274 (*s.inner) += c;
[f450f2f]275}
276
[6264087]277void ?+=?(string & s, const string & s2) {
[f450f2f]278 (*s.inner) += (*s2.inner);
279}
280
[e891349]281void append(string & s, const string & s2, size_t maxlen) {
282 append( (*s.inner), (*s2.inner), maxlen );
283}
284
[681e12f]285void ?+=?(string & s, const char * c) {
286 (*s.inner) += c;
[f450f2f]287}
288
[e891349]289void append(string & s, const char * buffer, size_t bsize) {
290 append( (*s.inner), buffer, bsize );
291}
292
[681e12f]293string ?+?(const string & s, char c) {
[f450f2f]294 string ret = s;
[681e12f]295 ret += c;
[f450f2f]296 return ret;
297}
298
[6264087]299string ?+?(const string & s, const string & s2) {
[f450f2f]300 string ret = s;
301 ret += s2;
302 return ret;
303}
304
[6264087]305string ?+?(const char * s1, const char * s2) {
[f450f2f]306 string ret = s1;
307 ret += s2;
308 return ret;
309}
310
[681e12f]311string ?+?(const string & s, const char * c) {
[f450f2f]312 string ret = s;
[681e12f]313 ret += c;
[f450f2f]314 return ret;
315}
316
317////////////////////////////////////////////////////////
318// Repetition
319
[38951c31]320void ?*=?(string & s, size_t factor) {
321 (*s.inner) *= factor;
[f450f2f]322}
323
[38951c31]324string ?*?(const string & s, size_t factor) {
325 string ret = s;
326 ret *= factor;
327 return ret;
[479fbe3]328}
329
330string ?*?(char c, size_t factor) {
331 string ret = c;
[38951c31]332 ret *= factor;
333 return ret;
[f450f2f]334}
335
[479fbe3]336string ?*?(const char * s, size_t factor) {
337 string ret = s;
[38951c31]338 ret *= factor;
339 return ret;
[f450f2f]340}
341
342////////////////////////////////////////////////////////
343// Character access
344
[6264087]345char ?[?](const string & s, size_t index) {
[f450f2f]346 return (*s.inner)[index];
347}
348
[6264087]349string ?[?](string & s, size_t index) {
[e8b3717]350 string ret = { *s.inner, index, 1 };
[f450f2f]351 return ret`shareEdits;
352}
353
354////////////////////////////////////////////////////////
355// Search
356
[6264087]357bool contains(const string & s, char ch) {
[f450f2f]358 return contains( *s.inner, ch );
359}
360
[6264087]361int find(const string & s, char search) {
[f450f2f]362 return find( *s.inner, search );
363}
364
[6264087]365int find(const string & s, const string & search) {
[f450f2f]366 return find( *s.inner, *search.inner );
367}
368
[6264087]369int find(const string & s, const char * search) {
[f450f2f]370 return find( *s.inner, search);
371}
372
[6264087]373int find(const string & s, const char * search, size_t searchsize) {
[f450f2f]374 return find( *s.inner, search, searchsize);
375}
376
[6264087]377int findFrom(const string & s, size_t fromPos, char search) {
[08ed947]378 return findFrom( *s.inner, fromPos, search );
379}
380
[6264087]381int findFrom(const string & s, size_t fromPos, const string & search) {
[08ed947]382 return findFrom( *s.inner, fromPos, *search.inner );
383}
384
[6264087]385int findFrom(const string & s, size_t fromPos, const char * search) {
[08ed947]386 return findFrom( *s.inner, fromPos, search );
387}
388
[6264087]389int findFrom(const string & s, size_t fromPos, const char * search, size_t searchsize) {
[08ed947]390 return findFrom( *s.inner, fromPos, search, searchsize );
391}
392
[6264087]393bool includes(const string & s, const string & search) {
[f450f2f]394 return includes( *s.inner, *search.inner );
395}
396
[6264087]397bool includes(const string & s, const char * search) {
[f450f2f]398 return includes( *s.inner, search );
399}
400
[6264087]401bool includes(const string & s, const char * search, size_t searchsize) {
[f450f2f]402 return includes( *s.inner, search, searchsize );
403}
404
[6264087]405bool startsWith(const string & s, const string & prefix) {
[f450f2f]406 return startsWith( *s.inner, *prefix.inner );
407}
408
[6264087]409bool startsWith(const string & s, const char * prefix) {
[f450f2f]410 return startsWith( *s.inner, prefix );
411}
412
[6264087]413bool startsWith(const string & s, const char * prefix, size_t prefixsize) {
[f450f2f]414 return startsWith( *s.inner, prefix, prefixsize );
415}
416
[6264087]417bool endsWith(const string & s, const string & suffix) {
[f450f2f]418 return endsWith( *s.inner, *suffix.inner );
419}
420
[6264087]421bool endsWith(const string & s, const char * suffix) {
[f450f2f]422 return endsWith( *s.inner, suffix );
423}
424
[6264087]425bool endsWith(const string & s, const char * suffix, size_t suffixsize) {
[f450f2f]426 return endsWith( *s.inner, suffix, suffixsize );
427}
428
429
430///////////////////////////////////////////////////////////////////////////
431// charclass, include, exclude
432
[681e12f]433void ?{}( charclass & s, const string & chars) {
434 (s.inner) { malloc() };
435 ?{}( *s.inner, *(const string_res *)chars.inner );
[f450f2f]436}
437
[681e12f]438void ?{}( charclass & s, const char * chars ) {
439 (s.inner) { malloc() };
440 ?{}( *s.inner, chars );
[f450f2f]441}
442
[681e12f]443void ?{}( charclass & s, const char * chars, size_t charssize ) {
444 (s.inner) { malloc() };
445 ?{}( *s.inner, chars, charssize );
[f450f2f]446}
447
[681e12f]448void ^?{}( charclass & s ) {
449 ^(*s.inner){};
450 free( s.inner );
451 s.inner = 0p;
[f450f2f]452}
453
454
[6264087]455int exclude(const string & s, const charclass & mask) {
[f450f2f]456 return exclude( *s.inner, *mask.inner );
457}
458/*
[6264087]459StrSlice exclude(string & s, const charclass & mask) {
[f450f2f]460}
461*/
462
[6264087]463int include(const string & s, const charclass & mask) {
[f450f2f]464 return include( *s.inner, *mask.inner );
465}
466
467/*
[6264087]468StrSlice include(string & s, const charclass & mask) {
[f450f2f]469}
470*/
471
Note: See TracBrowser for help on using the repository browser.