parseIntWithSign
Function parameters
Parameters
- Result:type
- Character:type
- buf:[]const Character
- base:u8
- sign:enum { pos, neg }
Type definitions in this namespace
Types
- FormatOptions
- Deprecated in favor of `Options`.
- Parser
- A stream based parser for format strings.
Deprecated in favor of `Writer.print`.
Functions
- format
- Deprecated in favor of `Writer.print`.
- printInt
- Asserts the rendered integer value fits in `buffer`.
- digits2
- Converts values in the range [0, 100) to a base 10 string.
- Formatter
- Deprecated in favor of `Alt`.
- Alt
- Creates a type suitable for instantiating and passing to a "{f}" placeholder.
- alt
- Helper for calling alternate format methods besides one named "format".
- parseInt
- Parses the string `buf` as signed or unsigned representation in the
- parseIntWithGenericCharacter
- Like `parseInt`, but with a generic `Character` type.
- parseUnsigned
- Parses the string `buf` as unsigned representation in the specified base
- parseIntSizeSuffix
- Parses a number like '2G', '2Gi', or '2GiB'.
- bufPrint
- Print a Formatter string into `buf`.
- count
- Count the characters needed for format.
- bytesToHex
- Encodes a sequence of bytes as hexadecimal digits.
- hexToBytes
- Decodes the sequence of bytes represented by the specified string of
- hex
- Converts an unsigned integer of any multiple of u8 to an array of lowercase
Error sets in this namespace
Error Sets
= 3
Values
- hex_charset
- = "0123456789abcdef"
Source
Implementation
fn parseIntWithSign(
comptime Result: type,
comptime Character: type,
buf: []const Character,
base: u8,
comptime sign: enum { pos, neg },
) ParseIntError!Result {
if (buf.len == 0) return error.InvalidCharacter;
var buf_base = base;
var buf_start = buf;
if (base == 0) {
// Treat is as a decimal number by default.
buf_base = 10;
// Detect the base by looking at buf prefix.
if (buf.len > 2 and buf[0] == '0') {
if (math.cast(u8, buf[1])) |c| switch (std.ascii.toLower(c)) {
'b' => {
buf_base = 2;
buf_start = buf[2..];
},
'o' => {
buf_base = 8;
buf_start = buf[2..];
},
'x' => {
buf_base = 16;
buf_start = buf[2..];
},
else => {},
};
}
}
const add = switch (sign) {
.pos => math.add,
.neg => math.sub,
};
// accumulate into Accumulate which is always 8 bits or larger. this prevents
// `buf_base` from overflowing Result.
const info = @typeInfo(Result);
const Accumulate = std.meta.Int(info.int.signedness, @max(8, info.int.bits));
var accumulate: Accumulate = 0;
if (buf_start[0] == '_' or buf_start[buf_start.len - 1] == '_') return error.InvalidCharacter;
for (buf_start) |c| {
if (c == '_') continue;
const digit = try charToDigit(math.cast(u8, c) orelse return error.InvalidCharacter, buf_base);
if (accumulate != 0) {
accumulate = try math.mul(Accumulate, accumulate, math.cast(Accumulate, buf_base) orelse return error.Overflow);
} else if (sign == .neg) {
// The first digit of a negative number.
// Consider parsing "-4" as an i3.
// This should work, but positive 4 overflows i3, so we can't cast the digit to T and subtract.
accumulate = math.cast(Accumulate, -@as(i8, @intCast(digit))) orelse return error.Overflow;
continue;
}
accumulate = try add(Accumulate, accumulate, math.cast(Accumulate, digit) orelse return error.Overflow);
}
return if (Result == Accumulate)
accumulate
else
math.cast(Result, accumulate) orelse return error.Overflow;
}