diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-04-07 00:46:26 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-04-07 00:46:26 -0400 |
| commit | ef23faa3e6e003282e53fc08031ec4eb9a2e2aae (patch) | |
| tree | 763944687f506e5dded02956ab3b45c456e16146 /src/stdlib | |
| parent | 3554c56b209a1544c69e189ddab3b19b4bf80ae6 (diff) | |
Add Byte.to() method and improved micro optimization of iterating over
fixed-width integer ranges
Diffstat (limited to 'src/stdlib')
| -rw-r--r-- | src/stdlib/bytes.c | 25 | ||||
| -rw-r--r-- | src/stdlib/bytes.h | 9 | ||||
| -rw-r--r-- | src/stdlib/datatypes.h | 8 |
3 files changed, 35 insertions, 7 deletions
diff --git a/src/stdlib/bytes.c b/src/stdlib/bytes.c index 09e19c40..1203aa55 100644 --- a/src/stdlib/bytes.c +++ b/src/stdlib/bytes.c @@ -30,6 +30,31 @@ public Text_t Byte$hex(Byte_t byte, bool uppercase, bool prefix) { return text; } +typedef struct { + OptionalByte_t current, last; + Int8_t step; +} ByteRange_t; + +static OptionalByte_t _next_Byte(ByteRange_t *info) { + OptionalByte_t i = info->current; + if (!i.is_none) { + Byte_t next; bool overflow = __builtin_add_overflow(i.value, info->step, &next); + if (overflow || (!info->last.is_none && (info->step >= 0 ? next > info->last.value : next < info->last.value))) + info->current = (OptionalByte_t){.is_none=true}; + else + info->current = (OptionalByte_t){.value=next}; + } + return i; +} + +public CONSTFUNC Closure_t Byte$to(Byte_t first, Byte_t last, OptionalInt8_t step) { + ByteRange_t *range = GC_MALLOC(sizeof(ByteRange_t)); + range->current = (OptionalByte_t){.value=first}; + range->last = (OptionalByte_t){.value=last}; + range->step = step.is_none ? (last >= first ? 1 : -1) : step.value; + return (Closure_t){.fn=_next_Byte, .userdata=range}; +} + public PUREFUNC Byte_t Byte$from_int(Int_t i, bool truncate) { if unlikely (truncate && Int$compare_value(i, I_small(0xFF)) > 0) fail("This value is too large to convert to a byte without truncation: ", i); diff --git a/src/stdlib/bytes.h b/src/stdlib/bytes.h index ac1b61a3..f875e7cb 100644 --- a/src/stdlib/bytes.h +++ b/src/stdlib/bytes.h @@ -6,6 +6,7 @@ #include <stdint.h> #include "datatypes.h" +#include "integers.h" #include "stdlib.h" #include "types.h" #include "util.h" @@ -18,6 +19,7 @@ Byte_t Byte$from_int(Int_t i, bool truncate); Byte_t Byte$from_int64(int64_t i, bool truncate); Byte_t Byte$from_int32(int32_t i, bool truncate); Byte_t Byte$from_int16(int16_t i, bool truncate); +Closure_t Byte$to(Byte_t first, Byte_t last, OptionalInt8_t step); MACROLIKE Byte_t Byte$from_int8(int8_t i) { return (Byte_t)i; } MACROLIKE Byte_t Byte$from_bool(bool b) { return (Byte_t)b; } @@ -28,11 +30,4 @@ extern const TypeInfo_t Byte$info; Text_t Byte$hex(Byte_t byte, bool uppercase, bool prefix); -typedef struct { - Byte_t value; - bool has_value:1; -} OptionalByte_t; - -#define NONE_BYTE ((OptionalByte_t){.has_value=false}) - // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/datatypes.h b/src/stdlib/datatypes.h index 950c9457..77c09ddb 100644 --- a/src/stdlib/datatypes.h +++ b/src/stdlib/datatypes.h @@ -111,4 +111,12 @@ typedef struct { #define OptionalText_t Text_t #define OptionalClosure_t Closure_t +typedef struct { + Byte_t value; + bool is_none:1; +} OptionalByte_t; + +#define NONE_BYTE ((OptionalByte_t){.is_none=true}) + + // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 |
