Skip to content

Commit 4fba140

Browse files
authored
Merge 2023-06 LWG Motion 22
P2641R4 Checking if a union alternative is active
2 parents 04cf6ed + 6a8b155 commit 4fba140

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

source/meta.tex

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@
583583

584584
// \ref{meta.const.eval}, constant evaluation context
585585
constexpr bool is_constant_evaluated() noexcept;
586+
consteval bool is_within_lifetime(const auto*) noexcept;
586587
}
587588
\end{codeblock}
588589

@@ -2432,6 +2433,60 @@
24322433
\end{example}
24332434
\end{itemdescr}
24342435

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

24372492
\rSec2[ratio.general]{In general}

source/support.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@
679679
#define @\defnlibxname{cpp_lib_is_pointer_interconvertible}@ 201907L // freestanding, also in \libheader{type_traits}
680680
#define @\defnlibxname{cpp_lib_is_scoped_enum}@ 202011L // freestanding, also in \libheader{type_traits}
681681
#define @\defnlibxname{cpp_lib_is_swappable}@ 201603L // freestanding, also in \libheader{type_traits}
682+
#define @\defnlibxname{cpp_lib_is_within_lifetime}@ 202306L // also in \libheader{type_traits}
682683
#define @\defnlibxname{cpp_lib_jthread}@ 201911L // also in \libheader{stop_token}, \libheader{thread}
683684
#define @\defnlibxname{cpp_lib_latch}@ 201907L // also in \libheader{latch}
684685
#define @\defnlibxname{cpp_lib_launder}@ 201606L // freestanding, also in \libheader{new}

0 commit comments

Comments
 (0)