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