source: libcfa/src/collections/string.cfa @ 92d8cda

Last change on this file since 92d8cda was 737988b, checked in by Michael Brooks <mlbrooks@…>, 14 months ago

Deduplicate manipulator read-to-string by delegating from string to string_res.

  • Property mode set to 100644
File size: 8.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
[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 ) {
[737988b]131    in | (*this.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 ) {
[7e1dbd7]140    (ifstream &)(in | f); ends( in );
141}
142
[f450f2f]143////////////////////////////////////////////////////////
144// Slicing
145
146string ?()( string & this, size_t start, size_t end ) {
147    string ret = { *this.inner, start, end };
148    return ret`shareEdits;
149}
150
[bc9f84a]151string ?()( string & this, size_t start ) {
152    string ret = { *this.inner, start, size( this ) };
153    return ret`shareEdits;
154}
155
[f450f2f]156////////////////////////////////////////////////////////
157// Comparison
158
[6264087]159bool ?==?(const string & s, const string & other) {
[f450f2f]160    return *s.inner == *other.inner;
161}
162
[6264087]163bool ?!=?(const string & s, const string & other) {
[f450f2f]164    return *s.inner != *other.inner;
165}
166
[6264087]167bool ?==?(const string & s, const char * other) {
[f450f2f]168    return *s.inner == other;
169}
170
[6264087]171bool ?!=?(const string & s, const char * other) {
[f450f2f]172    return *s.inner != other;
173}
174
175////////////////////////////////////////////////////////
176// Getter
177
[6264087]178size_t size(const string & s) {
[f450f2f]179    return size( * s.inner );
180}
181
182////////////////////////////////////////////////////////
183// Concatenation
184
[6264087]185void ?+=?(string & s, char other) {
[f450f2f]186    (*s.inner) += other;
187}
188
[6264087]189void ?+=?(string & s, const string & s2) {
[f450f2f]190    (*s.inner) += (*s2.inner);
191}
192
[6264087]193void ?+=?(string & s, const char * other) {
[f450f2f]194    (*s.inner) += other;
195}
196
[6264087]197string ?+?(const string & s, char other) {
[f450f2f]198    string ret = s;
199    ret += other;
200    return ret;
201}
202
[6264087]203string ?+?(const string & s, const string & s2) {
[f450f2f]204    string ret = s;
205    ret += s2;
206    return ret;
207}
208
[6264087]209string ?+?(const char * s1, const char * s2) {
[f450f2f]210    string ret = s1;
211    ret += s2;
212    return ret;
213}
214
[6264087]215string ?+?(const string & s, const char * other) {
[f450f2f]216    string ret = s;
217    ret += other;
218    return ret;
219}
220
221////////////////////////////////////////////////////////
222// Repetition
223
[6264087]224string ?*?(const string & s, size_t factor) {
[f450f2f]225    string ret = "";
226    for (factor) ret += s;
227    return ret;
228}
229
230string ?*?(char c, size_t size) {
231    string ret = "";
232    for ((size_t)size) ret += c;
233    return ret;
234}
235
236string ?*?(const char *s, size_t factor) {
237    string ss = s;
238    return ss * factor;
239}
240
241////////////////////////////////////////////////////////
242// Character access
243
[6264087]244char ?[?](const string & s, size_t index) {
[f450f2f]245    return (*s.inner)[index];
246}
247
[6264087]248string ?[?](string & s, size_t index) {
[f450f2f]249    string ret = { *s.inner, index, index + 1 };
250    return ret`shareEdits;
251}
252
253////////////////////////////////////////////////////////
254// Search
255
[6264087]256bool contains(const string & s, char ch) {
[f450f2f]257    return contains( *s.inner, ch );
258}
259
[6264087]260int find(const string & s, char search) {
[f450f2f]261    return find( *s.inner, search );
262}
263
[6264087]264int find(const string & s, const string & search) {
[f450f2f]265    return find( *s.inner, *search.inner );
266}
267
[6264087]268int find(const string & s, const char * search) {
[f450f2f]269    return find( *s.inner, search);
270}
271
[6264087]272int find(const string & s, const char * search, size_t searchsize) {
[f450f2f]273    return find( *s.inner, search, searchsize);
274}
275
[6264087]276int findFrom(const string & s, size_t fromPos, char search) {
[08ed947]277    return findFrom( *s.inner, fromPos, search );
278}
279
[6264087]280int findFrom(const string & s, size_t fromPos, const string & search) {
[08ed947]281    return findFrom( *s.inner, fromPos, *search.inner );
282}
283
[6264087]284int findFrom(const string & s, size_t fromPos, const char * search) {
[08ed947]285    return findFrom( *s.inner, fromPos, search );
286}
287
[6264087]288int findFrom(const string & s, size_t fromPos, const char * search, size_t searchsize) {
[08ed947]289    return findFrom( *s.inner, fromPos, search, searchsize );
290}
291
[6264087]292bool includes(const string & s, const string & search) {
[f450f2f]293    return includes( *s.inner, *search.inner );
294}
295
[6264087]296bool includes(const string & s, const char * search) {
[f450f2f]297    return includes( *s.inner, search );
298}
299
[6264087]300bool includes(const string & s, const char * search, size_t searchsize) {
[f450f2f]301    return includes( *s.inner, search, searchsize );
302}
303
[6264087]304bool startsWith(const string & s, const string & prefix) {
[f450f2f]305    return startsWith( *s.inner, *prefix.inner );
306}
307
[6264087]308bool startsWith(const string & s, const char * prefix) {
[f450f2f]309    return startsWith( *s.inner, prefix );
310}
311
[6264087]312bool startsWith(const string & s, const char * prefix, size_t prefixsize) {
[f450f2f]313    return startsWith( *s.inner, prefix, prefixsize );
314}
315
[6264087]316bool endsWith(const string & s, const string & suffix) {
[f450f2f]317    return endsWith( *s.inner, *suffix.inner );
318}
319
[6264087]320bool endsWith(const string & s, const char * suffix) {
[f450f2f]321    return endsWith( *s.inner, suffix );
322}
323
[6264087]324bool endsWith(const string & s, const char * suffix, size_t suffixsize) {
[f450f2f]325    return endsWith( *s.inner, suffix, suffixsize );
326}
327
328
329///////////////////////////////////////////////////////////////////////////
330// charclass, include, exclude
331
332void ?{}( charclass & this, const string & chars) {
333    (this.inner) { malloc() };
334    ?{}( *this.inner, *(const string_res *)chars.inner );
335}
336
337void ?{}( charclass & this, const char * chars ) {
338    (this.inner) { malloc() };
339    ?{}( *this.inner, chars );
340}
341
342void ?{}( charclass & this, const char * chars, size_t charssize ) {
343    (this.inner) { malloc() };
344    ?{}( *this.inner, chars, charssize );
345}
346
347void ^?{}( charclass & this ) {
348    ^(*this.inner){};
349    free( this.inner );
350    this.inner = 0p;
351}
352
353
[6264087]354int exclude(const string & s, const charclass & mask) {
[f450f2f]355    return exclude( *s.inner, *mask.inner );
356}
357/*
[6264087]358StrSlice exclude(string & s, const charclass & mask) {
[f450f2f]359}
360*/
361
[6264087]362int include(const string & s, const charclass & mask) {
[f450f2f]363    return include( *s.inner, *mask.inner );
364}
365
366/*
[6264087]367StrSlice include(string & s, const charclass & mask) {
[f450f2f]368}
369*/
370
Note: See TracBrowser for help on using the repository browser.