33 #include <type_traits> 36 #include <QStringList> 37 #include <boost/optional.hpp> 64 template<
typename T1,
typename T2,
template<
typename U>
class Container,
typename F>
72 auto i1 = begin (c1), e1 = end (c1);
73 auto i2 = begin (c2), e2 = end (c2);
74 for ( ; i1 != e1 && i2 != e2; ++i1, ++i2)
75 result.push_back (
f (*i1, *i2));
79 template<
typename T1,
typename T2,
80 template<
typename U>
class Container,
81 template<
typename U1,
typename U2>
class Pair = QPair>
82 auto Zip (
const Container<T1>& c1,
const Container<T2>& c2) -> Container<Pair<T1, T2>>
85 [] (
const T1& t1,
const T2& t2) -> Pair<T1, T2>
86 {
return { t1, t2}; });
91 template<
typename Res,
typename T>
92 void Append (Res& result, T&& val, decltype (result.push_back (std::forward<T> (val)))* =
nullptr)
94 result.push_back (std::forward<T> (val));
97 template<
typename Res,
typename T>
98 void Append (Res& result, T&& val, decltype (result.insert (std::forward<T> (val)))* =
nullptr)
100 result.insert (std::forward<T> (val));
109 template<
template<
typename...>
class Container,
typename... Args>
121 template<
typename Container,
typename T>
127 template<
template<
typename>
class Container,
typename U,
typename T>
142 template<
template<
typename...>
class Fallback,
bool ForceFallback,
typename Container,
typename F>
145 using FRet_t = std::decay_t<decltype (std::invoke (
f, *c.begin ()))>;
146 static_assert (!std::is_same<void, FRet_t> {},
"The function shall not return void.");
148 using DecayContainer_t = std::decay_t<Container>;
150 using ResultCont_t = std::conditional_t<
152 detail::IsSimpleContainer<DecayContainer_t> () &&
153 !detail::IsNotBrokenSFINAE_v<DecayContainer_t>,
164 template<
typename Container,
typename F>
167 return detail::MapImpl<QList, false> (std::forward<Container> (c), std::forward<F> (
f));
170 template<
template<
typename...>
class Fallback,
typename Container,
typename F>
173 return detail::MapImpl<Fallback, true> (std::forward<Container> (c), std::forward<F> (
f));
176 template<
typename T,
template<
typename U>
class Container,
typename F>
177 Container<T>
Filter (
const Container<T>& c, F
f)
180 for (
const auto& item : c)
181 if (std::invoke (
f, item))
186 template<
template<
typename>
class Container,
typename T>
187 Container<T>
Concat (
const Container<Container<T>>& containers)
190 for (
const auto& cont : containers)
191 std::copy (cont.begin (), cont.end (), std::back_inserter (result));
195 template<
template<
typename...>
class Container,
typename... ContArgs>
196 auto Concat (
const Container<ContArgs...>& containers) -> std::decay_t<decltype (*containers.begin ())>
198 std::decay_t<decltype (*containers.begin ())> result;
199 for (
const auto& cont : containers)
200 std::copy (cont.begin (), cont.end (), std::back_inserter (result));
204 template<
typename Cont,
typename F>
207 return Concat (
Map (std::forward<Cont> (c), std::forward<F> (
f)));
210 template<
template<
typename>
class Container,
typename T>
211 Container<Container<T>>
SplitInto (
size_t numChunks,
const Container<T>& container)
213 Container<Container<T>> result;
215 const size_t chunkSize = container.size () / numChunks;
216 for (
size_t i = 0; i < numChunks; ++i)
218 Container<T> subcont;
219 const auto start = container.begin () + chunkSize * i;
220 const auto end = start + chunkSize;
221 std::copy (start, end, std::back_inserter (subcont));
222 result.push_back (subcont);
225 const auto lastStart = container.begin () + chunkSize * numChunks;
226 const auto lastEnd = container.end ();
227 std::copy (lastStart, lastEnd, std::back_inserter (result.front ()));
232 template<
template<
typename Pair,
typename... Rest>
class Cont, template<typename K, typename V> class Pair, typename K, typename V, typename KV, typename... Rest>
233 boost::optional<V>
Lookup (const KV& key, const Cont<Pair<K, V>, Rest...>& cont)
235 for (
const auto& pair : cont)
236 if (pair.first == key)
242 template<
typename Cont>
245 std::sort (cont.begin (), cont.end ());
249 const auto Id = [] (
const auto& t) {
return t; };
254 return [r] (
const auto& left,
const auto& right) {
return std::invoke (r, left) < std::invoke (r, right); };
260 return [r] (
const auto& left,
const auto& right) {
return std::invoke (r, left) == std::invoke (r, right); };
263 const auto Apply = [] (
const auto& t) {
return t (); };
265 const auto Fst = [] (
const auto& pair) {
return pair.first; };
267 const auto Snd = [] (
const auto& pair) {
return pair.second; };
272 return [
f = std::forward<F> (
f)] (
const auto& pair) {
return std::invoke (
f, pair.first); };
278 return [
f = std::forward<F> (
f)] (
const auto& pair) {
return std::invoke (
f, pair.second); };
284 return [
f = std::move (
f)] (
auto&& left,
auto&& right)
286 return f (std::forward<decltype (right)> (right),
287 std::forward<decltype (left)> (left));
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
auto Zip(const Container< T1 > &c1, const Container< T2 > &c2) -> Container< Pair< T1, T2 >>
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)>>>>
constexpr bool IsNotBrokenSFINAE_v
static const size_t ArgsCount
Container< T > Concat(const Container< Container< T >> &containers)
void Append(Res &result, T &&val, decltype(result.push_back(std::forward< T >(val))) *=nullptr)
auto ConcatMap(Cont &&c, F &&f)
Container< T > Filter(const Container< T > &c, F f)
constexpr bool IsSimpleContainer()
auto Map(Container &&c, F f)
auto MapImpl(Container &&c, F f)
auto MapAs(Container &&c, F &&f)
boost::optional< V > Lookup(const KV &key, const Cont< Pair< K, V >, Rest... > &cont)
typename WrapType< T >::type WrapType_t
Container< Container< T > > SplitInto(size_t numChunks, const Container< T > &container)