LeechCraft
0.6.70-18808-g3467692359
Modular cross-platform feature rich live environment.
Toggle main menu visibility
Loading...
Searching...
No Matches
either.h
Go to the documentation of this file.
1
/**********************************************************************
2
* LeechCraft - modular cross-platform feature rich internet client.
3
* Copyright (C) 2006-2014 Georg Rudoy
4
*
5
* Distributed under the Boost Software License, Version 1.0.
6
* (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7
**********************************************************************/
8
9
#pragma once
10
11
#include <expected>
12
#include <optional>
13
#include <type_traits>
14
#include <variant>
15
#include "
overloaded.h
"
16
17
namespace
LC::Util
18
{
19
template
<
typename
T>
20
struct
Left
21
{
22
T
Value_
;
23
};
24
25
template
<>
26
struct
Left
<void> {};
27
28
constexpr
auto
AsLeft
=
Left<void>
{};
29
30
inline
struct
FromStdExpected_t
{}
FromStdExpected
;
31
32
template
<
typename
L,
typename
R>
33
class
Either
34
{
35
std::expected<R, L> This_;
36
public
:
37
using
L_t
= L;
38
using
R_t
= R;
39
40
Either
(
FromStdExpected_t
, std::expected<R, L>&& ex)
41
: This_ { std::move (ex) }
42
{
43
}
44
45
Either
() =
delete
;
46
47
Either
(R&& r)
48
: This_ { std::move (r) }
49
{
50
}
51
52
Either
(
const
R& r)
53
: This_ { r }
54
{
55
}
56
57
Either
(
Left<void>
,
const
L& l)
58
: This_ { std::unexpect, l }
59
{
60
}
61
62
explicit
Either
(
const
L& l)
requires
(!std::is_same_v<L, R>)
63
: This_ { std::unexpect, l }
64
{
65
}
66
67
Either
(
Left<L>
&& left)
68
: This_ { std::unexpect, std::move (left.Value_) }
69
{
70
}
71
72
template
<
typename
LL>
73
requires
std::is_constructible_v<L, LL&&>
74
Either
(
Left<LL>
&& left)
75
: This_ { std::unexpect, L { std::move (left.Value_) } }
76
{
77
}
78
79
Either
(
const
Either
&) =
default
;
80
Either
(
Either
&&) =
default
;
81
Either
&
operator=
(
const
Either
&) =
default
;
82
Either
&
operator=
(
Either
&&) =
default
;
83
84
bool
IsLeft
()
const
85
{
86
return
!
IsRight
();
87
}
88
89
bool
IsRight
()
const
90
{
91
return
This_.has_value ();
92
}
93
94
const
L&
GetLeft
()
const
95
{
96
if
(!
IsLeft
())
97
throw
std::runtime_error {
"Tried accessing Left for a Right Either"
};
98
return
This_.error ();
99
}
100
101
L&
GetLeft
()
102
{
103
if
(!
IsLeft
())
104
throw
std::runtime_error {
"Tried accessing Left for a Right Either"
};
105
return
This_.error ();
106
}
107
108
const
R&
GetRight
()
const
109
{
110
if
(!
IsRight
())
111
throw
std::runtime_error {
"Tried accessing Right for a Left Either"
};
112
return
This_.value ();
113
}
114
115
R&
GetRight
()
116
{
117
if
(!
IsRight
())
118
throw
std::runtime_error {
"Tried accessing Right for a Left Either"
};
119
return
This_.value ();
120
}
121
122
std::optional<L>
MaybeLeft
()
const
123
{
124
if
(!
IsLeft
())
125
return
{};
126
return
GetLeft
();
127
}
128
129
std::optional<R>
MaybeRight
()
const
130
{
131
if
(!
IsRight
())
132
return
{};
133
return
GetRight
();
134
}
135
136
template
<
typename
F>
137
R
ToRight
(F&& f)
const
138
{
139
return
IsRight
() ?
GetRight
() : std::forward<F> (f) (
GetLeft
());
140
}
141
142
template
<
typename
F>
143
auto
MapLeft
(F&& f)
const
144
{
145
using
Result =
Either<std::invoke_result_t<F, L>
, R>;
146
return
Result {
FromStdExpected
, This_.transform_error (std::forward<F> (f)) };
147
}
148
149
template
<
typename
F>
150
auto
MapRight
(F&& f)
const
151
{
152
using
Result =
Either<L, std::invoke_result_t<F, R>
>;
153
return
Result { This_.transform (std::forward<F> (f)) };
154
}
155
156
friend
bool
operator==
(
const
Either
& e1,
const
Either
& e2)
157
{
158
return
e1.This_ == e2.This_;
159
}
160
161
friend
bool
operator!=
(
const
Either
& e1,
const
Either
& e2)
162
{
163
return
!(e1 == e2);
164
}
165
};
166
167
template
<
typename
L,
typename
R>
168
Either<L, R>
EitherFromSwapped
(
const
std::variant<R, L>& variant)
169
{
170
if
(variant.index () == 0)
171
return
std::get<0> (variant);
172
return
Left<L>
{ std::get<1> (variant) };
173
}
174
175
template
<
template
<
typename
>
class
Cont,
typename
L,
typename
R>
176
std::pair<Cont<L>, Cont<R>>
Partition
(
const
Cont<
Either<L, R>
>& eithers)
177
{
178
std::pair<Cont<L>, Cont<R>> result;
179
for
(
const
auto
& either : eithers)
180
if
(either.IsLeft ())
181
result.first.push_back (either.GetLeft ());
182
else
183
result.second.push_back (either.GetRight ());
184
185
return
result;
186
}
187
188
template
<
typename
Left,
typename
Right,
typename
... Args>
189
auto
Visit
(
const
Either<Left, Right>
& either, Args&&... args)
190
{
191
Overloaded
visitor { std::forward<Args> (args)... };
192
return
either.
IsRight
() ?
193
std::move (visitor) (either.
GetRight
()) :
194
std::move (visitor) (either.
GetLeft
());
195
}
196
197
template
<
typename
Left,
typename
Right,
typename
... Args>
198
auto
Visit
(
Either<Left, Right>
&& either, Args&&... args)
199
{
200
Overloaded
visitor { std::forward<Args> (args)... };
201
return
either.IsRight () ?
202
std::move (visitor) (std::move (either.GetRight ())) :
203
std::move (visitor) (std::move (either.GetLeft ()));
204
}
205
}
LC::Util::Either
Definition
either.h:34
LC::Util::Either::Either
Either(Left< L > &&left)
Definition
either.h:67
LC::Util::Either::GetRight
R & GetRight()
Definition
either.h:115
LC::Util::Either::operator!=
friend bool operator!=(const Either &e1, const Either &e2)
Definition
either.h:161
LC::Util::Either< Error, Success >::L_t
Error L_t
Definition
either.h:37
LC::Util::Either::Either
Either(Left< void >, const L &l)
Definition
either.h:57
LC::Util::Either::Either
Either(const L &l)
Definition
either.h:62
LC::Util::Either::Either
Either()=delete
LC::Util::Either::Either
Either(Either &&)=default
LC::Util::Either::MaybeLeft
std::optional< L > MaybeLeft() const
Definition
either.h:122
LC::Util::Either::Either
Either(FromStdExpected_t, std::expected< R, L > &&ex)
Definition
either.h:40
LC::Util::Either::operator=
Either & operator=(const Either &)=default
LC::Util::Either::Either
Either(const R &r)
Definition
either.h:52
LC::Util::Either< Error, Success >::R_t
Success R_t
Definition
either.h:38
LC::Util::Either::GetLeft
L & GetLeft()
Definition
either.h:101
LC::Util::Either::GetLeft
const L & GetLeft() const
Definition
either.h:94
LC::Util::Either::MaybeRight
std::optional< R > MaybeRight() const
Definition
either.h:129
LC::Util::Either::IsRight
bool IsRight() const
Definition
either.h:89
LC::Util::Either::ToRight
R ToRight(F &&f) const
Definition
either.h:137
LC::Util::Either::Either
Either(Left< LL > &&left)
Definition
either.h:74
LC::Util::Either::operator==
friend bool operator==(const Either &e1, const Either &e2)
Definition
either.h:156
LC::Util::Either::MapLeft
auto MapLeft(F &&f) const
Definition
either.h:143
LC::Util::Either::IsLeft
bool IsLeft() const
Definition
either.h:84
LC::Util::Either::MapRight
auto MapRight(F &&f) const
Definition
either.h:150
LC::Util::Either::GetRight
const R & GetRight() const
Definition
either.h:108
LC::Util::Either::Either
Either(R &&r)
Definition
either.h:47
LC::Util::Either::Either
Either(const Either &)=default
LC::Util
Definition
icoreproxy.h:34
LC::Util::AsLeft
constexpr auto AsLeft
Definition
either.h:28
LC::Util::FromStdExpected
struct LC::Util::FromStdExpected_t FromStdExpected
LC::Util::EitherFromSwapped
Either< L, R > EitherFromSwapped(const std::variant< R, L > &variant)
Definition
either.h:168
LC::Util::Visit
auto Visit(const Either< Left, Right > &either, Args &&... args)
Definition
either.h:189
LC::Util::Partition
std::pair< Cont< L >, Cont< R > > Partition(const Cont< Either< L, R > > &eithers)
Definition
either.h:176
overloaded.h
LC::Util::FromStdExpected_t
Definition
either.h:30
LC::Util::Left
Definition
either.h:21
LC::Util::Left::Value_
T Value_
Definition
either.h:22
LC::Util::Overloaded
Definition
overloaded.h:15
src
util
sll
either.h
Generated by
1.17.0