Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- fn hasType(comptime CheckType: type, comptime rec: bool) TraitFn {
- const Closure = struct {
- pub fn trait(comptime T: type) bool {
- const info = @typeInfo(T);
- const fields = switch(info) {
- builtin.TypeId.Struct => |s| s.fields,
- builtin.TypeId.Union => |u| u.fields,
- builtin.TypeId.Enum => |e| e.fields,
- else => return false,
- };
- inline for(fields) |field| {
- if (mem.eql(u8, @typeName(field.field_type), @typeName(CheckType))) return true;
- if (rec) {
- if (hasType(CheckType, rec)(field.field_type)) return true;
- }
- }
- return false;
- }
- };
- return Closure.trait;
- }
- pub const Pinned = struct {};
- pub fn pin(comptime P: type) type {
- return struct {
- pointer: P,
- const Self = @This();
- fn init(p: P) Self {
- return Self { .pointer = p};
- }
- fn deref(self: *const Self) *const P {
- return &self.pointer;
- }
- fn deref_mut(self: *Self) *P {
- if(comptime hasType(Pinned, true)(P)) {
- @compileError(@typeName(P) ++ " can not be moved, or mutable dereferenced");
- }
- return &self.pointer;
- }
- };
- }
- test "pinn" {
- const pinned = struct {
- marker: Pinned,
- n: u32,
- };
- var x = pinned { .marker = Pinned{}, .n = 0};
- var p = pin(pinned).init(x);
- _ = p.deref_mut();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement