diff --git a/source/meta.tex b/source/meta.tex index 7a31e4e60e..7a7ec3a140 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -583,6 +583,7 @@ // \ref{meta.const.eval}, constant evaluation context constexpr bool is_constant_evaluated() noexcept; + consteval bool is_within_lifetime(const auto*) noexcept; } \end{codeblock} @@ -2432,6 +2433,60 @@ \end{example} \end{itemdescr} +\indexlibraryglobal{is_within_lifetime}% +\begin{itemdecl} +consteval bool is_within_lifetime(const auto* p) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{p} is a pointer to an object that is +within its lifetime\iref{basic.life}; otherwise, \tcode{false}. + +\pnum +\remarks +During the evaluation of an expression \tcode{E} as a core constant expression, +a call to this function is ill-formed +unless \tcode{p} points to an object that is usable +in constant expressions or +whose complete object's lifetime began within \tcode{E}. + +\pnum +\begin{example} +\begin{codeblock} +struct OptBool { + union { bool b; char c; }; + + // note: this assumes common implementation properties for \tcode{bool} and \tcode{char}: + // * \tcode{sizeof(bool) == sizeof(char)}, and + // * the value representations for \tcode{true} and \tcode{false} are distinct + // from the value representation for \tcode{2} + constexpr OptBool() : c(2) { } + constexpr OptBool(bool b) : b(b) { } + + constexpr auto has_value() const -> bool { + if consteval { + return std::is_within_lifetime(&b); // during constant evaluation, cannot read from \tcode{c} + } else { + return c != 2; // during runtime, must read from \tcode{c} + } + } + + constexpr auto operator*() -> bool& { + return b; + } +}; + +constexpr OptBool disengaged; +constexpr OptBool engaged(true); +static_assert(!disengaged.has_value()); +static_assert(engaged.has_value()); +static_assert(*engaged); +\end{codeblock} +\end{example} +\end{itemdescr} + \rSec1[ratio]{Compile-time rational arithmetic} \rSec2[ratio.general]{In general} diff --git a/source/support.tex b/source/support.tex index 47f4f97a0f..d4e2f65796 100644 --- a/source/support.tex +++ b/source/support.tex @@ -679,6 +679,7 @@ #define @\defnlibxname{cpp_lib_is_pointer_interconvertible}@ 201907L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_scoped_enum}@ 202011L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_swappable}@ 201603L // freestanding, also in \libheader{type_traits} +#define @\defnlibxname{cpp_lib_is_within_lifetime}@ 202306L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_jthread}@ 201911L // also in \libheader{stop_token}, \libheader{thread} #define @\defnlibxname{cpp_lib_latch}@ 201907L // also in \libheader{latch} #define @\defnlibxname{cpp_lib_launder}@ 201606L // freestanding, also in \libheader{new}