From: Brendan Hansen Date: Fri, 3 Feb 2023 15:44:04 +0000 (-0600) Subject: small additions and cleanup in core libraries X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=78df62a9fee624bd65fca9ad6232faf60d28b3c2;p=onyx.git small additions and cleanup in core libraries --- diff --git a/core/container/array.onyx b/core/container/array.onyx index 725f021f..5792ca85 100644 --- a/core/container/array.onyx +++ b/core/container/array.onyx @@ -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; + } + ); +} + diff --git a/core/container/iter.onyx b/core/container/iter.onyx index 9a8875a5..f9bd4e9e 100644 --- a/core/container/iter.onyx +++ b/core/container/iter.onyx @@ -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 {} diff --git a/core/container/optional.onyx b/core/container/optional.onyx index 36283f40..33aafefb 100644 --- a/core/container/optional.onyx +++ b/core/container/optional.onyx @@ -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();