126 template<
typename L2,
typename R2>
129 using left_storage_t = std::conditional_t<std::is_void_v<L>,
dummy, L>;
130 using right_storage_t = std::conditional_t<std::is_void_v<R>,
dummy, R>;
133 left_storage_t left_value;
134 right_storage_t right_value;
142 template<
typename L2>
143 inline either(left_t<L2>&&
value): left_value(std::move(
value.value)), has_right_v(
false) {};
146 template<
typename R2>
147 inline either(right_t<R2>&&
value): right_value(std::move(
value.value)), has_right_v(
true) {};
149 either(either &&other): has_right_v(std::move(other.has_right_v)) {
151 new(&right_value)R(std::move(other.right_value));
153 new(&left_value)L(std::move(other.left_value));
157 either(
const either &other): has_right_v(other.has_right_v) {
159 new(&right_value)R(other.right_value);
161 new(&left_value)L(other.left_value);
165 template<
typename L2,
typename R2>
166 either(either<L2, R2>&& other): has_right_v(std::move(other.has_right_v)) {
168 new(&right_value)R(std::move(other.right_value));
170 new(&left_value)L(std::move(other.left_value));
174 template<
typename L2,
typename R2>
175 either(
const either<L2, R2> &other): has_right_v(other.has_right_v) {
177 new(&right_value)R(other.right_value);
179 new(&left_value)L(other.left_value);
183 either<L, R>& operator=(
const either<L, R>& other) {
185 new(&right_value)R(other.right_value);
187 new(&left_value)L(other.left_value);
192 either<L, R>& operator=(either<L, R>&& other) {
194 new(&right_value)R(std::move(other.right_value));
196 new(&left_value)L(std::move(other.left_value));
202 ZEN_ASSERT(has_right_v);
206 template<
typename T = R>
207 T &operator*()
requires (!std::same_as<T, void>) {
208 ZEN_ASSERT(has_right_v);
228 operator bool()
const {
232 R unwrap()
requires (has_display<L>) {
234 ZEN_PANIC(
"error: %s", display(left_value).c_str());
239 R unwrap()
requires (!has_display<L>) {
241 ZEN_PANIC(
"trying to unwrap a zen::either which is left-valued");
248 ZEN_PANIC(
"trying to unwrap the left side a zen::either which is right-valued");
254 template<
typename T = L>
255 T &
left()
requires (!std::same_as<void, T>) {
256 ZEN_ASSERT(!has_right_v);
261 template<
typename T = R>
262 T &
right()
requires (!std::same_as<T, void>) {
263 ZEN_ASSERT(has_right_v);
270 ZEN_ASSERT(!has_right_v);
271 return std::move(left_value);
277 ZEN_ASSERT(has_right_v);
278 return std::move(right_value);
283 right_value.~right_storage_t();
285 left_value.~left_storage_t();