This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

### 3413. [fund.ts.v3] `propagate_const`'s `swap`'s `noexcept` specification needs to be constrained and use a trait

Section: 3.2.2.7 [fund.ts.v3::propagate_const.modifiers], 3.2.2.9 [fund.ts.v3::propagate_const.algorithms] Status: WP Submitter: Thomas Köppe Opened: 2020-02-29 Last modified: 2020-11-09

Priority: 0

View all issues with WP status.

Discussion:

Addresses: fund.ts.v3

In the Fundamentals TS, the `noexcept` specifications of both the member and non-member `swap` functions for `propagate_const` are using the old, ill-formed pattern of attempting to use "`noexcept(swap(...))`" as the boolean predicate. According to LWG 2456, this is ill-formed, and a resolution such as in P0185R1 is required.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4840.

> 1. Modify 3.2.1 [fund.ts.v3::propagate_const.syn], header `<experimental/propagate_const>` synopsis, as indicated:

>    >     // 3.2.2.9 [fund.ts.v3::propagate_const.algorithms], propagate_const specialized algorithms
>    >     template <class T>
>    >       constexpr void swap(propagate_const<T>& pt, propagate_const<T>& pt2) noexcept(see belowis_nothrow_swappable_v<T>);

> 2. Modify 3.2.2.1 [fund.ts.v3::propagate_const.overview], class template `propagate_const` synopsis, as indicated:

>    >     // 3.2.2.7 [fund.ts.v3::propagate_const.modifiers], propagate_const modifiers
>    >     constexpr void swap(propagate_const& pt) noexcept(see belowis_nothrow_swappable_v<T>);

> 3. Modify 3.2.2.7 [fund.ts.v3::propagate_const.modifiers] as indicated:

>    >     constexpr void swap(propagate_const& pt) noexcept(see belowis_nothrow_swappable_v<T>);

>    > > -2- The constant-expression in the exception-specification is `noexcept(swap(t_, pt.t_))`.

>    > > -3- Effects: `swap(t_, pt.t_)`.

> 4. Modify 3.2.2.9 [fund.ts.v3::propagate_const.algorithms] as indicated:

>    >     template <class T>
>    >       constexpr void swap(propagate_const<T>& pt1, propagate_const<T>& pt2) noexcept(see belowis_nothrow_swappable_v<T>);

>    > > -2- The constant-expression in the exception-specification is `noexcept(pt1.swap(pt2))`.

>    > > -3- Effects: `pt1.swap(pt2)`.

[2020-03-30; Reflector discussion]

This issue has very much overlap with LWG 2561, especially now that the library fundamentals has been rebased to C++20 the there reported problem for the corresponding `swap` problem for `optional` is now moot. During the reflector discussion of this issue here it was also observed that the free `swap` template for `propagate_const` needs to be constrained. This has been done below in the revised wording which also attempts to use a similar style as the IS.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4840.

> 1. Modify 3.2.2.1 [fund.ts.v3::propagate_const.overview], class template `propagate_const` synopsis, as indicated:

>    >     // 3.2.2.7 [fund.ts.v3::propagate_const.modifiers], propagate_const modifiers
>    >     constexpr void swap(propagate_const& pt) noexcept(see belowis_nothrow_swappable_v<T>);

> 2. Modify 3.2.2.7 [fund.ts.v3::propagate_const.modifiers] as indicated:

>    >     constexpr void swap(propagate_const& pt) noexcept(see belowis_nothrow_swappable_v<T>);

>    > > -2- The constant-expression in the exception-specification is `noexcept(swap(t_, pt.t_))`.

>    > > -3- Effects: `swap(t_, pt.t_)`.

> 3. Modify 3.2.2.9 [fund.ts.v3::propagate_const.algorithms] as indicated:

>    >     template <class T>
>    >       constexpr void swap(propagate_const<T>& pt1, propagate_const<T>& pt2) noexcept(see below);

>    > > -?- Constraints: `is_swappable_v<T>` is `true`.

>    > > -2- The constant-expression in the exception-specification is `noexcept(pt1.swap(pt2))`.

>    > > -3- Effects: `pt1.swap(pt2)`.

>    > > -?- Remarks: The expression inside `noexcept` is equivalent to:

>    > > >     noexcept(pt1.swap(pt2))

[2020-04-06; Wording update upon reflector discussions]

[2020-05-03 Issue Prioritization]

Status set to Tentatively Ready after five positive votes on the reflector.

[2020-11-09 Approved In November virtual meeting. Status changed: Tentatively Ready → WP.]

Proposed resolution:

This wording is relative to N4840.

1. Modify 3.2.2.1 [fund.ts.v3::propagate_const.overview], class template `propagate_const` synopsis, as indicated:

   >     // 3.2.2.7 [fund.ts.v3::propagate_const.modifiers], propagate_const modifiers
   >     constexpr void swap(propagate_const& pt) noexcept(see belowis_nothrow_swappable_v<T>);

2. Modify 3.2.2.7 [fund.ts.v3::propagate_const.modifiers] as indicated:

   >     constexpr void swap(propagate_const& pt) noexcept(see belowis_nothrow_swappable_v<T>);

   > > -?- Preconditions: Lvalues of type `T` are swappable (C++17 §20.5.3.2).

   > > -2- The constant-expression in the exception-specification is `noexcept(swap(t_, pt.t_))`.

   > > -3- Effects: `swap(t_, pt.t_)`.

3. Modify 3.2.2.9 [fund.ts.v3::propagate_const.algorithms] as indicated:

   >     template <class T>
   >       constexpr void swap(propagate_const<T>& pt1, propagate_const<T>& pt2) noexcept(see below);

   > > -?- Constraints: `is_swappable_v<T>` is `true`.

   > > -2- The constant-expression in the exception-specification is `noexcept(pt1.swap(pt2))`.

   > > -3- Effects: Equivalent to: `pt1.swap(pt2)`.

   > > -?- Remarks: The expression inside `noexcept` is equivalent to:

   > > >     noexcept(pt1.swap(pt2))