// // 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_res -- variable-length, mutable run of text, with resource semantics // // Author : Michael L. Brooks // Created On : Fri Sep 03 11:00:00 2021 // Last Modified By : Peter A. Buhr // Last Modified On : Sun Oct 13 10:51:11 2024 // Update Count : 60 // #pragma once #include #include // e.g. strlen //######################### HandleNode ######################### //private struct VbyteHeap; struct HandleNode { HandleNode *flink; // forward link HandleNode *blink; // backward link VbyteHeap *ulink; // upward link char *s; // pointer to byte string unsigned int lnth; // length of byte string }; // HandleNode VbyteHeap * DEBUG_string_heap(); size_t DEBUG_string_bytes_in_heap( VbyteHeap * heap ); size_t DEBUG_string_bytes_avail_until_gc( VbyteHeap * heap ); const char * DEBUG_string_heap_start( VbyteHeap * heap ); void TUNING_set_string_heap_liveness_threshold( double val ); //######################### String ######################### // A dynamically-sized string struct string_res { HandleNode Handle; // chars, start, end, global neighbours bool shareEditSet_owns_ulink; string_res * shareEditSet_prev; string_res * shareEditSet_next; }; //######################### charclass_res ######################### struct charclass_res { string_res chars; }; void ?{}( charclass_res & ) = void; void ?{}( charclass_res &, charclass_res) = void; charclass_res ?=?( charclass_res &, charclass_res) = void; void ?{}( charclass_res &, const string_res & chars); void ?{}( charclass_res &, const char * chars ); void ?{}( charclass_res &, const char * chars, size_t charssize ); void ^?{}( charclass_res & ); //######################### String ######################### // Getters size_t size(const string_res & s); // Constructors, Assignment Operators, Destructor void ?{}(string_res & s); // empty string void ?{}(string_res & s, const char * buffer, size_t bsize); // copy specific length from buffer static inline void ?{}(string_res & s, const char * rhs) { // copy from string literal (NULL-terminated) (s){ rhs, strlen(rhs) }; } static inline void ?{}(string_res & s, char c ) { ?{}( s, &c, 1); } // Deleting the copy constructors makes the compiler reject an attempt to call/return by value void ?{}(string_res & s, const string_res & s2) = void; void ?{}(string_res & s, string_res & s2) = void; enum StrResInitMode { COPY_VALUE, SHARE_EDITS }; void ?{}(string_res & s, const string_res & src, StrResInitMode, size_t start, size_t len ); static inline void ?{}(string_res & s, const string_res & src, StrResInitMode mode ) { ?{}( s, src, mode, 0, size(src)); } static inline void ?{}(string_res & s, const string_res & src, StrResInitMode mode, size_t maxlen ) { ?{}( s, src, mode, 0, (size(src) > maxlen)?maxlen:size(src) ); } void ?{}( string_res & s, ssize_t rhs ); void ?{}( string_res & s, size_t rhs ); void ?{}( string_res & s, double rhs ); void ?{}( string_res & s, long double rhs ); void ?{}( string_res & s, double _Complex rhs ); void ?{}( string_res & s, long double _Complex rhs ); string_res & assign(string_res & s, const string_res & src, size_t maxlen); // copy specific length from other string string_res & assign(string_res & s, const char * buffer, size_t bsize); // copy specific length from buffer static inline string_res & ?=?(string_res & s, const char * c) { // copy from string literal (NULL-terminated) return assign(s, c, strlen(c)); } string_res & ?=?(string_res & s, const string_res & c); string_res & ?=?(string_res & s, string_res & c); string_res & ?=?(string_res & s, char c); string_res & ?=?( string_res & s, ssize_t rhs ); string_res & ?=?( string_res & s, size_t rhs ); string_res & ?=?( string_res & s, double rhs ); string_res & ?=?( string_res & s, long double rhs ); string_res & ?=?( string_res & s, double _Complex rhs ); string_res & ?=?( string_res & s, long double _Complex rhs ); void ^?{}(string_res & s); // IO Operator ofstream & ?|?(ofstream & out, const string_res & s); void ?|?(ofstream & out, const string_res & s); ifstream & ?|?(ifstream & in, string_res & s); struct _Istream_Rwidth { string_res * s; inline _Istream_str_base; }; // _Istream_Rwidth struct _Istream_Rquoted { // string_res * s; // inline _Istream_str_base; _Istream_Rwidth rstr; }; // _Istream_Rquoted struct _Istream_Rstr { string_res * s; inline _Istream_str_base; // _Istream_Rwidth rstr; }; // _Istream_Rstr static inline { // read width does not include null terminator _Istream_Rwidth wdi( unsigned int rwd, string_res & s ) { return (_Istream_Rwidth)@{ .s = &s, { {.scanset = 0p}, .wd = rwd, {.flags.rwd = true} } }; } _Istream_Rstr getline( string_res & s, const char delimiter = '\n' ) { // return (_Istream_Rstr)@{ { .s = &s, { {.delimiters = { delimiter, '\0' } }, .wd = -1, {.flags.delimiter = true} } } }; return (_Istream_Rstr)@{ .s = &s, { {.delimiters = { delimiter, '\0' } }, .wd = -1, {.flags.delimiter = true} } }; } _Istream_Rstr & getline( _Istream_Rwidth & f, const char delimiter = '\n' ) { f.delimiters[0] = delimiter; f.delimiters[1] = '\0'; f.flags.delimiter = true; return (_Istream_Rstr &)f; } _Istream_Rquoted quoted( string_res & s, const char Ldelimiter = '\"', const char Rdelimiter = '\0' ) { return (_Istream_Rquoted)@{ { .s = &s, { {.delimiters = { Ldelimiter, Rdelimiter, '\0' }}, .wd = -1, {.flags.rwd = true} } } }; } _Istream_Rquoted & quoted( _Istream_Rwidth & f, const char Ldelimiter = '"', const char Rdelimiter = '\0' ) { f.delimiters[0] = Ldelimiter; f.delimiters[1] = Rdelimiter; f.delimiters[2] = '\0'; return (_Istream_Rquoted &)f; } _Istream_Rstr incl( const char scanset[], string_res & s ) { return (_Istream_Rstr)@{ .s = &s, { {.scanset = scanset}, .wd = -1, {.flags.inex = false} } }; } _Istream_Rstr & incl( const char scanset[], _Istream_Rwidth & f ) { f.scanset = scanset; f.flags.inex = false; return (_Istream_Rstr &)f; } _Istream_Rstr excl( const char scanset[], string_res & s ) { return (_Istream_Rstr)@{ .s = &s, { {.scanset = scanset}, .wd = -1, {.flags.inex = true} } }; } _Istream_Rstr & excl( const char scanset[], _Istream_Rwidth & f ) { f.scanset = scanset; f.flags.inex = true; return (_Istream_Rstr &)f; } _Istream_Rstr ignore( string_res & s ) { return (_Istream_Rstr)@{ .s = &s, { {.scanset = 0p}, .wd = -1, {.flags.ignore = true} } }; } _Istream_Rstr & ignore( _Istream_Rwidth & f ) { f.flags.ignore = true; return (_Istream_Rstr &)f; } _Istream_Rquoted & ignore( _Istream_Rquoted & f ) { f.rstr.flags.ignore = true; return (_Istream_Rquoted &)f; } _Istream_Rstr & ignore( _Istream_Rstr & f ) { f.flags.ignore = true; return (_Istream_Rstr &)f; } } // distribution ifstream & ?|?( ifstream & is, _Istream_Rquoted f ); ifstream & ?|?( ifstream & is, _Istream_Rstr f ); static inline ifstream & ?|?( ifstream & is, _Istream_Rwidth f ) { return is | *(_Istream_Rstr *)&f; } // Concatenation void ?+=?(string_res & s, const string_res & s2); void ?+=?(string_res & s, char c); void append(string_res & s, const string_res & s2, size_t maxlen); void ?+=?(string_res & s, const char * c); void append(string_res & s, const char * buffer, size_t bsize); static inline string_res & strcat(string_res & s, const string_res & s2) { s += s2; return s; } static inline string_res & strcat(string_res & s, const char * c) { s += c; return s; } static inline string_res & strncat(string_res & s, const string_res & s2, size_t maxlen) { append(s, s2, maxlen); return s; } static inline string_res & strncat(string_res & s, const char * buffer, size_t bsize) { append(s, buffer, bsize); return s; } // Repetition void ?*=?(string_res & s, size_t factor); // Character access void assignAt(const string_res & s, size_t index, char val); char ?[?](const string_res & s, size_t index); // Mike changed to ret by val from Sunjay's ref, to match Peter's //char codePointAt(const string_res & s, size_t index); // revisit under Unicode // Comparisons int strcmp (const string_res &, const string_res &); bool ?==?(const string_res &, const string_res &); bool ?!=?(const string_res &, const string_res &); bool ?>? (const string_res &, const string_res &); bool ?>=?(const string_res &, const string_res &); bool ?<=?(const string_res &, const string_res &); bool ?? (const string_res &, const char *); bool ?>=?(const string_res &, const char *); bool ?<=?(const string_res &, const char *); bool ?? (const char *, const string_res &); bool ?>=?(const char *, const string_res &); bool ?<=?(const char *, const string_res &); bool ?