12 #include <type_traits>
15 #include <QStringList>
42 template<
template<
typename U>
class Container,
typename T1,
typename T2,
typename F>
43 auto ZipWith (
const Container<T1>& c1,
const Container<T2>& c2, F
f) ->
WrapType_t<Container<std::decay_t<std::result_of_t<F (T1, T2)>>>>
45 WrapType_t<Container<std::decay_t<std::result_of_t<F (T1, T2)>>>> result;
50 auto i1 = begin (c1), e1 = end (c1);
51 auto i2 = begin (c2), e2 = end (c2);
52 for ( ; i1 != e1 && i2 != e2; ++i1, ++i2)
53 result.push_back (
f (*i1, *i2));
57 template<
typename T1,
typename T2,
58 template<
typename U>
class Container,
59 template<
typename U1,
typename U2>
class Pair = QPair>
60 auto Zip (
const Container<T1>& c1,
const Container<T2>& c2) -> Container<Pair<T1, T2>>
63 [] (
const T1& t1,
const T2& t2) -> Pair<T1, T2>
64 {
return { t1, t2}; });
69 template<
typename Res,
typename T>
70 void Append (Res& result, T&& val) noexcept
72 if constexpr (requires { result.push_back (std::forward<T> (val)); })
73 result.push_back (std::forward<T> (val));
75 result.insert (std::forward<T> (val));
84 template<
template<
typename...>
class Container,
typename... Args>
96 template<
typename Container,
typename T>
102 template<
template<
typename>
class Container,
typename U,
typename T>
117 template<
template<
typename...>
class Fallback,
bool ForceFallback,
typename Container,
typename F>
120 using FRet_t = std::decay_t<decltype (std::invoke (
f, *c.begin ()))>;
121 static_assert (!std::is_same<void, FRet_t> {},
"The function shall not return void.");
123 using DecayContainer_t = std::decay_t<Container>;
125 using ResultCont_t = std::conditional_t<
127 detail::IsSimpleContainer<DecayContainer_t> () &&
128 !detail::IsNotBrokenSFINAE_v<DecayContainer_t>,
134 Append (cont, std::invoke (
f, t));
148 template<
typename Container,
typename F>
149 auto Map (Container&& c, F&&
f) noexcept (noexcept (std::is_nothrow_invocable_v<F, decltype (*c.begin ())>))
151 return detail::MapImpl<QList, false> (std::forward<Container> (c), std::forward<F> (
f));
154 template<
template<
typename...>
class Fallback,
typename Container,
typename F>
155 auto MapAs (Container&& c, F&&
f) noexcept (noexcept (std::is_nothrow_invocable_v<F, decltype (*c.begin ())>))
157 return detail::MapImpl<Fallback, true> (std::forward<Container> (c), std::forward<F> (
f));
160 template<
typename T,
template<
typename U>
class Container,
typename F>
161 Container<T>
Filter (
const Container<T>& c, F
f)
164 for (
const auto& item : c)
165 if (std::invoke (
f, item))
170 template<
template<
typename>
class Container,
typename T>
171 Container<T>
Concat (
const Container<Container<T>>& containers)
174 for (
const auto& cont : containers)
175 std::copy (cont.begin (), cont.end (), std::back_inserter (result));
179 template<
template<
typename...>
class Container,
typename... ContArgs>
180 auto Concat (
const Container<ContArgs...>& containers) -> std::decay_t<decltype (*containers.begin ())>
182 std::decay_t<decltype (*containers.begin ())> result;
183 for (
const auto& cont : containers)
184 for (
const auto& item : cont)
189 template<
typename Cont,
typename F>
192 return Concat (
Map (std::forward<Cont> (c), std::forward<F> (
f)));
195 template<
template<
typename>
class Container,
typename T>
196 Container<Container<T>>
SplitInto (
size_t numChunks,
const Container<T>& container)
198 Container<Container<T>> result;
200 const size_t chunkSize = container.size () / numChunks;
201 for (
size_t i = 0; i < numChunks; ++i)
203 Container<T> subcont;
204 const auto start = container.begin () + chunkSize * i;
205 const auto end = start + chunkSize;
206 std::copy (start, end, std::back_inserter (subcont));
207 result.push_back (subcont);
210 const auto lastStart = container.begin () + chunkSize * numChunks;
211 const auto lastEnd = container.end ();
212 std::copy (lastStart, lastEnd, std::back_inserter (result.front ()));
217 template<
typename Cont>
220 std::sort (cont.begin (), cont.end ());
221 return std::forward<Cont> (cont);
224 constexpr
auto Id = [] (
auto&& t) -> decltype (
auto) {
return std::forward<decltype (t)> (t); };
229 return [r] (
const auto& left,
const auto& right) {
return std::invoke (r, left) < std::invoke (r, right); };
235 return [r] (
const auto& left,
const auto& right) {
return std::invoke (r, left) == std::invoke (r, right); };
238 constexpr
auto Apply = [] (
const auto& t) {
return t (); };
240 constexpr
auto Fst = [] (
const auto& pair) {
return pair.first; };
242 constexpr
auto Snd = [] (
const auto& pair) {
return pair.second; };
247 return [
f = std::forward<F> (
f)] (
const auto& pair) {
return std::invoke (
f, pair.first); };
253 return [
f = std::forward<F> (
f)] (
const auto& pair) {
return std::invoke (
f, pair.second); };