tqcq ec0718efc1
CI / build-and-test (clang) (push) Successful in 5m17s
CI / build-and-test (gcc) (push) Successful in 6m55s
CI / cross-arch-test (aarch64, aarch64-linux-gnu) (push) Successful in 8m23s
CI / cross-arch-test (armv7, arm-linux-gnueabihf) (push) Successful in 7m21s
CI / crash-dump-smoke (push) Successful in 1m57s
CI / format-check (push) Successful in 16s
CI / doxygen-build (push) Successful in 36s
CI / pdf-build (push) Successful in 2m42s
ci: auto-cancel superseded runs on the same ref
concurrency group CI-${{ github.ref }} with cancel-in-progress — on the
single runner an in-flight run for an older master commit blocks the newer
one for its full ~70 min; a new push now cancels the outdated run instead.
2026-09-05 12:24:13 +08:00

Teles — Cross-Platform C++14 Framework

Teles is a comprehensive C++14 framework providing a unified, modular set of utilities for building robust C++ applications. It abstracts away platform differences across Windows, macOS, and Linux, offering a single consistent API surface with no heavy dependencies (no Boost). Public headers are lightweight; implementation details are compiled into a static (or shared) library.

All third-party libraries ({fmt}, mpark::variant, ghc::filesystem, nlohmann/json, miniz) are fully encapsulated behind teles:: APIs — users never interact with upstream namespaces directly.

Quick Start

# Configure (builds static library by default)
cmake -B build -DCMAKE_BUILD_TYPE=Release

# Build (compiles tests if TELES_BUILD_TESTS=ON)
cmake --build build

# Run tests
cd build && ctest --output-on-failure

CMake Integration

# In your project's CMakeLists.txt:
find_package(teles REQUIRED)
target_link_libraries(my_app PRIVATE teles::teles)

Or add as a subdirectory:

add_subdirectory(teles)
target_link_libraries(my_app PRIVATE teles::teles)

Build Options

Option Default Description
TELES_BUILD_TESTS OFF Build Google Test unit tests + rapidcheck property tests
TELES_BUILD_FUZZ OFF Build libFuzzer/AFL++ fuzz targets
TELES_BUILD_SHARED OFF Build teles as a shared library (default: static)
TELES_INSTALL OFF Generate install targets (headers + library + CMake package)

Compiler Requirements

GCC 7+, Clang 7+, or MSVC 2019+ with full C++14 support.


Usage

Include everything via the umbrella header:

#include <teles/teles.h>

Or include individual module headers for finer control:

#include <teles/memory/allocator.h>
#include <teles/error/result.h>
#include <teles/str/string_ops.h>
#include <teles/concurrency/thread_pool.h>
#include <teles/fs/file_stream.h>
#include <teles/io/tcp.h>
#include <teles/reactive/reactive.h>
#include <teles/serialization/json.h>
#include <teles/config/config.h>
#include <teles/system/signal_handling.h>
#include <teles/system/crash_diagnostics.h>

Error Handling

#include <teles/teles.h>

using namespace teles;

// Success case
Result<int, Error> ParsePort(StringView s) {
    // ... parse logic ...
    return Ok(8080);
}

// Error case with cause chaining
Result<int, Error> ParsePort(StringView s) {
    return Err(Error::InvalidArgument("not a number")
                   .WithCause(Error::System(errno, "strtol failed")));
}

// Functional combinators
auto result = ParsePort("8080")
    .Map([](int port) { return port + 1; })
    .Inspect([](int v) { Print("port: {}\n", v); });

if (result) {
    int port = result.Value();
} else {
    Print("error: {}\n", result.Error().ToChainString());
}

Memory Allocation

#include <teles/teles.h>

using namespace teles;

// Default allocator (malloc/free)
void* p = memory::DefaultAllocator()->Allocate(128);

// Pool allocator — O(1) alloc/dealloc for fixed-size blocks
memory::PoolAllocator pool(sizeof(Node), 1024);
void* node = pool.Allocate(sizeof(Node));
pool.Deallocate(node);

// Arena allocator — bump-pointer, bulk-free for short-lived objects
{
    memory::ScopedArena arena(64 * 1024);
    char* buf = static_cast<char*>(arena.Allocate(256));
    // memory reclaimed on scope exit
}

// Tracking allocator — leak detection, guard bytes (debug builds)
memory::TrackingAllocator tracker(memory::DefaultAllocator());
void* tracked = tracker.Allocate(64);
tracker.Deallocate(tracked);
auto stats = tracker.Stats();  // allocCount, peakBytes, liveAllocations, ...

String Operations

#include <teles/teles.h>

using namespace teles;

// Split / Trim / Replace
auto parts = str::Split("a,b,c", ',');           // {"a", "b", "c"}
auto trimmed = str::Trim("  hello  ");            // "hello"
auto replaced = str::ReplaceAll("foo bar foo", "foo", "baz");

// Case conversion
str::ToCamelCase("hello_world");    // "helloWorld"
str::ToSnakeCase("HTTPServer");     // "http_server"
str::ToKebabCase("XMLParser");      // "xml-parser"

// Natural ordering
str::NaturalLess less;
less("file2", "file10");  // true — numeric comparison of digit runs

// StringBuilder / StrCat
std::string s = str::StrCat("x = ", 42, ", y = ", 3.14);

// UTF-8
str::utf8::IsValid("héllo");  // true
str::utf8::Length("héllo");   // 5 (code points, not bytes)

// Encoding conversion
auto utf16 = str::Utf8ToUtf16("héllo");
auto wide = str::Utf8ToWide("héllo");

Formatting

#include <teles/teles.h>

using namespace teles;

// {fmt} is a public dependency — format directly
auto s = fmt::format("x = {}, y = {:>8}", 42, "hi");
fmt::print("count: {}\n", 100);

// ToString: the only hand-written overloads are the null-safe pair
format::ToString("str");    // copy, null-safe
format::ToString(nullptr);  // ""

// TELES_ENUM macro — generates enum + Names + Count + ToString + TryParse
TELES_ENUM(Color, Red, Green, Blue);
// Generates:
//   enum class Color { Red, Green, Blue };
//   const char* const* ColorNames();
//   constexpr std::size_t ColorCount();
//   std::string ToString(Color);
//   bool TryParseColor(StringView, Color&);

Community Sugar

#include <teles/teles.h>

using namespace teles;

// TELES_TRY — Rust-style ? operator for Result propagation
Result<int, Error> Compute() {
    TELES_TRY_ASSIGN(a, ParseValue("42"));
    TELES_TRY_ASSIGN(b, ParseValue("100"));
    return Ok(a + b);
}

// Overloaded — visitor pattern with lambdas
auto visitor = core::MakeOverloaded(
    [](int x) { return "int"; },
    [](double x) { return "double"; },
    [](StringView x) { return "string"; }
);

