source: libcfa/src/collections/string.cfa@ f8913b7c

stuck-waitfor-destruct
Last change on this file since f8913b7c was 4223317, checked in by Peter A. Buhr <pabuhr@…>, 11 months ago

test some string operation changes

  • Property mode set to 100644
File size: 12.2 KB
Line 
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 : Peter A. Buhr
12// Last Modified On : Tue Apr 1 09:17:34 2025
13// Update Count : 288
14//
15
16#include "string.hfa"
17#include "string_res.hfa"
18#include <stdlib.hfa>
19
20#pragma GCC visibility push(default)
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)
32static void ?{}( string & s, string_res & src, size_t start, size_t len ) {
33 (s.inner) { malloc() };
34 ?{}( *s.inner, src, SHARE_EDITS, start, len );
35}
36
37void ?{}( string & s ) {
38 (s.inner) { malloc() };
39 ?{}( *s.inner );
40}
41
42void ?{}( string & s, const string & c ) {
43 (s.inner) { malloc() };
44 ?{}( *s.inner, *c.inner, COPY_VALUE );
45}
46
47void ?{}( string & s, const string & s2, size_t maxlen ) {
48 (s.inner) { malloc() };
49 ?{}( *s.inner, *s2.inner, COPY_VALUE, maxlen );
50}
51
52
53void ?{}( string & s, string & c ) {
54 ?{}( s, (const string &) c );
55}
56
57void ?{}( string & s, const char c ) {
58 (s.inner) { malloc() };
59 ?{}( *s.inner, c );
60}
61
62void ?{}( string & s, const char * c ) {
63 (s.inner) { malloc() };
64 ?{}( *s.inner, c );
65}
66
67void ?{}( string & s, const char * c, size_t size ) {
68 (s.inner) { malloc() };
69 ?{}( *s.inner, c, size );
70}
71
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
102string str( ssize_t rhs ) {
103 string s = rhs;
104 return s;
105}
106
107string str( size_t rhs ) {
108 string s = rhs;
109 return s;
110}
111
112string str( double rhs ) {
113 string s = rhs;
114 return s;
115}
116
117string str( long double rhs ) {
118 string s = rhs;
119 return s;
120}
121
122string str( double _Complex rhs ) {
123 string s = rhs;
124 return s;
125}
126
127string str( long double _Complex rhs ) {
128 string s = rhs;
129 return s;
130}
131
132void ^?{}( string & s ) {
133 ^(*s.inner){};
134 free( s.inner );
135 s.inner = 0p;
136}
137
138////////////////////////////////////////////////////////
139// Alternate construction: request shared edits
140
141string_Share ?`share( string & s ) {
142 string_Share ret = { &s };
143 return ret;
144}
145
146void ?{}( string & s, string_Share src ) {
147 ?{}( s, *src.s->inner, 0, src.s->inner->Handle.lnth );
148}
149
150////////////////////////////////////////////////////////
151// Assignment
152
153string & ?=?( string & s, const string & c ) {
154 (*s.inner) = (*c.inner);
155 return s;
156}
157
158string & ?=?( string & s, string & c ) {
159 (*s.inner) = (*c.inner);
160 return s;
161}
162
163string & ?=?( string & s, const char * val ) {
164 (*s.inner) = val;
165 return s;
166}
167
168string & ?=?( string & s, char val ) {
169 (*s.inner) = val;
170 return s;
171}
172
173string & assign( string & s, const string & c, size_t n ) {
174 assign( *s.inner, *c.inner, n );
175 return s;
176}
177
178string & assign( string & s, const char * c, size_t n ) {
179 assign( *s.inner, c, n );
180 return s;
181}
182
183string & ?=?( string & s, ssize_t rhs ) {
184 (*s.inner) = rhs;
185 return s;
186}
187
188string & ?=?( string & s, size_t rhs ) {
189 (*s.inner) = rhs;
190 return s;
191}
192
193string & ?=?( string & s, double rhs ) {
194 (*s.inner) = rhs;
195 return s;
196}
197
198string & ?=?( string & s, long double rhs ) {
199 (*s.inner) = rhs;
200 return s;
201}
202
203string & ?=?( string & s, double _Complex rhs ) {
204 (*s.inner) = rhs;
205 return s;
206}
207
208string & ?=?( string & s, long double _Complex rhs ) {
209 (*s.inner) = rhs;
210 return s;
211}
212
213////////////////////////////////////////////////////////
214// Input-Output
215
216ofstream & ?|?( ofstream & out, const string & s ) {
217 return out | (*s.inner); // print internal string_res
218}
219
220void ?|?( ofstream & out, const string & s ) {
221 (ofstream &)(out | (*s.inner)); ends( out );
222}
223
224ofstream & ?|?( ofstream & os, _Ostream_Manip(string) f ) {
225 size_t len = size( f.val );
226 char cstr[len + 1]; // room for null terminator
227 for ( i; len ) cstr[i] = f.val[i]; // copy string
228 cstr[len] = '\0'; // terminate
229 _Ostream_Manip(const char *) cf @= { cstr, f.wd, f.pc, f.base, {f.all} };
230 return os | cf | nonl;
231} // ?|?
232
233void ?|?( ofstream & os, _Ostream_Manip(string) f ) {
234 (ofstream &)(os | f); ends( os );
235}
236
237ifstream & ?|?( ifstream & in, string & s ) {
238 return in | (*s.inner); // read to internal string_res
239}
240
241ifstream & ?|?( ifstream & is, _Istream_Squoted f ) {
242 _Istream_Rquoted f2 = { { f.sstr.s.inner, (_Istream_str_base)f.sstr } };
243 return is | f2;
244} // ?|?
245
246ifstream & ?|?( ifstream & is, _Istream_Sstr f ) {
247// _Istream_Rstr f2 = {f.sstr.s.inner, (_Istream_str_base)f.sstr};
248 _Istream_Rstr f2 = {f.s.inner, (_Istream_str_base)f};
249 return is | f2;
250} // ?|?
251
252////////////////////////////////////////////////////////
253// Slicing
254
255string ?()( string & s, ssize_t start, ssize_t len ) {
256 if ( start < 0 ) { start += s`len; }
257 if ( len < 0 ) { len = -len; start -= len; }
258 if ( start > s`len ) return (string){ "" };
259 if ( start + len > s`len ) len = s`len - start;
260 string ret = { *s.inner, start, len };
261 return ret`share;
262}
263
264string ?()( string & s, ssize_t start ) {
265 if ( start < 0 ) { start += s`len; }
266 string ret = { *s.inner, start, size( s ) - start };
267 return ret`share;
268}
269
270////////////////////////////////////////////////////////
271// Comparison
272
273int strcmp( const string & s1, const string & s2 ) { return strcmp( *s1.inner, *s2.inner ); }
274bool ?==?( const string & s1, const string & s2 ) { return *s1.inner == *s2.inner; }
275bool ?!=?( const string & s1, const string & s2 ) { return *s1.inner != *s2.inner; }
276bool ?>? ( const string & s1, const string & s2 ) { return *s1.inner > *s2.inner; }
277bool ?>=?( const string & s1, const string & s2 ) { return *s1.inner >= *s2.inner; }
278bool ?<=?( const string & s1, const string & s2 ) { return *s1.inner <= *s2.inner; }
279bool ?<? ( const string & s1, const string & s2 ) { return *s1.inner < *s2.inner; }
280
281int strcmp( const string & s1, const char * s2 ) { return strcmp( *s1.inner, s2 ); }
282bool ?==?( const string & s1, const char * s2 ) { return *s1.inner == s2; }
283bool ?!=?( const string & s1, const char * s2 ) { return *s1.inner != s2; }
284bool ?>? ( const string & s1, const char * s2 ) { return *s1.inner > s2; }
285bool ?>=?( const string & s1, const char * s2 ) { return *s1.inner >= s2; }
286bool ?<=?( const string & s1, const char * s2 ) { return *s1.inner <= s2; }
287bool ?<? ( const string & s1, const char * s2 ) { return *s1.inner < s2; }
288
289int strcmp( const char * s1, const string & s2 ) { return strcmp( s1, *s2.inner ); }
290bool ?==?( const char * s1, const string & s2 ) { return s1 == *s2.inner; }
291bool ?!=?( const char * s1, const string & s2 ) { return s1 != *s2.inner; }
292bool ?>? ( const char * s1, const string & s2 ) { return s1 > *s2.inner; }
293bool ?>=?( const char * s1, const string & s2 ) { return s1 >= *s2.inner; }
294bool ?<=?( const char * s1, const string & s2 ) { return s1 <= *s2.inner; }
295bool ?<? ( const char * s1, const string & s2 ) { return s1 < *s2.inner; }
296
297
298////////////////////////////////////////////////////////
299// Getter
300
301size_t size( const string & s ) {
302 return size( *s.inner );
303}
304
305////////////////////////////////////////////////////////
306// Concatenation
307
308void ?+=?( string & s, char c ) {
309 (*s.inner) += c;
310}
311
312void ?+=?( string & s, const string & s2 ) {
313 (*s.inner) += (*s2.inner);
314}
315
316void append( string & s, const string & s2, size_t maxlen ) {
317 append( (*s.inner), (*s2.inner), maxlen );
318}
319
320void ?+=?( string & s, const char * c ) {
321 (*s.inner) += c;
322}
323
324void append( string & s, const char * buffer, size_t bsize ) {
325 append( (*s.inner), buffer, bsize );
326}
327
328string ?+?( const string & s, char c ) {
329 string ret = s;
330 ret += c;
331 return ret;
332}
333
334string ?+?( char c, const string & s ) {
335 string ret = s;
336 ret += c;
337 return ret;
338}
339
340string ?+?( const string & s, const string & s2 ) {
341 string ret = s;
342 ret += s2;
343 return ret;
344}
345
346string ?+?( const char * s, char c ) {
347 string ret = s;
348 ret += c;
349 return ret;
350}
351
352string ?+?( char c, const char * s ) {
353 string ret = c;
354 ret += s;
355 return ret;
356}
357
358string ?+?( const char * s1, const char * s2 ) {
359 string ret = s1;
360 ret += s2;
361 return ret;
362}
363
364string ?+?( const char * s1, string & s2 ) {
365 string ret = s1;
366 ret += s2;
367 return ret;
368}
369
370string ?+?( const string & s, const char * c ) {
371 string ret = s;
372 ret += c;
373 return ret;
374}
375
376////////////////////////////////////////////////////////
377// Repetition
378
379void ?*=?( string & s, size_t factor ) {
380 (*s.inner) *= factor;
381}
382
383string ?*?( const string & s, size_t factor ) {
384 string ret = s;
385 ret *= factor;
386 return ret;
387}
388
389string ?*?( char c, size_t factor ) {
390 string ret = c;
391 ret *= factor;
392 return ret;
393}
394
395string ?*?( const char * s, size_t factor ) {
396 string ret = s;
397 ret *= factor;
398 return ret;
399}
400
401////////////////////////////////////////////////////////
402// Character access
403
404char ?[?]( const string & s, size_t index ) {
405 return (*s.inner)[index];
406}
407
408string ?[?]( string & s, size_t index ) {
409 string ret = { *s.inner, index, 1 };
410 return ret`share;
411}
412
413////////////////////////////////////////////////////////
414// Search
415
416bool contains( const string & s, char ch ) {
417 return contains( *s.inner, ch );
418}
419
420int find( const string & s, char search ) {
421 return find( *s.inner, search );
422}
423
424int find( const string & s, const string & search ) {
425 return find( *s.inner, *search.inner );
426}
427
428int find( const string & s, const char * search ) {
429 return find( *s.inner, search );
430}
431
432int find( const string & s, const char * search, size_t searchsize ) {
433 return find( *s.inner, search, searchsize );
434}
435
436int find( const string & s, size_t fromPos, char search ) {
437 return findFrom( *s.inner, fromPos, search );
438}
439
440int find( const string & s, size_t fromPos, const string & search ) {
441 return findFrom( *s.inner, fromPos, *search.inner );
442}
443
444int find( const string & s, size_t fromPos, const char * search ) {
445 return findFrom( *s.inner, fromPos, search );
446}
447
448int find( const string & s, size_t fromPos, const char * search, size_t searchsize ) {
449 return findFrom( *s.inner, fromPos, search, searchsize );
450}
451
452bool includes( const string & s, const string & search ) {
453 return includes( *s.inner, *search.inner );
454}
455
456bool includes( const string & s, const char * search ) {
457 return includes( *s.inner, search );
458}
459
460bool includes( const string & s, const char * search, size_t searchsize ) {
461 return includes( *s.inner, search, searchsize );
462}
463
464bool startsWith( const string & s, const string & prefix ) {
465 return startsWith( *s.inner, *prefix.inner );
466}
467
468bool startsWith( const string & s, const char * prefix ) {
469 return startsWith( *s.inner, prefix );
470}
471
472bool startsWith( const string & s, const char * prefix, size_t prefixsize ) {
473 return startsWith( *s.inner, prefix, prefixsize );
474}
475
476bool endsWith( const string & s, const string & suffix ) {
477 return endsWith( *s.inner, *suffix.inner );
478}
479
480bool endsWith( const string & s, const char * suffix ) {
481 return endsWith( *s.inner, suffix );
482}
483
484bool endsWith( const string & s, const char * suffix, size_t suffixsize ) {
485 return endsWith( *s.inner, suffix, suffixsize );
486}
487
488
489///////////////////////////////////////////////////////////////////////////
490// charclass, include, exclude
491
492void ?{}( charclass & s, const string & chars ) {
493 (s.inner) { malloc() };
494 ?{}( *s.inner, *(const string_res *)chars.inner );
495}
496
497void ?{}( charclass & s, const char * chars ) {
498 (s.inner) { malloc() };
499 ?{}( *s.inner, chars );
500}
501
502void ?{}( charclass & s, const char * chars, size_t charssize ) {
503 (s.inner) { malloc() };
504 ?{}( *s.inner, chars, charssize );
505}
506
507void ^?{}( charclass & s ) {
508 ^(*s.inner){};
509 free( s.inner );
510 s.inner = 0p;
511}
512
513
514int exclude( const string & s, const charclass & mask ) {
515 return exclude( *s.inner, *mask.inner );
516}
517/*
518StrSlice exclude( string & s, const charclass & mask ) {
519}
520*/
521
522int include( const string & s, const charclass & mask ) {
523 return include( *s.inner, *mask.inner );
524}
525
526/*
527StrSlice include( string & s, const charclass & mask ) {
528}
529*/
Note: See TracBrowser for help on using the repository browser.