2017-01-05 00:57:48 -08:00
|
|
|
const assert = @import("std").debug.assert;
|
2017-05-20 20:06:32 -07:00
|
|
|
const builtin = @import("builtin");
|
2017-01-05 00:57:48 -08:00
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "compile time recursion" {
|
2016-12-21 22:42:30 -08:00
|
|
|
assert(some_data.len == 21);
|
|
|
|
}
|
2017-01-29 18:57:49 -08:00
|
|
|
var some_data: [usize(fibonacci(7))]u8 = undefined;
|
2018-01-25 01:10:11 -08:00
|
|
|
fn fibonacci(x: i32) i32 {
|
2016-12-21 22:42:30 -08:00
|
|
|
if (x <= 1) return 1;
|
2017-01-29 18:57:49 -08:00
|
|
|
return fibonacci(x - 1) + fibonacci(x - 2);
|
2016-12-21 21:12:27 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-21 22:42:30 -08:00
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn unwrapAndAddOne(blah: ?i32) i32 {
|
2016-12-21 21:12:27 -08:00
|
|
|
return ??blah + 1;
|
|
|
|
}
|
|
|
|
const should_be_1235 = unwrapAndAddOne(1234);
|
2017-05-23 18:38:31 -07:00
|
|
|
test "static add one" {
|
2016-12-21 21:12:27 -08:00
|
|
|
assert(should_be_1235 == 1235);
|
|
|
|
}
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "inlined loop" {
|
2017-01-22 16:51:37 -08:00
|
|
|
comptime var i = 0;
|
|
|
|
comptime var sum = 0;
|
2017-05-03 15:12:07 -07:00
|
|
|
inline while (i <= 5) : (i += 1)
|
2016-12-21 21:12:27 -08:00
|
|
|
sum += i;
|
|
|
|
assert(sum == 15);
|
|
|
|
}
|
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn gimme1or2(comptime a: bool) i32 {
|
2016-12-21 21:12:27 -08:00
|
|
|
const x: i32 = 1;
|
|
|
|
const y: i32 = 2;
|
2017-01-22 16:51:37 -08:00
|
|
|
comptime var z: i32 = if (a) x else y;
|
2016-12-21 21:12:27 -08:00
|
|
|
return z;
|
|
|
|
}
|
2017-05-23 18:38:31 -07:00
|
|
|
test "inline variable gets result of const if" {
|
2016-12-21 21:12:27 -08:00
|
|
|
assert(gimme1or2(true) == 1);
|
|
|
|
assert(gimme1or2(false) == 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "static function evaluation" {
|
2016-12-21 22:42:30 -08:00
|
|
|
assert(statically_added_number == 3);
|
|
|
|
}
|
|
|
|
const statically_added_number = staticAdd(1, 2);
|
2018-01-25 01:10:11 -08:00
|
|
|
fn staticAdd(a: i32, b: i32) i32 { return a + b; }
|
2016-12-21 22:42:30 -08:00
|
|
|
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "const expr eval on single expr blocks" {
|
2016-12-22 07:09:53 -08:00
|
|
|
assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
|
|
|
|
}
|
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {
|
2016-12-22 07:09:53 -08:00
|
|
|
const literal = 3;
|
|
|
|
|
2017-12-21 21:50:30 -08:00
|
|
|
const result = if (b) b: {
|
|
|
|
break :b literal;
|
|
|
|
} else b: {
|
|
|
|
break :b x;
|
2016-12-22 07:09:53 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-21 22:42:30 -08:00
|
|
|
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "statically initialized list" {
|
2016-12-26 00:05:33 -08:00
|
|
|
assert(static_point_list[0].x == 1);
|
|
|
|
assert(static_point_list[0].y == 2);
|
|
|
|
assert(static_point_list[1].x == 3);
|
|
|
|
assert(static_point_list[1].y == 4);
|
|
|
|
}
|
|
|
|
const Point = struct {
|
|
|
|
x: i32,
|
|
|
|
y: i32,
|
|
|
|
};
|
|
|
|
const static_point_list = []Point { makePoint(1, 2), makePoint(3, 4) };
|
2018-01-25 01:10:11 -08:00
|
|
|
fn makePoint(x: i32, y: i32) Point {
|
2016-12-26 00:05:33 -08:00
|
|
|
return Point {
|
|
|
|
.x = x,
|
|
|
|
.y = y,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "static eval list init" {
|
2016-12-26 00:16:19 -08:00
|
|
|
assert(static_vec3.data[2] == 1.0);
|
|
|
|
assert(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
|
|
|
|
}
|
|
|
|
const static_vec3 = vec3(0.0, 0.0, 1.0);
|
|
|
|
pub const Vec3 = struct {
|
|
|
|
data: [3]f32,
|
|
|
|
};
|
2018-01-25 01:10:11 -08:00
|
|
|
pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
|
2017-12-21 21:50:30 -08:00
|
|
|
return Vec3 {
|
2016-12-26 00:16:19 -08:00
|
|
|
.data = []f32 { x, y, z, },
|
2017-12-21 21:50:30 -08:00
|
|
|
};
|
2016-12-26 00:16:19 -08:00
|
|
|
}
|
2016-12-21 21:12:27 -08:00
|
|
|
|
2016-12-26 00:44:59 -08:00
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "constant expressions" {
|
2016-12-26 00:44:59 -08:00
|
|
|
var array : [array_size]u8 = undefined;
|
|
|
|
assert(@sizeOf(@typeOf(array)) == 20);
|
|
|
|
}
|
|
|
|
const array_size : u8 = 20;
|
|
|
|
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "constant struct with negation" {
|
2016-12-26 00:44:59 -08:00
|
|
|
assert(vertices[0].x == -0.6);
|
|
|
|
}
|
|
|
|
const Vertex = struct {
|
|
|
|
x: f32,
|
|
|
|
y: f32,
|
|
|
|
r: f32,
|
|
|
|
g: f32,
|
|
|
|
b: f32,
|
|
|
|
};
|
|
|
|
const vertices = []Vertex {
|
|
|
|
Vertex { .x = -0.6, .y = -0.4, .r = 1.0, .g = 0.0, .b = 0.0 },
|
|
|
|
Vertex { .x = 0.6, .y = -0.4, .r = 0.0, .g = 1.0, .b = 0.0 },
|
|
|
|
Vertex { .x = 0.0, .y = 0.6, .r = 0.0, .g = 0.0, .b = 1.0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "statically initialized struct" {
|
2016-12-26 00:44:59 -08:00
|
|
|
st_init_str_foo.x += 1;
|
|
|
|
assert(st_init_str_foo.x == 14);
|
|
|
|
}
|
|
|
|
const StInitStrFoo = struct {
|
|
|
|
x: i32,
|
|
|
|
y: bool,
|
|
|
|
};
|
|
|
|
var st_init_str_foo = StInitStrFoo { .x = 13, .y = true, };
|
|
|
|
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "statically initalized array literal" {
|
2016-12-26 00:44:59 -08:00
|
|
|
const y : [4]u8 = st_init_arr_lit_x;
|
|
|
|
assert(y[3] == 4);
|
|
|
|
}
|
|
|
|
const st_init_arr_lit_x = []u8{1,2,3,4};
|
2017-01-23 20:30:20 -08:00
|
|
|
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "const slice" {
|
2017-01-23 20:30:20 -08:00
|
|
|
comptime {
|
|
|
|
const a = "1234567890";
|
|
|
|
assert(a.len == 10);
|
2017-05-19 07:39:59 -07:00
|
|
|
const b = a[1..2];
|
2017-01-23 20:30:20 -08:00
|
|
|
assert(b.len == 1);
|
|
|
|
assert(b[0] == '2');
|
|
|
|
}
|
|
|
|
}
|
2017-01-26 12:34:36 -08:00
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "try to trick eval with runtime if" {
|
2017-01-26 12:34:36 -08:00
|
|
|
assert(testTryToTrickEvalWithRuntimeIf(true) == 10);
|
|
|
|
}
|
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn testTryToTrickEvalWithRuntimeIf(b: bool) usize {
|
2017-01-26 12:34:36 -08:00
|
|
|
comptime var i: usize = 0;
|
2017-05-03 15:12:07 -07:00
|
|
|
inline while (i < 10) : (i += 1) {
|
2017-01-26 12:34:36 -08:00
|
|
|
const result = if (b) false else true;
|
|
|
|
}
|
|
|
|
comptime {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
2017-01-29 16:10:56 -08:00
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn max(comptime T: type, a: T, b: T) T {
|
2017-01-29 16:10:56 -08:00
|
|
|
if (T == bool) {
|
2017-03-26 02:21:28 -07:00
|
|
|
return a or b;
|
2017-01-29 16:10:56 -08:00
|
|
|
} else if (a > b) {
|
|
|
|
return a;
|
|
|
|
} else {
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
}
|
2018-01-25 01:10:11 -08:00
|
|
|
fn letsTryToCompareBools(a: bool, b: bool) bool {
|
2017-12-21 21:50:30 -08:00
|
|
|
return max(bool, a, b);
|
2017-01-29 16:10:56 -08:00
|
|
|
}
|
2017-05-23 18:38:31 -07:00
|
|
|
test "inlined block and runtime block phi" {
|
2017-01-29 16:10:56 -08:00
|
|
|
assert(letsTryToCompareBools(true, true));
|
|
|
|
assert(letsTryToCompareBools(true, false));
|
|
|
|
assert(letsTryToCompareBools(false, true));
|
|
|
|
assert(!letsTryToCompareBools(false, false));
|
|
|
|
|
|
|
|
comptime {
|
|
|
|
assert(letsTryToCompareBools(true, true));
|
|
|
|
assert(letsTryToCompareBools(true, false));
|
|
|
|
assert(letsTryToCompareBools(false, true));
|
|
|
|
assert(!letsTryToCompareBools(false, false));
|
|
|
|
}
|
|
|
|
}
|
2017-01-29 18:57:49 -08:00
|
|
|
|
|
|
|
const CmdFn = struct {
|
|
|
|
name: []const u8,
|
2018-01-25 01:10:11 -08:00
|
|
|
func: fn(i32) i32,
|
2017-01-29 18:57:49 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
const cmd_fns = []CmdFn{
|
|
|
|
CmdFn {.name = "one", .func = one},
|
|
|
|
CmdFn {.name = "two", .func = two},
|
|
|
|
CmdFn {.name = "three", .func = three},
|
|
|
|
};
|
2018-01-25 01:10:11 -08:00
|
|
|
fn one(value: i32) i32 { return value + 1; }
|
|
|
|
fn two(value: i32) i32 { return value + 2; }
|
|
|
|
fn three(value: i32) i32 { return value + 3; }
|
2017-01-29 18:57:49 -08:00
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn performFn(comptime prefix_char: u8, start_value: i32) i32 {
|
2017-01-29 18:57:49 -08:00
|
|
|
var result: i32 = start_value;
|
|
|
|
comptime var i = 0;
|
2017-05-03 15:12:07 -07:00
|
|
|
inline while (i < cmd_fns.len) : (i += 1) {
|
2017-01-29 18:57:49 -08:00
|
|
|
if (cmd_fns[i].name[0] == prefix_char) {
|
|
|
|
result = cmd_fns[i].func(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "comptime iterate over fn ptr list" {
|
2017-01-29 18:57:49 -08:00
|
|
|
assert(performFn('t', 1) == 6);
|
|
|
|
assert(performFn('o', 0) == 1);
|
|
|
|
assert(performFn('w', 99) == 99);
|
|
|
|
}
|
2017-02-08 23:50:03 -08:00
|
|
|
|
2018-01-24 22:46:12 -08:00
|
|
|
test "eval @setRuntimeSafety at compile-time" {
|
|
|
|
const result = comptime fnWithSetRuntimeSafety();
|
2017-02-08 23:50:03 -08:00
|
|
|
assert(result == 1234);
|
|
|
|
}
|
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn fnWithSetRuntimeSafety() i32{
|
2018-01-24 22:46:12 -08:00
|
|
|
@setRuntimeSafety(true);
|
2017-02-08 23:50:03 -08:00
|
|
|
return 1234;
|
|
|
|
}
|
2017-02-11 10:13:45 -08:00
|
|
|
|
2017-05-20 20:06:32 -07:00
|
|
|
test "eval @setFloatMode at compile-time" {
|
|
|
|
const result = comptime fnWithFloatMode();
|
|
|
|
assert(result == 1234.0);
|
|
|
|
}
|
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn fnWithFloatMode() f32 {
|
2017-05-20 20:06:32 -07:00
|
|
|
@setFloatMode(this, builtin.FloatMode.Strict);
|
|
|
|
return 1234.0;
|
|
|
|
}
|
2017-02-11 10:13:45 -08:00
|
|
|
|
|
|
|
|
|
|
|
const SimpleStruct = struct {
|
|
|
|
field: i32,
|
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn method(self: &const SimpleStruct) i32 {
|
2017-02-11 10:13:45 -08:00
|
|
|
return self.field + 3;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
var simple_struct = SimpleStruct{ .field = 1234, };
|
|
|
|
|
|
|
|
const bound_fn = simple_struct.method;
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "call method on bound fn referring to var instance" {
|
2017-02-11 10:13:45 -08:00
|
|
|
assert(bound_fn() == 1237);
|
|
|
|
}
|
2017-02-12 14:22:35 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "ptr to local array argument at comptime" {
|
2017-02-12 14:22:35 -08:00
|
|
|
comptime {
|
|
|
|
var bytes: [10]u8 = undefined;
|
2017-05-19 07:39:59 -07:00
|
|
|
modifySomeBytes(bytes[0..]);
|
2017-02-12 14:22:35 -08:00
|
|
|
assert(bytes[0] == 'a');
|
|
|
|
assert(bytes[9] == 'b');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn modifySomeBytes(bytes: []u8) void {
|
2017-02-12 14:22:35 -08:00
|
|
|
bytes[0] = 'a';
|
|
|
|
bytes[9] = 'b';
|
|
|
|
}
|
2017-03-26 11:41:17 -07:00
|
|
|
|
|
|
|
|
|
|
|
test "comparisons 0 <= uint and 0 > uint should be comptime" {
|
|
|
|
testCompTimeUIntComparisons(1234);
|
|
|
|
}
|
2018-01-25 01:10:11 -08:00
|
|
|
fn testCompTimeUIntComparisons(x: u32) void {
|
2017-03-26 11:41:17 -07:00
|
|
|
if (!(0 <= x)) {
|
|
|
|
@compileError("this condition should be comptime known");
|
|
|
|
}
|
|
|
|
if (0 > x) {
|
|
|
|
@compileError("this condition should be comptime known");
|
|
|
|
}
|
|
|
|
if (!(x >= 0)) {
|
|
|
|
@compileError("this condition should be comptime known");
|
|
|
|
}
|
|
|
|
if (x < 0) {
|
|
|
|
@compileError("this condition should be comptime known");
|
|
|
|
}
|
|
|
|
}
|
2017-03-31 02:48:15 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test "const ptr to variable data changes at runtime" {
|
|
|
|
assert(foo_ref.name[0] == 'a');
|
|
|
|
foo_ref.name = "b";
|
|
|
|
assert(foo_ref.name[0] == 'b');
|
|
|
|
}
|
|
|
|
|
|
|
|
const Foo = struct {
|
|
|
|
name: []const u8,
|
|
|
|
};
|
|
|
|
|
|
|
|
var foo_contents = Foo { .name = "a", };
|
|
|
|
const foo_ref = &foo_contents;
|
2017-04-10 00:00:19 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test "create global array with for loop" {
|
|
|
|
assert(global_array[5] == 5 * 5);
|
|
|
|
assert(global_array[9] == 9 * 9);
|
|
|
|
}
|
|
|
|
|
2017-12-21 21:50:30 -08:00
|
|
|
const global_array = x: {
|
2017-04-10 00:00:19 -07:00
|
|
|
var result: [10]usize = undefined;
|
|
|
|
for (result) |*item, index| {
|
|
|
|
*item = index * index;
|
|
|
|
}
|
2017-12-21 21:50:30 -08:00
|
|
|
break :x result;
|
2017-04-10 00:00:19 -07:00
|
|
|
};
|
2017-05-16 14:04:35 -07:00
|
|
|
|
|
|
|
test "compile-time downcast when the bits fit" {
|
|
|
|
comptime {
|
|
|
|
const spartan_count: u16 = 255;
|
|
|
|
const byte = u8(spartan_count);
|
|
|
|
assert(byte == 255);
|
|
|
|
}
|
|
|
|
}
|
2017-05-26 20:31:38 -07:00
|
|
|
|
|
|
|
const hi1 = "hi";
|
|
|
|
const hi2 = hi1;
|
|
|
|
test "const global shares pointer with other same one" {
|
|
|
|
assertEqualPtrs(&hi1[0], &hi2[0]);
|
|
|
|
comptime assert(&hi1[0] == &hi2[0]);
|
|
|
|
}
|
2018-01-25 01:10:11 -08:00
|
|
|
fn assertEqualPtrs(ptr1: &const u8, ptr2: &const u8) void {
|
2017-05-26 20:31:38 -07:00
|
|
|
assert(ptr1 == ptr2);
|
|
|
|
}
|
2017-08-19 14:10:29 -07:00
|
|
|
|
|
|
|
test "@setEvalBranchQuota" {
|
|
|
|
comptime {
|
|
|
|
// 1001 for the loop and then 1 more for the assert fn call
|
|
|
|
@setEvalBranchQuota(1002);
|
|
|
|
var i = 0;
|
|
|
|
var sum = 0;
|
|
|
|
while (i < 1001) : (i += 1) {
|
|
|
|
sum += i;
|
|
|
|
}
|
|
|
|
assert(sum == 500500);
|
|
|
|
}
|
|
|
|
}
|
2017-08-19 21:33:05 -07:00
|
|
|
|
2017-09-13 22:44:22 -07:00
|
|
|
// TODO test "float literal at compile time not lossy" {
|
|
|
|
// TODO assert(16777216.0 + 1.0 == 16777217.0);
|
|
|
|
// TODO assert(9007199254740992.0 + 1.0 == 9007199254740993.0);
|
|
|
|
// TODO }
|
2017-08-19 21:33:05 -07:00
|
|
|
|
|
|
|
test "f32 at compile time is lossy" {
|
|
|
|
assert(f32(1 << 24) + 1 == 1 << 24);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "f64 at compile time is lossy" {
|
|
|
|
assert(f64(1 << 53) + 1 == 1 << 53);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "f128 at compile time is lossy" {
|
|
|
|
assert(f128(10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO need a better implementation of bigfloat_init_bigint
|
|
|
|
// assert(f128(1 << 113) == 10384593717069655257060992658440192);
|
2018-01-11 17:58:28 -08:00
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
|
2018-01-11 17:58:28 -08:00
|
|
|
return struct {
|
|
|
|
pub const Node = struct { };
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
test "string literal used as comptime slice is memoized" {
|
|
|
|
const a = "link";
|
|
|
|
const b = "link";
|
|
|
|
comptime assert(TypeWithCompTimeSlice(a).Node == TypeWithCompTimeSlice(b).Node);
|
|
|
|
comptime assert(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node);
|
|
|
|
}
|
2018-02-16 12:22:29 -08:00
|
|
|
|
|
|
|
test "comptime slice of undefined pointer of length 0" {
|
|
|
|
const slice1 = (&i32)(undefined)[0..0];
|
|
|
|
assert(slice1.len == 0);
|
|
|
|
const slice2 = (&i32)(undefined)[100..100];
|
|
|
|
assert(slice2.len == 0);
|
|
|
|
}
|
2018-03-08 14:15:55 -08:00
|
|
|
|
|
|
|
fn copyWithPartialInline(s: []u32, b: []u8) void {
|
|
|
|
comptime var i: usize = 0;
|
|
|
|
inline while (i < 4) : (i += 1) {
|
|
|
|
s[i] = 0;
|
|
|
|
s[i] |= u32(b[i*4+0]) << 24;
|
|
|
|
s[i] |= u32(b[i*4+1]) << 16;
|
|
|
|
s[i] |= u32(b[i*4+2]) << 8;
|
|
|
|
s[i] |= u32(b[i*4+3]) << 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
test "binary math operator in partially inlined function" {
|
|
|
|
var s: [4]u32 = undefined;
|
|
|
|
var b: [16]u8 = undefined;
|
|
|
|
|
|
|
|
for (b) |*r, i|
|
|
|
|
*r = u8(i + 1);
|
|
|
|
|
|
|
|
copyWithPartialInline(s[0..], b[0..]);
|
|
|
|
assert(s[0] == 0x1020304);
|
|
|
|
assert(s[1] == 0x5060708);
|
|
|
|
assert(s[2] == 0x90a0b0c);
|
|
|
|
assert(s[3] == 0xd0e0f10);
|
|
|
|
}
|
2018-03-09 11:20:44 -08:00
|
|
|
|
|
|
|
|
|
|
|
test "comptime function with the same args is memoized" {
|
|
|
|
comptime {
|
|
|
|
assert(MakeType(i32) == MakeType(i32));
|
|
|
|
assert(MakeType(i32) != MakeType(f64));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn MakeType(comptime T: type) type {
|
|
|
|
return struct {
|
|
|
|
field: T,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
test "comptime function with mutable pointer is not memoized" {
|
|
|
|
comptime {
|
|
|
|
var x: i32 = 1;
|
|
|
|
const ptr = &x;
|
|
|
|
increment(ptr);
|
|
|
|
increment(ptr);
|
|
|
|
assert(x == 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn increment(value: &i32) void {
|
|
|
|
*value += 1;
|
|
|
|
}
|
2018-03-11 21:08:52 -07:00
|
|
|
|
|
|
|
fn generateTable(comptime T: type) [1010]T {
|
|
|
|
var res : [1010]T = undefined;
|
|
|
|
var i : usize = 0;
|
|
|
|
while (i < 1010) : (i += 1) {
|
|
|
|
res[i] = T(i);
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn doesAlotT(comptime T: type, value: usize) T {
|
|
|
|
@setEvalBranchQuota(5000);
|
|
|
|
const table = comptime blk: {
|
|
|
|
break :blk generateTable(T);
|
|
|
|
};
|
|
|
|
return table[value];
|
|
|
|
}
|
|
|
|
|
|
|
|
test "@setEvalBranchQuota at same scope as generic function call" {
|
|
|
|
assert(doesAlotT(u32, 2) == 2);
|
|
|
|
}
|
2018-03-11 22:21:10 -07:00
|
|
|
|
|
|
|
test "comptime slice of slice preserves comptime var" {
|
|
|
|
comptime {
|
|
|
|
var buff: [10]u8 = undefined;
|
|
|
|
buff[0..][0..][0] = 1;
|
|
|
|
assert(buff[0..][0..][0] == 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
test "comptime slice of pointer preserves comptime var" {
|
|
|
|
comptime {
|
|
|
|
var buff: [10]u8 = undefined;
|
|
|
|
var a = &buff[0];
|
|
|
|
a[0..1][0] = 1;
|
|
|
|
assert(buff[0..][0..][0] == 1);
|
|
|
|
}
|
|
|
|
}
|
2018-03-12 05:35:41 -07:00
|
|
|
|
|
|
|
const SingleFieldStruct = struct {
|
|
|
|
x: i32,
|
|
|
|
|
|
|
|
fn read_x(self: &const SingleFieldStruct) i32 {
|
|
|
|
return self.x;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
test "const ptr to comptime mutable data is not memoized" {
|
|
|
|
|
|
|
|
comptime {
|
|
|
|
var foo = SingleFieldStruct {.x = 1};
|
|
|
|
assert(foo.read_x() == 1);
|
|
|
|
foo.x = 2;
|
|
|
|
assert(foo.read_x() == 2);
|
|
|
|
}
|
|
|
|
}
|