// Match — pattern matching on Optional
auto result = core::Match(maybeValue,
    [](int v) { return v * 2; },    // onSome
    []() { return 0; }              // onNone
);

// Box — ownership transfer (unique_ptr alias)
auto obj = std::make_unique<MyClass>(arg1, arg2);

// User-defined literals
using namespace teles::literals;
auto sv = "hello"_sv;           // StringView
auto s = "world"_s;             // std::string
auto sz = 4_KB;                 // std::size_t (4096)
auto dur = 500_ms;              // std::chrono::milliseconds

// Bit operations
bitops::PopCount32(0xFF);       // 8
bitops::CountLeadingZeros32(1); // 31
bitops::IsPowerOfTwo(64);       // true

// Hash combining
std::size_t h = core::HashValue(x, y, z);

Concurrency

#include <teles/teles.h>

using namespace teles;
using namespace teles::concurrency;

// --- ThreadPool with rejection policy ---
ThreadPoolConfig cfg;
cfg.coreThreads = 4;
cfg.maxThreads = 16;
cfg.queueCapacity = 256;
cfg.rejectionPolicy = RejectionPolicy::CallerRuns;  // run in submitting thread
ThreadPool pool(cfg);

// Submit returns Future<R>
Future<int> f = pool.Submit([] {
    // ... work ...
    return 42;
});
int result = f.Get();  // blocking

// --- Global pools (lazily initialized) ---
Future<int> f1 = CpuPool()->Submit([] { return 1; });
Future<int> f2 = IoPool()->Submit([] { return 2; });
Future<int> f3 = SinglePool()->Submit([] { return 3; });
Schedulers::Shutdown();  // optional teardown

// --- Async helpers ---
Future<int> a = Async([] { return 100; });           // submits to CpuPool
Future<int> b = AsyncOn(pool, [] { return 200; });    // submits to a specific pool

// --- Future combinators ---
Promise<int> p;
Future<int> base = MakeFuture(p);

auto chained = Then(base, [](int v) { return v * 2; });      // 84
auto recovered = OnError(chained, [](Error) { return -1; }); // recover on error
auto timed = WithTimeout(recovered, 500_ms);                  // error if > 500ms

p.SetValue(42);  // settle the chain

// All — wait for every future
std::vector<Future<int>> futures = {
    Async([] { return 1; }),
    Async([] { return 2; }),
    Async([] { return 3; })
};
Future<std::vector<int>> all = All(futures);
auto vals = all.Get();  // {1, 2, 3}

// Any — first to complete wins
std::vector<Future<int>> racers = {
    Async([] { return 10; }),
    Async([] { return 20; })
};
Future<int> winner = Any(racers);
int first = winner.Get();  // 10 or 20

// --- Channel<T> (Go-style) ---
Channel<int> ch(8);   // bounded, capacity 8
Channel<int> unbounded;  // unbounded

ch.Send(1);
Optional<int> v = ch.Recv();  // 1
Optional<int> e = ch.TryRecv();  // non-blocking; empty if nothing available
bool ok = ch.SendFor(2, Duration::Milliseconds(100));  // timed; false = timeout/closed
Optional<int> t = ch.RecvFor(Duration::Milliseconds(100));  // timed receive

// --- Mutex / RwLock ---
Mutex<int> mtx(0);
mtx.With([](int& v) { v++; });  // lambda executes under lock

RwLock<Config> rwlock;
rwlock.WithRead([](const Config& c) { /* read-only access */ });
rwlock.WithWrite([](Config& c) { c.Update(); });

// --- Synchronization primitives ---
Latch latch(3);
latch.CountDown();   // count down from 3
latch.Wait();        // blocks until count reaches 0

WaitGroup wg(5);
wg.Done();  // decrement
wg.Wait();  // blocks until 0

Filesystem

#include <teles/teles.h>

using namespace teles;
using namespace teles::fs;

// --- Path manipulation ---
Path p = Path("/usr/local") / "bin" / "app";
p.Filename();      // "app"
p.Extension();     // ""
p.Parent();        // "/usr/local/bin"
p.IsAbsolute();    // true

// --- One-shot file read/write ---
auto content = ReadFile("/etc/hostname");
if (content) {
    Print("hostname: {}\n", content.Value());
}

WriteFile(Path("/tmp/test.txt"), "hello world");

// --- File status (type, size, timestamps, permissions) ---
auto status = Status(Path("/tmp/test.txt"));
if (status) {
    // status.Value().type, .size, .modifiedNanos, .accessedNanos, .createdNanos
}

// --- FileStream: streaming sequential/random I/O ---
FileStream stream(Path("/tmp/data.bin"), FileMode::Read, 8192);
auto bytesRead = stream.Read(buf, sizeof(buf));
stream.Seek(0, SeekOrigin::Begin);   // rewind
auto pos = stream.Tell();
stream.Close();  // or let RAII close on destruction

// --- Directory iteration ---
for (auto& entry : BeginDirectory(Path("/tmp"))) {
    Print("{}\n", entry.path.Str());
}

// Recursive iteration with symlink-cycle-safe CopyRecursive
CopyRecursive(Path("/src"), Path("/dst"));

// --- TempDir / TempFile (RAII cleanup) ---
{
    TempDir tmp("myapp");
    WriteFile(tmp.Get() / "config.json", "{}");
    // directory deleted on scope exit
}

// --- Glob pattern matching ---
auto files = Glob("/tmp/*.log");
for (const auto& f : files.Value()) {
    Print("matched: {}\n", f.Str());
}

I/O (Networking + Async)

#include <teles/teles.h>

using namespace teles;
using namespace teles::io;

// --- EventLoop (signal-driven reactor, no external proactor lib) ---
concurrency::EventLoop loop;
std::thread loop_thread([&] { loop.Run(); });

// --- TCP client (signal-based; hold in a shared_ptr) ---
auto conn = std::make_shared<TcpConnection>(&loop);

auto connected = conn->OnConnected.Connect([](TcpConnection* c) {
    c->SetNoDelay(true);
    const uint8_t req[] = "GET / HTTP/1.0\r\n\r\n";
    c->Write(req, sizeof(req) - 1);  // buffered; OnWritable fires when drained
});
auto onData = conn->OnData.Connect(
    [](TcpConnection* c, const uint8_t* data, size_t len) {
        // data is valid only during the callback — copy it if needed
    });

// Connect() returns a Future resolving to Result<void> — Get() never throws
auto connectResult = conn->Connect("example.com", 80).Get();
if (connectResult.Ok()) {
    conn->SetTimeout(5_s);      // idle timeout watchdog
    conn->SetKeepAlive(true);   // TCP keep-alive
}

conn->Close();

// --- Timers (TimerQueue-based; RAII Disposable cancels on destruction) ---
concurrency::CoarseTimerQueue tq;
auto t1 = concurrency::SetTimeout(&tq, 500_ms, [&] { Print("fired!\n"); });
auto t2 = concurrency::SetInterval(&tq, 1_s, [&] { PollSensors(); },
                                   concurrency::MissedTick::Skip);

