C++ interop
Import a C++ header through the same source syntax as C:
import cpp from "cpp_math.hpp";
const origin = cpp.zcpp.Point({ x: 20, y: 22 });const moved = cpp.zcpp.translate(origin, 1, -1);const total = cpp.sum(moved);zcpp represents the C++ global namespace. Named C++ namespaces remain named:
const alpha = cpp.alpha.Point({ value: 20 });const beta = cpp.beta.Point({ value: 22 });No runtime namespace object is created. These are compile-time paths to the Clang-imported declarations.
Select and rename namespaces
Section titled “Select and rename namespaces”Selective imports make namespace-heavy APIs easier to read:
import { zcpp as math, alpha as left, beta as right} from "cpp_math.hpp";
const origin = math.Point({ x: 20, y: 22 });const adjusted = left.adjust(20) + right.adjust(22);This changes only the Z source name. It does not generate a forwarding wrapper or alter native symbol identity.
Values keep native construction and layout
Section titled “Values keep native construction and layout”Aggregate-like values use the familiar Z construction surface when their fields are safely importable:
const point = math.Point({ x: 20, y: 22 });Native constructors use their declared arguments:
const resource = native.zcpp.UniqueValue(40);Methods remain direct:
const value = resource.value();The type annotation is optional when construction makes the result clear.
RAII composes with Z ownership
Section titled “RAII composes with Z ownership”C++ value destructors become deterministic Z cleanup. Copyable native values use their C++ copy behavior; move-only values remain move-only in Z:
struct NativeOwner { value: native.zcpp.UniqueValue;}
function inspect(in value: native.zcpp.UniqueValue): i32 { return value.value();}
const first = native.zcpp.UniqueValue(40);const observed = inspect(first);const owner = NativeOwner({ value: first });The final construction transfers first into owner. Z rejects later use of
the moved source and runs the imported destructor exactly once when the final
owner leaves scope.
References use the same capability vocabulary as Z where the importer can prove
their native relation: immutable reference inputs become borrowed in, mutable
references require inout, and returned references become non-escaping views
when provenance is known.
Current boundary
Section titled “Current boundary”The implemented vertical slices include:
- namespaces and selective namespace imports;
- plain aggregates, constructors, functions, overloads, and methods;
- copyable values with native copy/destruction;
- move-only RAII values in locals, fields, arrays, and enums;
- supported references and callable boundaries;
- direct Swift-generated C++ compatibility values.
Broad templates, arbitrary standard-library types, exception translation, complex reference provenance, and library-scale compatibility remain active work. Z rejects unsupported shapes at the source boundary rather than exposing an invented approximation.
Runnable examples: C++ basics, selective namespaces, and move-only values.
Next: Swift interop.