DRAFT.md: state the T-vs-I special member rule and the move-semantics divergence from P3019
- Dominant language
- C++
- Stars
- 11
- Forks
- 4
- Avg merge
- 16h 39m
- Merged PRs (30d)
- 131
Description
Two gaps in `DRAFT.md` surfaced while looking at #187. Both concern how `protocol`'s special member functions relate to those of `std::polymorphic` (P3019R14).
## 1. Constraints on `T` relative to `I`
`DRAFT.md` (Design, "Generated structural subtyping") says that if `I` has deleted special member functions, the corresponding members of `protocol` are not generated. It does not state the converse requirement on the stored type: a `T` must be copy constructible if `I` is, and move constructible if `I` is.
P3019 states this per constructor as a *Constraints* element (`is_copy_constructible_v` on every constructor taking a `U`). `protocol` needs the generalised form, since it admits non-copyable interfaces:
> *Constraints*: `is_copy_constructible_v` is `true` if `is_copy_constructible_v` is `true`; `is_move_constructible_v` is `true` if `is_move_constructible_v` is `true`.
This belongs in the Design section now and in the formal wording when #76 restores it. The implementation side is #193.
## 2. Divergence from P3019 on moves with equal allocators
P3019 [polymorphic.ctor]/8-9 and [polymorphic.assign]/6 permit the implementation to construct a new owned object "considering the owned object as an rvalue" *even when the allocators compare equal*; the drafting notes say this is to leave room for a small-buffer optimisation. That is only sound because every owned `U` is required to be copy constructible.
`protocol` cannot adopt that freedom: an immovable `I` (deleted move constructor) must still yield a movable `protocol` for the default allocator and for any allocator where `is_always_equal` or `propagate_on_container_move_assignment` holds, and the only way to provide that is a guaranteed pointer steal when allocators compare equal. The paper should say so explicitly:
- Move construction and move assignment of `protocol` never construct a new object of the stored type when the allocators compare equal (or the allocator propagates). They are `noexcept` in those cases.
- Only the allocator-extended move constructor and move assignment with unequal, non-propagating allocators construct from the stored object as an rvalue, and those members are constrained on `is_move_constructible_v`.
This also constrains #148: SBO would only be permissible for a `protocol` where `I` is move constructible.
Contributor guide
Research direction
Start in DRAFT.md under Design, especially “Generated structural subtyping,” and compare the relevant constructor and assignment wording in P3019R14. Document the constraints relating T and I, then state the move-semantics divergence and allocator conditions; check #76, #193, and #148 for the formal-wording and implementation context.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend-api-design, documentation
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100