Update stdlib to use struct member docs from #2427 and other small changes (#2473)

* Doc comment improvements

* update `compression/qoi.c3` to use const enums

* revert sweeping doc comment changes that impacted readability for now

* Some tweaks.

---------

Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
Book-reader
2025-09-20 04:41:32 +12:00
committed by GitHub
parent b03ae8bb17
commit a6d33ec4af
19 changed files with 201 additions and 143 deletions

View File

@@ -30,8 +30,10 @@ struct HashMap (Printable)
{
Entry*[] table;
Allocator allocator;
uint count; // Number of elements
uint threshold; // Resize limit
<* Last inserted LinkedEntry *>
uint count;
<* Resize limit *>
uint threshold;
float load_factor;
}

View File

@@ -25,8 +25,10 @@ struct HashSet (Printable)
{
Entry*[] table;
Allocator allocator;
usz count; // Number of elements
usz threshold; // Resize limit
<* Number of elements *>
usz count;
<* Resize limit *>
usz threshold;
float load_factor;
}

View File

@@ -7,16 +7,22 @@ const INITIAL_CAPACITY = 16;
struct QueueEntry
{
Value value;
QueueEntry* next; // Next in queue order
QueueEntry* prev; // Previous in queue order
<* Next in queue order *>
QueueEntry* next;
<* Previous in queue order *>
QueueEntry* prev;
}
struct LinkedBlockingQueue
{
QueueEntry* head; // First element in queue
QueueEntry* tail; // Last element in queue
usz count; // Current number of elements
usz capacity; // Maximum capacity (0 for unbounded)
<* First element in queue *>
QueueEntry* head;
<* Last element in queue *>
QueueEntry* tail;
<* Current number of elements *>
usz count;
<* Maximum capacity (0 for unbounded) *>
usz capacity;
Mutex lock;
ConditionVariable not_empty;
ConditionVariable not_full;

View File

@@ -15,9 +15,12 @@ struct LinkedEntry
uint hash;
Key key;
Value value;
LinkedEntry* next; // For bucket chain
LinkedEntry* before; // Previous in insertion order
LinkedEntry* after; // Next in insertion order
<* For bucket chain *>
LinkedEntry* next;
<* Previous in insertion order *>
LinkedEntry* before;
<* Next in insertion order *>
LinkedEntry* after;
}
struct LinkedHashMap (Printable)
@@ -27,8 +30,10 @@ struct LinkedHashMap (Printable)
usz count;
usz threshold;
float load_factor;
LinkedEntry* head; // First inserted LinkedEntry
LinkedEntry* tail; // Last inserted LinkedEntry
<* First inserted LinkedEntry *>
LinkedEntry* head;
<* Last inserted LinkedEntry *>
LinkedEntry* tail;
}

View File

@@ -11,20 +11,27 @@ struct LinkedEntry
{
uint hash;
Value value;
LinkedEntry* next; // For bucket chain
LinkedEntry* before; // Previous in insertion order
LinkedEntry* after; // Next in insertion order
<* For bucket chain *>
LinkedEntry* next;
<* Previous in insertion order *>
LinkedEntry* before;
<* Next in insertion order *>
LinkedEntry* after;
}
struct LinkedHashSet (Printable)
{
LinkedEntry*[] table;
Allocator allocator;
usz count; // Number of elements
usz threshold; // Resize limit
<* Number of elements *>
usz count;
<* Resize limit *>
usz threshold;
float load_factor;
LinkedEntry* head; // First inserted LinkedEntry
LinkedEntry* tail; // Last inserted LinkedEntry
<* Resize limit *>
LinkedEntry* head;
<* First inserted LinkedEntry *>
LinkedEntry* tail;
}
fn int LinkedHashSet.len(&self) @operator(len) => (int) self.count;

View File

