// // 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 : Thu Jan 4 11:27:37 2024 // Update Count : 233 // #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 & s ) { (s.inner) { malloc() }; ?{}( *s.inner ); } // private (not in header) static void ?{}( string & s, string_res & src, size_t start, size_t end ) { (s.inner) { malloc() }; ?{}( *s.inner, src, SHARE_EDITS, start, end ); } void ?{}( string & s, const string & c ) { (s.inner) { malloc() }; ?{}( *s.inner, *c.inner, COPY_VALUE ); } void ?{}( string & s, string & c ) { ?{}( s, (const string &) c ); } void ?{}( string & s, const char * val ) { (s.inner) { malloc() }; ?{}( *s.inner, val ); } void ?{}( string & s, const char * buffer, size_t bsize) { (s.inner) { malloc() }; ?{}( *s.inner, buffer, bsize ); } void ^?{}( string & s ) { ^(*s.inner){}; free( s.inner ); s.inner = 0p; } //////////////////////////////////////////////////////// // Alternate construction: request shared edits string_WithSharedEdits ?`shareEdits( string & s ) { string_WithSharedEdits ret = { &s }; return ret; } void ?{}( string & s, string_WithSharedEdits src ) { ?{}( s, *src.s->inner, 0, src.s->inner->Handle.lnth); } //////////////////////////////////////////////////////// // Assignment void ?=?( string & s, const char * val ) { (*s.inner) = val; } void ?=?(string & s, const string & c) { (*s.inner) = (*c.inner); } void ?=?( string & s, char val ) { (*s.inner) = val; } string & ?=?(string & s, string & c) { //// <---- straw man change (*s.inner) = (*c.inner); return s; } //////////////////////////////////////////////////////// // Input-Output ofstream & ?|?( ofstream & out, const string & s ) { return out | (*s.inner); // print internal string_res } void ?|?( ofstream & out, const string & s ) { (ofstream &)(out | (*s.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 & s) { return in | (*s.inner); // read to internal string_res } void ?|?( ifstream & in, string & s ) { in | (*s.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); } //////////////////////////////////////////////////////// // Slicing string ?()( string & s, size_t start, size_t end ) { string ret = { *s.inner, start, end }; return ret`shareEdits; } string ?()( string & s, size_t start ) { string ret = { *s.inner, start, size( s ) }; return ret`shareEdits; } //////////////////////////////////////////////////////// // Comparison int strcmp(const string & s1, const string & s2) { return strcmp(*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 ?