// // 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 : Mon Aug 5 23:12:05 2024 // Update Count : 273 // #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 // private (not in header) static void ?{}( string & s, string_res & src, size_t start, size_t len ) { (s.inner) { malloc() }; ?{}( *s.inner, src, SHARE_EDITS, start, len ); } void ?{}( string & s ) { (s.inner) { malloc() }; ?{}( *s.inner ); } void ?{}( string & s, const string & c ) { (s.inner) { malloc() }; ?{}( *s.inner, *c.inner, COPY_VALUE ); } void ?{}( string & s, const string & s2, size_t maxlen ) { (s.inner) { malloc() }; ?{}( *s.inner, *s2.inner, COPY_VALUE, maxlen ); } void ?{}( string & s, string & c ) { ?{}( s, (const string &) c ); } void ?{}( string & s, const char c ) { (s.inner) { malloc() }; ?{}( *s.inner, c ); } void ?{}( string & s, const char * c ) { (s.inner) { malloc() }; ?{}( *s.inner, c ); } void ?{}( string & s, const char * c, size_t size ) { (s.inner) { malloc() }; ?{}( *s.inner, c, size ); } void ?{}( string & s, ssize_t rhs ) { (s.inner) { malloc() }; ?{}( *s.inner, rhs ); } void ?{}( string & s, size_t rhs ) { (s.inner) { malloc() }; ?{}( *s.inner, rhs ); } void ?{}( string & s, double rhs ) { (s.inner) { malloc() }; ?{}( *s.inner, rhs ); } void ?{}( string & s, long double rhs ) { (s.inner) { malloc() }; ?{}( *s.inner, rhs ); } void ?{}( string & s, double _Complex rhs ) { (s.inner) { malloc() }; ?{}( *s.inner, rhs ); } void ?{}( string & s, long double _Complex rhs ) { (s.inner) { malloc() }; ?{}( *s.inner, rhs ); } string str( ssize_t rhs ) { string s = rhs; return s; } string str( size_t rhs ) { string s = rhs; return s; } string str( double rhs ) { string s = rhs; return s; } string str( long double rhs ) { string s = rhs; return s; } string str( double _Complex rhs ) { string s = rhs; return s; } string str( long double _Complex rhs ) { string s = rhs; return s; } 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 string & ?=?( string & s, const string & c ) { (*s.inner) = (*c.inner); return s; } string & ?=?( string & s, string & c ) { (*s.inner) = (*c.inner); return s; } string & ?=?( string & s, const char * val ) { (*s.inner) = val; return s; } string & ?=?( string & s, char val ) { (*s.inner) = val; return s; } string & assign( string & s, const string & c, size_t n ) { assign( *s.inner, *c.inner, n ); return s; } string & assign( string & s, const char * c, size_t n ) { assign( *s.inner, c, n ); return s; } string & ?=?( string & s, ssize_t rhs ) { (*s.inner) = rhs; return s; } string & ?=?( string & s, size_t rhs ) { (*s.inner) = rhs; return s; } string & ?=?( string & s, double rhs ) { (*s.inner) = rhs; return s; } string & ?=?( string & s, long double rhs ) { (*s.inner) = rhs; return s; } string & ?=?( string & s, double _Complex rhs ) { (*s.inner) = rhs; return s; } string & ?=?( string & s, long double _Complex rhs ) { (*s.inner) = rhs; 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} }; return os | cf | nonl; } // ?|? 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 } ifstream & ?|?( ifstream & is, _Istream_Squoted f ) { _Istream_Rquoted f2 = { { f.sstr.s.inner, (_Istream_str_base)f.sstr } }; return is | f2; } // ?|? ifstream & ?|?( ifstream & is, _Istream_Sstr f ) { // _Istream_Rstr f2 = {f.sstr.s.inner, (_Istream_str_base)f.sstr}; _Istream_Rstr f2 = {f.s.inner, (_Istream_str_base)f}; return is | f2; } // ?|? //////////////////////////////////////////////////////// // Slicing string ?()( string & s, size_t start, size_t len ) { string ret = { *s.inner, start, len }; return ret`shareEdits; } string ?()( string & s, size_t start ) { string ret = { *s.inner, start, size( s ) - start }; 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 ?