source: libcfa/src/collections/string.cfa @ 686912c

Last change on this file since 686912c was 686912c, checked in by Peter A. Buhr <pabuhr@…>, 9 months ago

third attempt at input manipulators for strings

  • Property mode set to 100644
File size: 9.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 : Thu Aug 31 13:20:41 2023
13// Update Count     : 161
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
32void ?{}( string & this ) {
33    (this.inner) { malloc() };
34    ?{}( *this.inner );
35}
36
37// private (not in header)
38static 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
43void ?{}( string & this, const string & other ) {
44    (this.inner) { malloc() };
45    ?{}( *this.inner, *other.inner, COPY_VALUE );
46}
47
48void ?{}( string & this, string & other ) {
49    ?{}( this, (const string &) other );
50}
51
52void ?{}( string & this, const char * val ) {
53    (this.inner) { malloc() };
54    ?{}( *this.inner, val );
55}
56
57void ?{}( string & this, const char * buffer, size_t bsize) {
58    (this.inner) { malloc() };
59    ?{}( *this.inner, buffer, bsize );
60}
61
62void ^?{}( string & this ) {
63    ^(*this.inner){};
64    free( this.inner );
65    this.inner = 0p;
66}
67
68////////////////////////////////////////////////////////
69// Alternate construction: request shared edits
70
71string_WithSharedEdits ?`shareEdits( string & this ) {
72    string_WithSharedEdits ret = { &this };
73    return ret;
74}
75
76void ?{}( string & this, string_WithSharedEdits src ) {
77    ?{}( this, *src.s->inner, 0, src.s->inner->Handle.lnth);
78}
79
80////////////////////////////////////////////////////////
81// Assignment
82
83void ?=?( string & this, const char * val ) {
84    (*this.inner) = val;
85}
86
87void ?=?(string & this, const string & other) {
88    (*this.inner) = (*other.inner);
89}
90
91void ?=?( string & this, char val ) {
92    (*this.inner) = val;
93}
94
95string & ?=?(string & this, string & other) { //// <---- straw man change
96    (*this.inner) = (*other.inner);
97    return this;
98}
99
100
101////////////////////////////////////////////////////////
102// Input-Output
103
104ofstream & ?|?( ofstream & out, const string & this ) {
105    return out | (*this.inner); // print internal string_res
106}
107
108void ?|?( ofstream & out, const string & this ) {
109    (ofstream &)(out | (*this.inner)); ends( out );
110}
111
112ifstream & ?|?(ifstream & in, string & this) {
113    return in | (*this.inner); // read to internal string_res
114}
115
116void ?|?( ifstream & in, string & this ) {
117    (ifstream &)(in | this); ends( in );
118}
119
120ifstream & ?|?( ifstream & is, _Istream_str f ) {
121        // skip, same as for char *
122        if ( ! &f.s ) {
123                // fprintf( stderr,  "skip %s %d\n", f.scanset, f.wd );
124                if ( f.wd == -1 ) fmt( is, f.scanset, "" ); // no input arguments
125                else for ( f.wd ) fmt( is, "%*c" );
126                return is;
127        } // if
128
129        // .---------------,
130        // | | | | |...|0|0| check and guard
131        // `---------------'
132        enum { gwd = 128 + 2, wd = gwd - 1 };                           // guarded and unguarded width
133        char cstr[gwd];                                                                         // read in chunks
134        bool cont = false;
135
136        if ( f.wd == -1 ) f.wd = wd;
137        _Istream_Cstr cfmt = { cstr, (_Istream_str_base)f };
138
139        cstr[wd] = '\0';                                                                        // guard null terminate string
140        try {
141                is | cfmt;
142        } catch( cstring_length * ) {
143                cont = true;
144        } finally {
145                f.s = cstr;                                                                             // ok to initialize string
146        } // try
147        for ( ; cont; )  {                                                                      // overflow read ?
148                cont = false;
149                try {
150                        is | cfmt;
151                } catch( cstring_length * ) {
152                        cont = true;                                                            // continue not allowed
153                } finally {
154                        f.s += cstr;                                                            // build string chunk at a time
155                } // try
156        } // for
157        return is;
158} // ?|?
159
160void ?|?( ifstream & in, _Istream_str f ) {
161    (ifstream &)(in | f); ends( in );
162}
163
164////////////////////////////////////////////////////////
165// Slicing
166
167string ?()( string & this, size_t start, size_t end ) {
168    string ret = { *this.inner, start, end };
169    return ret`shareEdits;
170}
171
172string ?()( string & this, size_t start ) {
173    string ret = { *this.inner, start, size( this ) };
174    return ret`shareEdits;
175}
176
177////////////////////////////////////////////////////////
178// Comparison
179
180bool ?==?(const string & s, const string & other) {
181    return *s.inner == *other.inner;
182}
183
184bool ?!=?(const string & s, const string & other) {
185    return *s.inner != *other.inner;
186}
187
188bool ?==?(const string & s, const char * other) {
189    return *s.inner == other;
190}
191
192bool ?!=?(const string & s, const char * other) {
193    return *s.inner != other;
194}
195
196////////////////////////////////////////////////////////
197// Getter
198
199size_t size(const string & s) {
200    return size( * s.inner );
201}
202
203////////////////////////////////////////////////////////
204// Concatenation
205
206void ?+=?(string & s, char other) {
207    (*s.inner) += other;
208}
209
210void ?+=?(string & s, const string & s2) {
211    (*s.inner) += (*s2.inner);
212}
213
214void ?+=?(string & s, const char * other) {
215    (*s.inner) += other;
216}
217
218string ?+?(const string & s, char other) {
219    string ret = s;
220    ret += other;
221    return ret;
222}
223
224string ?+?(const string & s, const string & s2) {
225    string ret = s;
226    ret += s2;
227    return ret;
228}
229
230string ?+?(const char * s1, const char * s2) {
231    string ret = s1;
232    ret += s2;
233    return ret;
234}
235
236string ?+?(const string & s, const char * other) {
237    string ret = s;
238    ret += other;
239    return ret;
240}
241
242////////////////////////////////////////////////////////
243// Repetition
244
245string ?*?(const string & s, size_t factor) {
246    string ret = "";
247    for (factor) ret += s;
248    return ret;
249}
250
251string ?*?(char c, size_t size) {
252    string ret = "";
253    for ((size_t)size) ret += c;
254    return ret;
255}
256
257string ?*?(const char *s, size_t factor) {
258    string ss = s;
259    return ss * factor;
260}
261
262////////////////////////////////////////////////////////
263// Character access
264
265char ?[?](const string & s, size_t index) {
266    return (*s.inner)[index];
267}
268
269string ?[?](string & s, size_t index) {
270    string ret = { *s.inner, index, index + 1 };
271    return ret`shareEdits;
272}
273
274////////////////////////////////////////////////////////
275// Search
276
277bool contains(const string & s, char ch) {
278    return contains( *s.inner, ch );
279}
280
281int find(const string & s, char search) {
282    return find( *s.inner, search );
283}
284
285int find(const string & s, const string & search) {
286    return find( *s.inner, *search.inner );
287}
288
289int find(const string & s, const char * search) {
290    return find( *s.inner, search);
291}
292
293int find(const string & s, const char * search, size_t searchsize) {
294    return find( *s.inner, search, searchsize);
295}
296
297int findFrom(const string & s, size_t fromPos, char search) {
298    return findFrom( *s.inner, fromPos, search );
299}
300
301int findFrom(const string & s, size_t fromPos, const string & search) {
302    return findFrom( *s.inner, fromPos, *search.inner );
303}
304
305int findFrom(const string & s, size_t fromPos, const char * search) {
306    return findFrom( *s.inner, fromPos, search );
307}
308
309int findFrom(const string & s, size_t fromPos, const char * search, size_t searchsize) {
310    return findFrom( *s.inner, fromPos, search, searchsize );
311}
312
313bool includes(const string & s, const string & search) {
314    return includes( *s.inner, *search.inner );
315}
316
317bool includes(const string & s, const char * search) {
318    return includes( *s.inner, search );
319}
320
321bool includes(const string & s, const char * search, size_t searchsize) {
322    return includes( *s.inner, search, searchsize );
323}
324
325bool startsWith(const string & s, const string & prefix) {
326    return startsWith( *s.inner, *prefix.inner );
327}
328
329bool startsWith(const string & s, const char * prefix) {
330    return startsWith( *s.inner, prefix );
331}
332
333bool startsWith(const string & s, const char * prefix, size_t prefixsize) {
334    return startsWith( *s.inner, prefix, prefixsize );
335}
336
337bool endsWith(const string & s, const string & suffix) {
338    return endsWith( *s.inner, *suffix.inner );
339}
340
341bool endsWith(const string & s, const char * suffix) {
342    return endsWith( *s.inner, suffix );
343}
344
345bool endsWith(const string & s, const char * suffix, size_t suffixsize) {
346    return endsWith( *s.inner, suffix, suffixsize );
347}
348
349
350///////////////////////////////////////////////////////////////////////////
351// charclass, include, exclude
352
353void ?{}( charclass & this, const string & chars) {
354    (this.inner) { malloc() };
355    ?{}( *this.inner, *(const string_res *)chars.inner );
356}
357
358void ?{}( charclass & this, const char * chars ) {
359    (this.inner) { malloc() };
360    ?{}( *this.inner, chars );
361}
362
363void ?{}( charclass & this, const char * chars, size_t charssize ) {
364    (this.inner) { malloc() };
365    ?{}( *this.inner, chars, charssize );
366}
367
368void ^?{}( charclass & this ) {
369    ^(*this.inner){};
370    free( this.inner );
371    this.inner = 0p;
372}
373
374
375int exclude(const string & s, const charclass & mask) {
376    return exclude( *s.inner, *mask.inner );
377}
378/*
379StrSlice exclude(string & s, const charclass & mask) {
380}
381*/
382
383int include(const string & s, const charclass & mask) {
384    return include( *s.inner, *mask.inner );
385}
386
387/*
388StrSlice include(string & s, const charclass & mask) {
389}
390*/
391
Note: See TracBrowser for help on using the repository browser.