import "./core.zc" /// An optional value: `Some(v)` or `None`. struct Option { is_some: bool; val: T; } impl Option { /// Wraps a value in a `Some` option. fn Some(v: T) -> Option { return Option { is_some: true, val: v }; } /// Returns the `None` option. fn None() -> Option { let opt: Option; opt.is_some = false; memset(&opt.val, 0, sizeof(T)); return opt; } /// Returns `true` when the option is `Some`. fn is_some(self) -> bool { return self.is_some; } /// Returns `true` when the option is `None`. fn is_none(self) -> bool { return !self.is_some; } /// Zeroes out the internal value without calling destructors or freeing /// memory. fn forget(self) { memset(&self.val, 0, sizeof(T)); } /// Returns the contained value. Panics when `None`. fn unwrap(self) -> T { if (!self.is_some) { !"Panic: unwrap called on None"; exit(1); } let v = self.val; // Moved value return v; } /// Returns a pointer to the contained value. Panics when `None`. fn unwrap_ref(self) -> T* { if (!self.is_some) { !"Panic: unwrap_ref called on None"; exit(1); } return &self.val; } /// Returns the contained value, or `def_val` when `None`. fn unwrap_or(self, def_val: T) -> T { if (self.is_some) { return self.val; } return def_val; } /// Returns the contained value, or the result of `f` when `None`. fn unwrap_or_else(self, f: fn() -> T) -> T { if (self.is_some) { return self.val; } return f(); } /// Returns the contained value, or panics with `msg` when `None`. fn expect(self, msg: char*) -> T { if (!self.is_some) { !"Panic: {msg}"; exit(1); } return self.val; } /// Returns the option when `Some`, otherwise returns `other`. fn or_else(self, other: Option) -> Option { if (self.is_some) { return self; } return other; } /// Returns `true` when `Some` and `f` accepts the contained value. fn is_some_and(self, f: fn(T) -> bool) -> bool { return self.is_some && f(self.val); } /// Returns `true` when `None`, or when `Some` and `f` accepts the value. fn is_none_or(self, f: fn(T) -> bool) -> bool { return !self.is_some || f(self.val); } /// Keeps the value when `Some` and `f` accepts it, otherwise `None`. fn filter(self, f: fn(T) -> bool) -> Option { if (self.is_some && f(self.val)) { return self; } return Option::None(); } }