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

stuck-waitfor-destruct
Last change on this file since ac939461 was e8b3717, checked in by Michael Brooks <mlbrooks@…>, 2 years ago

Modify substring interface from start-end to start-len, and add a missing test.

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