@@ -120,16 +120,11 @@ pub fn SmallArrayListAlignedSized(comptime T: type, comptime alignment: ?u29, co
120120 pub const Slice = SliceType ;
121121 pub const SliceConst = SliceConstType ;
122122
123- /// Initialized an empty SmallArrayList. Deinitialize with `deinit`.
124- pub fn init () Self {
125- return empty ;
126- }
127-
128123 /// Initialize with capacity to hold `num` elements.
129124 /// The resulting capacity will equal `num` exactly.
130125 /// Deinitialize with `deinit`.
131126 pub fn initCapacity (gpa : Allocator , num : usize ) Allocator.Error ! Self {
132- var self = Self {} ;
127+ var self = Self . empty ;
133128 try self .ensureTotalCapacityPrecise (gpa , num );
134129 return self ;
135130 }
@@ -649,6 +644,47 @@ pub fn SmallArrayListAlignedSized(comptime T: type, comptime alignment: ?u29, co
649644 self .as .slice = new_mem ;
650645 self .capacity = new_capacity ;
651646 }
647+
648+ pub const WriterContext = struct {
649+ self : * Self ,
650+ allocator : Allocator ,
651+ };
652+
653+ pub const Writer = if (T != u8 )
654+ @compileError ("The Writer interface is only defined for SmallArrayList(u8) " ++
655+ "but the given type is SmallArrayList(" ++ @typeName (T ) ++ ")" )
656+ else
657+ std .io .Writer (WriterContext , Allocator .Error , appendWrite );
658+
659+ /// Initializes a Writer which will append to the list.
660+ pub fn writer (self : * Self , gpa : Allocator ) Writer {
661+ return .{ .context = .{ .self = self , .allocator = gpa } };
662+ }
663+
664+ /// Same as `append` except it returns the number of bytes written,
665+ /// which is always the same as `m.len`. The purpose of this function
666+ /// existing is to match `std.io.Writer` API.
667+ /// Invalidates element pointers if additional memory is needed.
668+ fn appendWrite (context : WriterContext , m : []const u8 ) Allocator.Error ! usize {
669+ try context .self .appendSlice (context .allocator , m );
670+ return m .len ;
671+ }
672+
673+ pub const FixedWriter = std .io .Writer (* Self , Allocator .Error , appendWriteFixed );
674+
675+ /// Initializes a Writer which will append to the list but will return
676+ /// `error.OutOfMemory` rather than increasing capacity.
677+ pub fn fixedWriter (self : * Self ) FixedWriter {
678+ return .{ .context = self };
679+ }
680+
681+ /// The purpose of this function existing is to match `std.io.Writer` API.
682+ fn appendWriteFixed (self : * Self , m : []const u8 ) error {OutOfMemory }! usize {
683+ const available_capacity = self .capacity - self .len ;
684+ if (m .len > available_capacity ) return error .OutOfMemory ;
685+ self .appendSliceAssumeCapacity (m );
686+ return m .len ;
687+ }
652688 };
653689}
654690
@@ -689,14 +725,14 @@ test "init" {
689725test "initCapacity" {
690726 {
691727 const a = testing .allocator ;
692- var list = try SmallArrayList (i8 ).initCapacity (a , 200 );
728+ var list = try SmallArrayList (u8 ).initCapacity (a , 200 );
693729 defer list .deinit (a );
694730 try testing .expect (list .len == 0 );
695731 try testing .expect (list .capacity >= 200 );
696732 }
697733 {
698734 const a = testing .allocator ;
699- var list = try SmallArrayListSized (i8 , 8 ).initCapacity (a , 6 );
735+ var list = try SmallArrayListSized (u8 , 8 ).initCapacity (a , 6 );
700736 try testing .expect (list .len == 0 );
701737 try testing .expect (list .capacity >= 6 );
702738 try testing .expect (! list .hasAllocation ());
@@ -805,6 +841,20 @@ test "basic" {
805841 try testing .expect (list .pop () == 33 );
806842}
807843
844+ test "appendSlice" {
845+ const a = testing .allocator ;
846+ var list : SmallArrayList (u8 ) = .empty ;
847+ defer list .deinit (a );
848+
849+ try list .appendSlice (a , "abcdefg" );
850+ try testing .expect (! list .hasAllocation ());
851+ try list .appendSlice (a , "hijklmn" );
852+ try testing .expect (! list .hasAllocation ());
853+ try list .appendSlice (a , "opqrstu" );
854+ try testing .expect (list .hasAllocation ());
855+ try testing .expectEqualStrings ("abcdefghijklmnopqrstu" , list .items ());
856+ }
857+
808858test "appendNTimes" {
809859 const a = testing .allocator ;
810860 var list : SmallArrayList (i32 ) = .empty ;
@@ -1185,3 +1235,76 @@ test "sized" {
11851235 try testing .expect (list1 .hasAllocation ());
11861236 try testing .expect (! list2 .hasAllocation ());
11871237}
1238+
1239+ test "expand and shrink" {
1240+ const List = SmallArrayList (u8 );
1241+ var list : List = .empty ;
1242+ try testing .expectEqual (list .len , 0 );
1243+ try testing .expectEqual (list .capacity , List .smallCapacity );
1244+
1245+ list .expandToCapacity ();
1246+ try testing .expectEqual (list .len , List .smallCapacity );
1247+ try testing .expectEqual (list .capacity , List .smallCapacity );
1248+
1249+ list .shrinkRetainingCapacity (4 );
1250+ try testing .expectEqual (list .len , 4 );
1251+ try testing .expectEqual (list .capacity , List .smallCapacity );
1252+
1253+ list .clearRetainingCapacity ();
1254+ try testing .expectEqual (list .len , 0 );
1255+ try testing .expectEqual (list .capacity , List .smallCapacity );
1256+ }
1257+
1258+ test "ensureTotalCapacity" {
1259+ const List = SmallArrayList (u8 );
1260+ const a = testing .allocator ;
1261+ var list : List = .empty ;
1262+
1263+ try list .ensureTotalCapacity (a , 100 );
1264+
1265+ try testing .expectEqual (list .len , 0 );
1266+ try testing .expectEqual (list .capacity , 128 );
1267+
1268+ list .clearAndFree (a );
1269+
1270+ try testing .expectEqual (list .len , 0 );
1271+ try testing .expectEqual (list .capacity , List .smallCapacity );
1272+ }
1273+
1274+ test "SmallArrayList(u8) implements writer" {
1275+ const a = testing .allocator ;
1276+
1277+ {
1278+ var buffer : SmallArrayList (u8 ) = .empty ;
1279+ defer buffer .deinit (a );
1280+
1281+ const x : i32 = 42 ;
1282+ const y : i32 = 1234 ;
1283+ try buffer .writer (a ).print ("x: {}\n y: {}\n " , .{ x , y });
1284+
1285+ try testing .expectEqualSlices (u8 , "x: 42\n y: 1234\n " , buffer .items ());
1286+ }
1287+ {
1288+ var list : SmallArrayListAligned (u8 , 2 ) = .empty ;
1289+ defer list .deinit (a );
1290+
1291+ const writer = list .writer (a );
1292+ try writer .writeAll ("a" );
1293+ try writer .writeAll ("bc" );
1294+ try writer .writeAll ("d" );
1295+ try writer .writeAll ("efg" );
1296+
1297+ try testing .expectEqualSlices (u8 , "abcdefg" , list .items ());
1298+ }
1299+ }
1300+
1301+ test "SmallArrayList(u8) implements fixedWriter" {
1302+ var buffer : SmallArrayList (u8 ) = .empty ;
1303+
1304+ const x : i32 = 42 ;
1305+ const y : i32 = 1234 ;
1306+ try buffer .fixedWriter ().print ("x: {}\n y: {}\n " , .{ x , y });
1307+
1308+ try testing .expectEqualSlices (u8 , "x: 42\n y: 1234\n " , buffer .items ());
1309+ try testing .expectError (error .OutOfMemory , buffer .fixedWriter ().print ("x: {}\n y: {}\n " , .{ x , y }));
1310+ }
0 commit comments