Apply an aggressive Orthodox Modern C++23 subset with explicit runtime behavior and type safety.
Use this skill to implement an explicit-runtime Orthodox Modern C++23 subset. Prefer type safety, readability, and predictable runtime behavior over hidden costs and abstraction-heavy designs.
Use this skill when the codebase or module requires a modern C++23 approach with explicit costs and type safety, but without the baggage of older conservative Orthodox C++ or the overhead of complex standard features like exceptions and RTTI.
Do not trigger this skill for general modern C++ codebases that rely on exceptions, RTTI, or framework conventions.
Simplicity over novelty.
Make runtime cost explicit.
Keep the runtime model predictable.
Use explicit error handling.
std::expected as the default explicit error model for expected failure paths.Adopt a modern C++23 subset aggressively when it improves clarity, type safety, and explicitness without hiding runtime cost.
Prefer portability-first build choices.
Zero-cost or near-zero-cost features blessed by this skill. All must respect active toolchain support.
struct only — class keyword is forbidden. Free functions over member methods. Scoped enums. Designated initializers for aggregate construction. std::optional and std::variant for presence/sum types.std::span and std::string_view for non-owning access. Views must never outlive underlying storage.std::expected for all expected failure paths. Validate std::print availability; fall back to std::format plus project output sink.std::format / std::print over printf, snprintf, and iostream.std::filesystem::path for all filesystem locations — never raw std::string/const char* path plumbing.std::source_location over __FILE__/__LINE__.auto for locals when initializer intent is clear; explicit types where contracts or readability require them.constexpr, consteval, constinit aggressively to push work to compile time.[[nodiscard]], [[maybe_unused]], [[likely]], [[unlikely]], [[no_unique_address]] aggressively. [[assume(expr)]] ONLY for proven hot-path invariants paired with debug assertions.struct types.Apply in order — escalate only when the simpler option is insufficient:
std::span, std::string_view) FIRST.std::unique_ptr ONLY for exclusive dynamic ownership when stack allocation is insufficient.std::shared_ptr ONLY for genuine shared lifetime where multiple components must co-own an object.std::weak_ptr ONLY for observing shared lifetime or breaking reference cycles.| Family | Status | Rationale |
|---|---|---|
Borrowed views (std::span, std::string_view) | Recommended | Zero-copy, zero-allocation non-owning access. |
std::array | Recommended | Fixed-size, stack-allocated, cache-friendly. |
std::vector | Recommended | Default growable container. Contiguous memory, cache-friendly. Prefer std::array when size is compile-time known; otherwise std::vector is the correct default. |
std::deque | Restricted | Fragmented storage across multiple blocks hurts cache locality. Allow only when front/back insertion is a real, documented requirement. |
std::list, std::forward_list | Forbidden | Node-based allocation destroys cache locality; per-element heap overhead; pointer chasing on every traversal. |
Ordered associative (std::map, std::set, std::multimap, std::multiset) | Forbidden | Node-based allocation, poor cache locality, hidden rebalancing costs on every insert/erase. |
Unordered associative (std::unordered_map, std::unordered_set, etc.) | Restricted | Hash table rehashing causes hidden bulk reallocation. Allowed only when hashed lookup need is proven and simpler alternatives are impractical. |
Adaptor containers (std::stack, std::queue, std::priority_queue) | Restricted | Thin wrappers — cost depends on underlying container. Allowed when operation semantics are needed and underlying container + thread policy is documented. |
For ALL containers used across threads: verify concurrency model explicitly — no unsynchronized concurrent mutation. Document synchronization/ownership strategy.
External libraries (e.g., Boost.DLL, system APIs) may throw exceptions that are outside our control. At integration boundaries:
std::expected<T, Error>.spdlog) for all runtime log output.std::format / std::print are for general string formatting, not for logging.std::print calls.std::print to stderr over iostream.struct only — the class keyword is forbidden. All types are struct.struct types instead of member methods.virtual destructors and methods are forbidden.std::expected as the primary error mechanism. Never use exceptions for expected failure paths.struct only — class keyword is forbidden. Free functions over member methods.NEVER:
class keyword — use struct for all types. Use free functions instead of member methods.dynamic_cast, typeid) for dispatch or design.std::format/std::print suffices.shared_ptr to dodge ownership modeling.std::list, std::forward_list, ordered associative).std::vector, which is Recommended).std::span/std::string_view must never outlive source storage.[[assume(expr)]] on unproven invariants or outside profiled hot paths.struct, scoped enums, designated initializers, and view/value types.std::expected before considering lower-level encodings.extern "C" exposure points.struct-only modeling (no class), Rule-of-5, free functions, and designated initializers respected?std::expected without exception-driven flow?extern "C" boundaries?When proposing or implementing changes, include:
std::expected flow)std::format/std::print + portability fallback)Rooted in Orthodox C++ (Branimir Karadžić / bgfx), emphasizing simplicity, portability, and explicit costs. This skill intentionally breaks from the conservative +5-year standard adoption rule, aggressively adopting C++23 features that meet the explicitness and zero-cost criteria.