Skip to content

Instantly share code, notes, and snippets.

@mikdusan
Created March 22, 2020 19:18
Show Gist options
  • Save mikdusan/1d867b0148b24f9c6923f44f4825df34 to your computer and use it in GitHub Desktop.
Save mikdusan/1d867b0148b24f9c6923f44f4825df34 to your computer and use it in GitHub Desktop.
const std = @import("std");
pub fn main() !void {
const heap = std.heap.c_allocator;
// comptime length
{
var ct = [_]f32{ 1.0, 2.0 };
const r = try foo(heap, ct);
std.debug.warn("\ntype: {}\n", .{@typeName(@TypeOf(r))});
for (r) |item,i| std.debug.warn("ct[{}] = {d:.1}\n", .{i,item});
}
// runtime length
{
var rt: []f32 = &[_]f32{ 3.0, 4.0 };
const r = try foo(heap, rt);
std.debug.warn("\ntype: {}\n", .{@typeName(@TypeOf(r))});
for (r) |item,i| std.debug.warn("rt[{}] = {d:.1}\n", .{i,item});
}
// anonymous list
{
const r = try foo(heap, .{ 5.0, 6.0 });
std.debug.warn("\ntype: {}\n", .{@typeName(@TypeOf(r))});
for (r) |item,i| std.debug.warn("anon[{}] = {d:.1}\n", .{i,item});
}
}
// when array: answers will be * 10
// when slice: answers will be * 100
// when anon: answers will be * 1000 (we assume f32)
fn foo(allocator: *std.mem.Allocator, list: var) !FooResult(@TypeOf(list)) {
const T = @TypeOf(list);
switch (@typeInfo(T)) {
.Array => |array| {
var result: [T.len]array.child = undefined;
for (list) |item,i| result[i] = list[i] * 10;
return result;
},
.Pointer => |pointer| switch (pointer.size) {
.Slice => {
var result: []pointer.child = try allocator.alloc(pointer.child, list.len);
for (list) |item,i| result[i] = list[i] * 100;
return result;
},
else => return void,
},
.Struct => |strukt| {
var result: [strukt.fields.len]f32 = undefined;
inline for (list) |item,i| result[i] = @as(f32, list[i]) * 100;
return result;
},
else => return void,
}
unreachable;
}
fn FooResult(comptime T: type) type {
// @compileLog(T);
// @compileLog(@tagName(@typeInfo(T)));
switch (@typeInfo(T)) {
.Array => |array| {
return [T.len]array.child;
},
.Pointer => |pointer| switch (pointer.size) {
.Slice => return []pointer.child,
else => return void,
},
.Struct => |strukt| {
// assume f32 is desired for now
return [strukt.fields.len]f32;
},
else => return void,
}
unreachable;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment