From 6ab7198f2f2aff6b2941bfc6d22f80e2a7576df7 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 21 Aug 2025 02:57:17 +0200 Subject: [PATCH] - Added `AsciiCharset` for matching ascii characters quickly. - Added `String.trim_charset`. --- lib/std/core/ascii.c3 | 24 ++++++++++++++++++++++++ lib/std/core/string.c3 | 20 ++++++++++++++++++-- releasenotes.md | 2 ++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/std/core/ascii.c3 b/lib/std/core/ascii.c3 index 68db253af..c67fc1620 100644 --- a/lib/std/core/ascii.c3 +++ b/lib/std/core/ascii.c3 @@ -112,3 +112,27 @@ const char[256] HEX_VALUE = { const char[256] TO_UPPER @private = { ['a'..'z'] = 'a' - 'A' }; const char[256] TO_LOWER @private = { ['A'..'Z'] = 'a' - 'A' }; +typedef AsciiCharset = uint128; + +macro AsciiCharset @create_set(String $string) @const +{ + AsciiCharset $set; + $foreach $c : $string: + $set |= 1ULL << $c; + $endforeach + return $set; +} + +fn AsciiCharset create_set(String string) +{ + AsciiCharset set; + foreach (c : string) set |= (AsciiCharset)1ULL << c; + return set; +} + +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"); + + diff --git a/lib/std/core/string.c3 b/lib/std/core/string.c3 index 4724c5569..bb309e2c4 100644 --- a/lib/std/core/string.c3 +++ b/lib/std/core/string.c3 @@ -1,6 +1,5 @@ module std::core::string; -import std::io; -import std::core::mem::allocator; +import std::io, std::ascii; typedef String @if(!$defined(String)) = inline char[]; @@ -219,6 +218,23 @@ fn String String.trim(self, String to_trim = "\t\n\r ") return self.trim_left(to_trim).trim_right(to_trim); } +<* + Remove characters from the front and end of a string. + + @param [in] self : `The string to trim` + @param to_trim : `The set of characters to trim, defaults to whitespace` + @pure + @return `a substring of the string passed in` +*> +fn String String.trim_charset(self, AsciiCharset to_trim = ascii::WHITESPACE_SET) +{ + usz start = 0; + usz len = self.len; + while (start < len && to_trim.contains(self[start])) start++; + while (len > start && to_trim.contains(self[len - 1])) len--; + return self[start..len - 1]; +} + <* Remove characters from the front of a string. diff --git a/releasenotes.md b/releasenotes.md index e58c39bd7..7c21e3bfd 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -72,6 +72,8 @@ - Added `HashSet.values` and `String.contains_char` #2386 - Added `&[]` overload to HashMap. - Deprecated `PollSubscribes` and `PollEvents` in favour of `PollSubscribe` and `PollEvent` and made them const enums. +- Added `AsciiCharset` for matching ascii characters quickly. +- Added `String.trim_charset`. ## 0.7.4 Change list