diff --git a/lib/std/core/builtin.c3 b/lib/std/core/builtin.c3 index 2500c2fad..b1515e8af 100644 --- a/lib/std/core/builtin.c3 +++ b/lib/std/core/builtin.c3 @@ -93,6 +93,21 @@ macro usz bitsizeof($Type) @builtin @const => $Type.sizeof * 8u; macro usz @bitsizeof(#expr) @builtin @const => $sizeof(#expr) * 8u; +<* + Compile-time check for whether a set of constants contains a certain expression. + + @param #needle : "The expression whose value should be located." +*> +macro bool @in(#needle, ...) @builtin @const +{ + $for var $x = 0; $x < $vacount; $x++: + $assert $defined(#needle == $vaconst[$x]) + : "Index %s: types '%s' (needle) and '%s' are not equatable", $x, $typeof(#needle), $typeof($vaconst[$x]); + $if #needle == $vaconst[$x]: return true; $endif + $endfor + return false; +} + <* Convert an `any` type to a type, returning an failure if there is a type mismatch. diff --git a/releasenotes.md b/releasenotes.md index 7f0cca371..9c8bba03b 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -27,6 +27,7 @@ ### Stdlib changes - Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads. +- Add `@in` compile-time macro to check for a value in a variable list of constants. #2662 - Return of Thread/Mutex/CondVar `destroy()` is now "@maydiscard" and should be ignored. It will return void in 0.8.0. - Return of Mutex `unlock()` and `lock()` is now "@maydiscard" and should be ignored. They will return void in 0.8.0. - Return of ConditionVariable `signal()` `broadcast()` and `wait()` are now "@maydiscard". They will return void in 0.8.0. diff --git a/test/unit/stdlib/core/builtintests.c3 b/test/unit/stdlib/core/builtintests.c3 index a565f2c74..601843aaa 100644 --- a/test/unit/stdlib/core/builtintests.c3 +++ b/test/unit/stdlib/core/builtintests.c3 @@ -224,3 +224,13 @@ fn void test_ct_min_max() assert(@max(0, 0, 1.234, 1.2345, 0.2) == 1.2345); assert(@max(127.9999999, 45 + 46, bitsizeof(uint128)) == 128); } + +const usz[] MY_OK_VALUES = { 128, 256, 384, 512 }; +fn void test_in() +{ + $assert @in(384, ...MY_OK_VALUES); + $assert !@in(123, ...MY_OK_VALUES); + $assert @in(384, 128, 256, 384, 512); + $assert @in("love", "joy", "cheer", "love", "friend"); + $assert !@in("hate", "joy", "cheer", "love", "friend"); +}