morph 0.1.0
Asynchronous bridge between GUI thread and business models
Loading...
Searching...
No Matches
morph::forms::Condition Concept Reference

Concept: Cond may be used as a nested condition — inside an andOf/orOf/notOf tree, or as the when clause of a requiredWhen / visibleWhen / readonlyWhen rule. More...

#include <forms.hpp>

Concept definition

template<typename Cond>
concept Condition = requires {
{ Cond::isCondition } -> std::convertible_to<bool>;
} && Cond::isCondition
Concept: Cond may be used as a nested condition — inside an andOf/orOf/notOf tree,...
Definition forms.hpp:909

Detailed Description

Concept: Cond may be used as a nested condition — inside an andOf/orOf/notOf tree, or as the when clause of a requiredWhen / visibleWhen / readonlyWhen rule.

Every rule and condition node in this header exposes the same shape (kind, test(const A&) const noexcept, emitNode()), which is what makes them substitutable — and what made "has a `test()`" a useless admission test. VisibleWhen::test() and ReadonlyWhen::test() return true unconditionally, by design: they are presentation rules and never gate submission, so a renderer reads their when clause rather than calling them. Nested as a condition, such a node therefore contributes a constant and can never influence the tree it sits in — andOf(visibleWhen(…), c) silently collapses to c, having compiled and looking like it says something. RequiredWhen is excluded for the neighbouring reason: it is a rule about a condition, not a condition, and nesting one emits a "requiredWhen" node in a when position that no renderer's condition vocabulary has a case for.

So the marker is declared explicitly by the nodes whose test() is a function of the action, rather than inferred from isPresentation — which would admit RequiredWhen — or from the presence of test(), which admits everything. Adding a node to the condition vocabulary is one line on the node itself.

The membership rules (exactlyOneOf / atLeastOneOf / mutuallyExclusive) are conditions by this rule: their test() really does range over the action. A renderer that does not recognise them nested treats them as "cannot evaluate" and defers to the server, which is the sanctioned fallback (forms.md, "Renderer fallback") rather than a disagreement.

(Cond is the candidate node type. It is deliberately not documented with a parameter-doc command: -Wdocumentation does not consider a concept a template declaration, so such a command here is an error under -Weverything -Werror, which is how the WASM ladder builds. HasFormRules and HasExplicitSubmit below omit it for the same reason.)

Definition at line 909 of file forms.hpp.