source: libcfa/src/collections/string.cfa@ 0ac8d07

stuck-waitfor-destruct
Last change on this file since 0ac8d07 was 34c6e1e6, checked in by Peter A. Buhr <pabuhr@…>, 2 years ago

add string output manipulators, third attempt at input manipulators for strings

  • Property mode set to 100644
File size: 9.4 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
[34c6e1e6]12// Last Modified On : Sat Sep 2 12:05:57 2023
13// Update Count : 206
[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
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
[6264087]57void ?{}( string & this, const char * buffer, size_t bsize) {
[f450f2f]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
[4b3b352]95string & ?=?(string & this, string & other) { //// <---- straw man change
[f450f2f]96 (*this.inner) = (*other.inner);
97 return this;
98}
99
100
101////////////////////////////////////////////////////////
[d32679d5]102// Input-Output
[f450f2f]103
[9ca5e56]104ofstream & ?|?( ofstream & out, const string & this ) {
105 return out | (*this.inner); // print internal string_res
[f450f2f]106}
107
[9ca5e56]108void ?|?( ofstream & out, const string & this ) {
109 (ofstream &)(out | (*this.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
[6264087]126ifstream & ?|?(ifstream & in, string & this) {
[d32679d5]127 return in | (*this.inner); // read to internal string_res
128}
129
[6264087]130void ?|?( ifstream & in, string & this ) {
131 (ifstream &)(in | this); ends( in );
132}
[d32679d5]133
[34c6e1e6]134ifstream & ?|?( ifstream & is, _Istream_Sstr f ) {
[686912c]135 // .---------------,
[34c6e1e6]136 // | | | | |...|0|0| null terminator and guard if missing
[686912c]137 // `---------------'
[34c6e1e6]138 enum { gwd = 128 + 1, wd = gwd - 1 }; // guard and unguard width
[88001dd]139 char cstr[gwd]; // read in chunks
[686912c]140 bool cont = false;
[88001dd]141
[34c6e1e6]142 _Istream_Cstr cf = { cstr, (_Istream_str_base)f };
143 if ( ! cf.flags.rwd ) cf.wd = wd;
[7e1dbd7]144
[88001dd]145 cstr[wd] = '\0'; // guard null terminate string
146 try {
[34c6e1e6]147 is | cf;
[88001dd]148 } catch( cstring_length * ) {
[7e1dbd7]149 cont = true;
[88001dd]150 } finally {
[7e1dbd7]151 f.s = cstr; // ok to initialize string
[88001dd]152 } // try
153 for ( ; cont; ) { // overflow read ?
154 cont = false;
155 try {
[34c6e1e6]156 is | cf;
[88001dd]157 } catch( cstring_length * ) {
158 cont = true; // continue not allowed
159 } finally {
[7e1dbd7]160 f.s += cstr; // build string chunk at a time
[88001dd]161 } // try
162 } // for
[7e1dbd7]163 return is;
164} // ?|?
165
[34c6e1e6]166void ?|?( ifstream & in, _Istream_Sstr f ) {
[7e1dbd7]167 (ifstream &)(in | f); ends( in );
168}
169
[f450f2f]170////////////////////////////////////////////////////////
171// Slicing
172
173string ?()( string & this, size_t start, size_t end ) {
174 string ret = { *this.inner, start, end };
175 return ret`shareEdits;
176}
177
[bc9f84a]178string ?()( string & this, size_t start ) {
179 string ret = { *this.inner, start, size( this ) };
180 return ret`shareEdits;
181}
182
[f450f2f]183////////////////////////////////////////////////////////
184// Comparison
185
[6264087]186bool ?==?(const string & s, const string & other) {
[f450f2f]187 return *s.inner == *other.inner;
188}
189
[6264087]190bool ?!=?(const string & s, const string & other) {
[f450f2f]191 return *s.inner != *other.inner;
192}
193
[6264087]194bool ?==?(const string & s, const char * other) {
[f450f2f]195 return *s.inner == other;
196}
197
[6264087]198bool ?!=?(const string & s, const char * other) {
[f450f2f]199 return *s.inner != other;
200}
201
202////////////////////////////////////////////////////////
203// Getter
204
[6264087]205size_t size(const string & s) {
[f450f2f]206 return size( * s.inner );
207}
208
209////////////////////////////////////////////////////////
210// Concatenation
211
[6264087]212void ?+=?(string & s, char other) {
[f450f2f]213 (*s.inner) += other;
214}
215
[6264087]216void ?+=?(string & s, const string & s2) {
[f450f2f]217 (*s.inner) += (*s2.inner);
218}
219
[6264087]220void ?+=?(string & s, const char * other) {
[f450f2f]221 (*s.inner) += other;
222}
223
[6264087]224string ?+?(const string & s, char other) {
[f450f2f]225 string ret = s;
226 ret += other;
227 return ret;
228}
229
[6264087]230string ?+?(const string & s, const string & s2) {
[f450f2f]231 string ret = s;
232 ret += s2;
233 return ret;
234}
235
[6264087]236string ?+?(const char * s1, const char * s2) {
[f450f2f]237 string ret = s1;
238 ret += s2;
239 return ret;
240}
241
[6264087]242string ?+?(const string & s, const char * other) {
[f450f2f]243 string ret = s;
244 ret += other;
245 return ret;
246}
247
248////////////////////////////////////////////////////////
249// Repetition
250
[6264087]251string ?*?(const string & s, size_t factor) {
[f450f2f]252 string ret = "";
253 for (factor) ret += s;
254 return ret;
255}
256
257string ?*?(char c, size_t size) {
258 string ret = "";
259 for ((size_t)size) ret += c;
260 return ret;
261}
262
263string ?*?(const char *s, size_t factor) {
264 string ss = s;
265 return ss * factor;
266}
267
268////////////////////////////////////////////////////////
269// Character access
270
[6264087]271char ?[?](const string & s, size_t index) {
[f450f2f]272 return (*s.inner)[index];
273}
274
[6264087]275string ?[?](string & s, size_t index) {
[f450f2f]276 string ret = { *s.inner, index, index + 1 };
277 return ret`shareEdits;
278}
279
280////////////////////////////////////////////////////////
281// Search
282
[6264087]283bool contains(const string & s, char ch) {
[f450f2f]284 return contains( *s.inner, ch );
285}
286
[6264087]287int find(const string & s, char search) {
[f450f2f]288 return find( *s.inner, search );
289}
290
[6264087]291int find(const string & s, const string & search) {
[f450f2f]292 return find( *s.inner, *search.inner );
293}
294
[6264087]295int find(const string & s, const char * search) {
[f450f2f]296 return find( *s.inner, search);
297}
298
[6264087]299int find(const string & s, const char * search, size_t searchsize) {
[f450f2f]300 return find( *s.inner, search, searchsize);
301}
302
[6264087]303int findFrom(const string & s, size_t fromPos, char search) {
[08ed947]304 return findFrom( *s.inner, fromPos, search );
305}
306
[6264087]307int findFrom(const string & s, size_t fromPos, const string & search) {
[08ed947]308 return findFrom( *s.inner, fromPos, *search.inner );
309}
310
[6264087]311int findFrom(const string & s, size_t fromPos, const char * search) {
[08ed947]312 return findFrom( *s.inner, fromPos, search );
313}
314
[6264087]315int findFrom(const string & s, size_t fromPos, const char * search, size_t searchsize) {
[08ed947]316 return findFrom( *s.inner, fromPos, search, searchsize );
317}
318
[6264087]319bool includes(const string & s, const string & search) {
[f450f2f]320 return includes( *s.inner, *search.inner );
321}
322
[6264087]323bool includes(const string & s, const char * search) {
[f450f2f]324 return includes( *s.inner, search );
325}
326
[6264087]327bool includes(const string & s, const char * search, size_t searchsize) {
[f450f2f]328 return includes( *s.inner, search, searchsize );
329}
330
[6264087]331bool startsWith(const string & s, const string & prefix) {
[f450f2f]332 return startsWith( *s.inner, *prefix.inner );
333}
334
[6264087]335bool startsWith(const string & s, const char * prefix) {
[f450f2f]336 return startsWith( *s.inner, prefix );
337}
338
[6264087]339bool startsWith(const string & s, const char * prefix, size_t prefixsize) {
[f450f2f]340 return startsWith( *s.inner, prefix, prefixsize );
341}
342
[6264087]343bool endsWith(const string & s, const string & suffix) {
[f450f2f]344 return endsWith( *s.inner, *suffix.inner );
345}
346
[6264087]347bool endsWith(const string & s, const char * suffix) {
[f450f2f]348 return endsWith( *s.inner, suffix );
349}
350
[6264087]351bool endsWith(const string & s, const char * suffix, size_t suffixsize) {
[f450f2f]352 return endsWith( *s.inner, suffix, suffixsize );
353}
354
355
356///////////////////////////////////////////////////////////////////////////
357// charclass, include, exclude
358
359void ?{}( charclass & this, const string & chars) {
360 (this.inner) { malloc() };
361 ?{}( *this.inner, *(const string_res *)chars.inner );
362}
363
364void ?{}( charclass & this, const char * chars ) {
365 (this.inner) { malloc() };
366 ?{}( *this.inner, chars );
367}
368
369void ?{}( charclass & this, const char * chars, size_t charssize ) {
370 (this.inner) { malloc() };
371 ?{}( *this.inner, chars, charssize );
372}
373
374void ^?{}( charclass & this ) {
375 ^(*this.inner){};
376 free( this.inner );
377 this.inner = 0p;
378}
379
380
[6264087]381int exclude(const string & s, const charclass & mask) {
[f450f2f]382 return exclude( *s.inner, *mask.inner );
383}
384/*
[6264087]385StrSlice exclude(string & s, const charclass & mask) {
[f450f2f]386}
387*/
388
[6264087]389int include(const string & s, const charclass & mask) {
[f450f2f]390 return include( *s.inner, *mask.inner );
391}
392
393/*
[6264087]394StrSlice include(string & s, const charclass & mask) {
[f450f2f]395}
396*/
397
Note: See TracBrowser for help on using the repository browser.