LeechCraft
0.6.70-19424-g027e980fd1
Modular cross-platform feature rich live environment.
Toggle main menu visibility
Loading...
Searching...
No Matches
prelude.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 <concepts>
12
#include <functional>
13
#include <type_traits>
14
#include <iterator>
15
#include <utility>
16
#include <QStringList>
17
18
namespace
LC
19
{
20
namespace
Util
21
{
22
template
<
typename
T>
23
struct
WrapType
24
{
25
using
type
= T;
26
};
27
28
template
<
typename
T>
29
using
WrapType_t
=
typename
WrapType<T>::type
;
30
31
template
<>
32
struct
WrapType
<
QList
<QString>>
33
{
34
using
type
= QStringList;
35
};
36
37
template
<
template
<
typename
U>
class
Container,
typename
T1,
typename
T2,
typename
F>
38
auto
ZipWith
(
const
Container<T1>& c1,
const
Container<T2>& c2, F f)
39
{
40
WrapType_t<Container<std::decay_t<std::invoke_result_t<F, T1, T2>
>>> result;
41
42
using
std::begin;
43
using
std::end;
44
45
auto
i1 = begin (c1), e1 = end (c1);
46
auto
i2 = begin (c2), e2 = end (c2);
47
for
( ; i1 != e1 && i2 != e2; ++i1, ++i2)
48
result.push_back (f (*i1, *i2));
49
return
result;
50
}
51
52
template
<
typename
T1,
typename
T2,
53
template
<
typename
U>
class
Container,
54
template
<
typename
U1,
typename
U2>
class
Pair = std::pair>
55
auto
Zip
(
const
Container<T1>& c1,
const
Container<T2>& c2) -> Container<Pair<T1, T2>>
56
{
57
return
ZipWith
(c1, c2,
58
[] (
const
T1& t1,
const
T2& t2) -> Pair<T1, T2>
59
{
return
{ t1, t2}; });
60
}
61
62
namespace
detail
63
{
64
template
<
typename
Res,
typename
T>
65
void
Append
(Res& result, T&& val)
noexcept
66
{
67
if
constexpr
(
requires
{ result.push_back (std::forward<T> (val)); })
68
result.push_back (std::forward<T> (val));
69
else
70
result.insert (std::forward<T> (val));
71
}
72
73
template
<
typename
Container,
typename
T>
74
struct
Replace
75
{
76
using
Type
=
QList<T>
;
77
};
78
79
template
<
template
<
typename
...>
class
Container,
typename
U,
typename
T>
80
requires
std::default_initializable<Container<T>>
81
struct
Replace
<Container<U>, T>
82
{
83
using
Type
= Container<T>;
84
};
85
86
template
<
typename
ResultContainer,
typename
Container,
typename
F>
87
auto
MapImpl
(Container&& c, F f)
88
{
89
WrapType_t<ResultContainer>
cont;
90
for
(
auto
&& t : c)
91
Append
(cont, std::invoke (f, t));
92
return
cont;
93
}
94
}
95
96
// NOTE
97
// The noexcept specifier here is somewhat misleading:
98
// this function indeed _might_ throw if the underlying container throws
99
// when appending an element, for any reason,
100
// (be it a copy/move ctor throwing or failure to allocate memory).
101
// Due to how LC is written and intended to be used,
102
// such exceptions are not and should not be handled,
103
// so they are fatal anyway.
104
// Thus we're totally fine with std::unexpected() and the likes.
105
template
<
typename
Container,
typename
F>
106
auto
Map
(Container&& c, F&& f)
noexcept
(
noexcept
(std::is_nothrow_invocable_v<F,
decltype
(*c.begin ())>))
107
{
108
using
FRet_t = std::decay_t<
decltype
(std::invoke (f, *c.begin ()))>;
109
return
detail::MapImpl<typename detail::Replace<std::decay_t<Container>
, FRet_t>::Type> (std::forward<Container> (c), std::forward<F> (f));
110
}
111
112
template
<
template
<
typename
...>
class
Fallback,
typename
Container,
typename
F>
113
auto
MapAs
(Container&& c, F&& f)
noexcept
(
noexcept
(std::is_nothrow_invocable_v<F,
decltype
(*c.begin ())>))
114
{
115
using
FRet_t = std::decay_t<
decltype
(std::invoke (f, *c.begin ()))>;
116
return
detail::MapImpl<Fallback<FRet_t>
> (std::forward<Container> (c), std::forward<F> (f));
117
}
118
119
template
<
typename
T,
template
<
typename
U>
class
Container,
typename
F>
120
Container<T> Filter (
const
Container<T>& c, F f)
121
{
122
Container<T> result;
123
for
(
const
auto
& item : c)
124
if
(std::invoke (f, item))
125
detail::Append
(result, item);
126
return
result;
127
}
128
129
template
<
template
<
typename
>
class
Container,
typename
T>
130
Container<T>
Concat
(
const
Container<Container<T>>& containers)
131
{
132
Container<T> result;
133
134
decltype
(result.size ()) size {};
135
for
(
const
auto
& cont : containers)
136
size += cont.size ();
137
result.reserve (size);
138
139
for
(
const
auto
& cont : containers)
140
std::copy (cont.begin (), cont.end (), std::back_inserter (result));
141
return
result;
142
}
143
144
template
<
template
<
typename
>
class
Container,
typename
T>
145
Container<T>
Concat
(Container<Container<T>>&& containers)
146
{
147
Container<T> result;
148
149
decltype
(result.size ()) size {};
150
for
(
const
auto
& cont : containers)
151
size += cont.size ();
152
result.reserve (size);
153
154
for
(
auto
&& cont : containers)
155
std::move (cont.begin (), cont.end (), std::back_inserter (result));
156
return
result;
157
}
158
159
template
<
template
<
typename
...>
class
Container,
typename
... ContArgs>
160
auto
Concat
(
const
Container<ContArgs...>& containers) -> std::decay_t<
decltype
(*containers.begin ())>
161
{
162
std::decay_t<
decltype
(*containers.begin ())> result;
163
for
(
const
auto
& cont : containers)
164
for
(
const
auto
& item : cont)
165
detail::Append
(result, item);
166
return
result;
167
}
168
169
template
<
typename
Cont,
typename
F>
170
auto
ConcatMap
(Cont&& c, F&& f)
171
{
172
return
Concat
(
Map
(std::forward<Cont> (c), std::forward<F> (f)));
173
}
174
175
template
<
template
<
typename
>
class
Container,
typename
T>
176
Container<Container<T>>
SplitInto
(
size_t
numChunks,
const
Container<T>& container)
177
{
178
Container<Container<T>> result;
179
180
const
size_t
chunkSize = container.size () / numChunks;
181
for
(
size_t
i = 0; i < numChunks; ++i)
182
{
183
Container<T> subcont;
184
const
auto
start = container.begin () + chunkSize * i;
185
const
auto
end = start + chunkSize;
186
std::copy (start, end, std::back_inserter (subcont));
187
result.push_back (subcont);
188
}
189
190
const
auto
lastStart = container.begin () + chunkSize * numChunks;
191
const
auto
lastEnd = container.end ();
192
std::copy (lastStart, lastEnd, std::back_inserter (result.front ()));
193
194
return
result;
195
}
196
197
template
<
typename
Cont>
198
decltype
(
auto
)
Sorted
(Cont&& cont)
199
{
200
std::sort (cont.begin (), cont.end ());
201
return
std::forward<Cont> (cont);
202
}
203
204
constexpr
auto
Id
= [] (
auto
&& t) ->
decltype
(
auto
) {
return
std::forward<decltype (t)> (t); };
205
206
template
<
typename
R>
207
auto
ComparingBy
(R r)
208
{
209
return
[r] (
const
auto
& left,
const
auto
& right) {
return
std::invoke (r, left) < std::invoke (r, right); };
210
}
211
212
template
<
typename
R>
213
auto
EqualityBy
(R r)
214
{
215
return
[r] (
const
auto
& left,
const
auto
& right) {
return
std::invoke (r, left) == std::invoke (r, right); };
216
}
217
218
constexpr
auto
Apply
= [] (
const
auto
& t) {
return
t (); };
219
220
constexpr
auto
Fst
= [] (
const
auto
& pair) {
return
pair.first; };
221
222
constexpr
auto
Snd
= [] (
const
auto
& pair) {
return
pair.second; };
223
224
template
<
typename
F>
225
auto
First
(F&& f)
226
{
227
return
[f = std::forward<F> (f)] (
const
auto
& pair) {
return
std::invoke (f, pair.first); };
228
}
229
230
template
<
typename
F>
231
auto
Second
(F&& f)
232
{
233
return
[f = std::forward<F> (f)] (
const
auto
& pair) {
return
std::invoke (f, pair.second); };
234
}
235
}
236
}
QList
Definition
ianrulesstorage.h:16
LC::Util::detail::Append
void Append(Res &result, T &&val) noexcept
Definition
prelude.h:65
LC::Util::detail::MapImpl
auto MapImpl(Container &&c, F f)
Definition
prelude.h:87
LC::Util
Definition
icoreproxy.h:34
LC::Util::EqualityBy
auto EqualityBy(R r)
Definition
prelude.h:213
LC::Util::ZipWith
constexpr auto ZipWith(Tup1 &&tup1, auto &&sep, Tup2 &&tup2) noexcept
Definition
ctstringutils.h:67
LC::Util::First
auto First(F &&f)
Definition
prelude.h:225
LC::Util::ConcatMap
auto ConcatMap(Cont &&c, F &&f)
Definition
prelude.h:170
LC::Util::Concat
Container< T > Concat(const Container< Container< T > > &containers)
Definition
prelude.h:130
LC::Util::Id
constexpr auto Id
Definition
prelude.h:204
LC::Util::WrapType_t
typename WrapType< T >::type WrapType_t
Definition
prelude.h:29
LC::Util::Sorted
decltype(auto) Sorted(Cont &&cont)
Definition
prelude.h:198
LC::Util::Zip
auto Zip(const Container< T1 > &c1, const Container< T2 > &c2) -> Container< Pair< T1, T2 > >
Definition
prelude.h:55
LC::Util::Snd
constexpr auto Snd
Definition
prelude.h:222
LC::Util::ComparingBy
auto ComparingBy(R r)
Definition
prelude.h:207
LC::Util::Map
auto Map(Container &&c, F &&f) noexcept(noexcept(std::is_nothrow_invocable_v< F, decltype(*c.begin())>))
Definition
prelude.h:106
LC::Util::Apply
constexpr auto Apply
Definition
prelude.h:218
LC::Util::MapAs
auto MapAs(Container &&c, F &&f) noexcept(noexcept(std::is_nothrow_invocable_v< F, decltype(*c.begin())>))
Definition
prelude.h:113
LC::Util::SplitInto
Container< Container< T > > SplitInto(size_t numChunks, const Container< T > &container)
Definition
prelude.h:176
LC::Util::Second
auto Second(F &&f)
Definition
prelude.h:231
LC::Util::Fst
constexpr auto Fst
Definition
prelude.h:220
LC
Definition
constants.h:15
LC::Util::WrapType< QList< QString > >::type
QStringList type
Definition
prelude.h:34
LC::Util::WrapType
Definition
prelude.h:24
LC::Util::WrapType::type
T type
Definition
prelude.h:25
LC::Util::detail::Replace< Container< U >, T >::Type
Container< T > Type
Definition
prelude.h:83
LC::Util::detail::Replace
Definition
prelude.h:75
LC::Util::detail::Replace::Type
QList< T > Type
Definition
prelude.h:76
src
util
sll
prelude.h
Generated by
1.18.0