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

Last change on this file since c0d8e62 was 211def2, checked in by Peter A. Buhr <pabuhr@…>, 5 months ago

omnibus I/O changes to get quoted manipulator to work

  • 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
[211def2]12// Last Modified On : Wed Feb  7 21:17:06 2024
13// Update Count     : 259
[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} };
200        os | cf | nonl;
201        return os;
202} // ?|?
203
204void ?|?( ofstream & os, _Ostream_Manip(string) f ) {
205        (ofstream &)(os | f); ends( os );
206}
207
[681e12f]208ifstream & ?|?(ifstream & in, string & s) {
209    return in | (*s.inner); // read to internal string_res
[d32679d5]210}
211
[211def2]212ifstream & ?|?( ifstream & is, _Istream_Squoted f ) {
213        _Istream_Rquoted f2 = { { f.sstr.s.inner, (_Istream_str_base)f.sstr } };
214    return is | f2;
215} // ?|?
[d32679d5]216
[34c6e1e6]217ifstream & ?|?( ifstream & is, _Istream_Sstr f ) {
[211def2]218//      _Istream_Rstr f2 = {f.sstr.s.inner, (_Istream_str_base)f.sstr};
[737988b]219        _Istream_Rstr f2 = {f.s.inner, (_Istream_str_base)f};
220    return is | f2;
[7e1dbd7]221} // ?|?
222
[f450f2f]223////////////////////////////////////////////////////////
224// Slicing
225
[e8b3717]226string ?()( string & s, size_t start, size_t len ) {
227    string ret = { *s.inner, start, len };
[f450f2f]228    return ret`shareEdits;
229}
230
[681e12f]231string ?()( string & s, size_t start ) {
[e8b3717]232    string ret = { *s.inner, start, size( s ) - start };
[bc9f84a]233    return ret`shareEdits;
234}
235
[f450f2f]236////////////////////////////////////////////////////////
237// Comparison
238
[681e12f]239int  strcmp(const string & s1, const string & s2) { return strcmp(*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; }
245bool ?<? (const string & s1, const string & s2) { return *s1.inner <  *s2.inner; }
246
247int  strcmp(const string & s1, const char * s2) { return strcmp(*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; }
253bool ?<? (const string & s1, const char * s2) { return *s1.inner <  s2; }
254
255int  strcmp(const char * s1, const string & s2) { return strcmp( 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; }
261bool ?<? (const char * s1, const string & s2) { return s1 <  *s2.inner; }
[f450f2f]262
263
264////////////////////////////////////////////////////////
265// Getter
266
[6264087]267size_t size(const string & s) {
[681e12f]268    return size( *s.inner );
[f450f2f]269}
270
271////////////////////////////////////////////////////////
272// Concatenation
273
[681e12f]274void ?+=?(string & s, char c) {
275    (*s.inner) += c;
[f450f2f]276}
277
[6264087]278void ?+=?(string & s, const string & s2) {
[f450f2f]279    (*s.inner) += (*s2.inner);
280}
281
[e891349]282void append(string & s, const string & s2, size_t maxlen) {
283    append( (*s.inner), (*s2.inner), maxlen );
284}
285
[681e12f]286void ?+=?(string & s, const char * c) {
287    (*s.inner) += c;
[f450f2f]288}
289
[e891349]290void append(string & s, const char * buffer, size_t bsize) {
291    append( (*s.inner), buffer, bsize );
292}
293
[681e12f]294string ?+?(const string & s, char c) {
[f450f2f]295    string ret = s;
[681e12f]296    ret += c;
[f450f2f]297    return ret;
298}
299
[6264087]300string ?+?(const string & s, const string & s2) {
[f450f2f]301    string ret = s;
302    ret += s2;
303    return ret;
304}
305
[6264087]306string ?+?(const char * s1, const char * s2) {
[f450f2f]307    string ret = s1;
308    ret += s2;
309    return ret;
310}
311
[681e12f]312string ?+?(const string & s, const char * c) {
[f450f2f]313    string ret = s;
[681e12f]314    ret += c;
[f450f2f]315    return ret;
316}
317
318////////////////////////////////////////////////////////
319// Repetition
320
[38951c31]321void ?*=?(string & s, size_t factor) {
322    (*s.inner) *= factor;
[f450f2f]323}
324
[38951c31]325string ?*?(const string & s, size_t factor) {
326    string ret = s;
327    ret *= factor;
328    return ret;
[479fbe3]329}
330
331string ?*?(char c, size_t factor) {
332    string ret = c;
[38951c31]333    ret *= factor;
334    return ret;
[f450f2f]335}
336
[479fbe3]337string ?*?(const char * s, size_t factor) {
338    string ret = s;
[38951c31]339    ret *= factor;
340    return ret;
[f450f2f]341}
342
343////////////////////////////////////////////////////////
344// Character access
345
[6264087]346char ?[?](const string & s, size_t index) {
[f450f2f]347    return (*s.inner)[index];
348}
349
[6264087]350string ?[?](string & s, size_t index) {
[e8b3717]351    string ret = { *s.inner, index, 1 };
[f450f2f]352    return ret`shareEdits;
353}
354
355////////////////////////////////////////////////////////
356// Search
357
[6264087]358bool contains(const string & s, char ch) {
[f450f2f]359    return contains( *s.inner, ch );
360}
361
[6264087]362int find(const string & s, char search) {
[f450f2f]363    return find( *s.inner, search );
364}
365
[6264087]366int find(const string & s, const string & search) {
[f450f2f]367    return find( *s.inner, *search.inner );
368}
369
[6264087]370int find(const string & s, const char * search) {
[f450f2f]371    return find( *s.inner, search);
372}
373
[6264087]374int find(const string & s, const char * search, size_t searchsize) {
[f450f2f]375    return find( *s.inner, search, searchsize);
376}
377
[6264087]378int findFrom(const string & s, size_t fromPos, char search) {
[08ed947]379    return findFrom( *s.inner, fromPos, search );
380}
381
[6264087]382int findFrom(const string & s, size_t fromPos, const string & search) {
[08ed947]383    return findFrom( *s.inner, fromPos, *search.inner );
384}
385
[6264087]386int findFrom(const string & s, size_t fromPos, const char * search) {
[08ed947]387    return findFrom( *s.inner, fromPos, search );
388}
389
[6264087]390int findFrom(const string & s, size_t fromPos, const char * search, size_t searchsize) {
[08ed947]391    return findFrom( *s.inner, fromPos, search, searchsize );
392}
393
[6264087]394bool includes(const string & s, const string & search) {
[f450f2f]395    return includes( *s.inner, *search.inner );
396}
397
[6264087]398bool includes(const string & s, const char * search) {
[f450f2f]399    return includes( *s.inner, search );
400}
401
[6264087]402bool includes(const string & s, const char * search, size_t searchsize) {
[f450f2f]403    return includes( *s.inner, search, searchsize );
404}
405
[6264087]406bool startsWith(const string & s, const string & prefix) {
[f450f2f]407    return startsWith( *s.inner, *prefix.inner );
408}
409
[6264087]410bool startsWith(const string & s, const char * prefix) {
[f450f2f]411    return startsWith( *s.inner, prefix );
412}
413
[6264087]414bool startsWith(const string & s, const char * prefix, size_t prefixsize) {
[f450f2f]415    return startsWith( *s.inner, prefix, prefixsize );
416}
417
[6264087]418bool endsWith(const string & s, const string & suffix) {
[f450f2f]419    return endsWith( *s.inner, *suffix.inner );
420}
421
[6264087]422bool endsWith(const string & s, const char * suffix) {
[f450f2f]423    return endsWith( *s.inner, suffix );
424}
425
[6264087]426bool endsWith(const string & s, const char * suffix, size_t suffixsize) {
[f450f2f]427    return endsWith( *s.inner, suffix, suffixsize );
428}
429
430
431///////////////////////////////////////////////////////////////////////////
432// charclass, include, exclude
433
[681e12f]434void ?{}( charclass & s, const string & chars) {
435    (s.inner) { malloc() };
436    ?{}( *s.inner, *(const string_res *)chars.inner );
[f450f2f]437}
438
[681e12f]439void ?{}( charclass & s, const char * chars ) {
440    (s.inner) { malloc() };
441    ?{}( *s.inner, chars );
[f450f2f]442}
443
[681e12f]444void ?{}( charclass & s, const char * chars, size_t charssize ) {
445    (s.inner) { malloc() };
446    ?{}( *s.inner, chars, charssize );
[f450f2f]447}
448
[681e12f]449void ^?{}( charclass & s ) {
450    ^(*s.inner){};
451    free( s.inner );
452    s.inner = 0p;
[f450f2f]453}
454
455
[6264087]456int exclude(const string & s, const charclass & mask) {
[f450f2f]457    return exclude( *s.inner, *mask.inner );
458}
459/*
[6264087]460StrSlice exclude(string & s, const charclass & mask) {
[f450f2f]461}
462*/
463
[6264087]464int include(const string & s, const charclass & mask) {
[f450f2f]465    return include( *s.inner, *mask.inner );
466}
467
468/*
[6264087]469StrSlice include(string & s, const charclass & mask) {
[f450f2f]470}
471*/
472
Note: See TracBrowser for help on using the repository browser.