source: libcfa/src/collections/string.cfa@ 5ecaeca

Last change on this file since 5ecaeca was 681e12f, checked in by Peter A. Buhr <pabuhr@…>, 22 months ago

formatting, change cmp to strcmp, add strlen and strcat

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