mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Revert 0.7.6 code for 0.7.5 re-release
This commit is contained in:
@@ -58,7 +58,7 @@ fn CInt __atomic_compare_exchange(CInt size, any ptr, any expected, any desired,
|
||||
nextcase;
|
||||
$endif
|
||||
default:
|
||||
unreachable("Unsupported size (%d) for atomic_compare_exchange", size);
|
||||
unreachable("Unsuported size (%d) for atomic_compare_exchange", size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,10 @@
|
||||
// Use of self source code is governed by the MIT license
|
||||
// a copy of which can be found in the LICENSE_STDLIB file.
|
||||
module std::collections::anylist;
|
||||
import std::collections::interfacelist;
|
||||
import std::io,std::math;
|
||||
|
||||
alias AnyPredicate = InterfacePredicate {any};
|
||||
alias AnyTest = InterfaceTest {any};
|
||||
alias AnyPredicate = fn bool(any value);
|
||||
alias AnyTest = fn bool(any type, any context);
|
||||
|
||||
<*
|
||||
The AnyList contains a heterogenous set of types. Anything placed in the
|
||||
@@ -18,7 +18,282 @@ alias AnyTest = InterfaceTest {any};
|
||||
If we're not doing pop, then things are easier, since we can just hand over
|
||||
the existing any.
|
||||
*>
|
||||
typedef AnyList = inline InterfaceList {any};
|
||||
struct AnyList (Printable)
|
||||
{
|
||||
usz size;
|
||||
usz capacity;
|
||||
Allocator allocator;
|
||||
any* entries;
|
||||
}
|
||||
|
||||
|
||||
<*
|
||||
Initialize the list. If not initialized then it will use the temp allocator
|
||||
when something is pushed to it.
|
||||
|
||||
@param [&inout] allocator : "The allocator to use"
|
||||
@param initial_capacity : "The initial capacity to reserve, defaults to 16"
|
||||
*>
|
||||
fn AnyList* AnyList.init(&self, Allocator allocator, usz initial_capacity = 16)
|
||||
{
|
||||
self.allocator = allocator;
|
||||
self.size = 0;
|
||||
if (initial_capacity > 0)
|
||||
{
|
||||
initial_capacity = math::next_power_of_2(initial_capacity);
|
||||
self.entries = allocator::alloc_array(allocator, any, initial_capacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
self.entries = null;
|
||||
}
|
||||
self.capacity = initial_capacity;
|
||||
return self;
|
||||
}
|
||||
|
||||
<*
|
||||
Initialize the list using the temp allocator.
|
||||
|
||||
@param initial_capacity : "The initial capacity to reserve"
|
||||
*>
|
||||
fn AnyList* AnyList.tinit(&self, usz initial_capacity = 16)
|
||||
{
|
||||
return self.init(tmem, initial_capacity) @inline;
|
||||
}
|
||||
|
||||
fn bool AnyList.is_initialized(&self) @inline => self.allocator != null;
|
||||
|
||||
<*
|
||||
Push an element on the list by cloning it.
|
||||
*>
|
||||
macro void AnyList.push(&self, element)
|
||||
{
|
||||
if (!self.allocator) self.allocator = tmem;
|
||||
self._append(allocator::clone(self.allocator, element));
|
||||
}
|
||||
|
||||
<*
|
||||
Free a retained element removed using *_retained.
|
||||
*>
|
||||
fn void AnyList.free_element(&self, any element) @inline
|
||||
{
|
||||
allocator::free(self.allocator, element.ptr);
|
||||
}
|
||||
|
||||
<*
|
||||
Pop a value who's type is known. If the type is incorrect, this
|
||||
will still pop the element.
|
||||
|
||||
@param $Type : "The type we assume the value has"
|
||||
@return "The last value as the type given"
|
||||
@return? TYPE_MISMATCH, NO_MORE_ELEMENT
|
||||
*>
|
||||
macro AnyList.pop(&self, $Type)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
defer self.free_element(self.entries[self.size]);
|
||||
return *anycast(self.entries[--self.size], $Type);
|
||||
}
|
||||
|
||||
<*
|
||||
Copy the last value, pop it and return the copy of it.
|
||||
|
||||
@param [&inout] allocator : "The allocator to use for copying"
|
||||
@return "A copy of the last value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn any? AnyList.copy_pop(&self, Allocator allocator)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
defer self.free_element(self.entries[self.size]);
|
||||
return allocator::clone_any(allocator, self.entries[--self.size]);
|
||||
}
|
||||
|
||||
|
||||
<*
|
||||
Copy the last value, pop it and return the copy of it.
|
||||
|
||||
@return "A temp copy of the last value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn any? AnyList.tcopy_pop(&self) => self.copy_pop(tmem);
|
||||
|
||||
|
||||
<*
|
||||
Pop the last value. It must later be released using `list.free_element()`.
|
||||
|
||||
@return "The last value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn any? AnyList.pop_retained(&self)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
return self.entries[--self.size];
|
||||
}
|
||||
|
||||
<*
|
||||
Remove all elements in the list.
|
||||
*>
|
||||
fn void AnyList.clear(&self)
|
||||
{
|
||||
for (usz i = 0; i < self.size; i++)
|
||||
{
|
||||
self.free_element(self.entries[i]);
|
||||
}
|
||||
self.size = 0;
|
||||
}
|
||||
|
||||
<*
|
||||
Pop a value who's type is known. If the type is incorrect, this
|
||||
will still pop the element.
|
||||
|
||||
@param $Type : "The type we assume the value has"
|
||||
@return "The first value as the type given"
|
||||
@return? TYPE_MISMATCH, NO_MORE_ELEMENT
|
||||
*>
|
||||
macro AnyList.pop_first(&self, $Type)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
defer self.remove_at(0);
|
||||
return *anycast(self.entries[0], $Type);
|
||||
}
|
||||
|
||||
<*
|
||||
Pop the first value. It must later be released using `list.free_element()`.
|
||||
|
||||
@return "The first value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn any? AnyList.pop_first_retained(&self)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
defer self.remove_at(0);
|
||||
return self.entries[0];
|
||||
}
|
||||
|
||||
|
||||
<*
|
||||
Copy the first value, pop it and return the copy of it.
|
||||
|
||||
@param [&inout] allocator : "The allocator to use for copying"
|
||||
@return "A copy of the first value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn any? AnyList.copy_pop_first(&self, Allocator allocator)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
defer self.free_element(self.entries[self.size]);
|
||||
defer self.remove_at(0);
|
||||
return allocator::clone_any(allocator, self.entries[0]);
|
||||
}
|
||||
|
||||
<*
|
||||
Copy the first value, pop it and return the temp copy of it.
|
||||
|
||||
@return "A temp copy of the first value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn any? AnyList.tcopy_pop_first(&self) => self.copy_pop_first(tmem);
|
||||
|
||||
<*
|
||||
Remove the element at the particular index.
|
||||
|
||||
@param index : "The index of the element to remove"
|
||||
@require index < self.size
|
||||
*>
|
||||
fn void AnyList.remove_at(&self, usz index)
|
||||
{
|
||||
if (!--self.size || index == self.size) return;
|
||||
self.free_element(self.entries[index]);
|
||||
self.entries[index .. self.size - 1] = self.entries[index + 1 .. self.size];
|
||||
}
|
||||
|
||||
<*
|
||||
Add all the elements in another AnyList.
|
||||
|
||||
@param [&in] other_list : "The list to add"
|
||||
*>
|
||||
fn void AnyList.add_all(&self, AnyList* other_list)
|
||||
{
|
||||
if (!other_list.size) return;
|
||||
self.reserve(other_list.size);
|
||||
foreach (value : other_list)
|
||||
{
|
||||
self.entries[self.size++] = allocator::clone_any(self.allocator, value);
|
||||
}
|
||||
}
|
||||
|
||||
<*
|
||||
Reverse the order of the elements in the list.
|
||||
*>
|
||||
fn void AnyList.reverse(&self)
|
||||
{
|
||||
if (self.size < 2) return;
|
||||
usz half = self.size / 2U;
|
||||
usz end = self.size - 1;
|
||||
for (usz i = 0; i < half; i++)
|
||||
{
|
||||
self.swap(i, end - i);
|
||||
}
|
||||
}
|
||||
|
||||
<*
|
||||
Return a view of the data as a slice.
|
||||
|
||||
@return "The slice view"
|
||||
*>
|
||||
fn any[] AnyList.array_view(&self)
|
||||
{
|
||||
return self.entries[:self.size];
|
||||
}
|
||||
|
||||
<*
|
||||
Push an element to the front of the list.
|
||||
|
||||
@param value : "The value to push to the list"
|
||||
*>
|
||||
macro void AnyList.push_front(&self, value)
|
||||
{
|
||||
self.insert_at(0, value);
|
||||
}
|
||||
|
||||
<*
|
||||
Insert an element at a particular index.
|
||||
|
||||
@param index : "the index where the element should be inserted"
|
||||
@param type : "the value to insert"
|
||||
@require index <= self.size : "The index is out of bounds"
|
||||
*>
|
||||
macro void AnyList.insert_at(&self, usz index, type)
|
||||
{
|
||||
if (index == self.size)
|
||||
{
|
||||
self.push(type);
|
||||
return;
|
||||
}
|
||||
any value = allocator::copy(self.allocator, type);
|
||||
self._insert_at(self, index, value);
|
||||
}
|
||||
|
||||
<*
|
||||
Remove the last element in the list. The list may not be empty.
|
||||
|
||||
@require self.size > 0 : "The list was already empty"
|
||||
*>
|
||||
fn void AnyList.remove_last(&self)
|
||||
{
|
||||
self.free_element(self.entries[--self.size]);
|
||||
}
|
||||
|
||||
<*
|
||||
Remove the first element in the list, the list may not be empty.
|
||||
|
||||
@require self.size > 0
|
||||
*>
|
||||
fn void AnyList.remove_first(&self)
|
||||
{
|
||||
self.remove_at(0);
|
||||
}
|
||||
|
||||
<*
|
||||
Return the first element by value, assuming it is the given type.
|
||||
@@ -38,7 +313,10 @@ macro AnyList.first(&self, $Type)
|
||||
@return "The first element"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn any? AnyList.first_any(&self) @inline => InterfaceList {any}.first(self);
|
||||
fn any? AnyList.first_any(&self) @inline
|
||||
{
|
||||
return self.size ? self.entries[0] : NO_MORE_ELEMENT?;
|
||||
}
|
||||
|
||||
<*
|
||||
Return the last element by value, assuming it is the given type.
|
||||
@@ -58,36 +336,29 @@ macro AnyList.last(&self, $Type)
|
||||
@return "The last element"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn any? AnyList.last_any(&self) @inline => InterfaceList {any}.last(self);
|
||||
|
||||
<*
|
||||
Pop a value who's type is known. If the type is incorrect, this
|
||||
will still pop the element.
|
||||
|
||||
@param $Type : "The type we assume the value has"
|
||||
@return "The last value as the type given"
|
||||
@return? TYPE_MISMATCH, NO_MORE_ELEMENT
|
||||
*>
|
||||
macro AnyList.pop(&self, $Type)
|
||||
fn any? AnyList.last_any(&self) @inline
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
defer self.free_element(self.entries[self.size]);
|
||||
return *anycast(self.entries[--self.size], $Type);
|
||||
return self.size ? self.entries[self.size - 1] : NO_MORE_ELEMENT?;
|
||||
}
|
||||
|
||||
<*
|
||||
Pop a value who's type is known. If the type is incorrect, this
|
||||
will still pop the element.
|
||||
Return whether the list is empty.
|
||||
|
||||
@param $Type : "The type we assume the value has"
|
||||
@return "The first value as the type given"
|
||||
@return? TYPE_MISMATCH, NO_MORE_ELEMENT
|
||||
@return "True if the list is empty"
|
||||
*>
|
||||
macro AnyList.pop_first(&self, $Type)
|
||||
fn bool AnyList.is_empty(&self) @inline
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
defer self.remove_at(0);
|
||||
return *anycast(self.entries[0], $Type);
|
||||
return !self.size;
|
||||
}
|
||||
|
||||
<*
|
||||
Return the length of the list.
|
||||
|
||||
@return "The number of elements in the list"
|
||||
*>
|
||||
fn usz AnyList.len(&self) @operator(len) @inline
|
||||
{
|
||||
return self.size;
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -112,11 +383,222 @@ macro AnyList.get(&self, usz index, $Type)
|
||||
@return? TYPE_MISMATCH, NO_MORE_ELEMENT
|
||||
@require index < self.size : "Index out of range"
|
||||
*>
|
||||
fn any AnyList.get_any(&self, usz index) @inline @operator([]) => InterfaceList {any}.get(self, index);
|
||||
fn any AnyList.get_any(&self, usz index) @inline @operator([])
|
||||
{
|
||||
return self.entries[index];
|
||||
}
|
||||
|
||||
<*
|
||||
Return the length of the list.
|
||||
|
||||
@return "The number of elements in the list"
|
||||
Completely free and clear a list.
|
||||
*>
|
||||
fn usz AnyList.len(&self) @operator(len) @inline => InterfaceList {any}.len(self);
|
||||
fn void AnyList.free(&self)
|
||||
{
|
||||
if (!self.allocator) return;
|
||||
self.clear();
|
||||
allocator::free(self.allocator, self.entries);
|
||||
self.capacity = 0;
|
||||
self.entries = null;
|
||||
}
|
||||
|
||||
<*
|
||||
Swap two elements in a list.
|
||||
|
||||
@param i : "Index of one of the elements"
|
||||
@param j : "Index of the other element"
|
||||
@require i < self.size : "The first index is out of range"
|
||||
@require j < self.size : "The second index is out of range"
|
||||
*>
|
||||
fn void AnyList.swap(&self, usz i, usz j)
|
||||
{
|
||||
any temp = self.entries[i];
|
||||
self.entries[i] = self.entries[j];
|
||||
self.entries[j] = temp;
|
||||
}
|
||||
|
||||
<*
|
||||
Print the list to a formatter.
|
||||
*>
|
||||
fn usz? AnyList.to_format(&self, Formatter* formatter) @dynamic
|
||||
{
|
||||
switch (self.size)
|
||||
{
|
||||
case 0:
|
||||
return formatter.print("[]")!;
|
||||
case 1:
|
||||
return formatter.printf("[%s]", self.entries[0])!;
|
||||
default:
|
||||
usz n = formatter.print("[")!;
|
||||
foreach (i, element : self.entries[:self.size])
|
||||
{
|
||||
if (i != 0) formatter.print(", ")!;
|
||||
n += formatter.printf("%s", element)!;
|
||||
}
|
||||
n += formatter.print("]")!;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
<*
|
||||
Remove any elements matching the predicate.
|
||||
|
||||
@param filter : "The function to determine if it should be removed or not"
|
||||
@return "the number of deleted elements"
|
||||
*>
|
||||
fn usz AnyList.remove_if(&self, AnyPredicate filter)
|
||||
{
|
||||
return self._remove_if(filter, false);
|
||||
}
|
||||
|
||||
<*
|
||||
Retain the elements matching the predicate.
|
||||
|
||||
@param selection : "The function to determine if it should be kept or not"
|
||||
@return "the number of deleted elements"
|
||||
*>
|
||||
fn usz AnyList.retain_if(&self, AnyPredicate selection)
|
||||
{
|
||||
return self._remove_if(selection, true);
|
||||
}
|
||||
|
||||
<*
|
||||
Remove any elements matching the predicate.
|
||||
|
||||
@param filter : "The function to determine if it should be removed or not"
|
||||
@param context : "The context to the function"
|
||||
@return "the number of deleted elements"
|
||||
*>
|
||||
fn usz AnyList.remove_using_test(&self, AnyTest filter, any context)
|
||||
{
|
||||
return self._remove_using_test(filter, false, context);
|
||||
}
|
||||
|
||||
<*
|
||||
Retain any elements matching the predicate.
|
||||
|
||||
@param selection : "The function to determine if it should be retained or not"
|
||||
@param context : "The context to the function"
|
||||
@return "the number of deleted elements"
|
||||
*>
|
||||
fn usz AnyList.retain_using_test(&self, AnyTest selection, any context)
|
||||
{
|
||||
return self._remove_using_test(selection, true, context);
|
||||
}
|
||||
|
||||
|
||||
<*
|
||||
Reserve memory so that at least the `min_capacity` exists.
|
||||
|
||||
@param min_capacity : "The min capacity to hold"
|
||||
*>
|
||||
fn void AnyList.reserve(&self, usz min_capacity)
|
||||
{
|
||||
if (!min_capacity) return;
|
||||
if (self.capacity >= min_capacity) return;
|
||||
if (!self.allocator) self.allocator = tmem;
|
||||
min_capacity = math::next_power_of_2(min_capacity);
|
||||
self.entries = allocator::realloc(self.allocator, self.entries, any.sizeof * min_capacity);
|
||||
self.capacity = min_capacity;
|
||||
}
|
||||
|
||||
<*
|
||||
Set the element at any index.
|
||||
|
||||
@param index : "The index where to set the value."
|
||||
@param value : "The value to set"
|
||||
@require index <= self.size : "Index out of range"
|
||||
*>
|
||||
macro void AnyList.set(&self, usz index, value)
|
||||
{
|
||||
if (index == self.size)
|
||||
{
|
||||
self.push(value);
|
||||
return;
|
||||
}
|
||||
self.free_element(self.entries[index]);
|
||||
self.entries[index] = allocator::copy(self.allocator, value);
|
||||
}
|
||||
|
||||
// -- private
|
||||
|
||||
fn void AnyList.ensure_capacity(&self, usz added = 1) @inline @private
|
||||
{
|
||||
usz new_size = self.size + added;
|
||||
if (self.capacity >= new_size) return;
|
||||
|
||||
assert(new_size < usz.max / 2U);
|
||||
usz new_capacity = self.capacity ? 2U * self.capacity : 16U;
|
||||
while (new_capacity < new_size) new_capacity *= 2U;
|
||||
self.reserve(new_capacity);
|
||||
}
|
||||
|
||||
fn void AnyList._append(&self, any element) @local
|
||||
{
|
||||
self.ensure_capacity();
|
||||
self.entries[self.size++] = element;
|
||||
}
|
||||
|
||||
<*
|
||||
@require index < self.size
|
||||
*>
|
||||
fn void AnyList._insert_at(&self, usz index, any value) @local
|
||||
{
|
||||
self.ensure_capacity();
|
||||
for (usz i = self.size; i > index; i--)
|
||||
{
|
||||
self.entries[i] = self.entries[i - 1];
|
||||
}
|
||||
self.size++;
|
||||
self.entries[index] = value;
|
||||
}
|
||||
|
||||
macro usz AnyList._remove_using_test(&self, AnyTest filter, bool $invert, ctx) @local
|
||||
{
|
||||
usz size = self.size;
|
||||
for (usz i = size, usz k = size; k > 0; k = i)
|
||||
{
|
||||
// Find last index of item to be deleted.
|
||||
$if $invert:
|
||||
while (i > 0 && !filter(&self.entries[i - 1], ctx)) i--;
|
||||
$else
|
||||
while (i > 0 && filter(&self.entries[i - 1], ctx)) i--;
|
||||
$endif
|
||||
// Remove the items from this index up to the one not to be deleted.
|
||||
usz n = self.size - k;
|
||||
for (usz j = i; j < k; j++) self.free_element(self.entries[j]);
|
||||
self.entries[i:n] = self.entries[k:n];
|
||||
self.size -= k - i;
|
||||
// Find last index of item not to be deleted.
|
||||
$if $invert:
|
||||
while (i > 0 && filter(&self.entries[i - 1], ctx)) i--;
|
||||
$else
|
||||
while (i > 0 && !filter(&self.entries[i - 1], ctx)) i--;
|
||||
$endif
|
||||
}
|
||||
return size - self.size;
|
||||
}
|
||||
|
||||
macro usz AnyList._remove_if(&self, AnyPredicate filter, bool $invert) @local
|
||||
{
|
||||
usz size = self.size;
|
||||
for (usz i = size, usz k = size; k > 0; k = i)
|
||||
{
|
||||
// Find last index of item to be deleted.
|
||||
$if $invert:
|
||||
while (i > 0 && !filter(&self.entries[i - 1])) i--;
|
||||
$else
|
||||
while (i > 0 && filter(&self.entries[i - 1])) i--;
|
||||
$endif
|
||||
// Remove the items from this index up to the one not to be deleted.
|
||||
usz n = self.size - k;
|
||||
for (usz j = i; j < k; j++) self.free_element(self.entries[j]);
|
||||
self.entries[i:n] = self.entries[k:n];
|
||||
self.size -= k - i;
|
||||
// Find last index of item not to be deleted.
|
||||
$if $invert:
|
||||
while (i > 0 && filter(&self.entries[i - 1])) i--;
|
||||
$else
|
||||
while (i > 0 && !filter(&self.entries[i - 1])) i--;
|
||||
$endif
|
||||
}
|
||||
return size - self.size;
|
||||
}
|
||||
|
||||
@@ -1,539 +0,0 @@
|
||||
// Copyright (c) 2024-2025 Christoffer Lerno. All rights reserved.
|
||||
// Use of self source code is governed by the MIT license
|
||||
// a copy of which can be found in the LICENSE_STDLIB file.
|
||||
<*
|
||||
@require Type.kindof == INTERFACE || Type.kindof == ANY : "The kind of an interfacelist must be an interface or `any`"
|
||||
*>
|
||||
module std::collections::interfacelist {Type};
|
||||
import std::io,std::math;
|
||||
|
||||
alias InterfacePredicate = fn bool(Type value);
|
||||
alias InterfaceTest = fn bool(Type type, Type context);
|
||||
|
||||
<*
|
||||
The InterfaceList contains a heterogenous set of types implementing an interface. anything placed in the
|
||||
list will shallowly copied in order to be stored as the interface. This means
|
||||
that the list will copy and free its elements.
|
||||
|
||||
However, because we're getting interface values back when we pop, those operations
|
||||
need to take an allocator, as we can only copy then pop then return the copy.
|
||||
|
||||
If we're not doing pop, then things are easier, since we can just hand over
|
||||
the existing value.
|
||||
*>
|
||||
struct InterfaceList (Printable)
|
||||
{
|
||||
usz size;
|
||||
usz capacity;
|
||||
Allocator allocator;
|
||||
Type* entries;
|
||||
}
|
||||
|
||||
|
||||
<*
|
||||
Initialize the list. If not initialized then it will use the temp allocator
|
||||
when something is pushed to it.
|
||||
|
||||
@param [&inout] allocator : "The allocator to use"
|
||||
@param initial_capacity : "The initial capacity to reserve, defaults to 16"
|
||||
*>
|
||||
fn InterfaceList* InterfaceList.init(&self, Allocator allocator, usz initial_capacity = 16)
|
||||
{
|
||||
self.allocator = allocator;
|
||||
self.size = 0;
|
||||
if (initial_capacity > 0)
|
||||
{
|
||||
initial_capacity = math::next_power_of_2(initial_capacity);
|
||||
self.entries = allocator::alloc_array(allocator, Type, initial_capacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
self.entries = null;
|
||||
}
|
||||
self.capacity = initial_capacity;
|
||||
return self;
|
||||
}
|
||||
|
||||
<*
|
||||
Initialize the list using the temp allocator.
|
||||
|
||||
@param initial_capacity : "The initial capacity to reserve"
|
||||
*>
|
||||
fn InterfaceList* InterfaceList.tinit(&self, usz initial_capacity = 16)
|
||||
{
|
||||
return self.init(tmem, initial_capacity) @inline;
|
||||
}
|
||||
|
||||
fn bool InterfaceList.is_initialized(&self) @inline => self.allocator != null;
|
||||
|
||||
<*
|
||||
Push an element on the list by cloning it.
|
||||
@require $defined(Type t = &element) : "Element must implement the interface"
|
||||
*>
|
||||
macro void InterfaceList.push(&self, element)
|
||||
{
|
||||
if (!self.allocator) self.allocator = tmem;
|
||||
self._append(allocator::clone(self.allocator, element));
|
||||
}
|
||||
|
||||
<*
|
||||
Free a retained element removed using *_retained.
|
||||
*>
|
||||
fn void InterfaceList.free_element(&self, Type element) @inline
|
||||
{
|
||||
allocator::free(self.allocator, element.ptr);
|
||||
}
|
||||
|
||||
<*
|
||||
Copy the last value, pop it and return the copy of it.
|
||||
|
||||
@param [&inout] allocator : "The allocator to use for copying"
|
||||
@return "A copy of the last value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn Type? InterfaceList.copy_pop(&self, Allocator allocator)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
defer self.free_element(self.entries[self.size]);
|
||||
return (Type)allocator::clone_any(allocator, self.entries[--self.size]);
|
||||
}
|
||||
|
||||
<*
|
||||
Copy the last value, pop it and return the copy of it.
|
||||
|
||||
@return "A temp copy of the last value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn Type? InterfaceList.tcopy_pop(&self) => self.copy_pop(tmem);
|
||||
|
||||
<*
|
||||
Pop the last value. It must later be released using `list.free_element()`.
|
||||
|
||||
@return "The last value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn Type? InterfaceList.pop_retained(&self)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
return self.entries[--self.size];
|
||||
}
|
||||
|
||||
<*
|
||||
Remove all elements in the list.
|
||||
*>
|
||||
fn void InterfaceList.clear(&self)
|
||||
{
|
||||
for (usz i = 0; i < self.size; i++)
|
||||
{
|
||||
self.free_element(self.entries[i]);
|
||||
}
|
||||
self.size = 0;
|
||||
}
|
||||
|
||||
<*
|
||||
Pop the first value. It must later be released using `list.free_element()`.
|
||||
|
||||
@return "The first value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn Type? InterfaceList.pop_first_retained(&self)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
defer self.remove_at(0);
|
||||
return self.entries[0];
|
||||
}
|
||||
|
||||
<*
|
||||
Copy the first value, pop it and return the copy of it.
|
||||
|
||||
@param [&inout] allocator : "The allocator to use for copying"
|
||||
@return "A copy of the first value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn Type? InterfaceList.copy_pop_first(&self, Allocator allocator)
|
||||
{
|
||||
if (!self.size) return NO_MORE_ELEMENT?;
|
||||
defer self.free_element(self.entries[self.size]);
|
||||
defer self.remove_at(0);
|
||||
return (Type)allocator::clone_any(allocator, self.entries[0]);
|
||||
}
|
||||
|
||||
<*
|
||||
Copy the first value, pop it and return the temp copy of it.
|
||||
|
||||
@return "A temp copy of the first value if it exists"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn Type? InterfaceList.tcopy_pop_first(&self) => self.copy_pop_first(tmem);
|
||||
|
||||
<*
|
||||
Remove the element at the particular index.
|
||||
|
||||
@param index : "The index of the element to remove"
|
||||
@require index < self.size
|
||||
*>
|
||||
fn void InterfaceList.remove_at(&self, usz index)
|
||||
{
|
||||
if (!--self.size || index == self.size) return;
|
||||
self.free_element(self.entries[index]);
|
||||
self.entries[index .. self.size - 1] = self.entries[index + 1 .. self.size];
|
||||
}
|
||||
|
||||
<*
|
||||
Add all the elements in another InterfaceList.
|
||||
|
||||
@param [&in] other_list : "The list to add"
|
||||
*>
|
||||
fn void InterfaceList.add_all(&self, InterfaceList* other_list)
|
||||
{
|
||||
if (!other_list.size) return;
|
||||
self.reserve(other_list.size);
|
||||
foreach (value : other_list)
|
||||
{
|
||||
self.entries[self.size++] = (Type)allocator::clone_any(self.allocator, value);
|
||||
}
|
||||
}
|
||||
|
||||
<*
|
||||
Reverse the order of the elements in the list.
|
||||
*>
|
||||
fn void InterfaceList.reverse(&self)
|
||||
{
|
||||
if (self.size < 2) return;
|
||||
usz half = self.size / 2U;
|
||||
usz end = self.size - 1;
|
||||
for (usz i = 0; i < half; i++)
|
||||
{
|
||||
self.swap(i, end - i);
|
||||
}
|
||||
}
|
||||
|
||||
<*
|
||||
Return a view of the data as a slice.
|
||||
|
||||
@return "The slice view"
|
||||
*>
|
||||
fn Type[] InterfaceList.array_view(&self)
|
||||
{
|
||||
return self.entries[:self.size];
|
||||
}
|
||||
|
||||
<*
|
||||
Push an element to the front of the list.
|
||||
|
||||
@param value : "The value to push to the list"
|
||||
@require $defined(Type t = &value) : "Value must implement the interface"
|
||||
*>
|
||||
macro void InterfaceList.push_front(&self, value)
|
||||
{
|
||||
self.insert_at(0, value);
|
||||
}
|
||||
|
||||
<*
|
||||
Insert an element at a particular index.
|
||||
|
||||
@param index : "the index where the element should be inserted"
|
||||
@param type : "the value to insert"
|
||||
@require index <= self.size : "The index is out of bounds"
|
||||
@require $defined(Type t = &type) : "Type must implement the interface"
|
||||
*>
|
||||
macro void InterfaceList.insert_at(&self, usz index, type)
|
||||
{
|
||||
if (index == self.size)
|
||||
{
|
||||
self.push(type);
|
||||
return;
|
||||
}
|
||||
Type value = allocator::clone(self.allocator, type);
|
||||
self._insert_at(self, index, value);
|
||||
}
|
||||
|
||||
<*
|
||||
Remove the last element in the list. The list may not be empty.
|
||||
|
||||
@require self.size > 0 : "The list was already empty"
|
||||
*>
|
||||
fn void InterfaceList.remove_last(&self)
|
||||
{
|
||||
self.free_element(self.entries[--self.size]);
|
||||
}
|
||||
|
||||
<*
|
||||
Remove the first element in the list, the list may not be empty.
|
||||
|
||||
@require self.size > 0
|
||||
*>
|
||||
fn void InterfaceList.remove_first(&self)
|
||||
{
|
||||
self.remove_at(0);
|
||||
}
|
||||
|
||||
<*
|
||||
Return the first element
|
||||
|
||||
@return "The first element"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn Type? InterfaceList.first(&self) @inline
|
||||
{
|
||||
return self.size ? self.entries[0] : NO_MORE_ELEMENT?;
|
||||
}
|
||||
|
||||
<*
|
||||
Return the last element
|
||||
|
||||
@return "The last element"
|
||||
@return? NO_MORE_ELEMENT
|
||||
*>
|
||||
fn Type? InterfaceList.last(&self) @inline
|
||||
{
|
||||
return self.size ? self.entries[self.size - 1] : NO_MORE_ELEMENT?;
|
||||
}
|
||||
|
||||
<*
|
||||
Return whether the list is empty.
|
||||
|
||||
@return "True if the list is empty"
|
||||
*>
|
||||
fn bool InterfaceList.is_empty(&self) @inline
|
||||
{
|
||||
return !self.size;
|
||||
}
|
||||
|
||||
<*
|
||||
Return the length of the list.
|
||||
|
||||
@return "The number of elements in the list"
|
||||
*>
|
||||
fn usz InterfaceList.len(&self) @operator(len) @inline
|
||||
{
|
||||
return self.size;
|
||||
}
|
||||
|
||||
<*
|
||||
Return an element in the list.
|
||||
|
||||
@param index : "The index of the element to retrieve"
|
||||
@return "The element at the index"
|
||||
@return? TYPE_MISMATCH, NO_MORE_ELEMENT
|
||||
@require index < self.size : "Index out of range"
|
||||
*>
|
||||
fn Type InterfaceList.get(&self, usz index) @inline @operator([])
|
||||
{
|
||||
return self.entries[index];
|
||||
}
|
||||
|
||||
<*
|
||||
Completely free and clear a list.
|
||||
*>
|
||||
fn void InterfaceList.free(&self)
|
||||
{
|
||||
if (!self.allocator) return;
|
||||
self.clear();
|
||||
allocator::free(self.allocator, self.entries);
|
||||
self.capacity = 0;
|
||||
self.entries = null;
|
||||
}
|
||||
|
||||
<*
|
||||
Swap two elements in a list.
|
||||
|
||||
@param i : "Index of one of the elements"
|
||||
@param j : "Index of the other element"
|
||||
@require i < self.size : "The first index is out of range"
|
||||
@require j < self.size : "The second index is out of range"
|
||||
*>
|
||||
fn void InterfaceList.swap(&self, usz i, usz j)
|
||||
{
|
||||
Type temp = self.entries[i];
|
||||
self.entries[i] = self.entries[j];
|
||||
self.entries[j] = temp;
|
||||
}
|
||||
|
||||
<*
|
||||
Print the list to a formatter.
|
||||
*>
|
||||
fn usz? InterfaceList.to_format(&self, Formatter* formatter) @dynamic
|
||||
{
|
||||
switch (self.size)
|
||||
{
|
||||
case 0:
|
||||
return formatter.print("[]")!;
|
||||
case 1:
|
||||
return formatter.printf("[%s]", self.entries[0])!;
|
||||
default:
|
||||
usz n = formatter.print("[")!;
|
||||
foreach (i, element : self.entries[:self.size])
|
||||
{
|
||||
if (i != 0) formatter.print(", ")!;
|
||||
n += formatter.printf("%s", element)!;
|
||||
}
|
||||
n += formatter.print("]")!;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
<*
|
||||
Remove Type elements matching the predicate.
|
||||
|
||||
@param filter : "The function to determine if it should be removed or not"
|
||||
@return "the number of deleted elements"
|
||||
*>
|
||||
fn usz InterfaceList.remove_if(&self, InterfacePredicate filter)
|
||||
{
|
||||
return self._remove_if(filter, false);
|
||||
}
|
||||
|
||||
<*
|
||||
Retain the elements matching the predicate.
|
||||
|
||||
@param selection : "The function to determine if it should be kept or not"
|
||||
@return "the number of deleted elements"
|
||||
*>
|
||||
fn usz InterfaceList.retain_if(&self, InterfacePredicate selection)
|
||||
{
|
||||
return self._remove_if(selection, true);
|
||||
}
|
||||
|
||||
<*
|
||||
Remove Type elements matching the predicate.
|
||||
|
||||
@param filter : "The function to determine if it should be removed or not"
|
||||
@param context : "The context to the function"
|
||||
@return "the number of deleted elements"
|
||||
*>
|
||||
fn usz InterfaceList.remove_using_test(&self, InterfaceTest filter, Type context)
|
||||
{
|
||||
return self._remove_using_test(filter, false, context);
|
||||
}
|
||||
|
||||
<*
|
||||
Retain Type elements matching the predicate.
|
||||
|
||||
@param selection : "The function to determine if it should be retained or not"
|
||||
@param context : "The context to the function"
|
||||
@return "the number of deleted elements"
|
||||
*>
|
||||
fn usz InterfaceList.retain_using_test(&self, InterfaceTest selection, Type context)
|
||||
{
|
||||
return self._remove_using_test(selection, true, context);
|
||||
}
|
||||
|
||||
<*
|
||||
Reserve memory so that at least the `min_capacity` exists.
|
||||
|
||||
@param min_capacity : "The min capacity to hold"
|
||||
*>
|
||||
fn void InterfaceList.reserve(&self, usz min_capacity)
|
||||
{
|
||||
if (!min_capacity) return;
|
||||
if (self.capacity >= min_capacity) return;
|
||||
if (!self.allocator) self.allocator = tmem;
|
||||
min_capacity = math::next_power_of_2(min_capacity);
|
||||
self.entries = allocator::realloc(self.allocator, self.entries, Type.sizeof * min_capacity);
|
||||
self.capacity = min_capacity;
|
||||
}
|
||||
|
||||
<*
|
||||
Set the element at Type index.
|
||||
|
||||
@param index : "The index where to set the value."
|
||||
@param value : "The value to set"
|
||||
@require index <= self.size : "Index out of range"
|
||||
@require $defined(Type t = &value) : "Value must implement the interface"
|
||||
*>
|
||||
macro void InterfaceList.set(&self, usz index, value)
|
||||
{
|
||||
if (index == self.size)
|
||||
{
|
||||
self.push(value);
|
||||
return;
|
||||
}
|
||||
self.free_element(self.entries[index]);
|
||||
self.entries[index] = allocator::clone(self.allocator, value);
|
||||
}
|
||||
|
||||
// -- private
|
||||
|
||||
fn void InterfaceList.ensure_capacity(&self, usz added = 1) @inline @private
|
||||
{
|
||||
usz new_size = self.size + added;
|
||||
if (self.capacity >= new_size) return;
|
||||
|
||||
assert(new_size < usz.max / 2U);
|
||||
usz new_capacity = self.capacity ? 2U * self.capacity : 16U;
|
||||
while (new_capacity < new_size) new_capacity *= 2U;
|
||||
self.reserve(new_capacity);
|
||||
}
|
||||
|
||||
fn void InterfaceList._append(&self, Type element) @local
|
||||
{
|
||||
self.ensure_capacity();
|
||||
self.entries[self.size++] = element;
|
||||
}
|
||||
|
||||
<*
|
||||
@require index < self.size
|
||||
*>
|
||||
fn void InterfaceList._insert_at(&self, usz index, Type value) @local
|
||||
{
|
||||
self.ensure_capacity();
|
||||
for (usz i = self.size; i > index; i--)
|
||||
{
|
||||
self.entries[i] = self.entries[i - 1];
|
||||
}
|
||||
self.size++;
|
||||
self.entries[index] = value;
|
||||
}
|
||||
|
||||
macro usz InterfaceList._remove_using_test(&self, InterfaceTest filter, bool $invert, ctx) @local
|
||||
{
|
||||
usz size = self.size;
|
||||
for (usz i = size, usz k = size; k > 0; k = i)
|
||||
{
|
||||
// Find last index of item to be deleted.
|
||||
$if $invert:
|
||||
while (i > 0 && !filter(self.entries[i - 1], ctx)) i--;
|
||||
$else
|
||||
while (i > 0 && filter(self.entries[i - 1], ctx)) i--;
|
||||
$endif
|
||||
// Remove the items from this index up to the one not to be deleted.
|
||||
usz n = self.size - k;
|
||||
for (usz j = i; j < k; j++) self.free_element(self.entries[j]);
|
||||
self.entries[i:n] = self.entries[k:n];
|
||||
self.size -= k - i;
|
||||
// Find last index of item not to be deleted.
|
||||
$if $invert:
|
||||
while (i > 0 && filter(self.entries[i - 1], ctx)) i--;
|
||||
$else
|
||||
while (i > 0 && !filter(self.entries[i - 1], ctx)) i--;
|
||||
$endif
|
||||
}
|
||||
return size - self.size;
|
||||
}
|
||||
|
||||
macro usz InterfaceList._remove_if(&self, InterfacePredicate filter, bool $invert) @local
|
||||
{
|
||||
usz size = self.size;
|
||||
for (usz i = size, usz k = size; k > 0; k = i)
|
||||
{
|
||||
// Find last index of item to be deleted.
|
||||
$if $invert:
|
||||
while (i > 0 && !filter(self.entries[i - 1])) i--;
|
||||
$else
|
||||
while (i > 0 && filter(self.entries[i - 1])) i--;
|
||||
$endif
|
||||
// Remove the items from this index up to the one not to be deleted.
|
||||
usz n = self.size - k;
|
||||
for (usz j = i; j < k; j++) self.free_element(self.entries[j]);
|
||||
self.entries[i:n] = self.entries[k:n];
|
||||
self.size -= k - i;
|
||||
// Find last index of item not to be deleted.
|
||||
$if $invert:
|
||||
while (i > 0 && filter(self.entries[i - 1])) i--;
|
||||
$else
|
||||
while (i > 0 && !filter(self.entries[i - 1])) i--;
|
||||
$endif
|
||||
}
|
||||
return size - self.size;
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import std::math;
|
||||
|
||||
The advantage over the BackedArenaAllocator, is that when allocating beyond the first "page", it will
|
||||
retain the characteristics of an arena allocator (allocating a large piece of memory then handing off
|
||||
memory from that memory), whereas the BackedArenaAllocator will have heap allocator characteristics.
|
||||
memory from that memory), wheras the BackedArenaAllocator will have heap allocator characteristics.
|
||||
*>
|
||||
struct DynamicArenaAllocator (Allocator)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ alias AllocMap = HashMap { uptr, Allocation };
|
||||
// It tracks allocations using a hash map but
|
||||
// is not compatible with allocators that uses mark()
|
||||
//
|
||||
// It is also embarrassingly single-threaded, so
|
||||
// It is also embarassingly single-threaded, so
|
||||
// do not use it to track allocations that cross threads.
|
||||
|
||||
struct TrackingAllocator (Allocator)
|
||||
@@ -216,4 +216,4 @@ fn void? TrackingAllocator.fprint_report(&self, OutStream out) => @pool()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,7 +142,7 @@ macro tconcat(arr1, arr2) @nodiscard => concat(tmem, arr1, arr2);
|
||||
|
||||
@param [in] array
|
||||
@param identity
|
||||
@param #operation : "The reduction/folding lambda function or function pointer to apply."
|
||||
@param #operation : "The reduction/folding labmda function or function pointer to apply."
|
||||
|
||||
@require @is_valid_list(array) : "Expected a valid list"
|
||||
@require $defined($typefrom(@reduce_fn(array, identity)) $func = #operation) : "Invalid lambda or function pointer type"
|
||||
@@ -554,4 +554,4 @@ macro bool @is_valid_fill(left, right, fill_with = ...)
|
||||
$endif
|
||||
}
|
||||
|
||||
macro usz find_len(list) => $defined(list.len()) ??? list.len() : list.len;
|
||||
macro usz find_len(list) => $defined(list.len()) ??? list.len() : list.len;
|
||||
@@ -7,7 +7,7 @@ import libc, std::hash, std::io, std::os::backtrace;
|
||||
|
||||
<*
|
||||
EMPTY_MACRO_SLOT is a value used for implementing optional arguments for macros in an efficient
|
||||
way. It relies on the fact that distinct types are not implicitly convertible.
|
||||
way. It relies on the fact that distinct types are not implicitly convertable.
|
||||
|
||||
You can use `@is_empty_macro_slot()` and `@is_valid_macro_slot()` to figure out whether
|
||||
the argument has been used or not.
|
||||
|
||||
@@ -115,9 +115,7 @@ fn bool TypeKind.is_int(kind) @inline
|
||||
return kind == TypeKind.SIGNED_INT || kind == TypeKind.UNSIGNED_INT;
|
||||
}
|
||||
|
||||
macro bool is_slice_convertable($Type) @deprecated("Use is_slice_convertible") => is_slice_convertible($Type);
|
||||
|
||||
macro bool is_slice_convertible($Type)
|
||||
macro bool is_slice_convertable($Type)
|
||||
{
|
||||
$switch $Type.kindof:
|
||||
$case SLICE:
|
||||
|
||||
@@ -365,7 +365,7 @@ fn void F25519Int.normalize(&s)
|
||||
{
|
||||
s.reduce_carry((*s)[^1] >> 7);
|
||||
|
||||
// Subtract p
|
||||
// Substract p
|
||||
F25519Int sub @noinit;
|
||||
ushort c = 19;
|
||||
foreach (i, v : (*s)[:^1])
|
||||
@@ -399,7 +399,7 @@ fn char eq(F25519Int* a, F25519Int* b)
|
||||
}
|
||||
|
||||
<*
|
||||
Constant-time conditional selection. Result is undefined if condition is neither 0 nor 1.
|
||||
Constant-time conditonal selection. Result is undefined if condition is neither 0 nor 1.
|
||||
|
||||
@param [&in] zero : "selected if condition is 0"
|
||||
@param [&in] one : "selected if condition is 1"
|
||||
@@ -441,7 +441,7 @@ fn F25519Int F25519Int.add(&s, F25519Int* n) @operator(+)
|
||||
macro F25519Int F25519Int.@sub(&s, F25519Int #n) @operator(-) => s.sub(@addr(#n));
|
||||
|
||||
<*
|
||||
Subtraction.
|
||||
Substraction.
|
||||
|
||||
@param [&in] s
|
||||
@param [&in] n
|
||||
@@ -638,7 +638,7 @@ fn FBaseInt from_bytes(char[] bytes)
|
||||
}
|
||||
|
||||
<*
|
||||
Constant-time conditional selection. Result is undefined if condition is neither 0 nor 1.
|
||||
Constant-time conditonal selection. Result is undefined if condition is neither 0 nor 1.
|
||||
|
||||
@param [&in] zero : "selected if condition is 0"
|
||||
@param [&in] one : "selected if condition is 1"
|
||||
@@ -676,7 +676,7 @@ fn FBaseInt FBaseInt.add(&s, FBaseInt* n) @operator(+)
|
||||
}
|
||||
|
||||
<*
|
||||
Subtraction if RHS is less than LHS else identity.
|
||||
Substraction if RHS is less than LHS else identity.
|
||||
|
||||
@param [&in] s
|
||||
@param [&in] n
|
||||
|
||||
@@ -20,7 +20,7 @@ fn char[] FileMmap.bytes(&self)
|
||||
}
|
||||
|
||||
<*
|
||||
Destroys the underlying VirtualMemory object ie. calls munmap()"
|
||||
Destroys the underlyng VirtualMemory object ie. calls munmap()"
|
||||
*>
|
||||
fn void? FileMmap.destroy(&self) @maydiscard
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ struct ByteBuffer (InStream, OutStream)
|
||||
|
||||
<*
|
||||
ByteBuffer provides a streamable read/write buffer.
|
||||
max_read defines how many bytes might be kept before its internal buffer is shrunk.
|
||||
max_read defines how many bytes might be kept before its internal buffer is shrinked.
|
||||
@require self.bytes.len == 0 : "Buffer already initialized."
|
||||
*>
|
||||
fn ByteBuffer* ByteBuffer.init(&self, Allocator allocator, usz max_read, usz initial_capacity = 16)
|
||||
@@ -145,4 +145,4 @@ macro ByteBuffer.shrink(&self)
|
||||
self.write_idx = 1 + readable;
|
||||
self.read_idx = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -438,7 +438,7 @@ alias TimeOffset @if(!env::WASI) = CLong ;
|
||||
const int TIME_UTC = 1;
|
||||
|
||||
|
||||
// This is a best-effort approximation, but the C standard does not enforce
|
||||
// This is a best-effort aproximation, but the C standard does not enforce
|
||||
// that this is a compile-time standard.
|
||||
const CLOCKS_PER_SEC @if(env::WIN32) = 1000;
|
||||
const CLOCKS_PER_SEC @if(!env::WIN32) = 1000000;
|
||||
|
||||
@@ -218,7 +218,7 @@ enum Speed : const CUInt
|
||||
MAX_BAUD = B4000000,
|
||||
}
|
||||
|
||||
enum Cc : const inline char
|
||||
enum Cc : const char
|
||||
{
|
||||
VINTR = 0,
|
||||
VQUIT = 1,
|
||||
|
||||
@@ -252,8 +252,8 @@ macro @ceil($input) @const => $$ceil($input);
|
||||
@return "lower if x < lower, upper if x > upper, otherwise return x."
|
||||
|
||||
@require types::is_numerical($typeof(x)) : `The input must be a numerical value or numerical vector`
|
||||
@require $defined(x = lower) : `The lower bound must be convertible to the value type.`
|
||||
@require $defined(x = upper) : `The upper bound must be convertible to the value type.`
|
||||
@require $defined(x = lower) : `The lower bound must be convertable to the value type.`
|
||||
@require $defined(x = upper) : `The upper bound must be convertable to the value type.`
|
||||
*>
|
||||
macro clamp(x, lower, upper) => $$max(($typeof(x))lower, $$min(x, ($typeof(x))upper));
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ const int SO_WANTMORE = 0x4000; // Apple: Give hint when more data re
|
||||
const int SO_WANTOOBFLAG = 0x8000; // Apple: Want OOB in MSG_FLAG on receive
|
||||
|
||||
const int SO_SNDBUF = 0x1001; // Send buffer size
|
||||
const int SO_RCVBUF = 0x1002; // Receive buffer size
|
||||
const int SO_RCVBUF = 0x1002; // Recieve buffer size
|
||||
const int SO_SNDLOWAT = 0x1003; // Send low-water mark
|
||||
const int SO_RCVLOWAT = 0x1004; // Receive low-water mark
|
||||
const int SO_SNDTIMEO = 0x1005; // Send timeout
|
||||
@@ -94,4 +94,4 @@ const CShort POLLATTRIB = 0x0400; // file attributes may have changed
|
||||
const CShort POLLNLINK = 0x0800; // (un)link/rename may have happened
|
||||
const CShort POLLWRITE = 0x1000; // file's contents may have changed
|
||||
|
||||
const CInt MSG_PEEK = 0x0002;
|
||||
const CInt MSG_PEEK = 0x0002;
|
||||
@@ -35,7 +35,7 @@ bitstruct SubProcessOptions : int
|
||||
{
|
||||
// Combine stdout and stderr to the same file
|
||||
bool combined_stdout_stderr;
|
||||
// Child process should inherit env variables of parent process
|
||||
// Child process should inhert env variables of parent process
|
||||
bool inherit_environment;
|
||||
// Enable async reading of stdout/stderr before completion
|
||||
bool read_async;
|
||||
|
||||
@@ -36,7 +36,7 @@ enum Win32_FreeType : const Win32_DWORD
|
||||
MEM_COALESCE_PLACEHOLDERS = 0x00000001,
|
||||
MEM_PRESERVE_PLACEHOLDER = 0x00000002,
|
||||
}
|
||||
extern fn Win32_LPVOID virtualAlloc(Win32_LPVOID lpAddress, Win32_SIZE_T dwSize, Win32_AllocationType flAllocationType, Win32_Protect flProtect) @extern("VirtualAlloc");
|
||||
extern fn Win32_LPVOID virtualAlloc(Win32_LPVOID lpAddres, Win32_SIZE_T dwSize, Win32_AllocationType flAllocationType, Win32_Protect flProtect) @extern("VirtualAlloc");
|
||||
extern fn Win32_PVOID virtualAlloc2(Win32_HANDLE process, Win32_PVOID baseAddress, Win32_SIZE_T size, Win32_AllocationType allocationType, Win32_ULONG pageProtection, Win32_MEM_EXTENDED_PARAMETER* extendedParameters, Win32_ULONG parameterCount) @extern("VirtualAlloc2");
|
||||
extern fn Win32_BOOL virtualFree(Win32_LPVOID lpAddress, Win32_SIZE_T dwSize, Win32_FreeType dwFreeType) @extern("VirtualFree");
|
||||
extern fn Win32_BOOL virtualProtect(Win32_LPVOID lpAddress, Win32_SIZE_T dwSize, Win32_Protect flNewProtect, Win32_Protect* lpflOldProtect) @extern("VirtualProtect");
|
||||
|
||||
@@ -432,7 +432,7 @@ struct Win32_XMM_SAVE_AREA32
|
||||
Win32_UCHAR tagWord;
|
||||
Win32_UCHAR reserved1;
|
||||
Win32_USHORT errorOpcode;
|
||||
Win32_ULONG errorOffset;
|
||||
Win32_ULONG errrorOffset;
|
||||
Win32_USHORT errorSelector;
|
||||
Win32_USHORT reserved2;
|
||||
Win32_ULONG dataOffset;
|
||||
|
||||
@@ -82,8 +82,8 @@ fn void qsort(Type list, isz low, isz high, CmpFn cmp, Context context)
|
||||
}
|
||||
|
||||
<*
|
||||
@require low <= k : "kth smallest element is smaller than lower bounds"
|
||||
@require k <= high : "kth smallest element is larger than upper bounds"
|
||||
@require low <= k : "kth smalles element is smaller than lower bounds"
|
||||
@require k <= high : "kth smalles element is larger than upper bounds"
|
||||
*>
|
||||
fn ElementType? qselect(Type list, isz low, isz high, isz k, CmpFn cmp, Context context)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user