small additions and cleanup in core libraries
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 3 Feb 2023 15:44:04 +0000 (09:44 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 3 Feb 2023 15:44:04 +0000 (09:44 -0600)
core/container/array.onyx
core/container/iter.onyx
core/container/optional.onyx

index 725f021ff6c3d0816ccb2a2ce37e84db764a9025..5792ca85a1f4cbaf3421a42a4d713778e5e8105d 100644 (file)
@@ -637,3 +637,39 @@ count_where :: macro (arr: [] $T, predicate_body: Code) -> u32 {
     }
     return count;
 }
+
+
+windows :: (arr: [] $T, width: i32) -> Iterator([] T) {
+    use core {iter}
+
+    return iter.generator(
+        ^.{ arr=arr, width=width, pos=0 },
+        ctx => {
+            if ctx.pos + ctx.width < ctx.arr.count {
+                defer ctx.pos += 1;
+                return ctx.arr.data[ctx.pos .. ctx.pos+ctx.width], true;
+            }
+
+            return .{}, false;
+        }
+    );
+}
+
+chunks :: (arr: [] $T, width: i32) -> Iterator([] T) {
+    use core {iter}
+
+    return iter.generator(
+        ^.{ arr=arr, width=width, pos=0 },
+        ctx => {
+            if ctx.pos < ctx.arr.count {
+                defer ctx.pos += ctx.width;
+
+                end := core.math.min(ctx.pos+ctx.width, ctx.arr.count);
+                return ctx.arr.data[ctx.pos .. end], true;
+            }
+
+            return .{}, false;
+        }
+    );
+}
+
index 9a8875a5d9982b2b87d2e3162dc0b8ef5b729814..f9bd4e9ecdb2c8bc638aef906067340586c98994 100644 (file)
@@ -676,40 +676,26 @@ as_iter :: (x: ^[..] $T, by_pointer: bool) -> Iterator(^T) {
 }
 
 #overload
-as_iter :: (r: range) -> Iterator(i32) {
-    Context :: struct {
-        r: range;
-        v: i32;
-    }
-
-    next :: (use c: ^Context) -> (i32, bool) {
-        if r.step > 0 {
-            if v >= r.high {
+as_iter :: (r: range) => generator(
+    ^.{ r = r, v = r.low },
+    ctx => {
+        if ctx.r.step > 0 {
+            if ctx.v >= ctx.r.high {
                 return 0, false;
             } else {
-                defer v += r.step;
-                return v, true;
+                defer ctx.v += ctx.r.step;
+                return ctx.v, true;
             }
 
         } else {
-            if v < r.high {
+            if ctx.v < ctx.r.high {
                 return 0, false;
             } else {
-                defer v += r.step;
-                return v, true;
+                defer ctx.v += ctx.r.step;
+                return ctx.v, true;
             }
         }
-    }
-
-    c := new(Context, allocator=context.temp_allocator);
-    c.r = r;
-    c.v = r.low;
-
-    return .{
-        data  = c,
-        next  = next,
-    };
-}
+    });
 
 fold :: #match #local {}
 
index 36283f4051c194f3c69cbfbce7aae59323a85ca4..33aafefb2f0a0ca64aeae2a7509d7ba28281d3e6 100644 (file)
@@ -11,10 +11,12 @@ package core
 // used by Map and Set in their `get_opt` function. In theory, it should
 // be used in many more places, instead of returning `.{}`.
 
-// Optional(T) is a simply a structure with a flag of whether or not
-// the optional contains a value. When the `has_value` is true, the
-// `value` member will be populated with an initialized value.
-// Otherwise, `value` should be a zeroed buffer.
+#doc """
+    Optional(T) is a simply a structure with a flag of whether or not
+    the optional contains a value. When the `has_value` is true, the
+    `value` member will be populated with an initialized value.
+    Otherwise, `value` should be a zeroed buffer.
+"""
 @conv.Custom_Format.{ #solidify format {T=Value_Type} }
 Optional :: struct (Value_Type: type_expr) {
     has_value: bool;
@@ -22,52 +24,60 @@ Optional :: struct (Value_Type: type_expr) {
 }
 
 #inject Optional {
-    // Helper procedure for creating an Optional with a value.
-    // Pass a type as the first argument to force the type, otherwise
-    // the type will be inferred from the parameter type.
+    #doc """
+        Helper procedure for creating an Optional with a value.
+        Pass a type as the first argument to force the type, otherwise
+        the type will be inferred from the parameter type.
+    """
     make :: #match #locked {
         ((x: $T) => Optional(T).{ has_value = true, value = x }),
         ($T: type_expr, x: T) => (Optional(T).{ has_value = true, value = x })
     }
 
-    // Create an empty Optional of a certain type. This procedure
-    // is mostly useless, because you can use `.{}` in type inferred
-    // places to avoid having to specify the type.
+    #doc """
+        Create an empty Optional of a certain type. This procedure
+        is mostly useless, because you can use `.{}` in type inferred
+        places to avoid having to specify the type.
+    """
     empty :: macro (T: type_expr) => Optional(T).{}; 
 
-    // Extracts the value from the Optional, or uses a default if
-    // no value is present.
+    #doc """
+        Extracts the value from the Optional, or uses a default if
+        no value is present.
+    """
     value_or :: (o: Optional, default: o.Value_Type) -> o.Value_Type {
         if !o.has_value do return default;
         return o.value;
     }
 
-    // Clears the value in the Optional, zeroing the memory of the value.
+    #doc "Clears the value in the Optional, zeroing the memory of the value."
     reset :: (o: ^Optional) {
         o.has_value = false;
         core.memory.set(^o.value, 0, sizeof o.Value_Type);
     }
 
-    // Sets the value in the Optional.
+    #doc "Sets the value in the Optional."
     set :: (o: ^Optional, value: o.Value_Type) {
         o.has_value = true;
         o.value = value;
     }
 
-    // Monadic chaining operation.
+    #doc "Monadic chaining operation."
     and_then :: (o: Optional($T), transform: (T) -> Optional($R)) -> Optional(R) {
         if !o.has_value do return .{ false };
         return transform(o.value);
     }
 
-    // Changes the value inside the optional, if present.
+    #doc "Changes the value inside the optional, if present."
     transform :: (o: Optional($T), transform: (T) -> $R) -> Optional(R) {
         if !o.has_value do return .{ false };
         return Optional.make(transform(o.value));
     }
 
-    // Like `value_or`, but instead of providing a value, you
-    // provide a function to generate a value.
+    #doc """
+        Like `value_or`, but instead of providing a value, you
+        provide a function to generate a value.
+    """
     or_else :: (o: Optional($T), generate: () -> Optional(T)) -> Optional(T) {
         if o.has_value do return o;
         return generate();