LeechCraft
0.6.70-18450-gabe19ee3b0
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 "
overloaded.h
"
15
16
namespace
LC::Util
17
{
18
template
<
typename
T>
19
struct
Left
20
{
21
T
Value_
;
22
};
23
24
template
<>
25
struct
Left
<void> {};
26
27
constexpr
auto
AsLeft
=
Left<void>
{};
28
29
inline
struct
FromStdExpected_t
{}
FromStdExpected
;
30
31
template
<
typename
L,
typename
R>
32
class
Either
33
{
34
std::expected<R, L> This_;
35
public
:
36
using
L_t
= L;
37
using
R_t
= R;
38
39
Either
(
FromStdExpected_t
, std::expected<R, L>&& ex)
40
: This_ { std::move (ex) }
41
{
42
}
43
44
Either
() =
delete
;
45
46
Either
(R&& r)
47
: This_ { std::move (r) }
48
{
49
}
50
51
Either
(
const
R& r)
52
: This_ { r }
53
{
54
}
55
56
Either
(
Left<void>
,
const
L& l)
57
: This_ { std::unexpect, l }
58
{
59
}
60
61
explicit
Either
(
const
L& l)
requires
(!std::is_same_v<L, R>)
62
: This_ { std::unexpect, l }
63
{
64
}
65
66
Either
(
Left<L>
&& left)
67
: This_ { std::unexpect, std::move (left.Value_) }
68
{
69
}
70
71
template
<
typename
LL>
72
requires
std::is_constructible_v<L, LL&&>
73
Either
(
Left<LL>
&& left)
74
: This_ { std::unexpect, L { std::move (left.Value_) } }
75
{
76
}
77
78
Either
(
const
Either
&) =
default
;
79
Either
(
Either
&&) =
default
;
80
Either
&
operator=
(
const
Either
&) =
default
;
81
Either
&
operator=
(
Either
&&) =
default
;
82
83
bool
IsLeft
()
const
84
{
85
return
!
IsRight
();
86
}
87
88
bool
IsRight
()
const
89
{
90
return
This_.has_value ();
91
}
92
93
const
L&
GetLeft
()
const
94
{
95
if
(!
IsLeft
())
96
throw
std::runtime_error {
"Tried accessing Left for a Right Either"
};
97
return
This_.error ();
98
}
99
100
L&
GetLeft
()
101
{
102
if
(!
IsLeft
())
103
throw
std::runtime_error {
"Tried accessing Left for a Right Either"
};
104
return
This_.error ();
105
}
106
107
const
R&
GetRight
()
const
108
{
109
if
(!
IsRight
())
110
throw
std::runtime_error {
"Tried accessing Right for a Left Either"
};
111
return
This_.value ();
112
}
113
114
R&
GetRight
()
115
{
116
if
(!
IsRight
())
117
throw
std::runtime_error {
"Tried accessing Right for a Left Either"
};
118
return
This_.value ();
119
}
120
121
std::optional<L>
MaybeLeft
()
const
122
{
123
if
(!
IsLeft
())
124
return
{};
125
return
GetLeft
();
126
}
127
128
std::optional<R>
MaybeRight
()
const
129
{
130
if
(!
IsRight
())
131
return
{};
132
return
GetRight
();
133
}
134
135
template
<
typename
F>
136
R
ToRight
(F&& f)
const
137
{
138
return
IsRight
() ?
GetRight
() : std::forward<F> (f) (
GetLeft
());
139
}
140
141
template
<
typename
F>
142
auto
MapLeft
(F&& f)
const
143
{
144
using
Result =
Either<std::invoke_result_t<F, L>
, R>;
145
return
Result {
FromStdExpected
, This_.transform_error (std::forward<F> (f)) };
146
}
147
148
template
<
typename
F>
149
auto
MapRight
(F&& f)
const
150
{
151
using
Result =
Either<L, std::invoke_result_t<F, R>
>;
152
return
Result { This_.transform (std::forward<F> (f)) };
153
}
154
155
friend
bool
operator==
(
const
Either
& e1,
const
Either
& e2)
156
{
157
return
e1.This_ == e2.This_;
158
}
159
160
friend
bool
operator!=
(
const
Either
& e1,
const
Either
& e2)
161
{
162
return
!(e1 == e2);
163
}
164
};
165
166
template
<
template
<
typename
>
class
Cont,
typename
L,
typename
R>
167
std::pair<Cont<L>, Cont<R>>
Partition
(
const
Cont<
Either<L, R>
>& eithers)
168
{
169
std::pair<Cont<L>, Cont<R>> result;
170
for
(
const
auto
& either : eithers)
171
if
(either.IsLeft ())
172
result.first.push_back (either.GetLeft ());
173
else
174
result.second.push_back (either.GetRight ());
175
176
return
result;
177
}
178
179
template
<
typename
Left,
typename
Right,
typename
... Args>
180
auto
Visit
(
const
Either<Left, Right>
& either, Args&&... args)
181
{
182
Overloaded
visitor { std::forward<Args> (args)... };
183
return
either.
IsRight
() ?
184
std::move (visitor) (either.
GetRight
()) :
185
std::move (visitor) (either.
GetLeft
());
186
}
187
188
template
<
typename
Left,
typename
Right,
typename
... Args>
189
auto
Visit
(
Either<Left, Right>
&& either, Args&&... args)
190
{
191
Overloaded
visitor { std::forward<Args> (args)... };
192
return
either.IsRight () ?
193
std::move (visitor) (std::move (either.GetRight ())) :
194
std::move (visitor) (std::move (either.GetLeft ()));
195
}
196
}
LC::Util::Either
Definition
either.h:33
LC::Util::Either::Either
Either(Left< L > &&left)
Definition
either.h:66
LC::Util::Either::GetRight
R & GetRight()
Definition
either.h:114
LC::Util::Either::operator!=
friend bool operator!=(const Either &e1, const Either &e2)
Definition
either.h:160
LC::Util::Either< Error, Success >::L_t
Error L_t
Definition
either.h:36
LC::Util::Either::Either
Either(Left< void >, const L &l)
Definition
either.h:56
LC::Util::Either::Either
Either(const L &l)
Definition
either.h:61
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:121
LC::Util::Either::Either
Either(FromStdExpected_t, std::expected< R, L > &&ex)
Definition
either.h:39
LC::Util::Either::operator=
Either & operator=(const Either &)=default
LC::Util::Either::Either
Either(const R &r)
Definition
either.h:51
LC::Util::Either< Error, Success >::R_t
Success R_t
Definition
either.h:37
LC::Util::Either::GetLeft
L & GetLeft()
Definition
either.h:100
LC::Util::Either::GetLeft
const L & GetLeft() const
Definition
either.h:93
LC::Util::Either::MaybeRight
std::optional< R > MaybeRight() const
Definition
either.h:128
LC::Util::Either::IsRight
bool IsRight() const
Definition
either.h:88
LC::Util::Either::ToRight
R ToRight(F &&f) const
Definition
either.h:136
LC::Util::Either::Either
Either(Left< LL > &&left)
Definition
either.h:73
LC::Util::Either::operator==
friend bool operator==(const Either &e1, const Either &e2)
Definition
either.h:155
LC::Util::Either::MapLeft
auto MapLeft(F &&f) const
Definition
either.h:142
LC::Util::Either::IsLeft
bool IsLeft() const
Definition
either.h:83
LC::Util::Either::MapRight
auto MapRight(F &&f) const
Definition
either.h:149
LC::Util::Either::GetRight
const R & GetRight() const
Definition
either.h:107
LC::Util::Either::Either
Either(R &&r)
Definition
either.h:46
LC::Util::Either::Either
Either(const Either &)=default
LC::Util
Definition
icoreproxy.h:34
LC::Util::AsLeft
constexpr auto AsLeft
Definition
either.h:27
LC::Util::FromStdExpected
struct LC::Util::FromStdExpected_t FromStdExpected
LC::Util::Visit
auto Visit(const Either< Left, Right > &either, Args &&... args)
Definition
either.h:180
LC::Util::Partition
std::pair< Cont< L >, Cont< R > > Partition(const Cont< Either< L, R > > &eithers)
Definition
either.h:167
overloaded.h
LC::Util::FromStdExpected_t
Definition
either.h:29
LC::Util::Left
Definition
either.h:20
LC::Util::Left::Value_
T Value_
Definition
either.h:21
LC::Util::Overloaded
Definition
overloaded.h:15
src
util
sll
either.h
Generated by
1.17.0