12 #include <type_traits> 15 #include <QStringList> 36 template<
template<
typename U>
class Container,
typename T1,
typename T2,
typename F>
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));
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>>
57 [] (
const T1& t1,
const T2& t2) -> Pair<T1, T2>
58 {
return { t1, t2}; });
63 template<
typename Res,
typename T>
66 if constexpr (
requires { result.push_back (std::forward<T> (val)); })
67 result.push_back (std::forward<T> (val));
69 result.insert (std::forward<T> (val));
72 template<
typename Container,
typename T>
78 template<
template<
typename...>
class Container,
typename U,
typename T>
84 template<
typename ResultContainer,
typename Container,
typename F>
89 Append (cont, std::invoke (
f, t));
103 template<
typename Container,
typename F>
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));
110 template<
template<
typename...>
class Fallback,
typename Container,
typename F>
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));
117 template<
typename T,
template<
typename U>
class Container,
typename F>
118 Container<T>
Filter (
const Container<T>& c, F
f)
121 for (
const auto& item : c)
122 if (std::invoke (
f, item))
127 template<
template<
typename>
class Container,
typename T>
128 Container<T>
Concat (
const Container<Container<T>>& containers)
132 decltype (result.size ()) size {};
133 for (
const auto& cont : containers)
134 size += cont.size ();
135 result.reserve (size);
137 for (
const auto& cont : containers)
138 std::copy (cont.begin (), cont.end (), std::back_inserter (result));
142 template<
template<
typename>
class Container,
typename T>
143 Container<T>
Concat (Container<Container<T>>&& containers)
147 decltype (result.size ()) size {};
148 for (
const auto& cont : containers)
149 size += cont.size ();
150 result.reserve (size);
152 for (
auto&& cont : containers)
153 std::move (cont.begin (), cont.end (), std::back_inserter (result));
157 template<
template<
typename...>
class Container,
typename... ContArgs>
158 auto Concat (
const Container<ContArgs...>& containers) -> std::decay_t<decltype (*containers.begin ())>
160 std::decay_t<decltype (*containers.begin ())> result;
161 for (
const auto& cont : containers)
162 for (
const auto& item : cont)
167 template<
typename Cont,
typename F>
170 return Concat (
Map (std::forward<Cont> (c), std::forward<F> (
f)));
173 template<
template<
typename>
class Container,
typename T>
174 Container<Container<T>>
SplitInto (
size_t numChunks,
const Container<T>& container)
176 Container<Container<T>> result;
178 const size_t chunkSize = container.size () / numChunks;
179 for (
size_t i = 0; i < numChunks; ++i)
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);
188 const auto lastStart = container.begin () + chunkSize * numChunks;
189 const auto lastEnd = container.end ();
190 std::copy (lastStart, lastEnd, std::back_inserter (result.front ()));
195 template<
typename Cont>
198 std::sort (cont.begin (), cont.end ());
199 return std::forward<Cont> (cont);
202 constexpr
auto Id = [] (
auto&& t) -> decltype (
auto) {
return std::forward<decltype (t)> (t); };
207 return [r] (
const auto& left,
const auto& right) {
return std::invoke (r, left) < std::invoke (r, right); };
213 return [r] (
const auto& left,
const auto& right) {
return std::invoke (r, left) == std::invoke (r, right); };
216 constexpr
auto Apply = [] (
const auto& t) {
return t (); };
218 constexpr
auto Fst = [] (
const auto& pair) {
return pair.first; };
220 constexpr
auto Snd = [] (
const auto& pair) {
return pair.second; };
225 return [
f = std::forward<F> (
f)] (
const auto& pair) {
return std::invoke (
f, pair.first); };
231 return [
f = std::forward<F> (
f)] (
const auto& pair) {
return std::invoke (
f, pair.second); };
Container< T > Concat(const Container< Container< T >> &containers)
auto MapAs(Container &&c, F &&f) noexcept(noexcept(std::is_nothrow_invocable_v< F, decltype(*c.begin())>))
auto Map(Container &&c, F &&f) noexcept(noexcept(std::is_nothrow_invocable_v< F, decltype(*c.begin())>))
Container< T > Filter(const Container< T > &c, F f)
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Type
Describes the various types of XDG .desktop files.
Container< Container< T > > SplitInto(size_t numChunks, const Container< T > &container)
requires(Tup1Size==Tup2Size) const expr auto ZipWith(Tup1 &&tup1
decltype(auto) Sorted(Cont &&cont)
auto MapImpl(Container &&c, F f)
auto Tup2 &&tup2 noexcept
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)>>>>
auto Zip(const Container< T1 > &c1, const Container< T2 > &c2) -> Container< Pair< T1, T2 >>
void Append(Res &result, T &&val) noexcept
auto ConcatMap(Cont &&c, F &&f)
typename WrapType< T >::type WrapType_t