Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ PR. A release PR moves the `[Unreleased]` entries into a new per-version file un

### Fixed

- Documentation: reconciled the spec §5 error-model wording with the shipped API — `FlatMap::find`
returns a `const_iterator` (compared to `end()`), not an "optional-like result"; added a
compile-verified constexpr `FlatMap` example (test + `flat_map.hpp` Doxygen) so the illustrative
example matches its "constexpr" title (roadmap 11.7, closes Milestone 11).

### Security

---
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ setup.
| 8 | Parsing & Input | ✅ done |
| 9 | I/O & Networking | ✅ done |
| 10 | Hardening & 1.0 | ✅ done |
| 11 | Specification & Assurance Hardening | 🚧 in progress |
| 11 | Specification & Assurance Hardening | ✅ done |


## License
Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ document the security posture. Documentation- and assurance-focused; no public A
SHA-256 non-cryptographic scoping statement with extended NIST test-vector validation.
- [x] 11.6 Turn the benchmark baselines into documented numeric targets/regression thresholds
with a stated methodology (warm-up, reps, p99) on the existing Stopwatch harness.
- [ ] 11.7 Fix the spec §3 example so it compiles and actually demonstrates constexpr `FlatMap`
- [x] 11.7 Fix the spec §3 example so it compiles and actually demonstrates constexpr `FlatMap`
construction; reconcile the §5 `find` wording with the shipped iterator-returning API.


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 2026-07-05 — FlatMap constexpr example + find wording (roadmap 11.7, closes M11)

## What got done

The last Milestone-11 item — the original discrepancy that started this milestone.

- **Reconciled the spec §5 error-model wording.** It claimed "`FlatMap::find` returns an
optional-like result"; the shipped API returns a `const_iterator` compared to `end()` (the
STL-idiomatic form). Reworded §5 to describe the actual per-channel model (iterator for
associative lookup, `std::optional` for a missing element, status types for N-way outcomes),
pointing at ADR-0029 and the contract table.
- **Made the "constexpr FlatMap" example real and verified.** The intake §3 example used
`find(1).has_value()`, which never compiled against the iterator API. Added the corrected
example (a) as a compile-time-verified `static_assert` in `flat_map_test.cpp`
(`config_map_example()` — `FlatMap<int, std::string_view>`, insert, iterator-based `find`, all in
a constant expression) and (b) as a fenced Doxygen snippet in `flat_map.hpp`. The example now
both compiles and matches its "constexpr" title.
- Marked Milestone 11 done in README + ROADMAP.

## Why no change to the untracked intake

The broken example lives in `d4np-cpp.md`, the untracked raw intake — not a repository artifact
(the frozen spec is `docs/specs/01_spec_util.md`). The durable fix belongs in the repo: the
reconciled §5 wording plus a mechanically-verified example. `d4np-cpp.md` is left untracked.

## Verification

- `python tools/consistency_lint.py` → OK (M11 now all-checked; README ↔ ROADMAP consistent).
- Local MSVC build: `flat_map_test` static_asserts compile (the new constexpr example evaluates at
compile time); full `util_tests` green; clang-format + clang-tidy clean on the changed sources.

## Project state

- **Milestones 1–11 complete.** Milestone 11 (Specification & Assurance Hardening) is closed:
11.1 error-model ADR, 11.2 C4 diagram, 11.3 contract table, 11.4 ABI policy, 11.5 security/fuzzing,
11.6 benchmark targets, 11.7 this. Version still `1.0.0`.

## How the next session resumes

