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

Last change on this file since cf34e82 was 416b443, checked in by Michael Brooks <mlbrooks@…>, 14 months ago

Implement full set of relational operators for strings

  • Property mode set to 100644
File size: 10.1 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 : Sat Sep  2 12:05:57 2023
13// Update Count     : 206
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
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
57void ?{}( string & this, const char * buffer, size_t bsize) {
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
95string & ?=?(string & this, string & other) { //// <---- straw man change
96    (*this.inner) = (*other.inner);
97    return this;
98}
99
100
101////////////////////////////////////////////////////////
102// Input-Output
103
104ofstream & ?|?( ofstream & out, const string & this ) {
105    return out | (*this.inner); // print internal string_res
106}
107
108void ?|?( ofstream & out, const string & this ) {
109    (ofstream &)(out | (*this.inner)); ends( out );
110}
111
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
126ifstream & ?|?(ifstream & in, string & this) {
127    return in | (*this.inner); // read to internal string_res
128}
129
130void ?|?( ifstream & in, string & this ) {
131    in | (*this.inner);
132}
133
134ifstream & ?|?( ifstream & is, _Istream_Sstr f ) {
135        _Istream_Rstr f2 = {f.s.inner, (_Istream_str_base)f};
136    return is | f2;
137} // ?|?
138
139void ?|?( ifstream & in, _Istream_Sstr f ) {
140    (ifstream &)(in | f); ends( in );
141}
142
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
151string ?()( string & this, size_t start ) {
152    string ret = { *this.inner, start, size( this ) };
153    return ret`shareEdits;
154}
155
156////////////////////////////////////////////////////////
157// Comparison
158
159int  cmp (const string &s1, const string &s2) { return cmp(*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  cmp (const string &s1, const char*   s2) { return cmp(*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  cmp (const char*   s1, const string &s2) { return cmp( 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 ; }
182
183
184////////////////////////////////////////////////////////
185// Getter
186
187size_t size(const string & s) {
188    return size( * s.inner );
189}
190
191////////////////////////////////////////////////////////
192// Concatenation
193
194void ?+=?(string & s, char other) {
195    (*s.inner) += other;
196}
197
198void ?+=?(string & s, const string & s2) {
199    (*s.inner) += (*s2.inner);
200}
201
202void ?+=?(string & s, const char * other) {
203    (*s.inner) += other;
204}
205
206string ?+?(const string & s, char other) {
207    string ret = s;
208    ret += other;
209    return ret;
210}
211
212string ?+?(const string & s, const string & s2) {
213    string ret = s;
214    ret += s2;
215    return ret;
216}
217
218string ?+?(const char * s1, const char * s2) {
219    string ret = s1;
220    ret += s2;
221    return ret;
222}
223
224string ?+?(const string & s, const char * other) {
225    string ret = s;
226    ret += other;
227    return ret;
228}
229
230////////////////////////////////////////////////////////
231// Repetition
232
233string ?*?(const string & s, size_t factor) {
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
253char ?[?](const string & s, size_t index) {
254    return (*s.inner)[index];
255}
256
257string ?[?](string & s, size_t index) {
258    string ret = { *s.inner, index, index + 1 };
259    return ret`shareEdits;
260}
261
262////////////////////////////////////////////////////////
263// Search
264
265bool contains(const string & s, char ch) {
266    return contains( *s.inner, ch );
267}
268
269int find(const string & s, char search) {
270    return find( *s.inner, search );
271}
272
273int find(const string & s, const string & search) {
274    return find( *s.inner, *search.inner );
275}
276
277int find(const string & s, const char * search) {
278    return find( *s.inner, search);
279}
280
281int find(const string & s, const char * search, size_t searchsize) {
282    return find( *s.inner, search, searchsize);
283}
284
285int findFrom(const string & s, size_t fromPos, char search) {
286    return findFrom( *s.inner, fromPos, search );
287}
288
289int findFrom(const string & s, size_t fromPos, const string & search) {
290    return findFrom( *s.inner, fromPos, *search.inner );
291}
292
293int findFrom(const string & s, size_t fromPos, const char * search) {
294    return findFrom( *s.inner, fromPos, search );
295}
296
297int findFrom(const string & s, size_t fromPos, const char * search, size_t searchsize) {
298    return findFrom( *s.inner, fromPos, search, searchsize );
299}
300
301bool includes(const string & s, const string & search) {
302    return includes( *s.inner, *search.inner );
303}
304
305bool includes(const string & s, const char * search) {
306    return includes( *s.inner, search );
307}
308
309bool includes(const string & s, const char * search, size_t searchsize) {
310    return includes( *s.inner, search, searchsize );
311}
312
313bool startsWith(const string & s, const string & prefix) {
314    return startsWith( *s.inner, *prefix.inner );
315}
316
317bool startsWith(const string & s, const char * prefix) {
318    return startsWith( *s.inner, prefix );
319}
320
321bool startsWith(const string & s, const char * prefix, size_t prefixsize) {
322    return startsWith( *s.inner, prefix, prefixsize );
323}
324
325bool endsWith(const string & s, const string & suffix) {
326    return endsWith( *s.inner, *suffix.inner );
327}
328
329bool endsWith(const string & s, const char * suffix) {
330    return endsWith( *s.inner, suffix );
331}
332
333bool endsWith(const string & s, const char * suffix, size_t suffixsize) {
334    return endsWith( *s.inner, suffix, suffixsize );
335}
336
337
338///////////////////////////////////////////////////////////////////////////
339// charclass, include, exclude
340
341void ?{}( charclass & this, const string & chars) {
342    (this.inner) { malloc() };
343    ?{}( *this.inner, *(const string_res *)chars.inner );
344}
345
346void ?{}( charclass & this, const char * chars ) {
347    (this.inner) { malloc() };
348    ?{}( *this.inner, chars );
349}
350
351void ?{}( charclass & this, const char * chars, size_t charssize ) {
352    (this.inner) { malloc() };
353    ?{}( *this.inner, chars, charssize );
354}
355
356void ^?{}( charclass & this ) {
357    ^(*this.inner){};
358    free( this.inner );
359    this.inner = 0p;
360}
361
362
363int exclude(const string & s, const charclass & mask) {
364    return exclude( *s.inner, *mask.inner );
365}
366/*
367StrSlice exclude(string & s, const charclass & mask) {
368}
369*/
370
371int include(const string & s, const charclass & mask) {
372    return include( *s.inner, *mask.inner );
373}
374
375/*
376StrSlice include(string & s, const charclass & mask) {
377}
378*/
379
Note: See TracBrowser for help on using the repository browser.