Options and Results instead of sentinels. Panics instead of undefined
behavior. Vectors, slices, strings, hash maps and sets that check their
bounds. defer, smart pointers, pattern matching, and Go-style CSP with
coroutines and channels.
Pronounced "See-yan" because I'm a monster
#include <cyan/cyan.h>
RESULT_DEFINE(i32, ParseError);
// `?`-style early return: on Err, the whole Result propagates to the caller
Result_i32_ParseError parse_port(const char *s) {
i32 port = try_ok(parse_int(s, NULL));
if (port < 1 || port > 65535)
return Err(i32, ParseError, "port out of range");
return Ok(i32, ParseError, port);
}
int main(void) {
match_result(parse_port("8080"), i32, ParseError, port, err,
{ printf("listening on %d\n", port); },
{ fprintf(stderr, "bad config: %s\n", err); }
);
}Option_TandResult_T_Emake "no value" and "error" impossible to ignore silently, withunwrap,expect,and_then,ok_or, andtry_ok/try_someearly returns.- Plain structs, zero machinery: no vtables, no hidden pointers, no
runtime. An
Option_i32is abooland ani32, and every generated function isstatic inline. - Every convenience macro evaluates each argument exactly once, and
type-first naming (
VEC_PUSH(i32, v, 42)) mirrors the constructors (Some(i32, 42)). - Bounds-checked access returns Options, capacity math is overflow-guarded, and allocation failures panic instead of corrupting. 141 property-based tests (theft) pass clean under ASan/UBSan.
- Channels called inside coroutines yield instead of failing;
coro_runschedules them and detects deadlock. - Configurable: custom panic handler, custom allocator hooks, and
CYAN_NO_SHORT_NAMESifmap/filter/unwrapwould collide.
Copy include/cyan/ into your project. That's the whole install.
#include <cyan/cyan.h> // everything
// or pick modules:
#include <cyan/option.h>
#include <cyan/vector.h>Compile with GCC or Clang (-std=gnu11 or -std=c11; both accept the GNU
extensions used). On macOS add -D_XOPEN_SOURCE=700 if you use coroutines
(see Requirements).
// Options and Results ------------------------------------------------
Option_i32 third = vec_i32_get(&v, 2); // bounds-checked: Option
i32 x = unwrap_or(third, -1); // never a stray NULL
// Collections --------------------------------------------------------
Vec_i32 v = vec_i32_new(); // growable, bounds-checked
VEC_PUSH(i32, v, 42);
VEC_FOREACH(i32, v, it) printf("%d ", *it);
HashMap_str_i32 counts = hashmap_str_i32_new(); // content-hashed str keys
hashmap_str_i32_insert(&counts, "apple", 1); // key is copied & owned
// Strings ------------------------------------------------------------
String s = string_from("a,b,c");
Slice_char rest = string_as_slice(&s), part;
while (string_split_next(&rest, ',', &part)) // zero-copy split
printf("%.*s\n", (int)part.len, part.data);
// Cleanup ------------------------------------------------------------
defer({ close_thing(&thing); }); // runs on scope exit
string_auto(tmp, string_from("freed automatically"));Every module has its own page in docs/, with runnable
counterparts in examples/.
| Area | Pages |
|---|---|
| Core | Option · Result · Pattern matching · Primitive types |
| Collections | Vector · Slice · String · HashMap · HashSet |
| Memory | Defer · Smart pointers |
| Concurrency | Coroutines · Channels |
| Utilities | Functional · Serialization · Bit-width integers · Bitset |
| Library | Method-style macros · Panic handler · Configuration · Examples guide |
Version history lives in the changelog.
- C11 compatible compiler (GCC, Clang, or MSVC with C11 support)
- GCC/Clang recommended for:
deferand auto-cleanup features (uses__attribute__((cleanup)))- Statement expressions in pattern matching
- Nested functions in defer
- POSIX system for coroutines (uses
ucontext.h) - pthreads for thread-safe channels
- macOS note: for the coroutine
ucontextAPIs to be visible, either include Cyan headers before any system header, or compile with-D_XOPEN_SOURCE=700(the project Makefile does this)
make test # 141 property-based tests (theft, vendored submodule)
make test SANITIZE=1 # the same suite under AddressSanitizer + UBSanProperty-based testing via theft
(git submodule update --init on first clone).
Twenty runnable programs in examples/, each an API tour
that ends with a realistic "putting it together" scenario. The
examples guide describes what each one covers.
cd examples
make # build all
make run # run allMIT License. See LICENSE for details.