# C++20標準ライブラリ仕様：Constraints／Mandates／Preconditions

C++2a(C++20)標準ライブラリの関数仕様記述で用いられる Constraints／Mandates／Preconditions の違いについてメモ。

• 現行C++17標準ライブラリの Requires は廃止され、C++2aでは Constraints／Mandates／Preconditions に細分化される。
• Mandates: 型や定数式に対する必須要件。違反時は ill-formed のためコンパイルエラー。
• Constraints: 型や定数式に対する制約条件。違反時は関数オーバーロード候補から除外される。“SFINAE-friendly”
• Preconditions: 引数値やオブジェクト状態に対する事前条件。違反時は実行時エラーや未定義動作(undefined behavior)を引き起こす。
• C++標準規格では関数仕様のみを定め、標準ライブラリの実現方式には言及しない。
• 例：Constraintsは requires節*1`enable_if`*2、constexpr if*3 など任意の仕組みで実現されうる。

C++17仕様）
Requires: `INVOKE<R>(f, t1, t2, ..., tN)`, where `t1, t2, ..., tN` are values of the corresponding types in `ArgTypes...`, shall be a valid expression. Invoking a copy of `f` shall behave the same as invoking `f`.
Remarks: This constructor shall not participate in overload resolution if `decay_t<F>` is the same type as `packaged_task<R(ArgTypes...)>`.

C++2a仕様）
Constraints: `remove_cvref_t<F>` is not the same type as `packaged_task<R(ArgTypes...)>`.
Mandates: `is_invocable_r_v<R, F&, ArgTypes...>` is `true`.
Preconditions: Invoking a copy of `f` behaves the same as invoking `f`.

I. Let's not recycle a Requires: element to mean something other than what it means today.

• a) Let's instead adopt new elements, described below, to specify the Library requirements that are (or that should have been) specified via our current Requires: elements. [(snip)]
• (snip)

II. Let's introduce a new Constraints: element.

• a) Let's use this Constraints: element to specify the compile-time circumstances that must be satisfied in order that the corresponding Library component will be compiled. [(snip)]
• b) Let's ensure that unsatisfied Constraints: not produce any diagnostic in and of themselves.
[This obviates the need for specification wording such as "shall not participate in overload resolution." Note that a consequential diagnostic might still result: for example, overload resolution might find no viable candidates due to unsatisfied constraints and/or other factors.]
• c) Let's introduce a new Mandates: element to specify the compile-time circumstances under which, when unsatisfied, an implementation must produce a diagnostic.
[(snip)]
[This element obviates the need for any "is ill-formed" specifications. For example, in [pair.astuple]/1 we today find the specification "Requires: `I < 2`. The program is ill-formed if I is out of bounds." Under the present proposal, this would be simplified to "Mandates: `I < 2`."]

III. Let's introduce a new Expects: element.

• a) Let's use this Expects: element to specify the circumstances that must be satisfied to avoid undefined behavior when the corresponding Library component is invoked.
[Industry-wide, such requirements have come to be known as preconditions, but the Contracts proposals [P0542R1] seem to have chosen "expects" as their preferred term of art; it seems better to have a single term and use it consistently.]
• (snip)

IV. Let's avoid any specification that demands any particular technology by which implementations must comply with Library specifications.

• a) Let's permit an implementation to use a requires-clause, an `enable_if`, a constexpr if, or any other technology or combination of technologies to meet Constraints: specifications.
• b) Let's permit an implementation to use `static_assert` and/or any other technologies to meet Mandates: specifications.
• c) Let's permit an implementation to use Contracts attributes [P0542R1] and/or any other technologies to meet Expects: and Ensures: specifications.
• d) Let's consider user code that relies on any specific technology on the part of an implementation to be ill-formed, with no diagnostic required.

#### C++17仕様

C++17 20.4.1.4/p3-4より一部引用。

3 Descriptions of function semantics contain the following elements (as appropriate):

• Requires: the preconditions for calling the function
• (snip)

4 (snip) If `F`'s semantics specifies a Requires: element, then that requirement is logically imposed prior to the equivalent-to semantics. (snip)

#### C++2a仕様

C++2a DIS(N4861) 16.4.1.4/p3より一部引用。

3 Descriptions of function semantics contain the following elements (as appropriate):

• Constraints: the conditions for the function's participation in overload resolution (12.4). [Note: Failure to meet such a condition results in the function's silent non-viability. --end note] [Example: An implementation might express such a condition via a constraint-expression (13.5.2). --end example]
• Mandates: the conditions that, if not met, render the program ill-formed. [Example: An implementation might express such a condition via the constant-expression in a static_assert-declaration (9.1). If the diagnostic is to be emitted only after the function has been selected by overload resolution, an implementation might express such a condition via a constraint-expression (13.5.2) and also define the function as deleted. --end example]
• Preconditions: the conditions that the function assumes to hold whenever it is called.
• (snip)

4 (snip) If `F`'s semantics specifies any Constraints or Mandates elements, then those requirements are logically imposed prior to the equivalent-to semantics. (snip)

*4:C++17 “INVOKE<R>(...) shall be a valid expression” は、C++2a “is_invocable_r_v<R, ...> is true” に対応する。