source: libcfa/src/collections/string.cfa @ 08e0d65

Last change on this file since 08e0d65 was 4dab7e8, checked in by Peter A. Buhr <pabuhr@…>, 3 months ago

formatting, add str conversion routines, add more combinations of ?+? routines

  • Property mode set to 100644
File size: 12.5 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
[4dab7e8]12// Last Modified On : Mon Aug  5 23:12:05 2024
13// Update Count     : 273
[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
[4dab7e8]47void ?{}( string & s, const string & s2, size_t maxlen ) {
[7abc3de]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
[4dab7e8]67void ?{}( string & s, const char * c, size_t size ) {
[479fbe3]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
[4dab7e8]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
[681e12f]132void ^?{}( string & s ) {
133    ^(*s.inner){};
134    free( s.inner );
135    s.inner = 0p;
[f450f2f]136}
137
138////////////////////////////////////////////////////////
139// Alternate construction: request shared edits
140
[681e12f]141string_WithSharedEdits ?`shareEdits( string & s ) {
142    string_WithSharedEdits ret = { &s };
[f450f2f]143    return ret;
144}
145
[681e12f]146void ?{}( string & s, string_WithSharedEdits src ) {
[4dab7e8]147    ?{}( s, *src.s->inner, 0, src.s->inner->Handle.lnth );
[f450f2f]148}
149
150////////////////////////////////////////////////////////
151// Assignment
152
[4dab7e8]153string & ?=?( string & s, const string & c ) {
[681e12f]154    (*s.inner) = (*c.inner);
[b1eefe50]155    return s;
[f450f2f]156}
[b1eefe50]157
[4dab7e8]158string & ?=?( string & s, string & c ) {
[906d8fa]159    (*s.inner) = (*c.inner);
160    return s;
161}
[f450f2f]162
[b1eefe50]163string & ?=?( string & s, const char * val ) {
[681e12f]164    (*s.inner) = val;
[b1eefe50]165    return s;
[f450f2f]166}
167
[b1eefe50]168string & ?=?( string & s, char val ) {
169    (*s.inner) = val;
170    return s;
171}
172
[4dab7e8]173string & assign( string & s, const string & c, size_t n ) {
174    assign( *s.inner, *c.inner, n );
[b1eefe50]175    return s;
[e891349]176}
[b1eefe50]177
[4dab7e8]178string & assign( string & s, const char * c, size_t n ) {
179    assign( *s.inner, c, n );
[b1eefe50]180    return s;
[e891349]181}
182
[f2898df]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}
[f450f2f]212
213////////////////////////////////////////////////////////
[d32679d5]214// Input-Output
[f450f2f]215
[681e12f]216ofstream & ?|?( ofstream & out, const string & s ) {
217    return out | (*s.inner); // print internal string_res
[f450f2f]218}
219
[681e12f]220void ?|?( ofstream & out, const string & s ) {
221    (ofstream &)(out | (*s.inner)); ends( out );
[f450f2f]222}
223
[34c6e1e6]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} };
[fbe3f03]230        return os | cf | nonl;
[34c6e1e6]231} // ?|?
232
233void ?|?( ofstream & os, _Ostream_Manip(string) f ) {
234        (ofstream &)(os | f); ends( os );
235}
236
[4dab7e8]237ifstream & ?|?( ifstream & in, string & s ) {
[681e12f]238    return in | (*s.inner); // read to internal string_res
[d32679d5]239}
240
[211def2]241ifstream & ?|?( ifstream & is, _Istream_Squoted f ) {
242        _Istream_Rquoted f2 = { { f.sstr.s.inner, (_Istream_str_base)f.sstr } };
243    return is | f2;
244} // ?|?
[d32679d5]245
[34c6e1e6]246ifstream & ?|?( ifstream & is, _Istream_Sstr f ) {
[211def2]247//      _Istream_Rstr f2 = {f.sstr.s.inner, (_Istream_str_base)f.sstr};
[737988b]248        _Istream_Rstr f2 = {f.s.inner, (_Istream_str_base)f};
249    return is | f2;
[7e1dbd7]250} // ?|?
251
[f450f2f]252////////////////////////////////////////////////////////
253// Slicing
254
[e8b3717]255string ?()( string & s, size_t start, size_t len ) {
256    string ret = { *s.inner, start, len };
[f450f2f]257    return ret`shareEdits;
258}
259
[681e12f]260string ?()( string & s, size_t start ) {
[e8b3717]261    string ret = { *s.inner, start, size( s ) - start };
[bc9f84a]262    return ret`shareEdits;
263}
264
[f450f2f]265////////////////////////////////////////////////////////
266// Comparison
267
[4dab7e8]268int strcmp( const string & s1, const string & s2 ) { return strcmp( *s1.inner, *s2.inner ); }
269bool ?==?( const string & s1, const string & s2 ) { return *s1.inner == *s2.inner; }
270bool ?!=?( const string & s1, const string & s2 ) { return *s1.inner != *s2.inner; }
271bool ?>? ( const string & s1, const string & s2 ) { return *s1.inner >  *s2.inner; }
272bool ?>=?( const string & s1, const string & s2 ) { return *s1.inner >= *s2.inner; }
273bool ?<=?( const string & s1, const string & s2 ) { return *s1.inner <= *s2.inner; }
274bool ?<? ( const string & s1, const string & s2 ) { return *s1.inner <  *s2.inner; }
275
276int strcmp( const string & s1, const char * s2 ) { return strcmp( *s1.inner, s2 ); }
277bool ?==?( const string & s1, const char * s2 ) { return *s1.inner == s2; }
278bool ?!=?( const string & s1, const char * s2 ) { return *s1.inner != s2; }
279bool ?>? ( const string & s1, const char * s2 ) { return *s1.inner >  s2; }
280bool ?>=?( const string & s1, const char * s2 ) { return *s1.inner >= s2; }
281bool ?<=?( const string & s1, const char * s2 ) { return *s1.inner <= s2; }
282bool ?<? ( const string & s1, const char * s2 ) { return *s1.inner <  s2; }
283
284int strcmp( const char * s1, const string & s2 ) { return strcmp( s1, *s2.inner ); }
285bool ?==?( const char * s1, const string & s2 ) { return s1 == *s2.inner; }
286bool ?!=?( const char * s1, const string & s2 ) { return s1 != *s2.inner; }
287bool ?>? ( const char * s1, const string & s2 ) { return s1 >  *s2.inner; }
288bool ?>=?( const char * s1, const string & s2 ) { return s1 >= *s2.inner; }
289bool ?<=?( const char * s1, const string & s2 ) { return s1 <= *s2.inner; }
290bool ?<? ( const char * s1, const string & s2 ) { return s1 <  *s2.inner; }
[f450f2f]291
292
293////////////////////////////////////////////////////////
294// Getter
295
[4dab7e8]296size_t size( const string & s ) {
[681e12f]297    return size( *s.inner );
[f450f2f]298}
299
300////////////////////////////////////////////////////////
301// Concatenation
302
[4dab7e8]303void ?+=?( string & s, char c ) {
[681e12f]304    (*s.inner) += c;
[f450f2f]305}
306
[4dab7e8]307void ?+=?( string & s, const string & s2 ) {
[f450f2f]308    (*s.inner) += (*s2.inner);
309}
310
[4dab7e8]311void append( string & s, const string & s2, size_t maxlen ) {
[e891349]312    append( (*s.inner), (*s2.inner), maxlen );
313}
314
[4dab7e8]315void ?+=?( string & s, const char * c ) {
[681e12f]316    (*s.inner) += c;
[f450f2f]317}
318
[4dab7e8]319void append( string & s, const char * buffer, size_t bsize ) {
[e891349]320    append( (*s.inner), buffer, bsize );
321}
322
[4dab7e8]323string ?+?( const string & s, char c ) {
324    string ret = s;
325    ret += c;
326    return ret;
327}
328
329string ?+?( char c, const string & s ) {
[f450f2f]330    string ret = s;
[681e12f]331    ret += c;
[f450f2f]332    return ret;
333}
334
[4dab7e8]335string ?+?( const string & s, const string & s2 ) {
[f450f2f]336    string ret = s;
337    ret += s2;
338    return ret;
339}
340
[4dab7e8]341string ?+?( const char * s,  char c ) {
342    string ret = s;
343    ret += c;
344    return ret;
345}
346
347string ?+?( char c, const char * s ) {
348    string ret = c;
349    ret += s;
350    return ret;
351}
352
353string ?+?( const char * s1, const char * s2 ) {
354    string ret = s1;
355    ret += s2;
356    return ret;
357}
358
359string ?+?( const char * s1, string & s2 ) {
[f450f2f]360    string ret = s1;
361    ret += s2;
362    return ret;
363}
364
[4dab7e8]365string ?+?( const string & s, const char * c ) {
[f450f2f]366    string ret = s;
[681e12f]367    ret += c;
[f450f2f]368    return ret;
369}
370
371////////////////////////////////////////////////////////
372// Repetition
373
[4dab7e8]374void ?*=?( string & s, size_t factor ) {
[38951c31]375    (*s.inner) *= factor;
[f450f2f]376}
377
[4dab7e8]378string ?*?( const string & s, size_t factor ) {
[38951c31]379    string ret = s;
380    ret *= factor;
381    return ret;
[479fbe3]382}
383
[4dab7e8]384string ?*?( char c, size_t factor ) {
[479fbe3]385    string ret = c;
[38951c31]386    ret *= factor;
387    return ret;
[f450f2f]388}
389
[4dab7e8]390string ?*?( const char * s, size_t factor ) {
[479fbe3]391    string ret = s;
[38951c31]392    ret *= factor;
393    return ret;
[f450f2f]394}
395
396////////////////////////////////////////////////////////
397// Character access
398
[4dab7e8]399char ?[?]( const string & s, size_t index ) {
[f450f2f]400    return (*s.inner)[index];
401}
402
[4dab7e8]403string ?[?]( string & s, size_t index ) {
[e8b3717]404    string ret = { *s.inner, index, 1 };
[f450f2f]405    return ret`shareEdits;
406}
407
408////////////////////////////////////////////////////////
409// Search
410
[4dab7e8]411bool contains( const string & s, char ch ) {
[f450f2f]412    return contains( *s.inner, ch );
413}
414
[4dab7e8]415int find( const string & s, char search ) {
[f450f2f]416    return find( *s.inner, search );
417}
418
[4dab7e8]419int find( const string & s, const string & search ) {
[f450f2f]420    return find( *s.inner, *search.inner );
421}
422
[4dab7e8]423int find( const string & s, const char * search ) {
424    return find( *s.inner, search );
[f450f2f]425}
426
[4dab7e8]427int find( const string & s, const char * search, size_t searchsize ) {
428    return find( *s.inner, search, searchsize );
[f450f2f]429}
430
[4dab7e8]431int findFrom( const string & s, size_t fromPos, char search ) {
[08ed947]432    return findFrom( *s.inner, fromPos, search );
433}
434
[4dab7e8]435int findFrom( const string & s, size_t fromPos, const string & search ) {
[08ed947]436    return findFrom( *s.inner, fromPos, *search.inner );
437}
438
[4dab7e8]439int findFrom( const string & s, size_t fromPos, const char * search ) {
[08ed947]440    return findFrom( *s.inner, fromPos, search );
441}
442
[4dab7e8]443int findFrom( const string & s, size_t fromPos, const char * search, size_t searchsize ) {
[08ed947]444    return findFrom( *s.inner, fromPos, search, searchsize );
445}
446
[4dab7e8]447bool includes( const string & s, const string & search ) {
[f450f2f]448    return includes( *s.inner, *search.inner );
449}
450
[4dab7e8]451bool includes( const string & s, const char * search ) {
[f450f2f]452    return includes( *s.inner, search );
453}
454
[4dab7e8]455bool includes( const string & s, const char * search, size_t searchsize ) {
[f450f2f]456    return includes( *s.inner, search, searchsize );
457}
458
[4dab7e8]459bool startsWith( const string & s, const string & prefix ) {
[f450f2f]460    return startsWith( *s.inner, *prefix.inner );
461}
462
[4dab7e8]463bool startsWith( const string & s, const char * prefix ) {
[f450f2f]464    return startsWith( *s.inner, prefix );
465}
466
[4dab7e8]467bool startsWith( const string & s, const char * prefix, size_t prefixsize ) {
[f450f2f]468    return startsWith( *s.inner, prefix, prefixsize );
469}
470
[4dab7e8]471bool endsWith( const string & s, const string & suffix ) {
[f450f2f]472    return endsWith( *s.inner, *suffix.inner );
473}
474
[4dab7e8]475bool endsWith( const string & s, const char * suffix ) {
[f450f2f]476    return endsWith( *s.inner, suffix );
477}
478
[4dab7e8]479bool endsWith( const string & s, const char * suffix, size_t suffixsize ) {
[f450f2f]480    return endsWith( *s.inner, suffix, suffixsize );
481}
482
483
484///////////////////////////////////////////////////////////////////////////
485// charclass, include, exclude
486
[4dab7e8]487void ?{}( charclass & s, const string & chars ) {
[681e12f]488    (s.inner) { malloc() };
489    ?{}( *s.inner, *(const string_res *)chars.inner );
[f450f2f]490}
491
[681e12f]492void ?{}( charclass & s, const char * chars ) {
493    (s.inner) { malloc() };
494    ?{}( *s.inner, chars );
[f450f2f]495}
496
[681e12f]497void ?{}( charclass & s, const char * chars, size_t charssize ) {
498    (s.inner) { malloc() };
499    ?{}( *s.inner, chars, charssize );
[f450f2f]500}
501
[681e12f]502void ^?{}( charclass & s ) {
503    ^(*s.inner){};
504    free( s.inner );
505    s.inner = 0p;
[f450f2f]506}
507
508
[4dab7e8]509int exclude( const string & s, const charclass & mask ) {
[f450f2f]510    return exclude( *s.inner, *mask.inner );
511}
512/*
[4dab7e8]513StrSlice exclude( string & s, const charclass & mask ) {
[f450f2f]514}
515*/
516
[4dab7e8]517int include( const string & s, const charclass & mask ) {
[f450f2f]518    return include( *s.inner, *mask.inner );
519}
520
521/*
[4dab7e8]522StrSlice include( string & s, const charclass & mask ) {
[f450f2f]523}
524*/
Note: See TracBrowser for help on using the repository browser.