|
583 | 583 |
|
584 | 584 | // \ref{meta.const.eval}, constant evaluation context
|
585 | 585 | constexpr bool is_constant_evaluated() noexcept;
|
| 586 | + template<class T> |
| 587 | + consteval bool is_within_lifetime(const T*) noexcept; |
586 | 588 | }
|
587 | 589 | \end{codeblock}
|
588 | 590 |
|
|
2432 | 2434 | \end{example}
|
2433 | 2435 | \end{itemdescr}
|
2434 | 2436 |
|
| 2437 | +\indexlibraryglobal{is_within_lifetime}% |
| 2438 | +\begin{itemdecl} |
| 2439 | +template<class T> |
| 2440 | + consteval bool is_within_lifetime(const T* p) noexcept; |
| 2441 | +\end{itemdecl} |
| 2442 | + |
| 2443 | +\begin{itemdescr} |
| 2444 | +\pnum |
| 2445 | +\returns |
| 2446 | +\tcode{true} if \tcode{p} is a pointer to an object that is |
| 2447 | +within its lifetime\iref{basic.life}; otherwise, \tcode{false}. |
| 2448 | + |
| 2449 | +\pnum |
| 2450 | +\remarks |
| 2451 | +During the evaluation of an expression \tcode{E} as a core constant expression, |
| 2452 | +a call to this function is ill-formed |
| 2453 | +unless \tcode{p} points to an object that is usable |
| 2454 | +in constant expressions or |
| 2455 | +whose complete object's lifetime began within \tcode{E}. |
| 2456 | + |
| 2457 | +\pnum |
| 2458 | +\begin{example} |
| 2459 | +\begin{codeblock} |
| 2460 | +struct OptBool { |
| 2461 | + union { bool b; char c; }; |
| 2462 | + |
| 2463 | + // note: this assumes common implementation properties for \tcode{bool} and \tcode{char}: |
| 2464 | + // * \tcode{sizeof(bool) == sizeof(char)}, and |
| 2465 | + // * the value representations for \tcode{true} and \tcode{false} are distinct |
| 2466 | + // from the value representation for \tcode{2} |
| 2467 | + constexpr OptBool() : c(2) { } |
| 2468 | + constexpr OptBool(bool b) : b(b) { } |
| 2469 | + |
| 2470 | + constexpr auto has_value() const -> bool { |
| 2471 | + if consteval { |
| 2472 | + return std::is_within_lifetime(&b); // during constant evaluation, cannot read from \tcode{c} |
| 2473 | + } else { |
| 2474 | + return c != 2; // during runtime, must read from \tcode{c} |
| 2475 | + } |
| 2476 | + } |
| 2477 | + |
| 2478 | + constexpr auto operator*() -> bool& { |
| 2479 | + return b; |
| 2480 | + } |
| 2481 | +}; |
| 2482 | + |
| 2483 | +constexpr OptBool disengaged; |
| 2484 | +constexpr OptBool engaged(true); |
| 2485 | +static_assert(!disengaged.has_value()); |
| 2486 | +static_assert(engaged.has_value()); |
| 2487 | +static_assert(*engaged); |
| 2488 | +\end{codeblock} |
| 2489 | +\end{example} |
| 2490 | +\end{itemdescr} |
| 2491 | + |
2435 | 2492 | \rSec1[ratio]{Compile-time rational arithmetic}
|
2436 | 2493 |
|
2437 | 2494 | \rSec2[ratio.general]{In general}
|
|
0 commit comments