Changeset 570e7ad


Ignore:
Timestamp:
Apr 11, 2025, 12:29:56 AM (5 months ago)
Author:
Michael Brooks <mlbrooks@…>
Branches:
master
Children:
d03a386
Parents:
3f631d6
Message:

Make string operator-overload costs match their intuitively equivalent arithmetics.

Replace many by-reference string args with by-value args to work around noise from the reference-cost column.

Use a special arithmetic type for the factor argument of ?*? to match conversion cost of (char*int=int).

Removes cost-function noise of char-arithmetic operators being preferred over their string-concatenation equivalents in the reference-cost column.

Notably, all former Spanish-A and numeric outputs have become ambiguous or been associated with a reproducible bug.

Files:
12 added
5 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/collections/string.cfa

    r3f631d6 r570e7ad  
    4040}
    4141
    42 void ?{}( string & s, const string & c ) {
     42void ?{}( string & s, string c ) {  // c is a memcpy of the real src string
    4343        (s.inner) { malloc() };
    4444        ?{}( *s.inner, *c.inner, COPY_VALUE );
    4545}
    4646
    47 void ?{}( string & s, const string & s2, size_t maxlen ) {
     47void ?{}( string & s, string s2, size_t maxlen ) {
    4848        (s.inner) { malloc() };
    4949        ?{}( *s.inner, *s2.inner, COPY_VALUE, maxlen );
    5050}
    5151
    52 
    53 void ?{}( string & s, string & c ) {
    54         ?{}( s, (const string &) c );
    55 }
    56 
    57 void ?{}( string & s, const char c ) {
     52void ?{}( string & s, char c ) {
    5853        (s.inner) { malloc() };
    5954        ?{}( *s.inner, c );
     
    7065}
    7166
    72 void ?{}( string & s, ssize_t rhs ) {
     67void ?{}( string & s, signed long int rhs ) {
    7368        (s.inner) { malloc() };
    7469        ?{}( *s.inner, rhs );
     
    151146// Assignment
    152147
    153 string & ?=?( string & s, const string & c ) {
    154         (*s.inner) = (*c.inner);
    155         return s;
    156 }
    157 
    158 string & ?=?( string & s, string & c ) {
     148string & ?=?( string & s, string c ) {
    159149        (*s.inner) = (*c.inner);
    160150        return s;
     
    181171}
    182172
    183 string & ?=?( string & s, ssize_t rhs ) {
     173string & ?=?( string & s, signed long int rhs ) {
    184174        (*s.inner) = rhs;
    185175        return s;
     
    324314}
    325315
    326 string ?+?( const string & s, char c ) {
     316string ?+?( string s, char c ) {
    327317        string ret = s;
    328318        ret += c;
     
    330320}
    331321
    332 string ?+?( char c, const string & s ) {
     322string ?+?( char c, string s ) {
    333323        string ret = c;
    334324        ret += s;
     
    336326}
    337327
    338 string ?+?( const string & s, const string & s2 ) {
     328string ?+?( string s, string s2 ) {
    339329        string ret = s;
    340330        ret += s2;
     
    360350}
    361351
    362 string ?+?( const char * s1, const string & s2 ) {
     352string ?+?( const char * s1, string s2 ) {
    363353        string ret = s1;
    364354        ret += s2;
     
    366356}
    367357
    368 string ?+?( const string & s, const char * c ) {
     358string ?+?( string s, const char * c ) {
    369359        string ret = s;
    370360        ret += c;
     
    381371// Repetition
    382372
    383 void ?*=?( string & s, size_t factor ) {
     373void ?*=?( string & s, strmul_factor_t factor ) {
    384374        (*s.inner) *= factor;
    385375}
    386376
    387 string ?*?( const string & s, size_t factor ) {
     377string ?*?( string s, strmul_factor_t factor ) {
    388378        string ret = s;
    389379        ret *= factor;
     
    391381}
    392382
    393 string ?*?( char c, size_t factor ) {
     383string ?*?( char c, strmul_factor_t factor ) {
    394384        string ret = c;
    395385        ret *= factor;
     
    397387}
    398388
    399 string ?*?( const char * s, size_t factor ) {
     389string ?*?( const char * s, strmul_factor_t factor ) {
    400390        string ret = s;
    401391        ret *= factor;
  • libcfa/src/collections/string.hfa

    r3f631d6 r570e7ad  
    2727
    2828void ?{}( string & s );                                                                 // empty string
    29 void ?{}( string & s, const string & s2 );
    30 void ?{}( string & s, const string & s2, size_t maxlen );
    31 void ?{}( string & s, string & s2 );
    32 
     29void ?{}( string & s, string s2, size_t maxlen );
     30void ?{}( string & s, string s2 );
    3331void ?{}( string & s, char );
    3432void ?{}( string & s, const char * c );                                 // copy from string literal (NULL-terminated)
    3533void ?{}( string & s, const char * c, size_t size );    // copy specific length from buffer
    3634
    37 void ?{}( string & s, ssize_t rhs );
     35void ?{}( string & s, signed long int rhs );
    3836void ?{}( string & s, size_t rhs );
    3937void ?{}( string & s, double rhs );
     
    4139void ?{}( string & s, double _Complex rhs );
    4240void ?{}( string & s, long double _Complex rhs );
     41static inline void ?{}( string & s, int rhs ) { (s){(signed long int) rhs}; }
    4342
    4443// string str( ssize_t rhs );
     
    4948// string str( long double _Complex rhs );
    5049
    51 string & ?=?( string & s, const string & c );
    52 string & ?=?( string & s, string & c );
     50string & ?=?( string & s, string c );
    5351string & ?=?( string & s, const char * c );                             // copy from "literal"
    5452string & ?=?( string & s, char c );                                             // copy from 'l'
    5553string & assign( string & s, const string & c, size_t n );
    5654string & assign( string & s, const char * c, size_t n );
    57 string & ?=?( string & s, ssize_t rhs );
     55string & ?=?( string & s, signed long int rhs );
    5856string & ?=?( string & s, size_t rhs );
    5957string & ?=?( string & s, double rhs );
     
    6159string & ?=?( string & s, double _Complex rhs );
    6260string & ?=?( string & s, long double _Complex rhs );
     61static inline string & ?=?( string & s, int rhs ) { return s = ((signed long int) rhs); } // to match cost of (char * int): int
    6362
    6463static inline string & strcpy( string & s, const char * c ) { s = c; return s; }
     
    161160void append( string & s, const char * buffer, size_t bsize );
    162161
    163 string ?+?( const string & s, char c );
    164 string ?+?( char c, const string & s );
    165 string ?+?( const string & s, const string & s2 );
     162string ?+?( string s, char c );
     163string ?+?( char c, string s );
     164string ?+?( string s, string s2 );
    166165string ?+?( const char * s, char c );                                   // not backwards compatible
    167166string ?+?( char c, const char * s );
    168167string ?+?( const char * c, const char * s );
    169 string ?+?( const char * c, const string & s );
    170 string ?+?( const string & s, const char * c );
     168string ?+?( const char * c, string s );
     169string ?+?( string s, const char * c );
    171170string ?+?( char, char );                                                               // not being called 8-(
    172171
     
    177176
    178177// Repetition
    179 void ?*=?( string & s, size_t factor );
    180 string ?*?( char c, size_t factor );                                    // not backwards compatible
    181 string ?*?( const string & s, size_t factor );
    182 static inline string ?*?( size_t factor, const string & s ) { return s * factor; }
    183 string ?*?( const char * s, size_t factor );
    184 static inline string ?*?( size_t factor, const char * s ) { return s * factor; }
     178
     179// Type `signed long long int` chosen for `factor` argument to achieve cost detente.
     180// This way, the call `'a' * 3` gets the same safe conversion cost calling here as for
     181// the built-in definition `int * int`.
     182typedef signed long long int strmul_factor_t;
     183
     184void ?*=?( string & s, strmul_factor_t factor );
     185string ?*?( char c, strmul_factor_t factor );                                   // not backwards compatible
     186string ?*?( string s, strmul_factor_t factor );
     187string ?*?( const char * s, strmul_factor_t factor );
     188static inline string ?*?( strmul_factor_t factor, char s ) { return s * factor; }
     189static inline string ?*?( strmul_factor_t factor, string s ) { return s * factor; }
     190static inline string ?*?( strmul_factor_t factor, const char * s ) { return s * factor; }
    185191
    186192// Character access
  • tests/Makefile.am

    r3f631d6 r570e7ad  
    288288        -cp ${test} ${abspath ${@}}
    289289
     290collections/string-operator-ERR01 : collections/string-operator.cfa
     291        ${CFACOMPILE_SYNTAX} -DTRY_MR01
     292        -cp ${test} ${abspath ${@}}
     293
     294collections/string-operator-ERR02 : collections/string-operator.cfa
     295        ${CFACOMPILE_SYNTAX} -DTRY_MR02
     296        -cp ${test} ${abspath ${@}}
     297
     298collections/string-operator-ERR03 : collections/string-operator.cfa
     299        ${CFACOMPILE_SYNTAX} -DTRY_MR03
     300        -cp ${test} ${abspath ${@}}
     301
     302collections/string-operator-ERR04 : collections/string-operator.cfa
     303        ${CFACOMPILE_SYNTAX} -DTRY_MR04
     304        -cp ${test} ${abspath ${@}}
     305
     306collections/string-operator-ERR05 : collections/string-operator.cfa
     307        ${CFACOMPILE_SYNTAX} -DTRY_MR05
     308        -cp ${test} ${abspath ${@}}
     309
     310collections/string-operator-ERR06 : collections/string-operator.cfa
     311        ${CFACOMPILE_SYNTAX} -DTRY_MR06
     312        -cp ${test} ${abspath ${@}}
     313
     314collections/string-operator-ERR07 : collections/string-operator.cfa
     315        ${CFACOMPILE_SYNTAX} -DTRY_MR07
     316        -cp ${test} ${abspath ${@}}
     317
     318collections/string-operator-ERR08 : collections/string-operator.cfa
     319        ${CFACOMPILE_SYNTAX} -DTRY_MR08
     320        -cp ${test} ${abspath ${@}}
     321
    290322collections/string-operator-ERR09 : collections/string-operator.cfa
    291323        ${CFACOMPILE_SYNTAX} -DTRY_MR09
    292324        -cp ${test} ${abspath ${@}}
    293325
     326collections/string-operator-ERR10 : collections/string-operator.cfa
     327        ${CFACOMPILE_SYNTAX} -DTRY_MR10
     328        -cp ${test} ${abspath ${@}}
     329
     330collections/string-operator-ERR11 : collections/string-operator.cfa
     331        ${CFACOMPILE_SYNTAX} -DTRY_MR11
     332        -cp ${test} ${abspath ${@}}
     333
     334collections/string-operator-ERR13 : collections/string-operator.cfa
     335        ${CFACOMPILE_SYNTAX} -DTRY_MR13
     336        -cp ${test} ${abspath ${@}}
     337
    294338collections/string-operator-ERR15 : collections/string-operator.cfa
    295339        ${CFACOMPILE_SYNTAX} -DTRY_MR15
     340        -cp ${test} ${abspath ${@}}
     341
     342collections/string-operator-ERR16 : collections/string-operator.cfa
     343        ${CFACOMPILE_SYNTAX} -DTRY_MR16
    296344        -cp ${test} ${abspath ${@}}
    297345
  • tests/collections/.expect/string-operator.txt

    r3f631d6 r570e7ad  
    33
    44------------- Initialization
    5 Ã
     5(skip)
    66ab
    77ab
    88ab
    99
    10 Ãx
     10(skip)
    1111abx
    1212abx
     
    2323axb
    2424
    25 aaa
     25(skip)
    2626bbb
    27 ÃÃÃ
     27585
    2828cdcdcd
    2929
    30 291
     30(skip)
    3131bbb
    32 ababab
     32585
    3333cdcdcd
    3434
    3535------------- Assignment
    36 Ã
     36(skip)
    3737ab
    3838ab
    3939ab
    4040
    41 Ã
    42 abÃ
    43 ababÃ
    44 abababÃ
     41(skip)
     42ab
     43abab
     44ababab
    4545
    4646ab
     
    5454aaaabbbb
    5555
    56 aaa
     56(skip)
    5757bbb
    58 ÃÃÃ
     58585
    5959cdcdcd
    6060
    61 291
     61(skip)
    6262bbb
    63 ababab
     63585
    6464cdcdcd
    6565
     
    7070ab
    7171
    72 Ãx
     72(skip)
    7373abx
    7474abx
     
    8585axb
    8686
    87 291
     87(skip)
    8888bbb
    8989585
    9090cdcdcd
    9191
    92 291
     92(skip)
    9393bbb
    9494585
     
    9797------------- Miscellany
    9898(skip)
    99 291
     99(skip)
    1001000x2a 0x2d
  • tests/collections/string-operator.cfa

    r3f631d6 r570e7ad  
    99
    1010// These MR points do reject in the current revision, so they have satellite "-ERR" cases:
     11// MR01
     12// MR02
     13// MR03
     14// MR04
     15// MR05
     16// MR06
     17// MR07
     18// MR08
    1119// MR09
     20// MR10
     21// MR11
     22// MR13
    1223// MR15
     24// MR16
    1325
    1426// These MR points do not reject in the current revision, so they join the "happy run":
    15 #define TRY_MR01
    16 #define TRY_MR02
    17 #define TRY_MR03
    18 #define TRY_MR04
    19 #define TRY_MR05
    20 #define TRY_MR06
    21 #define TRY_MR07
    22 #define TRY_MR08
    23 #define TRY_MR10
    24 #define TRY_MR11
    2527#define TRY_MR12
    26 #define TRY_MR13
    2728#define TRY_MR14
    28 #define TRY_MR16
    2929
    3030
     
    137137
    138138        sout | "------------- Initialization";
    139 MR01(  {string s = 'a' + 'b';           // Ãb
     139MR01(  {string s = 'a' + 'b';           // (ambiguous)
    140140        sout | s;}              )
    141141       {string s = 'a' + "b";           // ab
     
    149149        string s0 = "x";
    150150
    151 MR02(  {string s = 'a' + 'b' + s0;      // Ãx
     151MR02(  {string s = 'a' + 'b' + s0;      // (ambiguous)
    152152        sout | s;}              )
    153153       {string s = 'a' + "b" + s0;      // abx
     
    179179        sout | nl;                      //
    180180
    181 MR03(  {string s = 'a' * 3;             // aaa
     181MR03(  {string s = 'a' * 3;             // (ambiguous)
    182182        sout | s;}              )
    183183       {string s = "b" * 3;             // bbb
    184184        sout | s;}
    185        {string s = ('a' + 'b') * 3;     // ÃÃÃ
     185       {string s = ('a' + 'b') * 3;     // ÃÃà(expecting ambiguous, likely from #309)
    186186        sout | s;}
    187187       {string s = ('c' + "d") * 3;     // cdcdcd
     
    189189        sout | nl;                      //
    190190
    191 MR04(  {string s = 3 * 'a';             // 291
     191MR04(  {string s = 3 * 'a';             // (ambiguous)
    192192        sout | s;}              )
    193193       {string s = 3 * "b";             // bbb
     
    205205
    206206        s = "";
    207 MR05(   s = 'a' + 'b';          // Ã
     207MR05(   s = 'a' + 'b';          // (ambiguous)
    208208        sout | s;              )
    209209        s = 'a' + "b";          // ab
     
    216216
    217217        s = "";
    218 MR06(   s = 'a' + 'b' + s;      // Ã
     218MR06(   s = 'a' + 'b' + s;      // (ambiguous)
    219219        sout | s;              )
    220         s = 'a' + "b" + s;      // abÃ
    221         sout | s;
    222         s = "a" + 'b' + s;      // ababÃ
    223         sout | s;
    224         s = "a" + "b" + s;      // abababÃ
     220        s = 'a' + "b" + s;      // ab
     221        sout | s;
     222        s = "a" + 'b' + s;      // abab
     223        sout | s;
     224        s = "a" + "b" + s;      // ababab
    225225        sout | s;
    226226        sout | nl;              //
     
    249249
    250250        s = "";
    251 MR07(   s = 'a' * 3;            // aaa
     251MR07(   s = 'a' * 3;            // (ambiguous)
    252252        sout | s;              )
    253253        s = "b" * 3;            // bbb
    254254        sout | s;
    255         s = ('a' + 'b') * 3;    // ÃÃÃ
     255        s = ('a' + 'b') * 3;    // ÃÃà(expecting ambiguous, likely from #309)
    256256        sout | s;
    257257        s = ('c' + "d") * 3;    // cdcdcd
     
    260260
    261261        s = "";
    262 MR08(   s = 3 * 'a';            // 291
     262MR08(   s = 3 * 'a';            // (ambiguous)
    263263        sout | s;              )
    264264        s = 3 * "b";            // bbb
     
    281281        sout | nl;                  //
    282282
    283 MR10(   sout | 'a' + 'b' + s;  )    // Ãx
     283MR10(   sout | 'a' + 'b' + s;  )    // (ambiguous)
    284284        sout | 'a' + "b" + s;       // abx
    285285        sout | "a" + 'b' + s;       // abx
     
    299299        sout | nl;                  //
    300300
    301 MR11(   sout | 'a' * 3;          )  // 291
     301MR11(   sout | 'a' * 3;          )  // (ambiguous)
    302302        sout | "b" * 3;             // bbb
    303 MR12(   sout | ('a' + 'b') * 3;  )  // 585
     303MR12(   sout | ('a' + 'b') * 3;  )  // 585 (expecting ambiguous, likely from #309)
    304304        sout | ('c' + "d") * 3;     // cdcdcd
    305305        sout | nl;                  //
    306306
    307 MR13(   sout | 3 * 'a';          )  // 291
     307MR13(   sout | 3 * 'a';          )  // (ambiguous)
    308308        sout | 3 * "b";             // bbb
    309 MR14(   sout | 3 * ('a' + 'b');  )  // 585
     309MR14(   sout | 3 * ('a' + 'b');  )  // 585 (expecting ambiguous, likely from #309)
    310310        sout | 3 * ('c' + "d");     // cdcdcd
    311311        sout | nl;                  //
     
    316316
    317317MR15(   printf( "%c\n", 'a' + 'b'); )    // (ambiguous)
    318 MR16(   printf( "%d\n", 'a' * 3 );  )    // 291
     318MR16(   printf( "%d\n", 'a' * 3 );  )    // (ambiguous)
    319319
    320320        {   // (picks arithmetic; there is no interpretation of `_ + 3` that's string)
Note: See TracChangeset for help on using the changeset viewer.