- Added $kindof compile time function.

- Deprecated `@typekind` macro in favour of `$kindof`.
- Deprecated `@typeis` macro in favour of `$typeof(#foo) == int`.
This commit is contained in:
Christoffer Lerno
2025-08-27 20:38:12 +02:00
parent 7312c10b9e
commit 239d249f01
24 changed files with 169 additions and 150 deletions

View File

@@ -185,7 +185,7 @@ fn void Object.set_object(&self, String key, Object* new_object) @private
<*
@require self.allocator != null : "This object is not properly initialized, was it really created using 'new'"
@require !@typeis(value, void*) ||| value == null : "void pointers cannot be stored in an object"
@require $typeof(value) != void* ||| value == null : "void pointers cannot be stored in an object"
*>
macro Object* Object.object_from_value(&self, value) @private
{

View File

@@ -6,7 +6,7 @@ import std::collections::pair, std::io;
@param [in] array
@param [in] element
@require @typekind(array) == SLICE || @typekind(array) == ARRAY
@require $kindof(array) == SLICE || $kindof(array) == ARRAY
@require @typematch(array[0], element) : "array and element must have the same type"
*>
macro bool contains(array, element)
@@ -24,7 +24,7 @@ macro bool contains(array, element)
@param [in] array
@param [in] element
@require @typekind(array) == SLICE || @typekind(array) == ARRAY
@require $kindof(array) == SLICE || $kindof(array) == ARRAY
@require @typematch(array[0], element) : "array and element must have the same type"
@return "the first index of the element"
@return? NOT_FOUND
@@ -48,9 +48,9 @@ macro index_of(array, element)
@param xlen : "The length of the slice in x, defaults to the length of the array"
@param ylen : "The length of the slice in y, defaults to the length of the array"
@return "A Slice2d from the array"
@require @typekind(array_ptr) == POINTER
@require @typekind(*array_ptr) == VECTOR || @typekind(*array_ptr) == ARRAY
@require @typekind((*array_ptr)[0]) == VECTOR || @typekind((*array_ptr)[0]) == ARRAY
@require $kindof(array_ptr) == POINTER
@require $kindof(*array_ptr) == VECTOR || $kindof(*array_ptr) == ARRAY
@require $kindof((*array_ptr)[0]) == VECTOR || $kindof((*array_ptr)[0]) == ARRAY
*>
macro slice2d(array_ptr, x = 0, xlen = 0, y = 0, ylen = 0)
{
@@ -85,8 +85,8 @@ macro rindex_of(array, element)
@param [in] arr1
@param [in] arr2
@param [&inout] allocator : "The allocator to use, default is the heap allocator"
@require @typekind(arr1) == SLICE || @typekind(arr1) == ARRAY
@require @typekind(arr2) == SLICE || @typekind(arr2) == ARRAY
@require $kindof(arr1) == SLICE || $kindof(arr1) == ARRAY
@require $kindof(arr2) == SLICE || $kindof(arr2) == ARRAY
@require @typematch(arr1[0], arr2[0]) : "Arrays must have the same type"
@ensure result.len == arr1.len + arr2.len
*>
@@ -111,8 +111,8 @@ macro concat(Allocator allocator, arr1, arr2) @nodiscard
@param [in] arr1
@param [in] arr2
@require @typekind(arr1) == SLICE || @typekind(arr1) == ARRAY
@require @typekind(arr2) == SLICE || @typekind(arr2) == ARRAY
@require $kindof(arr1) == SLICE || $kindof(arr1) == ARRAY
@require $kindof(arr2) == SLICE || $kindof(arr2) == ARRAY
@require @typematch(arr1[0], arr2[0]) : "Arrays must have the same type"
@ensure return.len == arr1.len + arr2.len
*>
@@ -531,7 +531,7 @@ macro bool @is_valid_operation(#operation, #left, #right) @const
$switch:
$case @is_empty_macro_slot(#operation):
return true;
$case @typekind(#operation) != FUNC:
$case $kindof(#operation) != FUNC:
return false;
$default:
return $defined(#operation(#left[0], #right[0]));

View File

@@ -94,7 +94,7 @@ bitstruct UInt128LE : uint128 @littleendian
macro read(bytes, $Type)
{
char[] s;
$switch @typekind(bytes):
$switch $kindof(bytes):
$case POINTER:
s = (*bytes)[:$Type.sizeof];
$default:
@@ -110,7 +110,7 @@ macro read(bytes, $Type)
macro write(x, bytes, $Type)
{
char[] s;
$switch @typekind(bytes):
$switch $kindof(bytes):
$case POINTER:
s = (*bytes)[:$Type.sizeof];
$default:

View File

@@ -27,8 +27,8 @@ macro foo(a, #b = EMPTY_MACRO_SLOT)
const EmptySlot EMPTY_MACRO_SLOT @builtin = null;
typedef EmptySlot = void*;
macro @is_empty_macro_slot(#arg) @const @builtin => @typeis(#arg, EmptySlot);
macro @is_valid_macro_slot(#arg) @const @builtin => !@typeis(#arg, EmptySlot);
macro @is_empty_macro_slot(#arg) @const @builtin => $typeof(#arg) == EmptySlot;
macro @is_valid_macro_slot(#arg) @const @builtin => $typeof(#arg) != EmptySlot;
<*
Returns a random value at compile time.
@@ -99,7 +99,7 @@ macro usz @bitsizeof(#expr) @builtin @const => $sizeof(#expr) * 8u;
@param v : `the any to convert to the given type.`
@param $Type : `the type to convert to`
@return `The any.ptr converted to its type.`
@ensure @typeis(return, $Type*)
@ensure $typeof(return) == $Type*
@return? TYPE_MISMATCH
*>
macro anycast(any v, $Type) @builtin
@@ -124,12 +124,12 @@ macro typeid @typeid(#value) @const @builtin
return $typeof(#value).typeid;
}
macro TypeKind @typekind(#value) @const @builtin
macro TypeKind @typekind(#value) @const @builtin @deprecated("Use `$kindof(#value)`.")
{
return $typeof(#value).kindof;
return $kindof(#value);
}
macro bool @typeis(#value, $Type) @const @builtin
macro bool @typeis(#value, $Type) @const @builtin @deprecated("Use `$typeof(#value) == $Type` instead.")
{
return $typeof(#value).typeid == $Type.typeid;
}
@@ -285,7 +285,7 @@ macro any.as_inner(&self)
@param $Type : "the type to cast to"
@require $sizeof(expr) == $Type.sizeof : "Cannot bitcast between types of different size."
@ensure @typeis(return, $Type)
@ensure $typeof(return) == $Type*
*>
macro bitcast(expr, $Type) @builtin
{
@@ -302,7 +302,7 @@ macro bitcast(expr, $Type) @builtin
@param $Type : `The type of the enum`
@param [in] enum_name : `The name of the enum to search for`
@require $Type.kindof == ENUM : `Only enums may be used`
@ensure @typeis(return, $Type)
@ensure $typeof(return) == $Type*
@return? NOT_FOUND
*>
macro enum_by_name($Type, String enum_name) @builtin
@@ -320,7 +320,7 @@ macro enum_by_name($Type, String enum_name) @builtin
@require $Type.kindof == ENUM : `Only enums may be used`
@require $defined($Type.#value) : `Expected '#value' to match an enum associated value`
@require $defined($typeof(($Type){}.#value) v = value) : `Expected the value to match the type of the associated value`
@ensure @typeis(return, $Type)
@ensure $typeof(return) == $Type*
@return? NOT_FOUND
*>
macro @enum_from_value($Type, #value, value) @builtin @deprecated("Use Enum.lookup_field and Enum.lookup")
@@ -454,7 +454,7 @@ macro @clz($value) @builtin @const
Return the excuse in the Optional if it is Empty, otherwise
return a null fault.
@require @typekind(#expr) == OPTIONAL : `@catch expects an Optional value`
@require $kindof(#expr) == OPTIONAL : `@catch expects an Optional value`
*>
macro fault @catch(#expr) @builtin
{
@@ -466,7 +466,7 @@ macro fault @catch(#expr) @builtin
Check if an Optional expression holds a value or is empty, returning true
if it has a value.
@require @typekind(#expr) == OPTIONAL : `@ok expects an Optional value`
@require $kindof(#expr) == OPTIONAL : `@ok expects an Optional value`
*>
macro bool @ok(#expr) @builtin
{
@@ -609,7 +609,7 @@ macro uint char[].hash(char[] c) => (uint)a5hash::hash(c);
macro uint void*.hash(void* ptr) => @generic_hash(((ulong)(uptr)ptr));
<*
@require @typekind(array_ptr) == POINTER &&& @typekind(*array_ptr) == ARRAY
@require $kindof(array_ptr) == POINTER &&& $kindof(*array_ptr) == ARRAY
*>
macro uint hash_array(array_ptr) @local
{
@@ -623,7 +623,7 @@ macro uint hash_array(array_ptr) @local
}
<*
@require @typekind(vec) == VECTOR
@require $kindof(vec) == VECTOR
*>
macro uint hash_vec(vec) @local
{

View File

@@ -45,7 +45,7 @@ fn usz os_pagesize()
@param mask : "The mask for the load"
@param passthru : "The value to use for non masked values"
@require $defined(*ptr = passthru) : "Pointer and passthru must match"
@require @typekind(passthru) == VECTOR : "Expected passthru to be a vector"
@require $kindof(passthru) == VECTOR : "Expected passthru to be a vector"
@require passthru.len == mask.len : "Mask and passthru must have the same length"
@return "A vector with the loaded values where the mask is true, passthru where the mask is false"
@@ -64,7 +64,7 @@ macro masked_load(ptr, bool[<*>] mask, passthru)
@param $alignment : "The alignment to assume for the pointer"
@require $defined(*ptr = passthru) : "Pointer and passthru must match"
@require @typekind(passthru) == VECTOR : "Expected passthru to be a vector"
@require $kindof(passthru) == VECTOR : "Expected passthru to be a vector"
@require passthru.len == mask.len : "Mask and passthru must have the same length"
@require @constant_is_power_of_2($alignment) : "The alignment must be a power of two"
@@ -82,8 +82,8 @@ macro @masked_load_aligned(ptr, bool[<*>] mask, passthru, usz $alignment)
@param mask : "The mask for the load"
@param passthru : "The value to use for non masked values"
@require @typekind(ptrvec) == VECTOR : "Expected ptrvec to be a vector"
@require @typekind(passthru) == VECTOR : "Expected passthru to be a vector"
@require $kindof(ptrvec) == VECTOR : "Expected ptrvec to be a vector"
@require $kindof(passthru) == VECTOR : "Expected passthru to be a vector"
@require $defined(*ptrvec[0] = passthru[0]) : "Pointer and passthru must match"
@require passthru.len == mask.len : "Mask and passthru must have the same length"
@require mask.len == ptrvec.len : "Mask and ptrvec must have the same length"
@@ -104,8 +104,8 @@ macro gather(ptrvec, bool[<*>] mask, passthru)
@param passthru : "The value to use for non masked values"
@param $alignment : "The alignment to assume for the pointers"
@require @typekind(ptrvec) == VECTOR : "Expected ptrvec to be a vector"
@require @typekind(passthru) == VECTOR : "Expected passthru to be a vector"
@require $kindof(ptrvec) == VECTOR : "Expected ptrvec to be a vector"
@require $kindof(passthru) == VECTOR : "Expected passthru to be a vector"
@require $defined(*ptrvec[0] = passthru[0]) : "Pointer and passthru must match"
@require passthru.len == mask.len : "Mask and passthru must have the same length"
@require mask.len == ptrvec.len : "Mask and ptrvec must have the same length"
@@ -127,7 +127,7 @@ macro @gather_aligned(ptrvec, bool[<*>] mask, passthru, usz $alignment)
@param mask : "The mask for the store"
@require $defined(*ptr = value) : "Pointer and value must match"
@require @typekind(value) == VECTOR : "Expected value to be a vector"
@require $kindof(value) == VECTOR : "Expected value to be a vector"
@require value.len == mask.len : "Mask and value must have the same length"
*>
macro masked_store(ptr, value, bool[<*>] mask)
@@ -142,7 +142,7 @@ macro masked_store(ptr, value, bool[<*>] mask)
@param $alignment : "The alignment of the pointer"
@require $defined(*ptr = value) : "Pointer and value must match"
@require @typekind(value) == VECTOR : "Expected value to be a vector"
@require $kindof(value) == VECTOR : "Expected value to be a vector"
@require value.len == mask.len : "Mask and value must have the same length"
@require @constant_is_power_of_2($alignment) : "The alignment must be a power of two"
@@ -156,8 +156,8 @@ macro @masked_store_aligned(ptr, value, bool[<*>] mask, usz $alignment)
@param ptrvec : "The vector pointer containing the addresses to store to."
@param value : "The value to store masked"
@param mask : "The mask for the store"
@require @typekind(ptrvec) == VECTOR : "Expected ptrvec to be a vector"
@require @typekind(value) == VECTOR : "Expected value to be a vector"
@require $kindof(ptrvec) == VECTOR : "Expected ptrvec to be a vector"
@require $kindof(value) == VECTOR : "Expected value to be a vector"
@require $defined(*ptrvec[0] = value[0]) : "Pointer and value must match"
@require value.len == mask.len : "Mask and value must have the same length"
@require mask.len == ptrvec.len : "Mask and ptrvec must have the same length"
@@ -174,8 +174,8 @@ macro scatter(ptrvec, value, bool[<*>] mask)
@param mask : "The mask for the store"
@param $alignment : "The alignment of the load"
@require @typekind(ptrvec) == VECTOR : "Expected ptrvec to be a vector"
@require @typekind(value) == VECTOR : "Expected value to be a vector"
@require $kindof(ptrvec) == VECTOR : "Expected ptrvec to be a vector"
@require $kindof(value) == VECTOR : "Expected value to be a vector"
@require $defined(*ptrvec[0] = value[0]) : "Pointer and value must match"
@require value.len == mask.len : "Mask and value must have the same length"
@require mask.len == ptrvec.len : "Mask and ptrvec must have the same length"

View File

@@ -322,7 +322,7 @@ macro clone(Allocator allocator, value) @nodiscard
@param slice : "The slice to clone"
@return "A pointer to the cloned slice"
@require @typekind(slice) == SLICE || @typekind(slice) == ARRAY
@require $kindof(slice) == SLICE || $kindof(slice) == ARRAY
*>
macro clone_slice(Allocator allocator, slice) @nodiscard
{
@@ -365,7 +365,7 @@ macro void*? @aligned_alloc(#alloc_fn, usz bytes, usz alignment)
if (alignment < void*.alignof) alignment = void*.alignof;
usz header = AlignedBlock.sizeof + alignment;
usz alignsize = bytes + header;
$if @typekind(#alloc_fn(bytes)) == OPTIONAL:
$if $kindof(#alloc_fn(bytes)) == OPTIONAL:
void* data = #alloc_fn(alignsize)!;
$else
void* data = #alloc_fn(alignsize);
@@ -386,7 +386,7 @@ struct AlignedBlock
macro void? @aligned_free(#free_fn, void* old_pointer)
{
AlignedBlock* desc = (AlignedBlock*)old_pointer - 1;
$if @typekind(#free_fn(desc.start)) == OPTIONAL:
$if $kindof(#free_fn(desc.start)) == OPTIONAL:
#free_fn(desc.start)!;
$else
#free_fn(desc.start);
@@ -403,7 +403,7 @@ macro void*? @aligned_realloc(#calloc_fn, #free_fn, void* old_pointer, usz bytes
void* data_start = desc.start;
void* new_data = @aligned_alloc(#calloc_fn, bytes, alignment)!;
mem::copy(new_data, old_pointer, desc.len < bytes ? desc.len : bytes, 1, 1);
$if @typekind(#free_fn(data_start)) == OPTIONAL:
$if $kindof(#free_fn(data_start)) == OPTIONAL:
#free_fn(data_start)!;
$else
#free_fn(data_start);

View File

@@ -6,7 +6,7 @@
then free the pointer and the atomic variable assuming that they are allocated using the Allocator in the Ref.
@require !$defined(Type.dealloc) ||| $defined(Type.dealloc(&&(Type){})) : "'dealloc' must only take a pointer to the underlying type"
@require !$defined(Type.dealloc) ||| @typeis((Type){}.dealloc(), void) : "'dealloc' must return 'void'"
@require !$defined(Type.dealloc) ||| $typeof((Type){}.dealloc()) == void : "'dealloc' must return 'void'"
*>
module std::core::mem::ref { Type };
import std::thread, std::atomic;
@@ -113,7 +113,7 @@ macro retain(refcounted)
<*
@require $defined(RefCounted* c = refcounted) : "Expected a ref counted value"
@require !$defined(refcounted.dealloc()) ||| @typeis(refcounted.dealloc(), void)
@require !$defined(refcounted.dealloc()) ||| $typeof(refcounted.dealloc()) == void
: "Expected refcounted type to have a valid dealloc"
*>
macro void release(refcounted)

View File

@@ -27,7 +27,7 @@ macro bool is_struct_with_default_print($Type)
<*
Introspect a struct and print it to a formatter
@require @typekind(value) == STRUCT || @typekind(value) == BITSTRUCT : `This macro is only valid on macros`
@require $kindof(value) == STRUCT || $kindof(value) == BITSTRUCT : `This macro is only valid on macros`
*>
macro usz? struct_to_format(value, Formatter* f, bool $force_dump)
{

View File

@@ -98,14 +98,14 @@ macro String? treadline(stream = io::stdin())
*>
macro usz? readline_to_stream(out_stream, in_stream = io::stdin())
{
bool $is_stream = @typeis(in_stream, InStream);
bool $is_stream = $typeof(in_stream) == InStream;
$if $is_stream:
var func = &in_stream.read_byte;
char val = func((void*)in_stream)!;
$else
char val = in_stream.read_byte()!;
$endif
bool $is_out_stream = @typeis(out_stream, OutStream);
bool $is_out_stream = $typeof(out_stream) == OutStream;
$if $is_out_stream:
var out_func = &out_stream.write_byte;
$endif
@@ -215,7 +215,7 @@ macro usz? fprintn(out, x = "")
usz len = fprint(out, x)!;
out.write_byte('\n')!;
$switch:
$case @typeid(out) == OutStream.typeid:
$case $typeof(out) == OutStream:
if (&out.flush) out.flush()!;
$case $defined(out.flush):
out.flush()!;

View File

@@ -45,7 +45,7 @@ fn Path? tcwd() => cwd(tmem) @inline;
*>
macro void? chdir(path)
{
$if @typeis(path, String):
$if $typeof(path) == String:
@pool()
{
return os::native_chdir(temp(path));
@@ -59,7 +59,7 @@ fn Path? temp_directory(Allocator allocator) => os::native_temp_directory(alloca
fn void? delete(Path path) => os::native_remove(path.str_view()) @inline;
macro bool @is_pathlike(#path) => @typeis(#path, String) || @typeis(#path, Path);
macro bool @is_pathlike(#path) @const => $typeof(#path) == String ||| $typeof(#path) == Path;
macro bool is_separator(char c, PathEnv path_env = DEFAULT_ENV)
{
@@ -95,7 +95,7 @@ enum MkdirPermissions
*>
macro bool? mkdir(path, bool recursive = false, MkdirPermissions permissions = NORMAL)
{
$if @typeis(path, String):
$if $typeof(path) == String:
@pool() { return _mkdir(temp(path), recursive, permissions); };
$else
return _mkdir(path, recursive, permissions);
@@ -113,7 +113,7 @@ macro bool? mkdir(path, bool recursive = false, MkdirPermissions permissions = N
*>
macro bool? rmdir(path)
{
$if @typeis(path, String):
$if $typeof(path) == String:
@pool() { return _rmdir(temp(path)); };
$else
return _mkdir(path);

View File

@@ -197,7 +197,7 @@ const char[*] MAX_VARS @private = { [2] = 3, [4] = 5, [8] = 10 };
<*
@require @is_instream(stream)
@require @typekind(x_ptr) == POINTER && $typeof(x_ptr).inner.kindof.is_int()
@require $kindof(x_ptr) == POINTER && $typeof(x_ptr).inner.kindof.is_int()
*>
macro usz? read_varint(stream, x_ptr)
{
@@ -232,7 +232,7 @@ macro usz? read_varint(stream, x_ptr)
}
<*
@require @is_outstream(stream)
@require @typekind(x).is_int()
@require $kindof(x).is_int()
*>
macro usz? write_varint(stream, x)
{

View File

@@ -101,7 +101,7 @@ macro is_approx_rel(x, y, eps)
}
<*
@require values::@is_int(x) : `The input must be an integer`
@require $kindof(x).is_int() : `The input must be an integer`
*>
macro sign(x)
{
@@ -119,7 +119,7 @@ macro sign(x)
*>
macro atan2(x, y)
{
$if @typeis(x, float) && @typeis(y, float):
$if $typeof(x) == float &&& $typeof(y) == float:
return _atan2f(x, y);
$else
return _atan2(x, y);
@@ -128,16 +128,16 @@ macro atan2(x, y)
<*
@require values::@is_int(x) || values::@is_float(x) : "Expected an integer or floating point value"
@require @typekind(sinp) == POINTER : "Expected sinp to be a pointer"
@require $kindof(sinp) == POINTER : "Expected sinp to be a pointer"
@require @typematch(sinp, cosp) : "Expected sinp and cosp to have the same type"
@require $defined(*sinp = x) : "Expected x and sinp/cosp to have the same type"
@require $defined(*sinp = x) : "Expected x and *sinp/*cosp to have the same type"
*>
macro sincos_ref(x, sinp, cosp)
{
$if @typeis(sinp, float*.typeid):
return _sincosf(x, sinp, cosp);
$if $typeof(sinp) == float*:
_sincosf(x, sinp, cosp);
$else
return _sincos(x, sinp, cosp);
_sincos(x, sinp, cosp);
$endif
}
@@ -149,7 +149,7 @@ macro sincos_ref(x, sinp, cosp)
*>
macro sincos(x)
{
$if @typeis(x, float):
$if $typeof(x) == float:
float[<2>] v @noinit;
_sincosf(x, &v[0], &v[1]);
$else
@@ -164,7 +164,7 @@ macro sincos(x)
*>
macro atan(x)
{
$if @typeis(x, float):
$if $typeof(x) == float:
return _atanf(x);
$else
return _atan(x);
@@ -176,7 +176,7 @@ macro atan(x)
*>
macro atanh(x)
{
$if @typeis(x, float):
$if $typeof(x) == float:
return _atanhf(x);
$else
return _atanh(x);
@@ -188,7 +188,7 @@ macro atanh(x)
*>
macro acos(x)
{
$if @typeis(x, float):
$if $typeof(x) == float:
return _acosf(x);
$else
return _acos(x);
@@ -200,7 +200,7 @@ macro acos(x)
*>
macro acosh(x)
{
$if @typeis(x, float):
$if $typeof(x) == float:
return _acoshf(x);
$else
return _acosh(x);
@@ -212,7 +212,7 @@ macro acosh(x)
*>
macro asin(x)
{
$if @typeis(x, float):
$if $typeof(x) == float:
return _asinf(x);
$else
return _asin(x);
@@ -224,7 +224,7 @@ macro asin(x)
*>
macro asinh(x)
{
$if @typeis(x, float):
$if $typeof(x) == float:
return _asinhf(x);
$else
return _asinh(x);
@@ -239,7 +239,7 @@ macro ceil(x) => $$ceil(x);
<*
Ceil for compile time evaluation.
@require @typeis($input, double) || @typeis($input, float) : "Only float and double may be used"
@require $kindof($input) == FLOAT : "Only float and double may be used"
*>
macro @ceil($input) @const => $$ceil($input);

View File

@@ -8,7 +8,7 @@ Sort list using the quick sort algorithm.
*>
macro insertionsort(list, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @builtin @safemacro
{
$if @typekind(list) == POINTER &&& (@typekind(*list) == ARRAY || @typekind(*list) == VECTOR):
$if $kindof(list) == POINTER &&& ($kindof(*list) == ARRAY || $kindof(*list) == VECTOR):
$typeof((*list)[0])[] list2 = list;
is::isort{$typeof(list2), $typeof(cmp), $typeof(context)}(list2, 0, list.len, cmp, context);
$else

View File

@@ -9,7 +9,7 @@ Sort list using the quick sort algorithm.
*>
macro quicksort(list, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @builtin
{
$if @typekind(list) == POINTER &&& (@typekind(*list) == ARRAY || @typekind(*list) == VECTOR):
$if $kindof(list) == POINTER &&& ($kindof(*list) == ARRAY || $kindof(*list) == VECTOR):
$typeof((*list)[0])[] list2 = list;
qs::qsort{$typeof(list2), $typeof(cmp), $typeof(context)}(list2, 0, (isz)list.len - 1, cmp, context);
$else

View File

@@ -16,7 +16,7 @@ macro bool @is_sortable(#list)
return false;
$case !$defined(#list.len):
return false;
$case @typekind(#list) == VECTOR || @typekind(#list) == ARRAY:
$case $kindof(#list) == VECTOR || $kindof(#list) == ARRAY:
return false;
$case $defined(&#list[0]) &&& !types::is_same($typeof(&#list[0]), $typeof(#list[0])*):
return false;
@@ -49,7 +49,7 @@ macro bool @is_cmp_key_fn(#key_fn, #list)
{
$switch:
$case @is_empty_macro_slot(#key_fn): return true;
$case $typeof(#key_fn).kindof != FUNC: return false;
$case $kindof(#key_fn) != FUNC: return false;
$case $typeof(#key_fn).returns.kindof != UNSIGNED_INT: return false;
$case $defined(#key_fn(#list[0])): return true;
$case $defined(#key_fn(&&(#list[0]))): return true;