Prototype 2.0 · Version 2.0.0

Embedded C++ without the hidden cost.

CASTLE is a lightweight, header-only template library for firmware where memory, timing and failure behavior need to be visible parts of the design.

C++17 and lower · no mandatory heap · no mandatory RTTI · no mandatory exceptions · no STL dependency in public headers
main.cpp
#include "castle/container/vector.h"
#include "castle/utility/optional.h"

int main()
{
    castle::container::vector<uint16_t, 16> samples;

    if (samples.push_back(42U) != castle::status::ok)
    {
        // capacity failure is explicit
        return 1;
    }

    castle::optional<uint16_t> value = samples[0];
    return value.has_value() ? 0 : 2;
}
Header-onlydrop in the include tree
Fixed capacitybounds are part of the type
C++17 / lowerGCC · Clang · ARM families
MIT licensedopen source · © 2026
Engineering principles

Make the important costs explicit.

CASTLE 2.0 favors simple, inspectable building blocks over runtime machinery that can make embedded behavior harder to bound or reason about.

No hidden heap

Containers and storage helpers keep data in bounded objects. Capacity becomes a compile-time decision instead of an invisible runtime dependency.

Explicit failure

Full and empty states are ordinary control flow. Status values and boolean results make failure visible without requiring exception-based APIs.

Freestanding-friendly

The public headers do not depend on the C++ STL. The library is built around compiler features and small low-level building blocks.

Compile-time first

Type traits, fixed sizes, configuration and many utility operations can be expressed or evaluated at compile time, keeping firmware intent close to the type system.

Module map

Small parts. Composable by design.

CASTLE 2.0 currently spans the low-level primitives, containers, algorithms and event-oriented utilities that form a practical embedded foundation.

container/

Containers

Array, vector, ring buffer, stack, strings and associative containers.

Browse module ↗
core/

Core

Types, compiler abstraction, traits, configuration and assertions.

Browse module ↗
design_patterns/

Design patterns

Small embedded-oriented observer, singleton and visitor helpers.

Browse module ↗
events/

Events

Dispatchers, signals/slots, IPC events and tick timers.

Browse module ↗
iterator/

Iterators

Iterator tags, traits, bounded, circular and reverse iterators.

Browse module ↗
math/

Math

Integer math, ratios, square root, mean, logarithms and more.

Browse module ↗
memory/

Memory

Placement construction, destruction, storage, addresses and lifetimes.

Browse module ↗
mutex/

Mutex

Mutex and scoped locking helpers for synchronized firmware paths.

Browse module ↗
utility/

Utilities

Move, forward, swap, optional, variant, pair, tuple, bitset and safe casts.

Browse module ↗
algorithm/

Algorithms

Reusable algorithmic building blocks for the library ecosystem.

Browse module ↗
Get started

Drop it into a firmware tree.

CASTLE is header-only. Use the include directory directly, or consume the repository as a CMake subdirectory through its interface target.

Option 01 · CMakeINTERFACE target
add_subdirectory(third_party/castle)

target_link_libraries(my_app
    PRIVATE castle
)
1

Add the repository

Keep CASTLE anywhere under your firmware source tree or dependency directory.

2

Link the interface target

The project exposes the castle target and propagates its include directory and C++17 requirement.

Option 02 · Headers onlyzero build step
#include "castle/container/array.h"
#include "castle/container/vector.h"
#include "castle/utility/optional.h"
#include "castle/events/tick_timer.h"

// Add include/ to your compiler include path.
+

Compile for your target

A typical configuration may use -std=c++17 -fno-exceptions -fno-rtti -nostdinc++ where supported by the toolchain.

Open the docs

The documentation mirrors include/castle, one module guide at a time.

Architecture

A small runtime contract by default.

The point is not to ban every runtime mechanism. It is to keep the core data structures statically shaped, explicit and inspectable.

Firmwareapplication logic
CASTLEtemplates + storage
ToolchainGCC / Clang / ARM

Static shape, explicit behavior

Capacity, storage and configuration are visible at the API boundary. That makes it easier to budget memory and reason about normal failure modes.

  • Fixed-capacity containers such as vector<T, N>
  • Status values such as ok, full and empty
  • No mandatory heap, exceptions or RTTI
template<typename T, size_t N>
class vector
{
public:
    static constexpr size_type
        static_capacity = N;

    bool empty() const noexcept;
    bool full() const noexcept;
    size_type size() const noexcept;
    size_type capacity() const noexcept;

    status push_back(const T& value);
};

Familiar C++ shape

CASTLE uses recognizable C++ vocabulary—containers, optionals, variants, iterators, tuples and chrono-style types—adapted to embedded constraints.

  • Useful drop-in patterns without pretending the target is a desktop runtime
  • Header layout mirrors the documentation layout
  • Core interfaces favor templates over classical virtual inheritance
Good fit

Built for software that has a budget.

Firmware & device drivers

Keep buffers, state and helper objects bounded and close to the hardware-facing code.

Control software

Use predictable containers and explicit results in control loops and supervisory logic.

Protocol stacks

Model packets, lookup structures and communication buffers without making allocation the default.

Sensor pipelines

Use fixed-capacity queues and value wrappers where throughput and bounded storage matter.

Schedulers & events

Compose callbacks, event dispatchers, signals and tick timers from the existing event family.

Safety-oriented codebases

Make constraints visible in APIs and leave room for your project’s MISRA, AUTOSAR and process requirements.

Roadmap

Growing toward a broader embedded toolbox.

These are the project’s stated next areas after the current prototype 2.0 building blocks.

Next
Finite state machine framework

Explicit state transitions and embedded-friendly configuration.

Next
Protocol I/O + codecs

Input/output support plus encoder and decoder algorithms.

Planned
Checksums & CRC

CRC-8/16/32, Fletcher, Adler and related utilities.

Planned
Math & geometry

Additional basic math and geometry calculations.

Planned
Event configuration

More expressive compile-time configuration for event topologies.

Planned
Conformance notes

AUTOSAR / MISRA C++ guidance per module as the library matures.

Open source · CASTLE 2.0

Keep the runtime contract small. Let the type system do more of the work.

Explore the source, module guides and tests on the prototype 2.0 branch.