@@ -108,6 +108,21 @@ pub fn MatchIterator(
108108 }
109109 return null ;
110110 }
111+
112+ pub fn span (self : * Self ) ? struct { pos : usize , end : usize } {
113+ while (self .index < self .items .len ) : (self .index += 1 ) {
114+ if (tree .call (self .items , self .index , false )) | last | {
115+
116+ // non-advancing calls
117+ if (self .index == last )
118+ continue ;
119+
120+ defer self .index = last ;
121+ return .{ .pos = self .index , .end = last };
122+ }
123+ }
124+ return null ;
125+ }
111126 };
112127}
113128
@@ -149,6 +164,26 @@ fn SplitIterator(comptime expression: []const u8) type {
149164 defer self .index = end ;
150165 return Fluent .init (self .items [start .. stop ]);
151166 }
167+
168+ pub fn span (self : * Self ) struct { pos : usize , end : usize } {
169+ const start = self .index orelse return null ;
170+ var stop : usize = start ;
171+ const end : ? usize = blk : {
172+ while (stop < self .items .len ) : (stop += 1 ) {
173+
174+ const last = tree .call (self .items , stop , false ) orelse continue ;
175+
176+ // non-advancing calls
177+ if (start == last )
178+ continue ;
179+
180+ break :blk last ;
181+
182+ } else break :blk null ;
183+ };
184+ defer self .index = end ;
185+ return .{ .pos = start , .end = stop };
186+ }
152187 };
153188}
154189
@@ -1060,8 +1095,8 @@ fn ImmutableStringBackend(comptime Self: type) type {
10601095 /// float - parses the string as a floating-point number
10611096 pub fn cast (self : Self , comptime T : type ) ! T {
10621097 return switch (@typeInfo (T )) {
1063- .Int , .ComptimeInt = > self .digit (),
1064- .Float , .ComptimeFloat = > self .float (),
1098+ .Int = > self .digit (T ),
1099+ .Float = > self .float (T ),
10651100 else = > @compileError ("cast: requires floating point or integer types." )
10661101 };
10671102 }
@@ -2522,23 +2557,25 @@ fn isHorizontalWhitespace(c: u8) bool {
25222557}
25232558
25242559fn isWordBoundary (str : []const u8 , i : usize ) bool {
2525-
2526- if (str .len == 0 )
2527- return false ;
25282560
25292561 if (i == str .len )
25302562 return isWordCharacter (str [i - 1 ]);
25312563
2532- if (! isWordCharacter (str [i ]))
2533- return false ;
2564+ if (i == 0 and isWordCharacter (str [i ]))
2565+ return true ;
2566+
2567+ if ((i + 1 ) == str .len and isWordCharacter (str [i ]))
2568+ return true ;
25342569
2535- if (i == 0 )
2570+ // character, check boundary behind
2571+ if (isWordCharacter (str [i ]) and ! isWordCharacter (str [i - 1 ]))
25362572 return true ;
25372573
2538- if (i + 1 == str .len )
2574+ // character, check boundary behind
2575+ if (! isWordCharacter (str [i ]) and isWordCharacter (str [i - 1 ]))
25392576 return true ;
25402577
2541- return isWordCharacter ( str [ i + 1 ]) ;
2578+ return false ;
25422579}
25432580
25442581pub fn isZeroLength (comptime c : u8 ) bool {
@@ -3860,6 +3897,14 @@ test "string integer and float parsing : ConstSelf" {
38603897 const result = init ("42.5" ).float (f64 ) catch unreachable ;
38613898 try expect (result < 43.0 );
38623899 }
3900+ {
3901+ const result = init ("42" ).cast (usize ) catch unreachable ;
3902+ try expect (result == 42 );
3903+ }
3904+ {
3905+ const result = init ("42.5" ).cast (f64 ) catch unreachable ;
3906+ try expect (result < 43.0 );
3907+ }
38633908}
38643909
38653910////////////////////////////////////////////////////////////////////////////////
@@ -4437,3 +4482,16 @@ test "regex-engine39 : fluent interface-> replace reg
44374482 .equal ("qqb" )
44384483 );
44394484}
4485+
4486+ test "regex-engine40 : fluent interface-> word boundary" {
4487+ const expr = "\\ bWord\\ b" ;
4488+ const string = "WordWordWord Word WordWord" ;
4489+ var itr = match (expr , string );
4490+
4491+ const s = itr .span () orelse unreachable ;
4492+
4493+ try testing .expectEqual (13 , s .pos );
4494+ try testing .expectEqual (17 , s .end );
4495+ try testing .expect (itr .span () == null );
4496+ try testing .expectEqualSlices (u8 , string [s .pos .. s .end ], "Word" );
4497+ }
0 commit comments