Skip to content

null_sink.hpp

NullSink — the zero-cost default ITelemetrySink (§18.1).

This header declares 1 type (1 member).

Extracted from include/shulib/hal/null_sink.hpp — this page is that header's documentation, reformatted, so it cannot disagree with the code. Prose about how to think about the API lives in the user guide; worked recipes live in the cookbook; this page is the complete, mechanical list of what exists.

Contents

class NullSink

class NullSink final : public ITelemetrySink

The competition-build default sink: every channel is dropped. What matters is what it does NOT override — wantsRecord() stays false and emit()/summarize() stay the seam's no-ops, which is what makes it ≈free rather than merely fast. A tick loop going through hal::emitRecord() never even POPULATES a DebugRecord, because the builder callable is not invoked at all; the whole per-tick cost is one bool query the compiler can devirtualize. The ONE load-bearing omission is wantsRecord(): overriding it is what would reintroduce the per-tick population cost this class exists to remove. Overriding emit() alone would not — emitRecord() gates solely on wantsRecord(), so the builder would still never run, which is precisely why the seam says override the two as a PAIR — and summarize() is a once-per-run cold path that costs nothing per tick either way.

class, declared at include/shulib/hal/null_sink.hpp:29.

NullSink::log

void log(LogLevel /*level*/, std::string_view /*subsystem*/, std::string_view /*message*/) override

Discards the message. The parameters are unnamed on purpose — nothing is read, so nothing is formatted or copied, and the body inlines to nothing.

function, declared at include/shulib/hal/null_sink.hpp:33.

Design commentary, from the header

The header opens with the reasoning behind these shapes. It is reproduced here in full because a reference that only lists signatures teaches nobody why.

The header’s own reasoning — 10 lines
 NullSink — the zero-cost default ITelemetrySink (§18.1). Drops everything; the
 competition build routes telemetry here so observability costs ≈nothing when off.

 DELIBERATELY does not override wantsRecord()/emit(): it inherits the seam's defaults
 (wantsRecord() == false, no-op emit()), which is what makes it genuinely ≈free — a
 tick loop using hal::emitRecord() never even POPULATES a DebugRecord for it (the
 §18.2 cost mechanism; see telemetry_sink.hpp's header note). The absence of overrides
 here is also the living proof that the M2 emit() addition was additive: this M1 sink
 compiles untouched.

Last updated 2026-08-15 — published from the main release branch, commit fa545ff. This site tracks releases, so between them it can lag the repository — that lag is deliberate, and it is what keeps the development log off the public site. For the current state of the code, see the repository.