source: libcfa/src/collections/string.cfa @ 06280ad

Last change on this file since 06280ad was 38951c31, checked in by Michael Brooks <mlbrooks@…>, 10 months ago

Add missing test for string *= and refactor */*= to follow +/+= pattern with string_res.

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