formula-cpp
Declarative, traceable, self-documenting formulas for C++23. Header-only, no dependencies.
Write a formula once, with ordinary operators. Get back a number, a rendering, and a documentation page — from the same declaration.
#include <formula-cpp/formula.hpp>
#include <formula-cpp/document.hpp>
#include <formula-cpp/render.hpp>
namespace unit = formula::unit;
using formula::var;
// A quantity carries its own symbol, description and unit.
struct WaterVolume: formula::Quantity<WaterVolume, "V_w", "effective water content", unit::Litre> {};
struct CementVolume: formula::Quantity<CementVolume, "V_c", "cement content", unit::Litre> {};
struct WaterCementRatio: formula::Quantity<WaterCementRatio, "w/c", "ratio of water to cement", unit::One> {};
// The formula, and where it comes from, declared together.
constexpr auto ratio = formula::documented(var<WaterVolume> / var<CementVolume>,
{ .title = "Water/cement ratio",
.reference = "Example Standard 1:2020",
.section = "5.4.2",
.equation = "(3)" });
One declaration, four answers:
formula::render(ratio); // "V_w / V_c"
formula::render<formula::Dialect::LaTeX>(ratio); // "\frac{V_w}{V_c}"
formula::document(ratio); // text, citation and symbol table together
auto const environment = formula::environment(formula::Measured<WaterVolume> { formula::Rational { 180 } },
formula::Measured<CementVolume> { formula::Rational { 300 } });
formula::evaluate<WaterCementRatio>(ratio, environment); // 0.6, and it knows it computed it
Three things worth knowing before you read further
A dimensional mistake is a compile error. var<Volume> + var<Length> does not compile, and the
diagnostic names both quantities and points at the line that wrote the formula.
Nothing is silently zero. An evaluation returns a value, an absence, or a manual override. A quantity nobody measured stays absent through every operator, and the result says so — which is a different statement from "this is zero".
Arithmetic is exact by default. Rational does not drift. Rounding happens once, where you ask
for it, in the mode the method specifies.
Where to start
| Guide | What it covers |
|---|---|
| Exact numbers | Rational, the rounding modes, why exactness is the default |
| Dimensions and units | Compile-time dimensional analysis, exact unit conversion |
| Quantities and measurements | Declaring a quantity, Describe, measurements that may be absent |
| Expressions and evaluation | Operators, environments, outcomes, overrides |
| Citations and rendering | documented(), the three dialects, generated documentation |
| Tracing and audit trails | explain(), render_trace(), sinks, and the zero-cost untraced path |
| Rounding and conditionals | Rounding as a node, when(), and the traced numeric_value_of escape hatch |
| Constraints and verdicts | Validating a result with constraint() and check(), the four-state outcome, and checking a set without short-circuit |
| Lookup tables | The three table kinds, validation that refuses a gap, and why a miss is not a number |
| Gallery | A documentation page the library generated about itself |
New here? Read Expressions and evaluation first — it is the layer the library exists for. The API reference documents every public entity.
Each guide has a matching runnable program under examples/ in the repository, and every snippet
on this site is taken from code that compiles, so nothing here can drift from what the library
actually does.
A note on the examples
Every formula and citation on this site is invented — generic physics with fictional
Example Standard references. Real test-method standards are copyrighted and sold, so none of
their content appears in this repository: not their text, their tables, their threshold values,
nor their clause numbering. Real standards are implemented in downstream libraries that hold a
licence to them.
Status
Usable for what is listed as shipped, and still growing. The public API may change until 1.0.
| Area | State |
|---|---|
| Exact rational arithmetic, rounding modes | shipped |
| Dimensions with rational exponents, units, exact conversion | shipped |
| Quantities, metadata, absent measurements | shipped |
| Formulas, operators, environments, evaluation | shipped |
| Citations, rendering dialects, generated documentation | shipped |
| Calculation tracing and audit trails | shipped |
Rounding nodes (decimal places, significant digits), conditionals (when()) |
shipped |
| Constraints, verdicts, checking a set without short-circuit | shipped |
| Lookup tables: banded, exact and interpolating | shipped |
| Methods, series, statistics | planned |
Apache-2.0. Source at github.com/LASTRADA-Software/formula-cpp.