// // 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 : Thu Jan 4 11:28:06 2024 // Update Count : 27 // #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) }; } 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 end ); static inline void ?{}(string_res & s, const string_res & src, StrResInitMode mode ) { ?{}( s, src, mode, 0, size(src)); } 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); 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); void ?|?( ifstream & in, string_res & s ); struct _Istream_Rstr { string_res * s; inline _Istream_str_base; }; // _Istream_Rstr static inline { // read width does not include null terminator _Istream_Rstr wdi( unsigned int rwd, string_res & s ) { return (_Istream_Rstr)@{ &s, {{0p}, rwd, {.flags.rwd : true}} }; } _Istream_Rstr getline( string_res & s, const char delimiter = '\n' ) { return (_Istream_Rstr)@{ &s, {{.delimiters : { delimiter, '\0' } }, -1, {.flags.delimiter : true, .flags.inex : true}} }; } _Istream_Rstr & getline( _Istream_Rstr & fmt, const char delimiter = '\n' ) { fmt.delimiters[0] = delimiter; fmt.delimiters[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt; } _Istream_Rstr incl( const char scanset[], string_res & s ) { return (_Istream_Rstr)@{ &s, {{scanset}, -1, {.flags.inex : false}} }; } _Istream_Rstr & incl( const char scanset[], _Istream_Rstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; } _Istream_Rstr excl( const char scanset[], string_res & s ) { return (_Istream_Rstr)@{ &s, {{scanset}, -1, {.flags.inex : true}} }; } _Istream_Rstr & excl( const char scanset[], _Istream_Rstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; } _Istream_Rstr ignore( string_res & s ) { return (_Istream_Rstr)@{ &s, {{0p}, -1, {.flags.ignore : true}} }; } _Istream_Rstr & ignore( _Istream_Rstr & fmt ) { fmt.flags.ignore = true; return fmt; } } // distribution ifstream & ?|?( ifstream & is, _Istream_Rstr f ); void ?|?( ifstream & is, _Istream_Rstr t ); // Concatenation void append(string_res & s, const char * buffer, size_t bsize); void ?+=?(string_res & s, char c); // append a character void ?+=?(string_res & s, const string_res & s2); // append-concatenate to first string static inline void ?+=?(string_res & s, const char * c) { append( s, c, strlen(c) ); } // 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 ?