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.

### 3572. `copyable-box` should be fully `constexpr`

Section: 24.7.3 [range.copy.wrap] Status: WP Submitter: Tim Song Opened: 2021-06-19 Last modified: 2021-10-14

Priority: Not Prioritized

View all issues with WP status.

Discussion:

P2231R1 made `optional` fully `constexpr`, but missed its cousin `semiregular-box` (which was renamed to `copyable-box` by P2325R3). Most operations of `copyable-box` are already `constexpr` simply because `copyable-box` is specified in terms of `optional`; the only missing ones are the assignment operators layered on top when the wrapped type isn't assignable itself.

[2021-06-23; Reflector poll]

Set status to Tentatively Ready after eight votes in favour during reflector poll.

[2021-10-14 Approved at October 2021 virtual plenary. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4892.

1. Modify 24.7.3 [range.copy.wrap] as indicated:

   > -1- Many types in this subclause are specified in terms of an exposition-only class template `copyable-box`. `copyable-box<T>` behaves exactly like `optional<T>` with the following differences:

   > 1. (1.1) — […]

   > 2. (1.2) — […]

   > 3. (1.3) — If `copyable<T>` is not modeled, the copy assignment operator is equivalent to:

   >    >     constexpr copyable-box& operator=(const copyable-box& that)
   >    >       noexcept(is_nothrow_copy_constructible_v<T>) {
   >    >       if (this != addressof(that)) {
   >    >         if (that) emplace(*that);
   >    >         else reset();
   >    >       }
   >    >       return *this;
   >    >     }

   > 4. (1.4) — If `movable<T>` is not modeled, the move assignment operator is equivalent to:

   >    >     constexpr copyable-box& operator=(copyable-box&& that)
   >    >       noexcept(is_nothrow_move_constructible_v<T>) {
   >    >       if (this != addressof(that)) {
   >    >         if (that) emplace(std::move(*that));
   >    >         else reset();
   >    >       }
   >    >       return *this;
   >    >     }