// --- Blocking sleep (monotonic base) ---
time::SleepFor(100_ms);

// --- Async file I/O (offloaded to a ThreadPool) ---
concurrency::ThreadPoolConfig cfg;
cfg.coreThreads = 4;
concurrency::ThreadPool pool(cfg);
auto data = AsyncReadFile(pool, Path("/tmp/large.bin")).Get().Value();

loop.Stop();
loop_thread.join();

Reactive (teles::reactive)

Push-based composable streams — Flowable<T> with Rx-style operators, backpressure strategies, schedulers, and subjects.

#include <teles/teles.h>

using namespace teles;
using namespace teles::reactive;

// --- Flowable basics: Subscribe returns a Subscription (RAII auto-cancel) ---
auto src = FlowableRange(1, 5);  // emits 1, 2, 3, 4, 5

{
    auto sub = src.Subscribe(
        [](int v) { Print("got: {}\n", v); },
        [](std::exception_ptr) { Print("error\n"); },
        []() { Print("done\n"); }
    );
    // Callback-style Subscribe requests unbounded demand for you.
    // sub auto-cancels at scope exit.
}

// SubscribeAndForget — fire-and-forget (no Subscription to manage)
src.SubscribeAndForget([](int v) { Print("val: {}\n", v); });

// --- Chain methods (preferred) ---
auto doubled = FlowableRange(1, 3)
    .Map<int>([](int x) { return x * 2; });          // 2, 4, 6

auto scan = FlowableRange(1, 4).Scan<int>(
    0, [](int acc, int x) { return acc + x; });      // 1, 3, 6, 10 (running sum)

// FlatMap — map each item to an inner Flowable, merge results
auto flat = FlowableRange(1, 3).FlatMap<int>(
    [](int x) { return FlowableRange(x, 2); });      // 1,2, 2,3, 3,4 (interleaved)

// --- Filtering operators ---
auto evens = FlowableRange(1, 10).Filter(
    [](int x) { return x % 2 == 0; });
auto first3 = FlowableRange(1, 100).Take(3);   // 1, 2, 3 then complete
auto skip2 = FlowableRange(1, 5).Skip(2);      // 3, 4, 5
auto uniq = FlowableFromIterable<int>({1, 1, 2, 2, 3, 3, 1})
    .DistinctUntilChanged();                   // 1, 2, 3, 1

// --- Combining operators ---
auto merged = Merge(std::vector<Flowable<int>>{
    FlowableFromIterable<int>({1, 2}),
    FlowableFromIterable<int>({3, 4})
});  // 1, 2, 3, 4 (interleaved)

auto concatenated = Concat(
    FlowableFromIterable<int>({1, 2}),
    FlowableFromIterable<int>({3, 4}));  // 1, 2, 3, 4 (sequential)

// Zip — binary form with a zipper; the vector-emitting form uses a vector zipper
auto zipped = Zip<int, int, std::vector<int>>(
    FlowableFromIterable<int>({1, 2}),
    FlowableFromIterable<int>({10, 20}),
    [](int a, int b) { return std::vector<int>{a, b}; });
// {1,10}, {2,20}

auto prefixed = StartWith(FlowableRange(3, 2), {0, 1, 2});  // 0, 1, 2, 3, 4

// --- Aggregate operators ---
auto sum = FlowableRange(1, 5).Reduce(
    [](int a, int b) { return a + b; });  // 15

auto cnt = Count(FlowableRange(1, 100));  // 100 (emits int64_t)

auto list = FlowableRange(1, 3).ToList();
// emits {1, 2, 3} as a single std::vector<int>

auto collected = Collect<int, std::string>(
    FlowableRange(1, 3),
    std::string(""),
    [](std::string& acc, int x) { acc += std::to_string(x); }
);  // "123"

// --- Error handling ---
auto withFallback = OnErrorReturnItem<int>(
    FlowableThrow<int>(std::make_exception_ptr(std::runtime_error("oops"))),
    -1
);  // emits -1, then completes

// --- Side-effect / utility ---
auto logged = FlowableRange(1, 3).DoOnNext(
    [](int v) { Print("side: {}\n", v); });

auto cleaned = FlowableRange(1, 3).DoFinally(
    []() { Print("cleanup\n"); });

// --- First (emit first item, then complete) ---
auto firstOnly = First(FlowableRange(1, 100));  // emits 1, then completes

// --- Blocking operators (synchronous extraction) ---
// BlockingFirst — block until the first emission, return T by value
int first = BlockingFirst(FlowableRange(1, 100));       // 1
int last = BlockingLast(FlowableRange(1, 5));           // 5
// Empty/erroring sources throw std::out_of_range (or rethrow the upstream error).

// --- Custom sources: Create(fn, strategy) + FlowableEmitter ---
auto custom = Flowable<int>::Create(
    [](FlowableEmitter<int>& em) {
        for (int i = 1; i <= 3 && !em.State()->IsCancelled(); ++i) {
            em.OnNext(i);
        }
        em.OnComplete();
    },
    BackpressureStrategy::Missing);

// --- Backpressure strategies (OnBackpressure*) ---
// OnBackpressureBuffer — buffer items when downstream can't keep up
auto buffered = OnBackpressureBuffer(FlowableRange(1, 10));
// OnBackpressureDrop — drop items when downstream can't keep up
auto dropped = OnBackpressureDrop(FlowableRange(1, 100));
// OnBackpressureLatest — keep only the most recent value
auto latest = OnBackpressureLatest(FlowableRange(1, 100));

// --- Defer — lazy factory (creates a Flowable per subscription) ---
int counter = 0;
auto deferred = FlowableDefer<int>([&counter]() {
    counter++;
    return FlowableJust(counter);  // fresh source each subscribe
});
// Each subscription gets a new FlowableJust(counter) at subscribe-time

// --- Factory methods ---
FlowableJust(42);                 // single value, then complete
FlowableEmpty<int>();             // immediate complete
FlowableNever<int>();             // never emits, never completes
FlowableThrow<int>(ep);           // immediate error

// --- Bridge to Future (teles/reactive/future_bridge.h) ---
auto fut = FlowableJust(7).ToFuture();       // resolves with the first value
auto flw = FromFuture<int>(some_future);     // Future → Flowable

// --- Subjects (hot flowables) ---
PublishSubject<int> pub;          // broadcast, no history
auto flw1 = pub.AsFlowable();
flw1.Subscribe([](int v) { Print("A: {}\n", v); });
pub.OnNext(1);                    // A: 1
pub.OnNext(2);                    // A: 2

BehaviorSubject<int> beh(0);      // replays last value to new subscribers
beh.OnNext(42);
beh.AsFlowable().Subscribe(
    [](int v) { Print("late: {}\n", v); });  // late: 42 (replayed)

