From 3f7a547d8afc3907918137627ec15a80b9e4c4db Mon Sep 17 00:00:00 2001 From: Zack Puhl Date: Thu, 15 Jan 2026 15:39:48 -0500 Subject: [PATCH] Merge AsciiCharset CT/non-CT Functions (#2688) * Merge AsciiCharset CT/non-CT Functions * release notes * incorporate helpful review feedback * re-separate 'create_set' and 'contains' but keep 'combine_sets'; update tests * tabs (annoying IDE) * Restored old code verbatim for smaller diff. Split combine_sets into easier to macro/function for runtime / macro version, this also allows for more easy type checks. --------- Co-authored-by: Christoffer Lerno --- lib/std/core/ascii.c3 | 22 +++++++++++++++-- releasenotes.md | 1 + test/unit/stdlib/core/ascii.c3 | 44 ++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/lib/std/core/ascii.c3 b/lib/std/core/ascii.c3 index c67fc1620..533d33e6a 100644 --- a/lib/std/core/ascii.c3 +++ b/lib/std/core/ascii.c3 @@ -130,9 +130,27 @@ fn AsciiCharset create_set(String string) return set; } +macro bool AsciiCharset.@contains($set, char $c) @const => !!($c < 128) & !!($set & (AsciiCharset)(1ULL << $c)); + +macro AsciiCharset @combine_sets(AsciiCharset $first, AsciiCharset... $sets) @const +{ + var $res = $first; + $foreach $c : $sets: + $res |= $c; + $endforeach + return $res; +} +fn AsciiCharset combine_sets(AsciiCharset first, AsciiCharset... sets) +{ + foreach (c : sets) first |= c; + return first; +} + macro bool AsciiCharset.contains(set, char c) => !!(c < 128) & !!(set & (AsciiCharset)(1ULL << c)); const AsciiCharset WHITESPACE_SET = @create_set("\t\n\v\f\r "); const AsciiCharset NUMBER_SET = @create_set("0123456789"); - - +const AsciiCharset ALPHA_UPPER_SET = @create_set("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); +const AsciiCharset ALPHA_LOWER_SET = @create_set("abcdefghijklmnopqrstuvwxyz"); +const AsciiCharset ALPHA_SET = @combine_sets(ALPHA_UPPER_SET, ALPHA_LOWER_SET); +const AsciiCharset ALPHANUMERIC_SET = @combine_sets(ALPHA_SET, NUMBER_SET); diff --git a/releasenotes.md b/releasenotes.md index d33eef73b..152f82523 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -84,6 +84,7 @@ - Added `DString.append_bytes`. - Add `streebog` (aka "GOST-12") hashing with 256-bit and 512-bit outputs. #2659 - Add unit tests for HMAC 256 based on RFC 4231. #2743 +- Add extra `AsciiCharset` constants and combine its related compile-time/runtime macros. #2688 ## 0.7.8 Change list diff --git a/test/unit/stdlib/core/ascii.c3 b/test/unit/stdlib/core/ascii.c3 index 39f705889..2da6c784e 100644 --- a/test/unit/stdlib/core/ascii.c3 +++ b/test/unit/stdlib/core/ascii.c3 @@ -15,7 +15,7 @@ fn void test_all() if (c.is_bdigit()) check.updatec(8); if (c.is_odigit()) check.updatec(16); if (c.is_xdigit()) check.updatec(16); - if (c.is_digit()) check.updatec(32); + if (c.is_digit()) check.updatec(32); if (c.is_graph()) check.updatec(64); check.updatec(128); if (c.is_punct()) check.updatec(1); @@ -25,4 +25,44 @@ fn void test_all() check.updatec(c.to_lower()); } test::eq(check.final(), 7327699757963224526UL); -} \ No newline at end of file +} + +const AsciiCharset ALPHANUMERIC_WHITESPACE + = @combine_sets(ALPHA_UPPER_SET, ALPHA_LOWER_SET, NUMBER_SET, WHITESPACE_SET); + +fn void asciicharset_contains() +{ + $assert !ALPHANUMERIC_WHITESPACE.@contains('.'); + $assert ALPHANUMERIC_WHITESPACE.@contains('T'); + $assert ALPHANUMERIC_WHITESPACE.@contains('t'); + $assert ALPHANUMERIC_WHITESPACE.@contains('8'); + $assert ALPHANUMERIC_WHITESPACE.@contains(' '); + + test::@check(!ALPHANUMERIC_WHITESPACE.contains('.')); + test::@check(ALPHANUMERIC_WHITESPACE.contains('T')); + test::@check(ALPHANUMERIC_WHITESPACE.contains('t')); + test::@check(ALPHANUMERIC_WHITESPACE.contains('8')); + test::@check(ALPHANUMERIC_WHITESPACE.contains(' ')); +} + +fn void asciicharset_create_set() +{ + var $s = @create_set("abc"); + $foreach $c : "abc": $assert $s.@contains($c); $endforeach + + AsciiCharset xyz = create_set("xyz"); + foreach (c : "xyz") test::@check(xyz.contains(c)); +} + +fn void asciicharset_combine_sets() +{ + var $a_set = @combine_sets(@create_set("123"), @create_set("89"), @create_set("!@#$"), @create_set("something")); + $foreach $c : "something@123!": $assert $a_set.@contains($c); $endforeach + + AsciiCharset a_set = combine_sets(create_set("123"), create_set("89"), create_set("!@#$"), create_set("something")); + foreach (c : "something@123!") test::@check(a_set.contains(c)); + + // Mixture of runtime and compile-time sets. + AsciiCharset mixed_set = combine_sets($a_set, a_set, @create_set("456")); + foreach (c : "something@123!456") test::@check(mixed_set.contains(c)); +}