Created
August 12, 2025 16:23
-
-
Save InfiniteCoder01/23b5056883988e186d8fe7baf58d41f2 to your computer and use it in GitHub Desktop.
Revisions
-
InfiniteCoder01 created this gist
Aug 12, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,116 @@ #include <assert.h> #include <stddef.h> #include <stdbool.h> // Option implementation #define option(T) option_ ## T #define option_method(T, M) option_ ## T ## _ ## M #define option_genimpl(T) \ typedef struct { \ bool tag; \ T value; \ } option(T); \ \ option(T) option_method(T, some) (T value) {\ return (option(T)) { \ .tag = true, \ .value = value, \ }; \ }\ \ option(T) option_method(T, none) () {\ return (option(T)) { \ .tag = false, \ }; \ }\ \ bool option_method(T, eq) (\ option(T) lhs,\ option(T) rhs\ ) {\ if (lhs.tag != rhs.tag) return false;\ if (lhs.tag) return lhs.value == rhs.value;\ return true;\ } option_genimpl(size_t); // Trait impl #define impl_assoc(T, S, A) T ## _ ## S ## _ ## A #define impl_assoc2(T, S, A) impl_assoc(T, S, A) // Peekable #define peekable(T, I) peekable_ ## T ## _ ## I #define peekable_method(T, I, M) peekable_ ## T ## _ ## I ## _ ## M #define peekable_genimpl(T, I) \ typedef struct { \ T iter; \ option(I) peeked; \ } peekable(T, I);\ \ option(I) peekable_method(T, I, peek)(peekable(T, I) *self) {\ if (!self->peeked.tag) {\ self->peeked = impl_assoc(simple_iterator, T, next)(&self->iter);\ }\ \ return self->peeked;\ }\ \ option(I) impl_assoc2(simple_iterator, peekable(T, I), next)(peekable(T, I) *self) {\ if (self->peeked.tag) {\ option(I) tmp = self->peeked;\ self->peeked = option_method(I, none)();\ return tmp;\ } else {\ return impl_assoc(simple_iterator, T, next)(&self->iter);\ }\ }\ \ typedef I impl_assoc2(simple_iterator, peekable(T, I), item);\ \ peekable(T, I) iter_peekable(T iter) {\ return (peekable(T, I)) {\ .iter = iter,\ .peeked = option_method(I, none)(),\ };\ } // Iota implementation typedef struct { size_t field0; } iota; iota iota_new() { return (iota) { .field0 = 0, }; } option_size_t impl_assoc(simple_iterator, iota, next)(iota *self) { size_t prev = self->field0; self->field0 = prev + 1; return option_size_t_some(prev); } typedef size_t impl_assoc(simple_iterator, iota, item); peekable_genimpl(iota, size_t) // Main #include <stdio.h> int main() { iota iota = iota_new(); assert(option_size_t_eq(impl_assoc(simple_iterator, iota, next)(&iota), option_size_t_some(0))); assert(option_size_t_eq(impl_assoc(simple_iterator, iota, next)(&iota), option_size_t_some(1))); assert(option_size_t_eq(impl_assoc(simple_iterator, iota, next)(&iota), option_size_t_some(2))); assert(option_size_t_eq(impl_assoc(simple_iterator, iota, next)(&iota), option_size_t_some(3))); peekable(iota, size_t) peekable_iota = iter_peekable(iota); assert(option_size_t_eq(peekable_method(iota, size_t, peek)(&peekable_iota), option_size_t_some(4))); assert(option_size_t_eq(peekable_method(iota, size_t, peek)(&peekable_iota), option_size_t_some(4))); assert(option_size_t_eq(peekable_method(iota, size_t, peek)(&peekable_iota), option_size_t_some(4))); assert(option_size_t_eq(impl_assoc2(simple_iterator, peekable(iota, size_t), next)(&peekable_iota), option_size_t_some(4))); assert(option_size_t_eq(impl_assoc2(simple_iterator, peekable(iota, size_t), next)(&peekable_iota), option_size_t_some(5))); assert(option_size_t_eq(impl_assoc2(simple_iterator, peekable(iota, size_t), next)(&peekable_iota), option_size_t_some(6))); } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,70 @@ pub trait SimpleIterator { type Item; fn next(&mut self) -> Option<Self::Item>; fn peekable(self) -> Peekable<Self, Self::Item> where Self: Sized, { Peekable { iter: self, peeked: None, } } } pub struct Peekable<T, I> { iter: T, peeked: Option<I>, } impl<I: Clone, T: SimpleIterator<Item = I>> Peekable<T, I> { pub fn peek(&mut self) -> Option<I> { if self.peeked.is_none() { self.peeked = self.iter.next(); } self.peeked.clone() } } impl<I, T: SimpleIterator<Item = I>> SimpleIterator for Peekable<T, I> { type Item = T::Item; fn next(&mut self) -> Option<T::Item> { match &self.peeked { Some(_) => std::mem::replace(&mut self.peeked, None), None => self.iter.next(), } } } pub struct Iota(usize); impl Iota { pub fn new() -> Self { Iota(0) } } impl SimpleIterator for Iota { type Item = usize; fn next(&mut self) -> Option<usize> { let prev = self.0; self.0 = prev + 1; Some(prev) } } fn main() { let mut iota = Iota::new(); assert_eq!(iota.next(), Some(0)); assert_eq!(iota.next(), Some(1)); assert_eq!(iota.next(), Some(2)); assert_eq!(iota.next(), Some(3)); let mut peekable_iota = iota.peekable(); assert_eq!(peekable_iota.peek(), Some(4)); assert_eq!(peekable_iota.peek(), Some(4)); assert_eq!(peekable_iota.peek(), Some(4)); assert_eq!(peekable_iota.next(), Some(4)); assert_eq!(peekable_iota.next(), Some(5)); assert_eq!(peekable_iota.next(), Some(6)); }