ReplaySubject<int> repl(3);       // bounded replay buffer (last 3)
repl.OnNext(10);
repl.OnNext(20);
repl.OnNext(30);
repl.AsFlowable().Subscribe(
    [](int v) { Print("replay: {}\n", v); });
// replay: 10, replay: 20, replay: 30

// --- ConnectableFlowable (multicast) ---
// Publish wraps a source so it can be shared among multiple subscribers
auto connectable = Publish(FlowableRange(1, 5));

// Subscribe before connecting — all subscribers see the same emissions
connectable.Ref().Subscribe([](int v) { Print("A: {}\n", v); });
connectable.Ref().Subscribe([](int v) { Print("B: {}\n", v); });

// Connect starts broadcasting upstream to all subscribers
auto conn = connectable.Connect();
// Both A and B see 1, 2, 3, 4, 5

// Share — auto-connect on first subscriber, auto-disconnect on last unsubscribe
auto shared = Share(FlowableRange(1, 5));
shared.Subscribe([](int v) { Print("shared: {}\n", v); });

// --- Schedulers ---
// ImmediateScheduler runs tasks inline on the calling thread
teles::concurrency::ImmediateScheduler imm;
imm.Submit([] { Print("inline\n"); });

// Global thread pools (lazily initialized)
CpuPool()->Submit([] { Print("on cpu pool\n"); });
IoPool()->Submit([] { Print("on io pool\n"); });
Schedulers::Shutdown();           // optional teardown

System (teles::system)

Signal handling and crash diagnostics for production reliability.

#include <teles/teles.h>

using namespace teles;
using namespace teles::system;

// --- Signal handling (self-pipe pattern — callbacks run on a normal thread) ---
SignalHandler handler;
handler.Register(Signal::Interrupt, [](Signal s) {
    Print("Caught signal: {}\n", SignalName(s));
    // graceful shutdown logic here
});
handler.Register(Signal::Hangup, [](Signal) { ReloadConfig(); });
// Signal::Terminate, Signal::User1, Signal::User2, ... also available

// Block signals in a critical section (restored on scope exit)
SignalBlocker blocker(SignalSet{Signal::Interrupt, Signal::Quit});

// Ignore / restore default disposition
IgnoreSignal(Signal::Pipe);      // SIG_IGN — don't crash on broken pipe
DefaultSignal(Signal::Pipe);     // restore SIG_DFL

// Thread naming for diagnostics
SetThreadName("worker-1");
Print("thread: {}\n", ThreadName());   // "worker-1"
Print("tid: {}\n", CurrentThreadId());

// Spawn a configured thread: named/pinned before its first instruction
system::ThreadOptions opts;
opts.name = "db-worker";
opts.affinity = {0};
system::Thread worker(std::move(opts), [] { /* ... */ });
worker.TryJoinFor(teles::time::Duration::Milliseconds(500));

// --- Crash diagnostics ---
// Install a global crash handler for SIGSEGV/SIGABRT/SIGFPE/SIGILL/SIGBUS.
// The config also arms the minidump tier: a crash (or CaptureDump below)
// freezes every thread and a raw-clone child writes a standard MDMP file.
system::CrashHandlerConfig crash;
crash.callback = [](const system::CrashReport& report) {
    // Invoked in a forked child — safe to use std::string, malloc, etc.
    // Persist the report to a monitoring system, send an alert, ...
};
crash.log_file_path = "/var/log/myapp/crash.log";  // "" = stderr only
crash.dump_dir = "/var/log/myapp";                 // "" = working dir
auto installed = system::InstallCrashHandler(crash);  // Result<void, Error>

// Capture a minidump at any point (not just on crash) — the process
// survives and resumes. Optionally pin app-owned memory into every dump:
system::RegisterDumpRegion(&app_state, sizeof(app_state), "app-state");
auto dump = system::CaptureDump("pre-upgrade snapshot");  // Result<path>

// Capture a backtrace at any point (not just on crash)
auto frames = Backtrace(1, 32);   // skip this frame, max 32 deep
Print("{}\n", FormatBacktrace(frames));

// CrashReport fields: signal, message, timestamp, threadId,
//   stackTrace, platformInfo, threadName, dumpPath

Design notes:

  • SignalHandler uses the self-pipe pattern: the async-signal-safe handler only writes a byte to a pipe, and user callbacks execute on an internal reader thread — never inside a signal handler context
  • SignalBlocker wraps pthread_sigmask and restores the previous mask on destruction
  • InstallCrashHandler collects the backtrace using only async-signal-safe functions, then forks a child process to invoke the user callback — this allows the callback to use non-signal-safe functions (std::string, malloc, etc.)
  • After writing the crash report, the handler re-raises the signal so the process terminates with the correct exit status

Application Layer

#include <teles/teles.h>

using namespace teles;
using namespace teles::serialization;

// --- JSON parsing and serialization ---
auto j = Json::Parse(R"({"name":"teles","version":1,"enabled":true})");
if (j.HasValue()) {
    Json root = j.Value();
    std::string name = root["name"].AsString();    // "teles"
    bool enabled = root["enabled"].AsBool();       // true
    Print("name: {}, enabled: {}\n", name, enabled);
}

// Build JSON programmatically
Json obj;
obj["port"] = Json(8080);
obj["host"] = Json("localhost");
Print("config: {}\n", obj.Dump());   // {"host":"localhost","port":8080}

// --- TELES_SERIALIZABLE: automatic ToJson generation ---
struct ServerConfig {
    std::string host;
    int port;
    bool tls;
};
TELES_SERIALIZABLE(ServerConfig, host, port, tls)

ServerConfig cfg{"0.0.0.0", 443, true};
Json json = ToJson(cfg);               // {"host":"0.0.0.0","port":443,"tls":true}
std::string str = ToJsonString(cfg);   // compact JSON string

// --- Configuration management ---
using namespace teles::config;

ConfigManager manager;

// JSON config provider with dot-path traversal
auto cfgJson = Json::Parse(R"({"server":{"port":8080,"host":"0.0.0.0"},"debug":false})");
if (cfgJson.HasValue()) {
    manager.AddProvider(std::make_shared<JsonConfigProvider>(cfgJson.Value(), "app", 0));
}

// Load from file
auto fileSrc = JsonConfigProvider::FromFile("/etc/myapp/config.json", 0);
if (fileSrc.IsOk()) {
    manager.AddProvider(std::make_shared<JsonConfigProvider>(fileSrc.Value()));
}

// Environment variable provider (MYAPP_ prefix, type inference)
// e.g. MYAPP_SERVER_PORT=9090 overrides the JSON value
manager.AddProvider(std::make_shared<EnvConfigProvider>("MYAPP_", 10));

// Priority-ordered merge: higher priority provider wins
int port = manager.GetInt("server.port", 8080);
bool debug = manager.GetBool("debug", false);
std::string host = manager.GetString("server.host", "localhost");

