aboutsummaryrefslogtreecommitdiff
path: root/src/strings.zig
blob: 189116b2b9519535f46d8aaee058d0744cd7adba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
const mutable = @import("string_mutable.zig");
const std = @import("std");

pub usingnamespace @import("string_types.zig");

pub const strings = @import("string_immutable.zig");

pub const MutableString = mutable.MutableString;

pub const eql = std.meta.eql;

pub fn NewStringBuilder(comptime size: usize) type {
    return struct {
        const This = @This();
        buffer: [*]u8 = undefined,
        remain: []u8 = undefined,

        pub fn init() This {
            return This{};
        }

        pub fn load(this: *This) void {
            this.remain = (&this.buffer)[0..size];
        }

        pub fn append(this: *This, _str: string) void {
            std.mem.copy(u8, this.remain, _str);
            this.remain = this.remain[_str.len..];
        }

        pub fn str(this: *This) string {
            var buf = this.buffer[0 .. @ptrToInt(this.remain.ptr) - @ptrToInt(&this.buffer)];
            // Always leave a sentinel so that anything that expects a sentinel Just Works
            // specifically, the reason for this is so C-based APIs can be used without an extra copy.
            // one byte is cheap...right?
            this.buffer[buf.len] = 0;
            return buf;
        }

        pub fn pop(this: *This, count: usize) string {
            this.remain = this.buffer[0 .. @ptrToInt(this.remain.ptr) - @ptrToInt(&this.buffer) - count];
        }

        pub fn reset(this: *This) void {
            this.load();
        }
    };
}

pub fn nql(a: anytype, b: @TypeOf(a)) bool {
    return !eql(a, b);
}