73#ifndef LIB_BRANCH_CASE_H
74#define LIB_BRANCH_CASE_H
93 template<
typename...TYPES>
99 static constexpr size_t siz = 0;
100 static constexpr size_t align = 0;
103 template<
typename T,
typename...TYPES>
121 template<
typename...TYPES>
125 static constexpr auto TOP =
sizeof...(TYPES) -1;
126 static constexpr auto SIZ = _MaxBuf<TYPES...>::siz;
129 using SlotType = std::tuple_element_t<idx, tuple<TYPES...>>;
139 alignas(_MaxBuf<TYPES...>::align)
143 template<
typename TX,
typename...INITS>
147 return *
new(&
buffer_) TX(forward<INITS> (inits)...);
150 template<
typename TX>
154 return * std::launder (
reinterpret_cast<TX*
> (&
buffer_[0]));
158 template<
size_t idx,
class FUN>
162 if constexpr (0 < idx)
165 return fun (get<idx>());
180 return selectBranch<TOP> (forward<FUN> (visitor));
186 {
using Elm = decay_t<
decltype(it)>;
187 access<Elm>().~Elm();
192 template<
typename...INITS>
196 accept ([&,
this](
auto& it)
197 {
using Elm = decay_t<
decltype(it)>;
198 if constexpr (std::is_constructible_v<Elm,INITS...>)
199 this->emplace<Elm> (forward<INITS> (inits)...);
207 unConst.accept ([
this](
auto& it)
208 {
using Elm = decay_t<
decltype(it)>;
209 this->emplace<Elm> (it);
216 ro.accept ([
this](
auto& it)
217 {
using Elm = decay_t<
decltype(it)>;
218 this->emplace<Elm> (move (it));
229 {
using Elm = decay_t<
decltype(it)>;
234 {
using Elm = decay_t<
decltype(it)>;
238 {
using Elm = decay_t<
decltype(it)>;
264 return access<SlotType<idx>>();
273 return accept([](
auto val){
return val; });
A Sum Type to hold alternative results from a branched evaluation.
SlotType< idx > & get()
re-access the value, using compile-time slot-index param.
TX & emplace(INITS &&...inits)
BranchCase(BranchCase &&ro)
std::byte buffer_[SIZ]
opaque inline storage buffer with suitable size and alignment
static constexpr auto SIZ
friend void swap(BranchCase &o1, BranchCase &o2)
BranchCase(size_t idx, INITS &&...inits)
Standard constructor: select branch and provide initialiser.
BranchCase(BranchCase const &o)
size_t branch_
selector field to designate the chosen branch
auto getAny()
access the selected value of a homogeneous model.
auto selectBranch(FUN &&fun)
apply generic functor to the currently selected branch
auto accept(FUN &&visitor)
Accept a visitor-functor (double dispatch).
BranchCase & operator=(BranchCase ref)
static constexpr auto TOP
std::tuple_element_t< idx, tuple< TYPES... > > SlotType
Implementation namespace for support and library code.