Changeset 5b21636b
- Timestamp:
- Apr 13, 2026, 9:41:59 AM (2 weeks ago)
- Branches:
- master
- Children:
- 0f9c67bf
- Parents:
- 1abcec9b
- Files:
-
- 3 edited
-
libcfa/src/collections/array.hfa (modified) (2 diffs)
-
libcfa/src/collections/string.cfa (modified) (1 diff)
-
tests/collections/string-overwrite.cfa (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/collections/array.hfa
r1abcec9b r5b21636b 1 1 #pragma once 2 2 3 3 4 … … 175 176 } 176 177 177 // RAII for copying interacts poorly with CFA RAII's default (quasi-mandate) to take178 // 'src' parameters by value; note doc/proposals/autogen.md suggests changing this pattern.179 // If Timmed offers a by-value copy-ctor, then180 // - the array copy-ctor will make lots of memcpys of them181 // - the array assignment operator will make temporaries (and call their RAII, implying182 // the above memcpys) of them183 // - the array assignment operator will scale poorly to higher dimensionality due to #226184 // Furthermore, enabling this experimental flag breaks some multidimensional behaviour,185 // as illustraed by a test failure in array-md-sbscr-cases, which has not been investigated.186 // These limitations kick in upon calling the copy operation, not upon including the definitions.187 // Design choice here:188 // - FIX ME: deal with `const &` on params189 #ifdef EXPERIMENTAL_ARRAY_ALLOW_COPY_RAII190 // call copy ctor on elements191 // array(float, 5) y; // given192 // array(float, 5) x = y; // <- do193 forall( [N], S & | sized(S), Timmed *, Tbase & | { void ?{}( Timmed &, Timmed & ); } )194 static inline void ?{}( arpk( N, S, Timmed, Tbase ) & this, arpk( N, S, Timmed, Tbase ) & src ) {195 ?{}( this, delay_init );196 for (i; N) ?{}( (Timmed &)this.strides[i], src[i] );197 }198 forall( [N], S & | sized(S), Timmed *, Tbase & | { void ?{}( Timmed &, const Timmed & ); } )199 static inline void ?{}( arpk( N, S, Timmed, Tbase ) & this, arpk( N, S, Timmed, Tbase ) & src ) {200 ?{}( this, delay_init );201 for (i; N) ?{}( (Timmed &)this.strides[i], src[i] );202 }203 204 // call assignment on elements205 // array(float, 5) x, y; // given206 // x = y; // <- do207 forall( [N], S & | sized(S), Timmed & | is_value(Timmed), Tbase & )208 static inline void ?=?( arpk( N, S, Timmed, Tbase ) & this, arpk( N, S, Timmed, Tbase ) & src ) {209 for (i; N) this[i] = src[i];210 return src;211 }212 forall( [N], S & | sized(S), Timmed &, Tbase & | { void ?=?( Timmed &, const Timmed & ); } )213 static inline void ?=?( arpk( N, S, Timmed, Tbase ) & this, arpk( N, S, Timmed, Tbase ) & src ) {214 for (i; N) this[i] = src[i];215 return src;216 }217 #endif // EXPERIMENTAL_ARRAY_ALLOW_COPY_RAII218 219 178 220 179 // -
libcfa/src/collections/string.cfa
r1abcec9b r5b21636b 244 244 245 245 string ?()( string & s, ssize_t start, ssize_t len ) { 246 // if ( start < 0 ) start += len( s ); 247 // if ( len < 0 ) { len = -len; start -= len - 1; } 248 // if ( start < 0 ) start = 0; 249 // if ( start > len( s ) ) start = len( s ); 250 // if ( start + len > len( s ) ) len = len( s ) - start; 246 if ( start < 0 ) start += len( s ); 247 if ( len < 0 ) { len = -len; start -= len - 1; } 248 if ( start < 0 || start >= len( s ) ) return (string){ "" }; 249 if ( start + len > len( s ) ) len = len( s ) - start; 251 250 string ret = { *s.inner, start, len }; 252 251 return ret`share; -
tests/collections/string-overwrite.cfa
r1abcec9b r5b21636b 73 73 */ 74 74 75 const char * OUT_DELIM = "------------------------------------------------------------------------";76 75 77 76 void showOneReplacement(string & s, int ms, int ml, int ws, int wl, const char* replaceWith) { … … 233 232 }; 234 233 for ( i; sizeof(cases)/sizeof(cases[0]) ) { 235 sout | OUT_DELIM| cases[i].label;234 sout | "------------------------------------------------------------------------" | cases[i].label; 236 235 string replaceIn = alphabetTemplate; 237 236 showOneReplacement( replaceIn, cases[i].ms, cases[i].ml, cases[i].ws, cases[i].wl, cases[i].replaceWith ); … … 247 246 248 247 249 runReplaceCases();250 251 252 // in `s(i, k) = sr`:253 // - whlln, whole-string length = len(s)254 // - sctln, selection length = k255 // - rplln, replacement length = len(sr)256 257 // Extra cases via syntax that appears more direct.258 // Indirect, as drives the table:259 // string replace = src(strt, len)`share;260 // replace = "xyz";261 // Direct, following:262 // src(strt, len) = "xyz";263 sout | OUT_DELIM | "syn-direct";264 265 248 // 0 1 2 266 249 // 01234567890123456789012345 … … 268 251 269 252 s(5,5) = "qqqqq"; // start=5, end=10, len=5 270 sout | s; 253 254 sout | s; 255 271 256 272 257 s(5,0) = "-----"; // start=5, end=5, len=0 273 sout | s; 274 275 276 // Extra cases for at-/out-of-bound access 277 // Every selection starts and ends at a position between characters, inclusive of before-first and after-last 278 // Intended behaviour is 279 // - negative start means "back from whlln;" i.e., -1 is before-last 280 // - negative sctln menas "back from start;" i.e., -1 from middle selects 1 character before start 281 // - squish inward at subject string's first/last character 282 // - start > whlln means same as start == whlln: after last character, with sctln >= 0 selecting zero characters 283 // - start < -whlln means same as start == -whlln: before first character, with sctln <= 0 selecting zero characters 284 // - (let xstart be the position in [0,whlln] equivalent to start, by the above, in the following...) 285 // - xstart + sctln > whlln means same as sctln = whlln - xstart (significant when sctln is positive) 286 // - xstart + sctln < 0 means same as sctln = -xstart (significant when sctln is negative) 287 // - start = 0 means 288 // - before first, when sctln is zero or positive 289 // - after last, when sctln is negative 290 // - start "outside the string" cases are: 291 // - start = 0 can select forward from first or backward from last (as just stated); note the asymmetric "sctln = 0" handling 292 // - (so, the following cases are available to specify front-v-back explicitly...) 293 // - start >= whlln can select only backward from last, i.e. selects final epsilon when sctln >= 0 294 // - start <= -whln can select only forward from first, i.e. selects initial epsilon when sctln <= 0 295 // most selections have two equivalent representations 296 sout | OUT_DELIM | "boundary"; 297 /* 298 The test 299 300 base = 01234 301 302 303 (Start|Step) is (just over|right on|just under) the (min|mid|max) value 304 | 305 whlln (>|=|<) rplln 306 | 307 0 (=|<) (whlln|rplln) 308 309 Every case needs concrete & independent 310 whlln 311 rpln 312 start 313 step, aka sctln 314 315 Constraint space is 316 sel[Start] 317 * 318 sel[Step] 319 * 320 lens1 321 * 322 lens2 323 , 324 excluding when the lens pair contradicts 325 = 326 972 concrete test cases (all combinations) 327 328 Toward all pairs 329 Each case achieves up to 6 further pairings. 330 Best-case, achieved with 81 cases. (162 permutations / 2 orderings of a pair) 331 332 333 334 Start 335 just over the min value 336 just over the mid value 337 just over the max value 338 just over the min value 339 just over the mid value 340 just over the max value 341 just over the min value 342 just over the mid value 343 just over the max value 344 345 346 */ 347 348 349 // Extra cases for modifying substring of substring. 350 sout | OUT_DELIM | "compound"; 351 352 s = "abcdefghijklmnopqrstuvwxyz"; 353 string sx = s(5,5)`share; 354 258 259 sout | s; 260 261 runReplaceCases(); 355 262 }
Note:
See TracChangeset
for help on using the changeset viewer.