// Copyright (c) 2021-2024 Christoffer Lerno and contributors. All rights reserved. // Use of this source code is governed by the MIT license // a copy of which can be found in the LICENSE_STDLIB file. module std::core::builtin; <* @require types::@comparable_value(a) && types::@comparable_value(b) *> macro less(a, b) @builtin { $switch: $case $defined(a.less): return a.less(b); $case $defined(a.compare_to): return a.compare_to(b) < 0; $default: return a < b; $endswitch } <* @require types::@comparable_value(a) && types::@comparable_value(b) *> macro less_eq(a, b) @builtin { $switch: $case $defined(a.less): return !b.less(a); $case $defined(a.compare_to): return a.compare_to(b) <= 0; $default: return a <= b; $endswitch } <* @require types::@comparable_value(a) && types::@comparable_value(b) *> macro greater(a, b) @builtin { $switch: $case $defined(a.less): return b.less(a); $case $defined(a.compare_to): return a.compare_to(b) > 0; $default: return a > b; $endswitch } <* @require types::@comparable_value(a) && types::@comparable_value(b) *> macro int compare_to(a, b) @builtin { $switch: $case $defined(a.compare_to): return a.compare_to(b); $case $defined(a.less): return (int)b.less(a) - (int)a.less(b); $default: return (int)(a > b) - (int)(a < b); $endswitch } <* @require types::@comparable_value(a) && types::@comparable_value(b) *> macro greater_eq(a, b) @builtin { $switch: $case $defined(a.less): return !a.less(b); $case $defined(a.compare_to): return a.compare_to(b) >= 0; $default: return a >= b; $endswitch } <* @require types::@equatable_value(a) && types::@equatable_value(b) : `values must be equatable` *> macro bool equals(a, b) @builtin { $switch: $case $defined(a.equals, a.equals(b)): return a.equals(b); $case $defined(a.compare_to, a.compare_to(b)): return a.compare_to(b) == 0; $case $defined(a.less): return !a.less(b) && !b.less(a); $default: return a == b; $endswitch } macro min(x, ...) @builtin { $if $vacount == 1: return less(x, $vaarg[0]) ? x : $vaarg[0]; $else var result = x; $for var $i = 0; $i < $vacount; $i++: if (less($vaarg[$i], result)) { result = $vaarg[$i]; } $endfor return result; $endif } macro max(x, ...) @builtin { $if $vacount == 1: return greater(x, $vaarg[0]) ? x : $vaarg[0]; $else var result = x; $for var $i = 0; $i < $vacount; $i++: if (greater($vaarg[$i], result)) { result = $vaarg[$i]; } $endfor return result; $endif } <* @require types::is_numerical($typeof($a)) *> macro @max($a, ...) @builtin @const { $if $vacount == 1: return $a > $vaconst[0] ? $a : $vaconst[0]; $else var $result = $a; $for var $x = 0; $x < $vacount; ++$x: $if $vaconst[$x] > $result: $result = $vaconst[$x]; $endif $endfor return $result; $endif } <* @require types::is_numerical($typeof($a)) *> macro @min($a, ...) @builtin @const { $if $vacount == 1: return $a < $vaconst[0] ? $a : $vaconst[0]; $else var $result = $a; $for var $x = 0; $x < $vacount; ++$x: $if $vaconst[$x] < $result: $result = $vaconst[$x]; $endif $endfor return $result; $endif }