C+
Packages · View as Markdown

stdlib

The standard library is a vendored package. Every module lives in vendor/stdlib/src/<name>.cplus and imports as "stdlib/<name>". You import the modules you use, not the whole library.

I/O

import "stdlib/io" as io;
io::print("no newline");
io::println("with newline");
io::eprintln("to stderr");

Backed by printf, buffered through stdio.

Result and Option

Both are generic. There is no ? propagation; match on the variant or use guard let.

import "stdlib/result" as result;
import "stdlib/option" as option;

let r: result::Result[i32, result::IoError] = result::io_ok::[i32](42);
let some_n: option::Option[i32] = option::some::[i32](7);

Collections

stdlib/vec is a growable, ownership-safe vector that implements Drop, so its buffer frees on scope exit. Allocation sizing is overflow-checked, malloc/realloc are null-checked, and every read is bounds-checked: there are no silent out-of-bounds reads.

import "stdlib/vec" as vec;

let mut v: vec::Vec[i32] = vec::with_capacity::[i32](16 as usize);
v.push(1);
v.push(2);
let n: usize = v.len();

let first: option::Option[i32] = vec::get::[i32](v, 0 as usize);  // bounds-checked
let x: i32                     = vec::at_copy::[i32](v, 0 as usize); // asserts in-bounds

Reading is split by element kind, and bounds safety is the default:

  • vec::get::[T](v, i) -> Option[T] (Copy elements) — bounds-checked, None when out of range. A free function that borrows v.
  • vec::at_copy::[T](v, i) -> T (Copy elements) — asserts in-bounds, returns the value.
  • at(i) -> Option[*T] — reads a non-Copy element in place, by pointer.

Mutating and sizing methods: push(value), pop() -> Option[T], set(i, value), swap_remove(i) -> Option[T], truncate(new_len), clear(), reserve(extra), shrink_to_fit(). Plus len(), is_empty(), capacity(), as_slice() -> T[], the gen method iter(), and the unsafe bulk fast path extend_from_raw(ptr, count).

stdlib/hash_map is a generic HashMap[K, V] (open addressing, linear probing, 0.75 load-factor grow). K must be Hash + Eq; primitives and str work today:

import "stdlib/hash_map" as hash_map;

let mut m: hash_map::HashMap[str, i32] = hash_map::new::[str, i32]();
m.insert("hello", 42);
let present: bool = m.contains_key("hello");

Text — the owned string

stdlib/text is the owned, growable string, Text. It is a plain stdlib type (the compiler knows it only through one lang-item), so its whole API lives here and grows without touching the compiler. The borrowed view str stays a built-in; Text is what you reach for when you need to own and build up text.

import "stdlib/text" as text;

let mut s: text::Text = text::from_str("hello");
s.push_str(", world");
let n: usize = s.len();
let parts: vec::Vec[text::Text] = s.split(",");

The surface: new / with_capacity / from_str; push_str / clear / truncate / clone; len / capacity / is_empty; find / rfind / contains / starts_with / ends_with; slice, the trim family, and split -> Vec[Text]; the unsafe as_str borrow escape hatch; and c_str -> Option[CString] for the C ABI. Text is Send + Sync, so it is a valid thread::spawn payload and works inside Arc[Text].

String interpolation and .to_string() both produce a Text. They work even without importing the type — the value is just un-nameable until you import "stdlib/text".

Files and networking

  • stdlib/fsopen_read, create, read_to_end. File implements Drop and closes on scope exit.
  • stdlib/net — TCP client and server (connect_tcp, listen_tcp, accept). IPv4, numeric IPs.
  • stdlib/env — environment variables (var_into) and argv access.

Ownership wrappers

  • stdlib/box — a single heap-allocated owned value; unwrap() consumes it.
  • stdlib/arc — atomic refcounted shared ownership; clone() increments atomically, the last reference frees.
  • stdlib/rc — the single-threaded, non-atomic version. Rc[T] is !Send and !Sync, so the compiler rejects passing one across threads (E0502). Use Arc[T] to share across threads.

Concurrency

  • stdlib/thread, stdlib/atomic — threads and atomics.
  • stdlib/mutex — pthread-backed mutual exclusion, internally refcounted (it collapses Arc into itself, since C+ has no &T to make Arc[Mutex[T]] work).
  • stdlib/channel — typed message passing; handles clone for multi-producer / multi-consumer use.
  • stdlib/future, stdlib/executor, stdlib/reactor, stdlib/time — the async runtime.

Other modules

stdlib/cow (clone-on-write string), stdlib/range (the 0..n for in type), stdlib/iterator, and stdlib/marker (the compiler's Copy / Send / Sync markers, which you rarely touch directly).