@@ -512,36 +512,54 @@ pub fn toSlice(comptime T: type, ptr: [*:0]T) [:0]T {
512
512
/// the constness of the input type. `[*c]` pointers are assumed to be 0-terminated,
513
513
/// and assumed to not allow null.
514
514
pub fn Span (comptime T : type ) type {
515
- var ptr_info = @typeInfo (T ).Pointer ;
516
- switch (ptr_info .size ) {
517
- .One = > switch (@typeInfo (ptr_info .child )) {
518
- .Array = > | info | {
519
- ptr_info .child = info .child ;
520
- ptr_info .sentinel = info .sentinel ;
521
- },
522
- else = > @compileError ("invalid type given to std.mem.Span" ),
515
+ switch (@typeInfo (T )) {
516
+ .Optional = > | optional_info | {
517
+ return ? Span (optional_info .child );
523
518
},
524
- .C = > {
525
- ptr_info .sentinel = 0 ;
526
- ptr_info .is_allowzero = false ;
519
+ .Pointer = > | ptr_info | {
520
+ var new_ptr_info = ptr_info ;
521
+ switch (ptr_info .size ) {
522
+ .One = > switch (@typeInfo (ptr_info .child )) {
523
+ .Array = > | info | {
524
+ new_ptr_info .child = info .child ;
525
+ new_ptr_info .sentinel = info .sentinel ;
526
+ },
527
+ else = > @compileError ("invalid type given to std.mem.Span" ),
528
+ },
529
+ .C = > {
530
+ new_ptr_info .sentinel = 0 ;
531
+ new_ptr_info .is_allowzero = false ;
532
+ },
533
+ .Many , .Slice = > {},
534
+ }
535
+ new_ptr_info .size = .Slice ;
536
+ return @Type (std.builtin.TypeInfo { .Pointer = new_ptr_info });
527
537
},
528
- .Many , .Slice = > {} ,
538
+ else = > @compileError ( "invalid type given to std.mem.Span" ) ,
529
539
}
530
- ptr_info .size = .Slice ;
531
- return @Type (std.builtin.TypeInfo { .Pointer = ptr_info });
532
540
}
533
541
534
542
test "Span" {
535
543
testing .expect (Span (* [5 ]u16 ) == []u16 );
544
+ testing .expect (Span (? * [5 ]u16 ) == ? []u16 );
536
545
testing .expect (Span (* const [5 ]u16 ) == []const u16 );
546
+ testing .expect (Span (? * const [5 ]u16 ) == ? []const u16 );
537
547
testing .expect (Span ([]u16 ) == []u16 );
548
+ testing .expect (Span (? []u16 ) == ? []u16 );
538
549
testing .expect (Span ([]const u8 ) == []const u8 );
550
+ testing .expect (Span (? []const u8 ) == ? []const u8 );
539
551
testing .expect (Span ([:1 ]u16 ) == [:1 ]u16 );
552
+ testing .expect (Span (? [:1 ]u16 ) == ? [:1 ]u16 );
540
553
testing .expect (Span ([:1 ]const u8 ) == [:1 ]const u8 );
554
+ testing .expect (Span (? [:1 ]const u8 ) == ? [:1 ]const u8 );
541
555
testing .expect (Span ([* :1 ]u16 ) == [:1 ]u16 );
556
+ testing .expect (Span (? [* :1 ]u16 ) == ? [:1 ]u16 );
542
557
testing .expect (Span ([* :1 ]const u8 ) == [:1 ]const u8 );
558
+ testing .expect (Span (? [* :1 ]const u8 ) == ? [:1 ]const u8 );
543
559
testing .expect (Span ([* c ]u16 ) == [:0 ]u16 );
560
+ testing .expect (Span (? [* c ]u16 ) == ? [:0 ]u16 );
544
561
testing .expect (Span ([* c ]const u8 ) == [:0 ]const u8 );
562
+ testing .expect (Span (? [* c ]const u8 ) == ? [:0 ]const u8 );
545
563
}
546
564
547
565
/// Takes a pointer to an array, a sentinel-terminated pointer, or a slice, and
@@ -553,6 +571,9 @@ test "Span" {
553
571
/// length value is used instead of the sentinel.
554
572
pub fn span (ptr : var ) Span (@TypeOf (ptr )) {
555
573
const Result = Span (@TypeOf (ptr ));
574
+ if (@typeInfo (@TypeOf (ptr )) == .Optional and ptr == null ) {
575
+ return null ;
576
+ }
556
577
const l = len (ptr );
557
578
if (@typeInfo (Result ).Pointer .sentinel ) | s | {
558
579
return ptr [0.. l :s ];
@@ -573,6 +594,9 @@ test "span" {
573
594
/// rather than using the length.
574
595
pub fn spanZ (ptr : var ) Span (@TypeOf (ptr )) {
575
596
const Result = Span (@TypeOf (ptr ));
597
+ if (@typeInfo (@TypeOf (ptr )) == .Optional and ptr == null ) {
598
+ return null ;
599
+ }
576
600
const l = lenZ (ptr );
577
601
if (@typeInfo (Result ).Pointer .sentinel ) | s | {
578
602
return ptr [0.. l :s ];
0 commit comments