@@ -7,10 +7,12 @@ const uint PIXELS_MAX = 400000000;
Purely informative. It will be saved to the file header,
but does not affect how chunks are en-/decoded.
*>
enum QOIColorspace : char (char id)
enum QOIColorspace : const char
{
SRGB = 0, // sRGB with linear alpha
LINEAR = 1 // all channels linear
<* sRGB with linear alpha *>
SRGB = 0,
<* all channels linear *>
LINEAR = 1
}
<*
@@ -19,7 +21,7 @@ enum QOIColorspace : char (char id)
AUTO can be used when decoding to automatically determine
the channels from the file's header.
*>
enum QOIChannels : char (char id)
enum QOIChannels : const inline char
{
AUTO = 0,
RGB = 3,
@@ -132,7 +134,7 @@ fn char[]? encode(Allocator allocator, char[] input, QOIDesc* desc) @nodiscard
if (pixels > PIXELS_MAX) return TOO_MANY_PIXELS?;
// check input data size
uint image_size = pixels * desc.channels.id;
uint image_size = pixels * desc.channels;
if (image_size != input.len) return INVALID_DATA?;
// allocate memory for encoded data (output)
@@ -146,13 +148,13 @@ fn char[]? encode(Allocator allocator, char[] input, QOIDesc* desc) @nodiscard
.be_magic = bswap('qoif'),
.be_width = bswap(desc.width),
.be_height = bswap(desc.height),
.channels = desc.channels.id,
.colorspace = desc.colorspace.id
.channels = desc.channels,
.colorspace = desc.colorspace
};
uint pos = Header.sizeof; // Current position in output
uint loc; // Current position in image (top-left corner)
uint loc_end = image_size - desc.channels.id; // End of image data
uint loc_end = image_size - desc.channels; // End of image data
char run_length = 0; // Length of the current run
Pixel[64] palette; // Zero-initialized by default
@@ -163,7 +165,7 @@ fn char[]? encode(Allocator allocator, char[] input, QOIDesc* desc) @nodiscard
ichar[<3>] luma; // ...and luma
// write chunks
for (loc = 0; loc < image_size; loc += desc.channels.id)
for (loc = 0; loc < image_size; loc += desc.channels)
{
// set previous pixel
prev = p;
@@ -292,8 +294,8 @@ fn char[]? decode(Allocator allocator, char[] data, QOIDesc* desc, QOIChannels c
// copy header data to desc
desc.width = bswap(header.be_width);
desc.height = bswap(header.be_height);
desc.channels = @enumcast(QOIChannels, header.channels)!; // Rethrow if invalid
desc.colorspace = @enumcast(QOIColorspace, header.colorspace)!; // Rethrow if invalid
desc.channels = header.channels;
desc.colorspace = header.colorspace;
if (desc.channels == AUTO) return INVALID_DATA?; // Channels must be specified in the header
// check width and height
@@ -314,11 +316,11 @@ fn char[]? decode(Allocator allocator, char[] data, QOIDesc* desc, QOIChannels c
if (channels == AUTO) channels = desc.channels;
// allocate memory for image data
usz image_size = (usz)pixels * channels.id;
usz image_size = (usz)pixels * channels;
char[] image = allocator::alloc_array(allocator, char, image_size);
defer catch allocator::free(allocator, image);
for (loc = 0; loc < image_size; loc += channels.id)
for (loc = 0; loc < image_size; loc += channels)
{
// get chunk tag
tag = data[pos];
@@ -391,31 +393,22 @@ const OP_RUN = 0b11;
struct Header @packed
{
uint be_magic; // magic bytes "qoif"
uint be_width; // image width in pixels (BE)
uint be_height; // image height in pixels (BE)
<* magic bytes "qoif" *>
uint be_magic;
<* image width in pixels (BE) *>
uint be_width;
<* image height in pixels (BE) *>
uint be_height;
// informative fields
char channels; // 3 = RGB, 4 = RGB
char colorspace; // 0 = sRGB with linear alpha, 1 = all channels linear
<* 3 = RGB, 4 = RGB *>
QOIChannels channels;
<* 0 = sRGB with linear alpha, 1 = all channels linear *>
QOIColorspace colorspace;
}
const char[*] END_OF_STREAM = {0, 0, 0, 0, 0, 0, 0, 1};
// inefficient, but it's only run once at a time
<*
@return? INVALID_DATA
*>
macro @enumcast($Type, raw)
{
foreach (value : $Type.values)
{
if (value.id == raw) return value;
}
return INVALID_DATA?;
}
typedef Pixel = inline char[<4>];
macro char Pixel.hash(Pixel p)
{

View File

@@ -22,9 +22,12 @@ struct Vmem (Allocator)
bitstruct VmemOptions : int
{
bool shrink_on_reset; // Release memory on reset
bool protect_unused_pages; // Protect unused pages on reset
bool scratch_released_data; // Overwrite released data with 0xAA
<* Release memory on reset *>
bool shrink_on_reset;
<* Protect unused pages on reset *>
bool protect_unused_pages;
<* Overwrite released data with 0xAA *>
bool scratch_released_data;
}
<*
@@ -38,11 +41,11 @@ bitstruct VmemOptions : int
fn void? Vmem.init(&self, usz preferred_size, usz reserve_page_size = 0, VmemOptions options = { true, true, env::COMPILER_SAFE_MODE }, usz min_size = 0)
{
static usz page_size = 0;
if (!page_size) page_size = mem::os_pagesize();
if (page_size < reserve_page_size) page_size = reserve_page_size;
preferred_size = mem::aligned_offset(preferred_size, page_size);
if (!min_size) min_size = max(preferred_size / 1024, 1);
VirtualMemory? memory = mem::OUT_OF_MEMORY?;
if (!page_size) page_size = mem::os_pagesize();
if (page_size < reserve_page_size) page_size = reserve_page_size;
preferred_size = mem::aligned_offset(preferred_size, page_size);
if (!min_size) min_size = max(preferred_size / 1024, 1);
VirtualMemory? memory = mem::OUT_OF_MEMORY?;
while (preferred_size >= min_size)
{
memory = vm::virtual_alloc(preferred_size, PROTECTED);

View File

@@ -14,9 +14,9 @@ TestContext* test_context @private;
struct TestContext
{
JmpBuf buf;
// Allows filtering test cased or modules by substring, e.g. 'foo::', 'foo::test_add'
<* Allows filtering test cased or modules by substring, e.g. 'foo::', 'foo::test_add' *>
String test_filter;
// Triggers debugger breakpoint when assert or test:: checks failed
<* Triggers debugger breakpoint when assert or test:: checks failed *>
bool breakpoint_on_assert;
// internal state

View File

@@ -212,7 +212,8 @@ fn F25519Int pack(Point* p)
struct Unpacking
{
Point point;
char on_curve; // Non-zero if true.
<* Non-zero if true. *>
char on_curve;
}
<*

View File

@@ -1,52 +1,52 @@
// Copyright (c) 2025 Zack Puhl <github@xmit.xyz>. 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.
//
// SipHash is a secure pseudorandom function (PRF) which digests a 128-bit key
// and a variable-length message to produce a 64- or 128-bit hash value.
//
// SipHash can be employed in numerous useful ways and structures, e.g.:
// - Hash Tables
// - Message Authentication Codes
// - Denial of Service (hash flooding) resistance
// - Bloom filters
// - Keyed runtime identifier derivation
//
// Read more: https://en.wikipedia.org/wiki/SipHash
//
//
// COMMON HASH VARIANTS.
// These two forms of SipHash (24 and 48) are the most widely
// used by many implementations.
// These provide typical 64-bit hash results.
// -- Best for performance-critical applications.
<*
Best for performance-critical applications.
See std::hash::siphash for more information.
*>
module std::hash::siphash24;
import std::hash::siphash;
alias SipHash24 = SipHash { ulong, 2, 4 };
alias hash = siphash::hash { ulong, 2, 4 };
// -- Best for conservative security applications.
<*
Best for security-focused applications.
See std::hash::siphash for more information.
*>
module std::hash::siphash48;
import std::hash::siphash;
alias SipHash48 = SipHash { ulong, 4, 8 };
alias hash = siphash::hash { ulong, 4, 8 };
// Exact same as above, but for 128-bit outputs. Algorithm internally changes slightly.
<* Exact same as siphash24, but for 128-bit outputs. Algorithm internally changes slightly. *>
module std::hash::siphash24_128;
import std::hash::siphash;
alias SipHash24_128 = SipHash { uint128, 2, 4 };
alias hash = siphash::hash { uint128, 2, 4 };
<* Exact same as siphash48, but for 128-bit outputs. Algorithm internally changes slightly. *>
module std::hash::siphash48_128;
import std::hash::siphash;
alias SipHash48_128 = SipHash { uint128, 4, 8 };
alias hash = siphash::hash { uint128, 4, 8 };
<*
@require OutType.typeid == uint128.typeid || OutType.typeid == ulong.typeid : "Module OutType must be either uint128 or ulong."
SipHash is a secure pseudorandom function (PRF) which digests a 128-bit key
and a variable-length message to produce a 64- or 128-bit hash value.
SipHash can be employed in numerous useful ways and structures, e.g.:
- Hash Tables
- Message Authentication Codes
- Denial of Service (hash flooding) resistance
- Bloom filters
- Keyed runtime identifier derivation
Read more: https://en.wikipedia.org/wiki/SipHash
@require OutType.typeid == uint128.typeid || OutType.typeid == ulong.typeid : "Module OutType must be either uint128 or ulong."
*>
module std::hash::siphash { OutType, BLOCK_ROUNDS, FINALIZE_ROUNDS };

View File

@@ -407,17 +407,28 @@ alias SeekIndex = CLong;
struct Tm
{
CInt tm_sec; // seconds after the minute [0-60]
CInt tm_min; // minutes after the hour [0-59]
CInt tm_hour; // hours since midnight [0-23]
CInt tm_mday; // day of the month [1-31]
CInt tm_mon; // months since January [0-11]
CInt tm_year; // years since 1900
CInt tm_wday; // days since Sunday [0-6]
CInt tm_yday; // days since January 1 [0-365]
CInt tm_isdst; // Daylight Savings Time flag
TimeOffset tm_gmtoff @if(!env::WIN32); /* offset from UTC in seconds */
char* tm_zone @if(!env::WIN32); /* timezone abbreviation */
<* seconds after the minute [0-60] *>
CInt tm_sec;
<* minutes after the hour [0-59] *>
CInt tm_min;
<* hours since midnight [0-23] *>
CInt tm_hour;
<* day of the month [1-31] *>
CInt tm_mday;
<* months since January [0-11] *>
CInt tm_mon;
<* years since 1900 *>
CInt tm_year;
<* days since Sunday [0-6] *>
CInt tm_wday;
<* days since January 1 [0-365] *>
CInt tm_yday;
<* Daylight Savings Time flag *>
CInt tm_isdst;
<* offset from UTC in seconds *>
TimeOffset tm_gmtoff @if(!env::WIN32);
<* timezone abbreviation *>
char* tm_zone @if(!env::WIN32);
CInt tm_nsec @if(env::WASI);
}
@@ -433,7 +444,7 @@ alias Clock_t @if(env::WIN32) = int;
alias Clock_t @if(!env::WIN32) = CLong;
alias TimeOffset @if(env::WASI) = int;
alias TimeOffset @if(!env::WASI) = CLong ;
alias TimeOffset @if(!env::WASI) = CLong;
const int TIME_UTC = 1;

View File

@@ -17,17 +17,28 @@ struct Stat
Gid_t st_gid;
Dev_t st_rdev;
TimeSpec st_atimespec; // time of last access
TimeSpec st_mtimespec; // time of last data modification
TimeSpec st_ctimespec; // time of last status change
TimeSpec st_birthtimespec; // time of file creation(birth)
Off_t st_size; // file size, in bytes
Blkcnt_t st_blocks; // blocks allocated for file
Blksize_t st_blocksize; // optimal blocksize for I/O
uint st_flags; // user defined flags for file
uint st_gen; // file generation number
int st_lspare; // RESERVED
long[2] st_qspare; // RESERVED
<* time of last access *>
TimeSpec st_atimespec;
<* time of last data modification *>
TimeSpec st_mtimespec;
<* time of last status change *>
TimeSpec st_ctimespec;
<* time of file creation(birth) *>
TimeSpec st_birthtimespec;
<* file size, in bytes *>
Off_t st_size;
<* blocks allocated for file *>
Blkcnt_t st_blocks;
<* optimal blocksize for I/O *>
Blksize_t st_blocksize;
<* user defined flags for file *>
uint st_flags;
<* file generation number *>
uint st_gen;
<* RESERVED *>
int st_lspare;
<* RESERVED *>
long[2] st_qspare;
}
extern fn int stat(ZString str, Stat* stat) @extern("stat64");

View File

@@ -55,7 +55,8 @@ struct Exp2Data @private
double shift;
double negln2hiN;
double negln2loN;
double[4] poly; // Last four coefficients.
<* Last four coefficients. *>
double[4] poly;
double exp2_shift;
double[EXP2_POLY_ORDER] exp2_poly;
ulong[2 * EXP_DATA_WIDTH] tab;

View File

@@ -52,8 +52,10 @@ union EpollData
struct EpollEvent @packed
{
uint events; /* Epoll events */
EpollData data; /* User data variable */
<* Epoll events *>
uint events;
<* User data variable *>
EpollData data;
}
struct EpollParams
@@ -62,7 +64,7 @@ struct EpollParams
ushort busy_poll_budget;
char prefer_busy_poll;
/* pad the struct to a multiple of 64bits */
<* pad the struct to a multiple of 64bits *>
char __pad;
}

View File

@@ -33,19 +33,21 @@ struct SubProcess
bitstruct SubProcessOptions : int
{
// Combine stdout and stderr to the same file
<* Combine stdout and stderr to the same file *>
bool combined_stdout_stderr;
// Child process should inherit env variables of parent process
<* Child process should inherit env variables of parent process *>
bool inherit_environment;
// Enable async reading of stdout/stderr before completion
<* Enable async reading of stdout/stderr before completion *>
bool read_async;
// Spawn child process without window if supported
<* Spawn child process without window if supported *>
bool no_window;
// Search for program names in the PATH variable. Always enabled on Windows.
// Note: this will **not** search for paths in any provided custom environment
// and instead uses the PATH of the spawning process.
<*
Search for program names in the PATH variable. Always enabled on Windows.
Note: this will **not** search for paths in any provided custom environment
and instead uses the PATH of the spawning process.
*>
bool search_user_path;
// Inherit the parent's stdin, stdout, and stderr handles instead of creating pipes
<* Inherit the parent's stdin, stdout, and stderr handles instead of creating pipes *>
bool inherit_stdio;
}

View File

@@ -31,9 +31,12 @@ struct Win32_WIN32_FIND_DATAW
Win32_DWORD dwReserved1;
Win32_WCHAR[260] cFileName;
Win32_WCHAR[14] cAlternateFileName;
Win32_DWORD dwFileType; // Obsolete. Do not use.
Win32_DWORD dwCreatorType; // Obsolete. Do not use
Win32_WORD wFinderFlags; // Obsolete. Do not use
<* Obsolete. Do not use. *>
Win32_DWORD dwFileType;
<* Obsolete. Do not use *>
Win32_DWORD dwCreatorType;
<* Obsolete. Do not use *>
Win32_WORD wFinderFlags;
}
alias Win32_LPWIN32_FIND_DATAW = Win32_WIN32_FIND_DATAW*;

View File

@@ -15,23 +15,30 @@ alias Win32_PMEM_EXTENDED_PARAMETER_TYPE = Win32_MEM_EXTENDED_PARAMETER_TYPE;
enum Win32_MEM_EXTENDED_PARAMETER_ATTRIBUTE : const Win32_DWORD64
{
NONPAGED = 0x02, // The allocation is non-pageable.
NONPAGED_LARGE = 0x08, // The allocation is mapped using large pages.
NONPAGED_HUGE = 0x10, // The allocation is mapped using huge pages.
EC_CODE = 0x40, // The allocation will contain emulation-compatible (EC) code.
<* The allocation is non-pageable. *>
NONPAGED = 0x02,
<* The allocation is mapped using large pages. *>
NONPAGED_LARGE = 0x08,
<* The allocation is mapped using huge pages. *>
NONPAGED_HUGE = 0x10,
<* The allocation will contain emulation-compatible (EC) code. *>
EC_CODE = 0x40,
}
struct Win32_MEM_EXTENDED_PARAMETER
{
Win32_MEM_EXTENDED_PARAMETER_TYPE type;
union
{
Win32_MEM_EXTENDED_PARAMETER_ATTRIBUTE attribute; // If type is ATTRIBUTE_FLAGS
Win32_DWORD64 nodeNumber; // If type is NUMA_NODE
Win32_PVOID pointer; // If type is ADDRESS_REQUIREMENTS
Win32_SIZE_T size;
Win32_HANDLE handle;
Win32_DWORD uLong;
}
union
{
<* If type is ATTRIBUTE_FLAGS *>
Win32_MEM_EXTENDED_PARAMETER_ATTRIBUTE attribute;
<* If type is NUMA_NODE *>
Win32_DWORD64 nodeNumber;
<* If type is ADDRESS_REQUIREMENTS *>
Win32_PVOID pointer;
Win32_SIZE_T size;
Win32_HANDLE handle;
Win32_DWORD uLong;
}
}
alias Win32_PMEM_EXTENDED_PARAMETER = Win32_MEM_EXTENDED_PARAMETER*;

View File

@@ -2,7 +2,8 @@ module std::sort;
import std::sort::is;
<*
Sort list using the quick sort algorithm.
Sort list using the quick sort algorithm.
@require @is_sortable(list) : "The list must be indexable and support .len or .len()"
@require @is_valid_cmp_fn(cmp, list, context) : "Expected a comparison function which compares values"
*>

View File

@@ -2,7 +2,8 @@ module std::sort;
import std::sort::qs;
<*
Sort list using the quick sort algorithm.
Sort list using the quick sort algorithm.
@require @is_sortable(list) : "The list must be indexable and support .len or .len()"
@require @is_valid_cmp_fn(cmp, list, context) : "Expected a comparison function which compares values"
@require @is_valid_context(cmp, context) : "Expected a valid context"