diff --git a/lib/std/core/builtin.c3 b/lib/std/core/builtin.c3 index 8016bad12..79b82a19b 100644 --- a/lib/std/core/builtin.c3 +++ b/lib/std/core/builtin.c3 @@ -120,17 +120,37 @@ macro enum_by_name($Type, String enum_name) @builtin return SearchResult.MISSING!; } -macro bool @expect_true(bool value) @builtin => $$expect(value, true); -macro bool @expect_false(bool value) @builtin => $$expect(value, false); +macro bool @likely(bool value, $probability = 1.0) @builtin +{ + $if ($probability == 1.0): + return $$expect(value, true); + $else: + return $$expect_with_probability(value, true, $probability); + $endif; +} + +macro bool @unlikely(bool value, $probability = 1.0) @builtin +{ + $if ($probability == 1.0): + return $$expect(value, false); + $else: + return $$expect_with_probability(value, false, $probability); + $endif; +} /** - * @require values::@is_int(value) + * @require values::@is_int(value) || values::@is_bool(value) * @checked $typeof(value) a = expected **/ -macro @expect(value, expected) @builtin +macro @expect(value, expected, $probability = 1.0) @builtin { + $if ($probability == 1.0): return $$expect(value, ($typeof(value))expected); + $else: + return $$expect_with_probability(value, expected, $probability); + $endif; } + /** * Locality for prefetch, levels 0 - 3, corresponding * to "extremely local" to "no locality" diff --git a/lib/std/core/types.c3 b/lib/std/core/types.c3 index 0f866f9b9..682c80a11 100644 --- a/lib/std/core/types.c3 +++ b/lib/std/core/types.c3 @@ -123,6 +123,7 @@ macro bool is_subarray_convertable($Type) $endswitch; } +macro bool is_bool($Type) => $Type.kindof == TypeKind.BOOL; macro bool is_int($Type) => $Type.kindof == TypeKind.SIGNED_INT || $Type.kindof == TypeKind.UNSIGNED_INT; macro bool is_intlike($Type) diff --git a/lib/std/core/values.c3 b/lib/std/core/values.c3 index dadf46dcb..021050ef0 100644 --- a/lib/std/core/values.c3 +++ b/lib/std/core/values.c3 @@ -2,6 +2,7 @@ module std::core::values; macro TypeKind @typekind(#value) @builtin => $typeof(#value).kindof; macro bool @typeis(#value, $Type) @builtin => $typeof(#value).typeid == $Type.typeid; +macro bool @is_bool(#value) => types::is_bool($typeof(#value)); macro bool @is_int(#value) => types::is_int($typeof(#value)); macro bool @convertable_to(#a, #b) => $checks($typeof(#b) x = #a); macro bool @is_floatlike(#value) => types::is_floatlike($typeof(#value)); diff --git a/test/unit/stdlib/macros/core_builtins.c3 b/test/unit/stdlib/macros/core_builtins.c3 new file mode 100644 index 000000000..a67a1e897 --- /dev/null +++ b/test/unit/stdlib/macros/core_builtins.c3 @@ -0,0 +1,23 @@ +module core_builtin_tests; + +fn void! test_likely() @test +{ + assert(@likely(2 > 1)); + assert(@likely(2 > 1, 0.5)); +} + +fn void! test_unlikely() @test +{ + assert(@unlikely(2 < 1)); + assert(@unlikely(2 < 1, 0.5)); +} + +fn void! test_expect() @test +{ + assert(@expect(2 > 1, true)); + assert(@expect(2 < 1, false)); + + assert(@expect(2 > 1, true, 0.5)); + assert(@expect(2 < 1, false, 0.5)); +} +