- **Release PR.** M11 added user-visible surface (the `EGL_UTIL_BUILD_FUZZERS` option + `fuzz`
preset, threat model, extended vectors) — a **MINOR** bump under SemVer (`v1.1.0`). Per AGENTS
§11: bump `D4NP_UTIL_VERSION_*` in `version.hpp` + the README `Status-vX.Y.Z` badge (consistency
lint checks version lockstep), roll `[Unreleased]` in `CHANGELOG.md` into
`docs/changelog/v1/v1.1.0.md` (+ index row), draft release notes under `docs/releases/`, and
close the "M11 — Specification & Assurance Hardening" GitHub milestone. The agent drafts; the
maintainer opens/merges and publishes.
2 changes: 1 addition & 1 deletion docs/specs/01_spec_util.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Consumers import via `#include <it/d4np/util/util.hpp>`. The public surface:
- I/O: it::d4np::util::FileStream, TcpSocket, TcpServer, BinarySerializer.
- Diagnostics: it::d4np::util::Stopwatch, Logger, StackTrace.
- Parsing: it::d4np::util::CliParser, JsonParser, HashAlgorithms, TypeTraits.
- Error model: fallible operations return a value-or-error type (e.g. FlatMap::find returns an optional-like result); no exceptions cross module boundaries except where explicitly documented. The full policy is [ADR-0029](../adr/0029-error-handling-policy.md).
- Error model: fallible operations report failure by value, never by throwing on well-formed input, using the smallest fitting channel — an iterator compared to `end()` for associative lookup (`FlatMap::find`/`FlatSet::find` return a `const_iterator`, the STL-idiomatic result), `std::optional` for a missing element (e.g. `CircularBuffer::pop`, `LockFreeQueue::try_pop`), or a status-typed result for N-way outcomes (e.g. `TcpSocket` `IoResult`). No exceptions cross module boundaries except where explicitly documented. The full policy is [ADR-0029](../adr/0029-error-handling-policy.md); the per-operation channels are in the [contract table](../architecture/component-contracts.md).
- Per-component contracts (thread-safety, exception-safety, allocation behavior, and algorithmic complexity for all 25 components) are tabulated in [`docs/architecture/component-contracts.md`](../architecture/component-contracts.md).


Expand Down
17 changes: 15 additions & 2 deletions src/main/cpp/it/d4np/util/flat_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,21 @@ namespace it::d4np::util {
/// key (e.g. in an initializer list) the first one wins.
///
/// The entire interface is `constexpr`: a `FlatMap` can be built and queried inside a constant
/// expression (e.g. behind a `static_assert`). See ADR-0009 (flat model) and ADR-0010 (the
/// constexpr construction strategy).
/// expression (e.g. behind a `static_assert`). `find` returns a `const_iterator` compared against
/// `end()` (the STL-idiomatic result), not an optional:
///
/// ```cpp
/// constexpr bool ok = [] {
/// it::d4np::util::FlatMap<int, std::string_view> config;
/// config.insert(1, "Service.Start");
/// config.insert(2, "Service.Stop");
/// const auto it = config.find(1); // const_iterator, not optional
/// return it != config.end() && it->second == "Service.Start";
/// }();
/// static_assert(ok);
/// ```
///
/// See ADR-0009 (flat model) and ADR-0010 (the constexpr construction strategy).
///
/// @tparam Key the key type.
/// @tparam Value the mapped type.
Expand Down
13 changes: 13 additions & 0 deletions src/test/cpp/it/d4np/util/flat_map_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <iterator>
#include <stdexcept>
#include <string>
#include <string_view>
#include <vector>

namespace {
Expand Down Expand Up @@ -45,6 +46,18 @@ constexpr int subscript_inserts() {
}
static_assert(subscript_inserts() == 55, "constexpr operator[] insert-then-update");

// The spec's illustrative "constexpr FlatMap" example (spec §5 / the d4np-cpp intake §3),
// corrected to the shipped iterator-returning `find` and proven here to compile *and* evaluate as
// a constant expression — the example now matches its "constexpr" title (roadmap 11.7).
constexpr bool config_map_example() {
FlatMap<int, std::string_view> config_map;
config_map.insert(1, "Service.Start");
config_map.insert(2, "Service.Stop");
const auto it = config_map.find(1); // find returns a const_iterator, not an optional
return it != config_map.end() && it->second == "Service.Start";
}
static_assert(config_map_example(), "constexpr FlatMap construction + iterator-based find");

} // namespace

TEST_CASE("insert keeps entries ordered by key and rejects duplicate keys") {
Expand Down
Loading