Skip to content

Commit 0b2b1a8

Browse files
committed
docs: update plan after Fix 4, mark checklist complete
1 parent 926589e commit 0b2b1a8

2 files changed

Lines changed: 38 additions & 34 deletions

File tree

docs/conformance-fixes/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ constraint that libstdc++ doesn't enforce, put it in the beman-only target.
6363
- [x] Fix 1: Constructor/assignment/equality constraints
6464
- [x] Fix 2: Trivial special member functions
6565
- [x] Fix 3: Monadic operation constraints
66-
- [ ] Fix 4: Mandates static_asserts
66+
- [x] Fix 4: Mandates static_asserts
6767
- [ ] Fix 5: Hardened preconditions and minor fixes
6868

6969
## After All Fixes

docs/plan/handoff-next.md

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,66 @@
1-
# Handoff: After Fix 3
1+
# Handoff: After Fix 4
22

33
## What Was Done
44

5-
Fix 3 is complete. SFINAE-friendly `requires` clauses added to all monadic
6-
operations per standard Constraints. Branch `fix3-monadic-constraints` merged
7-
(--no-ff) into `expected-over-references`.
5+
Fix 4 is complete. `static_assert` Mandates added to observers and monadic
6+
operations per standard wording. Branch `fix4-mandates` merged (--no-ff) into
7+
`expected-over-references`.
88

99
### Changes in `include/beman/expected/expected.hpp`
1010

11-
**Primary template (16 overloads — 4 operations × 4 ref-qualifiers):**
12-
- `and_then` / `transform`: `requires std::is_constructible_v<E, E-ref>`
13-
(E& for &, E&& for &&, const E& for const&, const E&& for const&&)
14-
- `or_else` / `transform_error`: `requires std::is_constructible_v<T, T-ref>`
15-
(same ref-qualifier pattern)
11+
**Primary template class-level:**
12+
- `static_assert(!detail::is_unexpected_specialization<remove_cv_t<T>>::value, ...)`
1613

17-
**Void specialization (8 of 16 overloads):**
18-
- `and_then` / `transform`: same E-constructibility constraints as primary
19-
- `or_else` / `transform_error`: NO constraints (standard specifies none)
14+
**Primary template `value()` (4 overloads):**
15+
- `const&` / `&`: `is_copy_constructible_v<E>`
16+
- `&&` / `const&&`: `is_copy_constructible_v<E> && is_constructible_v<E, decltype(std::move(error()))>`
2017

21-
Both in-class declarations and out-of-line definitions updated.
18+
**Primary template `value_or()` (2 overloads):**
19+
- `const&`: `is_copy_constructible_v<T>`, `is_convertible_v<U, T>`
20+
- `&&`: `is_move_constructible_v<T>`, `is_convertible_v<U, T>`
21+
22+
**`error_or()` (4 overloads — both primary and void):**
23+
- `const&`: `is_copy_constructible_v<E>`, `is_convertible_v<G, E>`
24+
- `&&`: `is_move_constructible_v<E>`, `is_convertible_v<G, E>`
25+
26+
**Void specialization `value()` (2 overloads):**
27+
- `const&`: `is_copy_constructible_v<E>`
28+
- `&&`: `is_copy_constructible_v<E> && is_move_constructible_v<E>`
29+
30+
**`transform()` (8 overloads — both primary and void):**
31+
- In `if constexpr (!is_void_v<U>)` block: U not array, not in_place_t, not unexpect_t, not unexpected<>
32+
33+
**`transform_error()` (8 overloads — both primary and void):**
34+
- G is object, not array, not cv-qualified, not unexpected<>
2235

2336
### Tests added
2437

25-
- `tests/beman/expected/expected_monadic_constraints.test.cpp` — beman-only:
26-
- Concept detectors using `std::declval<X>()` to preserve value category
27-
- MoveOnly type (deleted copy ctor) as E: verifies `and_then`/`transform`
28-
lvalue overloads are SFINAE-removed, rvalue overloads remain available
29-
- MoveOnly type as T: verifies `or_else`/`transform_error` same pattern
30-
- Void specialization: same E-constructibility tests for `and_then`/`transform`
31-
- Void specialization: `or_else`/`transform_error` unconstrained (always available)
32-
- Normal types: all operations remain available on all overloads
33-
- 6 Catch2 runtime tests exercising rvalue monadic chains with move-only types
38+
- `tests/beman/expected/expected_unexpected_value_type_fail.cpp` — negative compile
39+
test verifying `expected<unexpected<int>, int>` is ill-formed
3440

3541
### Test count
3642

37-
247 tests total, all passing.
43+
248 tests total, all passing.
3844

3945
## Build Commands
4046

4147
```bash
42-
make TOOLCHAIN=gcc-16 test # 247 tests, all passing
48+
make TOOLCHAIN=gcc-16 test # 248 tests, all passing
4349
make lint # all linters pass (beman-tidy crash is pre-existing)
4450
```
4551

4652
## Conformance Fix Checklist
4753

4854
- [x] Fix 1: Constructor/assignment/equality constraints
4955
- [x] Fix 2: Trivial special member functions
50-
- [x] Fix 3: Monadic operation constraints ← just done
51-
- [ ] Fix 4: Mandates static_asserts
56+
- [x] Fix 3: Monadic operation constraints
57+
- [x] Fix 4: Mandates static_asserts ← just done
5258
- [ ] Fix 5: Hardened preconditions and minor fixes
5359

54-
## Next Step: Fix 4
60+
## Next Step: Fix 5
5561

56-
Fix 4 adds `static_assert` Mandates to observers and monadic operations.
57-
These go on the same functions that just received requires clauses (Fix 3),
58-
plus `value()`, `value_or()`, and `error_or()` observers.
62+
Fix 5 adds hardened precondition checks to observers (`operator->`, `operator*`,
63+
`error()`) and miscellaneous minor fixes (friend swap constraint on
64+
`unexpected<E>`, etc.).
5965

60-
The Mandates are compile-time checks that produce clear diagnostics when
61-
violated, as opposed to Constraints which affect overload resolution.
62-
See `docs/conformance-fixes/fix4-mandates.md`.
66+
See `docs/conformance-fixes/fix5-preconditions-and-minor.md`.

0 commit comments

Comments
 (0)