// // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // string -- variable-length, mutable run of text, with value semantics // // Author : Michael L. Brooks // Created On : Fri Sep 03 11:00:00 2021 // Last Modified By : Peter A. Buhr // Last Modified On : Sat Sep 2 12:05:57 2023 // Update Count : 206 // #include "string.hfa" #include "string_res.hfa" #include #pragma GCC visibility push(default) /* Implementation Principle: typical operation translates to the equivalent operation on `inner`. Exceptions are implementing new RAII pattern for value semantics and some const-hell handling. */ //////////////////////////////////////////////////////// // string RAII void ?{}( string & this ) { (this.inner) { malloc() }; ?{}( *this.inner ); } // private (not in header) static void ?{}( string & this, string_res & src, size_t start, size_t end ) { (this.inner) { malloc() }; ?{}( *this.inner, src, SHARE_EDITS, start, end ); } void ?{}( string & this, const string & other ) { (this.inner) { malloc() }; ?{}( *this.inner, *other.inner, COPY_VALUE ); } void ?{}( string & this, string & other ) { ?{}( this, (const string &) other ); } void ?{}( string & this, const char * val ) { (this.inner) { malloc() }; ?{}( *this.inner, val ); } void ?{}( string & this, const char * buffer, size_t bsize) { (this.inner) { malloc() }; ?{}( *this.inner, buffer, bsize ); } void ^?{}( string & this ) { ^(*this.inner){}; free( this.inner ); this.inner = 0p; } //////////////////////////////////////////////////////// // Alternate construction: request shared edits string_WithSharedEdits ?`shareEdits( string & this ) { string_WithSharedEdits ret = { &this }; return ret; } void ?{}( string & this, string_WithSharedEdits src ) { ?{}( this, *src.s->inner, 0, src.s->inner->Handle.lnth); } //////////////////////////////////////////////////////// // Assignment void ?=?( string & this, const char * val ) { (*this.inner) = val; } void ?=?(string & this, const string & other) { (*this.inner) = (*other.inner); } void ?=?( string & this, char val ) { (*this.inner) = val; } string & ?=?(string & this, string & other) { //// <---- straw man change (*this.inner) = (*other.inner); return this; } //////////////////////////////////////////////////////// // Input-Output ofstream & ?|?( ofstream & out, const string & this ) { return out | (*this.inner); // print internal string_res } void ?|?( ofstream & out, const string & this ) { (ofstream &)(out | (*this.inner)); ends( out ); } ofstream & ?|?( ofstream & os, _Ostream_Manip(string) f ) { size_t len = size( f.val ); char cstr[len + 1]; // room for null terminator for ( i; len ) cstr[i] = f.val[i]; // copy string cstr[len] = '\0'; // terminate _Ostream_Manip(const char *) cf @= { cstr, f.wd, f.pc, f.base, {f.all} }; os | cf | nonl; return os; } // ?|? void ?|?( ofstream & os, _Ostream_Manip(string) f ) { (ofstream &)(os | f); ends( os ); } ifstream & ?|?(ifstream & in, string & this) { return in | (*this.inner); // read to internal string_res } void ?|?( ifstream & in, string & this ) { in | (*this.inner); } ifstream & ?|?( ifstream & is, _Istream_Sstr f ) { _Istream_Rstr f2 = {f.s.inner, (_Istream_str_base)f}; return is | f2; } // ?|? void ?|?( ifstream & in, _Istream_Sstr f ) { (ifstream &)(in | f); ends( in ); } //////////////////////////////////////////////////////// // Slicing string ?()( string & this, size_t start, size_t end ) { string ret = { *this.inner, start, end }; return ret`shareEdits; } string ?()( string & this, size_t start ) { string ret = { *this.inner, start, size( this ) }; return ret`shareEdits; } //////////////////////////////////////////////////////// // Comparison int cmp (const string &s1, const string &s2) { return cmp(*s1.inner , *s2.inner); } bool ?==?(const string &s1, const string &s2) { return *s1.inner == *s2.inner ; } bool ?!=?(const string &s1, const string &s2) { return *s1.inner != *s2.inner ; } bool ?>? (const string &s1, const string &s2) { return *s1.inner > *s2.inner ; } bool ?>=?(const string &s1, const string &s2) { return *s1.inner >= *s2.inner ; } bool ?<=?(const string &s1, const string &s2) { return *s1.inner <= *s2.inner ; } bool ?? (const string &s1, const char* s2) { return *s1.inner > s2 ; } bool ?>=?(const string &s1, const char* s2) { return *s1.inner >= s2 ; } bool ?<=?(const string &s1, const char* s2) { return *s1.inner <= s2 ; } bool ?? (const char* s1, const string &s2) { return s1 > *s2.inner ; } bool ?>=?(const char* s1, const string &s2) { return s1 >= *s2.inner ; } bool ?<=?(const char* s1, const string &s2) { return s1 <= *s2.inner ; } bool ?