mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
123 lines
3.3 KiB
Plaintext
123 lines
3.3 KiB
Plaintext
// 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.
|
|
module std::collections::anylist;
|
|
import std::collections::interfacelist;
|
|
|
|
alias AnyPredicate = InterfacePredicate {any};
|
|
alias AnyTest = InterfaceTest {any};
|
|
|
|
<*
|
|
The AnyList contains a heterogenous set of types. Anything placed in the
|
|
list will shallowly copied in order to be stored as an `any`. This means
|
|
that the list will copy and free its elements.
|
|
|
|
However, because we're getting `any` 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 any.
|
|
*>
|
|
typedef AnyList = inline InterfaceList {any};
|
|
|
|
<*
|
|
Return the first element by value, assuming it is the given type.
|
|
|
|
@param $Type : "The type of the first element"
|
|
@return "The first element"
|
|
@return? TYPE_MISMATCH, NO_MORE_ELEMENT
|
|
*>
|
|
macro AnyList.first(&self, $Type)
|
|
{
|
|
return *anycast(self.first_any(), $Type);
|
|
}
|
|
|
|
<*
|
|
Return the first element
|
|
|
|
@return "The first element"
|
|
@return? NO_MORE_ELEMENT
|
|
*>
|
|
fn any? AnyList.first_any(&self) @inline => InterfaceList {any}.first(self);
|
|
|
|
<*
|
|
Return the last element by value, assuming it is the given type.
|
|
|
|
@param $Type : "The type of the last element"
|
|
@return "The last element"
|
|
@return? TYPE_MISMATCH, NO_MORE_ELEMENT
|
|
*>
|
|
macro AnyList.last(&self, $Type)
|
|
{
|
|
return *anycast(self.last_any(), $Type);
|
|
}
|
|
|
|
<*
|
|
Return the last element
|
|
|
|
@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)
|
|
{
|
|
if (!self.size) return NO_MORE_ELEMENT?;
|
|
defer self.free_element(self.entries[self.size]);
|
|
return *anycast(self.entries[--self.size], $Type);
|
|
}
|
|
|
|
<*
|
|
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);
|
|
}
|
|
|
|
<*
|
|
Return an element in the list by value, assuming it is the given type.
|
|
|
|
@param index : "The index of the element to retrieve"
|
|
@param $Type : "The type of the element"
|
|
@return "The element at the index"
|
|
@return? TYPE_MISMATCH, NO_MORE_ELEMENT
|
|
@require index < self.size : "Index out of range"
|
|
*>
|
|
macro AnyList.get(&self, usz index, $Type)
|
|
{
|
|
return *anycast(self.entries[index], $Type);
|
|
}
|
|
|
|
<*
|
|
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 any AnyList.get_any(&self, usz index) @inline @operator([]) => InterfaceList {any}.get(self, index);
|
|
|
|
<*
|
|
Return the length of the list.
|
|
|
|
@return "The number of elements in the list"
|
|
*>
|
|
fn usz AnyList.len(&self) @operator(len) @inline => InterfaceList {any}.len(self);
|