System (teles::system)

Signal handling and crash diagnostics for production-grade applications.

Component Header Description
Signal enum system/signal_handling.h 17 named signals (Interrupt, Terminate, SegFault, Abort, ...) mapped to platform constants
ToNativeSignal() / FromNativeSignal() system/signal_handling.h Convert between Signal enum and native integer signal numbers
SignalName() system/signal_handling.h Human-readable name for a Signal value
SignalSet system/signal_handling.h Signal set builder: Add/Remove/Contains/Size, converts to sigset_t for pthread_sigmask
SignalHandler system/signal_handling.h Self-pipe pattern handler: Register/Unregister callbacks that run on an internal thread (not in signal context)
SignalBlocker system/signal_handling.h RAII guard around pthread_sigmask — blocks signals in scope, restores previous mask on destruction
IgnoreSignal() / DefaultSignal() system/signal_handling.h Set SIG_IGN / SIG_DFL disposition for a signal
CurrentThreadId() system/thread_info.h Stable uint64_t identifier for the calling thread
ThreadName() / SetThreadName() system/thread_info.h Get/set the calling thread's name (pthread_getname_np / SetThreadDescription); truncated to 15 bytes on Linux
Thread + ThreadOptions system/thread.h Native thread with spawn-time name/priority/affinity/stack-size (applied before the first instruction), bounded TryJoinFor, RAII join
StackFrame system/crash_diagnostics.h Stack frame info: address, functionName, fileName, line, column
Backtrace() system/crash_diagnostics.h Capture current call stack with skipFrames and maxDepth; symbols resolved via dladdr
FormatBacktrace() system/crash_diagnostics.h Format vector<StackFrame> into readable text
CrashReport system/crash_diagnostics.h Structured crash info: signal, message, timestamp, threadId, stackTrace, platformInfo, threadName, dumpPath
FormatCrashReport() system/crash_diagnostics.h Format a CrashReport into a human-readable string
InstallCrashHandler(CrashHandlerConfig) system/crash_diagnostics.h Install global handler for SIGSEGV/SIGABRT/SIGFPE/SIGILL/SIGBUS; async-signal-safe backtrace, fork-based callback, minidump tier. Result<void, Error> — an Err leaves nothing installed
UninstallCrashHandler() / IsCrashHandlerInstalled() system/crash_diagnostics.h Remove crash handler / query installation state
CaptureDump(reason) system/crash_dump.h On-demand standard-minidump capture of the whole process; synchronous, process-surviving, returns the dump path
RegisterDumpRegion() / UnregisterDumpRegion() system/crash_dump.h Pin app-owned memory ranges into every dump (64-entry table, tagged)
GetResolvedDumpTracerMode() system/crash_dump.h What DumpTracerMode::kAuto resolved to at install time (also recorded in every dump's marker)
GetPlatformInfo() system/crash_diagnostics.h OS name, version, and architecture string

Design notes:

  • SignalHandler uses the self-pipe pattern: the actual signal handler (installed via sigaction) only performs an async-signal-safe write() to a pipe; user callbacks execute on an internal reader thread, so they are never constrained by async-signal-safety rules
  • Only one callback per signal is supported; re-registering replaces the previous callback
  • SignalBlocker saves the previous signal mask on construction and restores it on destruction — safe for nested blocking scopes
  • InstallCrashHandler operates in two phases: (1) the signal-safe handler collects the backtrace and writes to a file descriptor or stderr, then (2) forks a child process to invoke the user CrashCallback — this allows the callback to use std::string, malloc, std::function, etc. without undefined behavior
  • After reporting, the crash handler re-raises the signal so the process terminates with the correct status (and core dumps are generated if enabled)
  • Backtrace() uses backtrace() + dladdr() for symbol resolution; fileName and line may be empty if debug symbols are unavailable

Serialization (teles::serialization)

JSON wrapper around nlohmann/json with automatic struct serialization via macros.

Component Header Description
Json serialization/json.h Opaque JSON value wrapper: Parse/Dump/DumpPretty, type queries (IsNull/IsBool/...), At/Set/operator[] const reads, Native access
Json::Type serialization/json.h Type enum: Null/Bool/Number/String/Array/Object
ToJson() serialization/serializer.h Built-in overloads for bool, int, int64_t, double, const char*, string, vector, map<string,V>
FromJson<T>() serialization/serializer.h Deserialize built-in types from Json (bool, int, int64_t, double, string)
FromJsonVector<T>() serialization/serializer.h Deserialize JSON array to vector<T>
To<T>() / TryFrom<T>() serialization/serializer.h Generic serialize/deserialize entry points
ToJsonString() / FromJsonString<T>() serialization/serializer.h Convenience: serialize to string / parse + deserialize in one call
TELES_SERIALIZABLE serialization/serializer.h Macro generating ToJson() for user structs (112 fields)

Design notes:

  • Json fully encapsulates nlohmann/json — users never interact with the upstream namespace directly
  • TELES_SERIALIZABLE(Type, field1, field2, ...) generates a ToJson(const Type&) free function found via ADL; supports 112 fields
  • FromJsonString<T>() returns Optional<T> — empty Optional indicates a parse failure

Configuration (teles::config)

Multi-provider configuration with priority-ordered merge, JSON file loading, and environment variable support.

Component Header Description
ConfigValue config/config.h Type-safe value: Bool/Int/Double/String/Null with As* and As*Or accessors
ConfigProvider config/config.h Abstract interface: Name()/Priority()/Get(key) — higher priority overrides lower
JsonConfigProvider config/config.h JSON-backed provider with dot-path traversal ("server.port") and FromFile factory
EnvConfigProvider config/config.h Environment variable provider with prefix transformation and type inference (int/double/bool/string)
ConfigManager config/config.h Multi-provider priority merge: AddProvider/RemoveProvider, GetBool/GetInt/GetDouble/GetString with defaults

Design notes:

  • ConfigManager::AddProvider() sorts providers by priority descending — the first provider that has a key wins on lookup
  • JsonConfigProvider::Get() traverses dot-separated paths (e.g. "server.port"data["server"]["port"])
  • EnvConfigProvider transforms keys by uppercasing and replacing . with _, prefixed with the configured prefix (e.g. "server.port" with prefix "MYAPP_""MYAPP_SERVER_PORT")
  • EnvConfigProvider infers types: numeric strings become Int or Double, "true"/"1"/"yes" become Bool(true), everything else stays String
  • JsonConfigProvider::FromFile() returns Result<JsonConfigProvider> for structured error handling on file I/O or JSON parse failures

Core Types (teles::core)

Self-implemented C++14 standard-library gaps and community sugar.

Component Header Description
Optional<T> core/optional.h Self-implemented optional with Map/AndThen/Filter/OrElse combinators
Variant<Ts...> core/variant.h Type-safe union (wraps mpark::variant)
StringView core/string_view.h Non-owning string reference (~150 lines)
Span<T> core/span.h Non-owning array view (~120 lines)
Byte core/byte.h Type-safe byte type
Platform core/platform.h Compile-time OS/compiler/arch detection with 8 categories
Assert core/assert.h TELES_ASSERT / TELES_CHECK macros
Defer / TELES_SCOPE_* core/utility.h RAII deferred execution
NotNull<T> core/not_null.h Non-null pointer wrapper
Any core/any.h Type-erased single value
FunctionRef<Sig> core/function_ref.h Non-owning callable reference

Community Sugar (Phase 2):

Component Header Description
TELES_TRY / TELES_TRY_ASSIGN core/try_macros.h Rust-style ? operator for Result error propagation
Overloaded<Fs...> core/overloaded.h Multi-lambda visitor via inheritance pack
Literals (_sv, _s, _ms, _KB, ...) core/literals.h User-defined literal operators
SourceLocation core/source_location.h Lightweight source-position capture (TELES_HERE)
HashCombine / HashValue core/hash.h Boost-style hash combining for heterogeneous args
bitops:: core/bitops.h CLZ/CTZ/PopCount/Rotate/IsPowerOfTwo/Bit — constexpr intrinsics
IsDetected / DetectedOrT core/detect.h N4502 detection idiom for C++14
ArraySize / MakeArray / MakeSpan core/array_utils.h Array utilities
Box<T> core/utility.h unique_ptr alias
Match(optional, onSome, onNone) core/match.h Functional pattern matching on Optional<T>

Memory (teles::memory)

Allocator model with diagnostics, alignment, and factory functions.

Component Header Description
IAllocator memory/allocator.h Abstract allocator interface (Allocate/Deallocate/Name)
MallocAllocator memory/allocator.h Thread-safe malloc/free reference implementation
DefaultAllocator() / SetDefaultAllocator() memory/allocator.h Process-wide singleton with one-shot replacement
PoolAllocator memory/pool_allocator.h Fixed-block O(1) allocator via intrusive free list
ArenaAllocator memory/arena_allocator.h Bump-pointer allocator with chunk linked list, Reset()
ScopedArena memory/scoped_arena.h RAII wrapper around ArenaAllocator
TrackingAllocator memory/tracking_allocator.h Debug wrapper: guard bytes, fill patterns, leak detection, stats
AlignedAlloc / AlignedFree memory/aligned.h Platform-native aligned allocation + constants
MakeUnique / MakeShared memory/factory.h Allocator-aware smart-pointer factories
GetProcessMemory() memory/process_info.h RSS, virtual, and peak-RSS reporting (Linux/macOS/Windows)
Debug fill constants memory/debug_fill.h 0xCD/0xDD/0xFD patterns + sanitizer coexistence gating

Design principles:

  • Allocate returns nullptr on failure (never throws)
  • Debug instrumentation (guard bytes, fill patterns) is compile-time gated against ASan/MSan to avoid double overhead
  • TrackingAllocator degrades to stats-only mode when a sanitizer is active
  • Pool and arena allocators are not thread-safe (callers synchronize)

Error & Result (teles::error)

Result-first error handling with functional combinators.

Component Header Description
Error error/error.h Structured error: code + message + category + cause chain
ErrorCategory error/error.h System / Network / IO / Config / InvalidArgument / Runtime / Unknown
Result<T, E> error/result.h Rust-inspired result type with Map/MapErr/AndThen/OrElse/Inspect/Unwrap
Ok() / Err() error/result.h Concise construction helpers
Exception hierarchy error/exceptions.h TelesException base + 6 category-specific subclasses

Result<T, E> combinators:

Combinator Signature Description
Map(f) T → U Transform Ok value, propagate Err
MapErr(f) E → F Transform Err value, propagate Ok
AndThen(f) T → Result<U,E> Monadic bind; Err short-circuits
OrElse(f) E → Result<T,F> Error recovery; Ok short-circuits
Inspect(f) T& → void Side-effect on Ok, returns *this
InspectErr(f) E& → void Side-effect on Err, returns *this
Unwrap() Value or throw on Err
UnwrapOr(fallback) Value or fallback
UnwrapOrElse(f) Value or f(error)

String (teles::str)

Locale-independent string operations, UTF-8 codec, and encoding conversion.

Component Header Description
ascii:: classifiers str/ascii.h 11 classifiers (IsDigit, IsAlpha, IsSpace, ...)
String operations str/string_ops.h Split/Trim/Replace/Search/Pad/Repeat/Truncate/Partition
Case conversions str/case.h ToCamelCase / ToSnakeCase / ToKebabCase / ToPascalCase / ToTrainCase
StringBuilder str/string_builder.h Mutable builder with AppendFmt() and StrCat()
NaturalCompare str/natural_compare.h Numeric-aware ordering ("file2" < "file10")
Layout helpers str/string_ops.h WordWrap, Indent, Dedent
UTF-8 codec str/utf8.h Validate/Length/Encode/Decode/Substring/Iterator, ToUpper/ToLower
Encoding conversion str/utf_convert.h UTF-8 ↔ UTF-16/UTF-32/Wide with BOM detection

All functions are locale-independent (pure ASCII range tests, ICU-free).

Format (teles::format)

Enum name tables and null-safe ToString helpers. Everything else is {fmt} — a public dependency — used directly.

Component Header Description
ToString null-safe overloads format/to_string.h const char* and nullptr_t (fmt covers scalars/containers natively)
FormatEnum / TELES_ENUM format/enum_format.h Enum-to-string via name table + X-macro generating Names/Count/ToString/TryParse

Concurrency (teles::concurrency)

Thread pools, futures, channels, synchronization primitives, and concurrency patterns.

Component Header Description
ThreadPool concurrency/thread_pool.h Configurable pool with priority queue, timed/periodic scheduling, metrics
ThreadPoolConfig / ThreadPoolMetrics concurrency/thread_pool.h Config (core/max threads, keepAlive, queue capacity, RejectionPolicy) + runtime stats
RejectionPolicy concurrency/thread_pool.h Abort / CallerRuns / Discard / DiscardOldest
Future<T> / Promise<T> concurrency/future.h Shared-state future: Get/IsReady/WaitFor/WaitUntil/TryGet + cancellation
Ready() / Then() / ThenOn() concurrency/future_combinators.h Value factory, continuation chaining (inline or on a pool)
OnError() / WithTimeout() concurrency/future_combinators.h Error recovery continuation + deadline race
All() / Any() / ThenCompose() concurrency/future_combinators.h Wait-all, race (first-wins), flatMap chaining
Async() / AsyncOn() concurrency/future_combinators.h Submit to CpuPool or a specified pool
CpuPool() / IoPool() / SinglePool() concurrency/schedulers.h Lazy global pools: fixed CPU, elastic IO, single-thread
Schedulers::Shutdown() concurrency/schedulers.h Teardown for all global pools
Channel<T> concurrency/channel.h Go-style bounded/unbounded channels with timed SendFor/RecvFor
Mutex<T> / RecursiveMutex<T> concurrency/mutex.h Timed mutex with data slot + lambda sugar; reentrant variant
RwLock<T> concurrency/rwlock.h Writer-preference read-write lock with ReadGuard/WriteGuard
Atomic<T> / AtomicIntegral<T> / AtomicEnum<T> concurrency/atomic.h std::atomic wrappers with teles MemoryOrder enum
AtomicFlag / AtomicOptional<T> concurrency/atomic.h Flag and optional-with-CAS atomic types
CondVar / Semaphore / WaitGroup concurrency/sync.h Condition variable, counting semaphore, wait-group
Latch / Barrier / Once concurrency/sync.h Countdown latch, generation barrier (timed wait + IsBroken()), one-time call

Design notes:

  • Future<T> / Promise<T> use a final shared-state control block (no std::future); Promise is move-only, Future is move-only and one-shot
  • RejectionPolicy::Abort (the default) rejects by settling the future with an Error; CallerRuns executes the task inline in the submitting thread
  • Channel<T> default-constructs as unbounded; Channel(capacity) constructs bounded. Close() signals completion; Recv() returns empty Optional on a closed/empty channel
  • Select polls multiple channels and returns the first available SelectResult<T> (index + value); returns {index: -1} when all channels are closed and empty

Filesystem (teles::fs)

Cross-platform path manipulation, file/directory operations, streaming I/O, and memory-mapped files.

Component Header Description
Path fs/path.h Cross-platform path (wraps ghc::filesystem): decomposition, join (/), normalize, iterate components
FileStatus / FileType fs/file_ops.h File metadata: type, size, timestamps (modified/accessed/created nanos), permissions
Status() / Exists() / IsFile() / IsDir() fs/file_ops.h File queries returning Result<T>
CreateDir() / Remove() / RemoveAll() / Rename() fs/file_ops.h Directory operations
Copy() / CopyRecursive() fs/file_ops.h File/tree copy; recursive variant has symlink-cycle detection
CreateSymlink() / ReadSymlink() fs/file_ops.h Symlink creation and resolution
SetPermissions() fs/file_ops.h POSIX-style permission bitmask
ReadFile() / ReadFileBytes() / WriteFile() / AppendFile() fs/file_ops.h One-shot file read/write
FileStream fs/file_stream.h RAII streaming file I/O: Read/Write/Seek/Tell/Flush/Close with configurable buffer
FileMode / SeekOrigin fs/file_stream.h Open modes (Read/Write/Append/ReadWrite) + seek origins (Begin/Current/End)
DirectoryIterator fs/directory.h Single-level directory iteration (STL-compatible input iterator)
RecursiveDirectoryIterator fs/directory.h Recursive directory walk with Depth() and Pop()
MappedFile fs/directory.h Memory-mapped file (mmap): ReadOnly/ReadWrite, Advise/Prefetch/Flush
TempDir / TempFile fs/temp.h RAII temporary directory/file (auto-deleted on destruction)
Glob() / GlobMatch() fs/glob.h Glob pattern expansion and pure pattern matching

Design notes:

  • All operations return Result<T> for structured error handling — no exceptions thrown by the API
  • FileStream wraps C stdio FILE* with RAII; move-only (non-copyable); configurable buffer size (default 4096)
  • Status() populates all timestamp fields (modified/accessed/created) via POSIX stat; createdNanos may be 0 on filesystems without birth time
  • CopyRecursive tracks canonical paths to detect and skip symlink cycles
  • MappedFile uses platform-native mmap (Linux/macOS: mmap+madvise, Windows: CreateFileMapping); falls back gracefully on failure

I/O (teles::io)

Networking (TCP/UDP/TLS), X.509, and async file I/O — native fds driven by the signal-driven EventLoop reactor (no external proactor library).

Component Header Description
EventLoop concurrency/event_loop.h Signal-driven completion engine: epoll (POSIX) / IOCP (Windows): Run/Stop/RunOnIo — fd registration internal (IoEngine seam, .omo/plans/io-model-redesign.md)
TcpConnection io/tcp.h TCP client (signal-driven): Connect() returns concurrency::Future<void> (Get() yields Result<void>), buffered Write(), OnConnected/OnData/OnWritable/OnError/OnClosed, SetTimeout/SetNoDelay/SetKeepAlive
TcpAcceptor io/tcp.h TCP server: binds and listens on construction, Port() reads back the assigned port, OnAccepted delivers adopted connections
UdpSocket io/udp.h UDP: Bind(0) + LocalPort() for ephemeral ports, Connect/SendTo, OnPacket signal, broadcast/multicast options
TlsConnection / TlsContext io/tls.h TLS 1.2/1.3 layered over TcpConnection signals (mbedtls-backed, platform-agnostic)
X509Certificate / PrivateKey / X509Verifier io/x509.h X.509 RAII types (no mbedtls headers leak into public API)
SocketPair io/socket_pair.h Portable socketpair (raw-fd tests + EventLoop fd API)
ByteBuffer io/byte_buffer.h Immutable refcounted byte slice: O(1) slicing, implicit conversion to Bytes
RecvBuffer io/recv_buffer.h Mutable recv-side accumulator for protocol parsing
AsyncReadFile() / AsyncWriteFile() / AsyncAppendFile() io/async_file.h Async file I/O offloaded to a ThreadPool; returns concurrency::Future<T> (Get() yields Result<T>)
SetTimeout() / SetInterval() / SetTimer() concurrency/timer.h One-shot, periodic (MissedTick policy), and deadline timers — RAII Disposable cancellation

Design notes:

  • The data path is signals, not callbacks or std futures: OnData(conn, data, len) pushes received bytes — the data pointer is valid only during the slot call
  • TcpConnection::Connect() returns concurrency::Future<void> (Get() yields Result<void>, never throws); async file operations also return concurrency::Future — no std::future in the library
  • TcpConnection / UdpSocket inherit enable_shared_from_this; the EventLoop holds the final reference while the fd is registered — Close() it (or wait for error/EOF) to release
  • Ephemeral-port pattern: TcpAcceptor::Create(loop, 0) + Port(), UdpSocket::Bind(0) + LocalPort() — never probe ports with raw sockets
  • MissedTick policies: Burst (catch up all missed ticks), Delay (realign to period), Skip (discard missed)

Reactive (teles::reactive)

Push-based composable streams — Flowable<T> with Rx-style operators, backpressure, schedulers, and subjects.

Component Header Description
Flowable<T> reactive/flowable.h Push-based stream; Subscribe() returns a Subscription (RAII auto-cancel), SubscribeAndForget() for fire-and-forget, Subscribe(Subscriber<T>&) for explicit demand control
Subscriber<T> reactive/subscriber.h Callback triple (on_next / on_error / on_complete) bound to a SubscriptionState
Subscription reactive/subscription.h RAII cancellation handle (move-only); Cancel() / Request(n) via its state
Single<T> / Maybe<T> / Completable reactive/single.h / maybe.h / completable.h 0/1-item reactive types built on Flowable (ToFlowable() / FromFlowable())
Scheduler concurrency/scheduler.h Abstract scheduler interface: Submit() / SubmitAfter() / Now()
ImmediateScheduler concurrency/schedulers.h Runs tasks inline on the caller thread
ThreadPool concurrency/thread_pool.h Worker-thread pool implementing Scheduler; Submit() returns a Future<T>

Operators — each operator lives in its own header under reactive/operators/<category>/ (transform, filter, combining, scheduling, side_effect, aggregate, factories, backpressure, convert); the umbrellas reactive/operators.h and reactive/reactive.h include them all. Most operators are available both as free functions and as Flowable<T> chain methods (.Map(), .Filter(), …):

Category Operator Description
Factory FlowableJust() / FlowableRange() / FlowableInterval() / FlowableEmpty() / FlowableNever() / FlowableThrow() / FlowableFromIterable() Create source Flowables (FlowableFromIterable accepts any STL container or initializer_list)
Factory FlowableDefer() / Flowable<T>::Create(fn, strategy) Lazy factory / custom emitter source with an explicit BackpressureStrategy
Transform Map() / Scan() / FlatMap() / ConcatMap() / SwitchMap() Element transformation, rolling accumulator, inner-Flowable merge (interleaved / sequential / cancel-previous)
Filter Filter() / Take() / Skip() / Distinct() / DistinctUntilChanged() / First() / Last() / ElementAt() / IgnoreElements() Predicate- and position-based filtering
Combine Concat() / Merge() / Amb() / StartWith() / Zip() / CombineLatest() / WithLatestFrom() Multi-source combining (sequential, interleaved, race, prepend, element-wise)
Windowing Window() / GroupBy() / Buffer() Split into sub-streams / keyed groups / bounded chunks
Aggregate Reduce() / Count() / Collect() / ToList() Terminal reductions emitting a single value
Error OnErrorReturnItem() / Retry() Fallback value on error / resubscribe on error
Utility DoOnNext() / DoOnError() / DoOnComplete() / DoFinally() / Timestamp() / Delay() / Debounce() / Sample() Side effects and timing without altering the payload
Async ObserveOn() / SubscribeOn() / Timeout() / Serialize() Scheduler hopping, serialization of concurrent emissions
Blocking BlockingFirst() / BlockingLast() Block until first/last emission; return T by value (throw on empty/erroring source)
Backpressure OnBackpressureBuffer() / OnBackpressureDrop() / OnBackpressureLatest() Buffer, drop, or keep-latest when downstream is slow
Future ToFuture() / FromFuture() Bridge Flowable<T>concurrency::Future<T> (reactive/future_bridge.h)

Subjects (reactive/subjects.h) — hot, multicast Flowables:

Subject Description
PublishSubject<T> Broadcast to current subscribers; no replay history
BehaviorSubject<T> Replays the most recent value to new subscribers; requires initial value
ReplaySubject<T> Replays all (or bounded) emitted values to new subscribers; optional max_size buffer
ConnectableFlowable<T> Multicast wrapper: Ref() for subscriber view, Connect() to start upstream, RefCount() for auto-connect/auto-disconnect
Publish() Free function: wraps a Flowable<T> into a ConnectableFlowable<T>
Share() Free function: Publish(src).RefCount() — auto-connecting multicast

Design notes:

  • Subscribe(callbacks...) requests unbounded demand automatically; Subscribe(Subscriber<T>&) gives the caller full control via SubscriptionState::Request(n) / kUnboundedDemand
  • Each operator creates per-subscription state, so multiple subscriptions get independent state
  • Subscriber::OnNext wraps user callbacks in try/catch — uncaught exceptions are routed to on_error (FR-209)
  • OnError and OnComplete are terminal — the first one fires and subsequent calls are suppressed
  • concurrency::CpuPool() / IoPool() / SinglePool() are lazily initialized global ThreadPools sharing GlobalTimerQueue(); Schedulers::Shutdown() releases them
  • TestScheduler uses a priority queue keyed by (virtual_time, sequence)AdvanceTime() flushes all due tasks in order
  • ConnectableFlowable::RefCount() subscribes to the internal subject before connecting upstream, ensuring no synchronous emissions are missed
  • BlockingFirst() / BlockingLast() capture the Subscription internally and release it after unblocking — empty sources throw std::out_of_range; upstream errors are rethrown

Architecture: Dogfooding

Teles uses its own primitives internally throughout every module: locks and atomics via teles::sync (Mutex<T> is pimpl'd over base::MutexCore in the internal freestanding base layer src/base/), blocking sleeps via time::SleepFor/SleepUntil, and async results via concurrency::Future. This dogfooding is lint-enforced, not aspirational: tools/check_layering.py (run via ctest as teles_layering) fails raw std::mutex/std::thread/ socket-syscall usage outside the single-point base layer and the shrinking out-of-scope baseline, keeping the abstractions battle-tested in production code paths.


Naming Conventions

Element Convention Example
Class / Type PascalCase Result, PoolAllocator
Method / Function PascalCase IsOk(), Allocate()
Private member snake_case_ code_, message_
Macro / Constant UPPER_SNAKE TELES_TRY, kCacheLine
Namespace lowercase teles::core, teles::memory
Enum value PascalCase ErrorCategory::System

Namespace Strategy

Layered namespaces with root aliases for common types:

teles::core::          — core types, sugar utilities
teles::memory::        — allocators, memory diagnostics
teles::error::         — Error, Result, exceptions
teles::str::           — string operations, UTF codecs
teles::format::        — enum name tables (TELES_ENUM), null-safe ToString
teles::concurrency::   — thread pools, futures, channels, sync primitives
teles::fs::            — paths, file ops, streaming I/O, memory-mapped files
teles::io::            — networking, event loop, async file I/O, timers
teles::reactive::      — Flowable<T>, operators, subjects, schedulers
teles::system::        — signal handling, crash diagnostics, thread info
teles::serialization:: — JSON wrapper, serialization macros
teles::config::        — configuration management, multi-provider merge

Root-level aliases (in teles::): Optional, Variant, StringView, Span, Byte, Error, Result, Ok, Err.

Testing

cmake -B build -DTELES_BUILD_TESTS=ON
cmake --build build
cd build && ctest --output-on-failure

Tests use Google Test (unit tests) and rapidcheck (property-based testing). The sanitizer matrix (ASan + UBSan + TSan + LSan) runs on x86_64 CI.

S
Description
No description provided
Readme
55 MiB
Languages
C++ 96.4%
CMake 1.4%
Python 1.1%
Shell 0.7%
C 0.3%