generated from mg/zig-template
added SmolStr
This commit is contained in:
parent
650a824b16
commit
b4cc10b252
6 changed files with 130 additions and 48 deletions
|
|
@ -1,3 +1,3 @@
|
|||
# zig-template
|
||||
# zig-smolstr
|
||||
|
||||
Template for zig repositories
|
||||
String with inlining support, based on [smol_str](https://github.com/rust-analyzer/smol_str)
|
||||
|
|
|
|||
33
build.zig
33
build.zig
|
|
@ -10,57 +10,28 @@ pub fn build(b: *std.Build) void {
|
|||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const exe_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
exe_mod.addImport("zig_template_lib", lib_mod);
|
||||
|
||||
const lib = b.addLibrary(.{
|
||||
.linkage = .static,
|
||||
.name = "zig_template",
|
||||
.root_module = lib_mod,
|
||||
});
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "zig_template",
|
||||
.root_module = exe_mod,
|
||||
});
|
||||
|
||||
b.installArtifact(lib);
|
||||
b.installArtifact(exe);
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
|
||||
if (b.args) |args| {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
const run_step = b.step("run", "Run the app");
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
|
||||
const lib_unit_tests = b.addTest(.{
|
||||
.root_module = lib_mod,
|
||||
});
|
||||
|
||||
const exe_unit_tests = b.addTest(.{
|
||||
.root_module = exe_mod,
|
||||
});
|
||||
|
||||
const ext_tests = b.addTest(.{
|
||||
.root_source_file = b.path("tests/root.zig"),
|
||||
});
|
||||
|
||||
ext_tests.root_module.addImport("smolstr", lib.root_module);
|
||||
|
||||
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
||||
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
|
||||
const run_ext_tests = b.addRunArtifact(ext_tests);
|
||||
|
||||
const test_step = b.step("test", "Run unit tests");
|
||||
test_step.dependOn(&run_lib_unit_tests.step);
|
||||
test_step.dependOn(&run_exe_unit_tests.step);
|
||||
test_step.dependOn(&run_ext_tests.step);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
//
|
||||
// It is redundant to include "zig" in this name because it is already
|
||||
// within the Zig package namespace.
|
||||
.name = .zig_template,
|
||||
.name = .smol_str,
|
||||
|
||||
// This is a [Semantic Version](https://semver.org/).
|
||||
// In a future version of Zig it will be used for package deduplication.
|
||||
.version = "0.0.0",
|
||||
.version = "0.1.0",
|
||||
|
||||
// Together with name, this represents a globally unique package
|
||||
// identifier. This field is generated by the Zig toolchain when the
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
// original project's identity. Thus it is recommended to leave the comment
|
||||
// on the following line intact, so that it shows up in code reviews that
|
||||
// modify the field.
|
||||
.fingerprint = 0xf2a3560362615322, // Changing this has security and trust implications.
|
||||
.fingerprint = 0x387d26e34b457035, // Changing this has security and trust implications.
|
||||
|
||||
// Tracks the earliest Zig version that the package considers to be a
|
||||
// supported use case.
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
"build.zig.zon",
|
||||
"src",
|
||||
// For example...
|
||||
//"LICENSE",
|
||||
"LICENSE",
|
||||
//"README.md",
|
||||
},
|
||||
}
|
||||
|
|
|
|||
11
src/main.zig
11
src/main.zig
|
|
@ -1,11 +0,0 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
const stdout_file = std.io.getStdOut().writer();
|
||||
var bw = std.io.bufferedWriter(stdout_file);
|
||||
const stdout = bw.writer();
|
||||
|
||||
try stdout.print("Hello, World.\n", .{});
|
||||
|
||||
try bw.flush();
|
||||
}
|
||||
85
src/root.zig
85
src/root.zig
|
|
@ -1 +1,86 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub const SmolStr = struct {
|
||||
pub const max_inline_len: usize = 22;
|
||||
|
||||
const Inner = union(enum) {
|
||||
inl: struct {
|
||||
len: u8,
|
||||
data: [22]u8,
|
||||
},
|
||||
heap: []const u8,
|
||||
};
|
||||
|
||||
inner: Inner,
|
||||
|
||||
pub fn init(alloc: std.mem.Allocator, s: []const u8) !SmolStr {
|
||||
if (s.len <= max_inline_len) {
|
||||
return initInline(s);
|
||||
}
|
||||
|
||||
const s_ = try alloc.dupe(u8, s);
|
||||
|
||||
const inner = Inner{
|
||||
.heap = s_,
|
||||
};
|
||||
|
||||
return .{ .inner = inner };
|
||||
}
|
||||
|
||||
pub fn initInline(s: []const u8) SmolStr {
|
||||
if (s.len > max_inline_len) {
|
||||
var buf: [1024]u8 = undefined;
|
||||
|
||||
var msg: []const u8 = undefined;
|
||||
|
||||
msg = std.fmt.bufPrint(&buf, "Tried to inline string \"{s}\" of len {}", .{ s, s.len }) catch |e| switch (e) {
|
||||
error.NoSpaceLeft => blk: {
|
||||
break :blk std.fmt.bufPrint(&buf, "Tried to inline string of len {}", .{s.len}) catch unreachable;
|
||||
},
|
||||
};
|
||||
|
||||
@panic(msg);
|
||||
}
|
||||
|
||||
var inner = Inner{ .inl = .{
|
||||
.len = @intCast(s.len),
|
||||
.data = undefined,
|
||||
} };
|
||||
|
||||
@memcpy(inner.inl.data[0..s.len], s);
|
||||
|
||||
return .{ .inner = inner };
|
||||
}
|
||||
|
||||
pub fn deinit(self: SmolStr, alloc: std.mem.Allocator) void {
|
||||
switch (self.inner) {
|
||||
.inl => {},
|
||||
.heap => |s| alloc.free(s),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn str(self: *const SmolStr) []const u8 {
|
||||
switch (self.inner) {
|
||||
.inl => |*inl| return inl.data[0..self.len()],
|
||||
.heap => |s| return s,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(self: SmolStr) usize {
|
||||
switch (self.inner) {
|
||||
.inl => |*inl| return inl.len,
|
||||
.heap => |s| return s.len,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format(self: SmolStr, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
|
||||
try writer.print("{s}", .{self.str()});
|
||||
}
|
||||
};
|
||||
|
||||
test {
|
||||
try std.testing.expectEqual(24, @sizeOf(SmolStr));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,38 @@
|
|||
const std = @import("std");
|
||||
|
||||
const SmolStr = @import("smolstr").SmolStr;
|
||||
|
||||
test "inline" {
|
||||
const alloc = std.testing.allocator;
|
||||
|
||||
const s = "abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
for (1..SmolStr.max_inline_len + 1) |i| {
|
||||
const sub_s: []const u8 = s[0..i];
|
||||
|
||||
const str = try SmolStr.init(alloc, sub_s);
|
||||
defer str.deinit(alloc);
|
||||
|
||||
try std.testing.expectEqual(i, str.inner.inl.len);
|
||||
try std.testing.expectEqualStrings(s[0..i], str.inner.inl.data[0..str.inner.inl.len]);
|
||||
|
||||
try std.testing.expectEqual(i, str.len());
|
||||
try std.testing.expectEqualStrings(s[0..i], str.str());
|
||||
|
||||
try std.testing.expectEqual(s[0], str.str()[0]);
|
||||
}
|
||||
}
|
||||
|
||||
test "heap" {
|
||||
const alloc = std.testing.allocator;
|
||||
|
||||
const s = "abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
const str = try SmolStr.init(alloc, s);
|
||||
defer str.deinit(alloc);
|
||||
|
||||
try std.testing.expectEqualStrings(s, str.inner.heap);
|
||||
|
||||
try std.testing.expectEqual(s.len, str.len());
|
||||
try std.testing.expectEqualStrings(s, str.str());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue