LeechCraft  0.6.70-3565-g2d86529
Modular cross-platform feature rich live environment.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  * Boost Software License - Version 1.0 - August 17th, 2003
6  *
7  * Permission is hereby granted, free of charge, to any person or organization
8  * obtaining a copy of the software and accompanying documentation covered by
9  * this license (the "Software") to use, reproduce, display, distribute,
10  * execute, and transmit the Software, and to prepare derivative works of the
11  * Software, and to permit third-parties to whom the Software is furnished to
12  * do so, all subject to the following:
13  *
14  * The copyright notices in the Software and this entire statement, including
15  * the above license grant, this restriction and the following disclaimer,
16  * must be included in all copies of the Software, in whole or in part, and
17  * all derivative works of the Software, unless such copies or derivative
18  * works are solely in the form of machine-executable object code generated by
19  * a source language processor.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
24  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
25  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  **********************************************************************/
29 
30 #pragma once
31 
32 #include <type_traits>
33 #include <iterator>
34 #include <QPair>
35 #include <QStringList>
36 #include <boost/optional.hpp>
37 #include "oldcppkludges.h"
38 
39 namespace LeechCraft
40 {
41 namespace Util
42 {
43  template<typename T1, typename T2, template<typename U> class Container, typename F>
44  auto ZipWith (const Container<T1>& c1, const Container<T2>& c2, F f) -> Container<typename std::result_of<F (T1, T2)>::type>
45  {
46  Container<typename std::result_of<F (T1, T2)>::type> result;
47 
48  using std::begin;
49  using std::end;
50 
51  auto i1 = begin (c1), e1 = end (c1);
52  auto i2 = begin (c2), e2 = end (c2);
53  for ( ; i1 != e1 && i2 != e2; ++i1, ++i2)
54  result.push_back (f (*i1, *i2));
55  return result;
56  }
57 
58  template<typename T1, typename T2,
59  template<typename U> class Container,
60  template<typename U1, typename U2> class Pair = QPair>
61  auto Zip (const Container<T1>& c1, const Container<T2>& c2) -> Container<Pair<T1, T2>>
62  {
63  return ZipWith (c1, c2,
64  [] (const T1& t1, const T2& t2) -> Pair<T1, T2>
65  { return { t1, t2}; });
66  }
67 
68  template<typename T>
69  struct WrapType
70  {
71  using type = T;
72  };
73 
74  template<typename T>
75  using WrapType_t = typename WrapType<T>::type;
76 
77  template<>
78  struct WrapType<QList<QString>>
79  {
80  using type = QStringList;
81  };
82 
83  namespace detail
84  {
85  template<typename Res, typename T>
86  void Append (Res& result, T&& val, decltype (result.push_back (std::forward<T> (val)))* = nullptr)
87  {
88  result.push_back (std::forward<T> (val));
89  }
90 
91  template<typename Res, typename T>
92  void Append (Res& result, T&& val, decltype (result.insert (std::forward<T> (val)))* = nullptr)
93  {
94  result.insert (std::forward<T> (val));
95  }
96 
97  template<typename T, typename F>
98  constexpr bool IsInvokableWithConstImpl (typename std::result_of<F (const T&)>::type*)
99  {
100  return true;
101  }
102 
103  template<typename T, typename F>
104  constexpr bool IsInvokableWithConstImpl (...)
105  {
106  return false;
107  }
108 
109  template<typename T, typename F>
110  constexpr bool IsInvokableWithConst ()
111  {
112  return IsInvokableWithConstImpl<typename std::decay<T>::type, F> (0);
113  }
114  }
115 
116  template<typename T, template<typename U> class Container, typename F>
117  auto Map (const Container<T>& c, F f) -> typename std::enable_if<!std::is_same<void, decltype (Invoke (f, std::declval<T> ()))>::value,
118  WrapType_t<Container<typename std::decay<decltype (Invoke (f, std::declval<T> ()))>::type>>>::type
119  {
120  Container<typename std::decay<decltype (Invoke (f, std::declval<T> ()))>::type> result;
121  for (auto&& t : c)
122  detail::Append (result, Invoke (f, t));
123  return result;
124  }
125 
126  template<template<typename...> class Container, typename F, template<typename> class ResultCont = QList, typename... ContArgs>
127  auto Map (const Container<ContArgs...>& c, F f) -> typename std::enable_if<!std::is_same<void, decltype (Invoke (f, *c.begin ()))>::value,
128  WrapType_t<ResultCont<typename std::decay<decltype (Invoke (f, *c.begin ()))>::type>>>::type
129  {
130  ResultCont<typename std::decay<decltype (Invoke (f, *c.begin ()))>::type> cont;
131  for (auto&& t : c)
132  detail::Append (cont, Invoke (f, t));
133  return cont;
134  }
135 
136  template<template<typename...> class Container, typename F, typename... ContArgs>
137  auto Map (Container<ContArgs...>& c, F f) -> typename std::enable_if<std::is_same<void, decltype (Invoke (f, *c.begin ()))>::value>::type
138  {
139  for (auto&& t : c)
140  Invoke (f, t);
141  }
142 
143  template<template<typename...> class Container, typename F, typename... ContArgs>
144  auto Map (const Container<ContArgs...>& c, F f) -> typename std::enable_if<std::is_same<void, decltype (Invoke (f, *c.begin ()))>::value>::type
145  {
146  auto copy = c;
147  Map (copy, f);
148  }
149 
150 #ifndef USE_CPP14
151  template<typename F>
153  {
155  for (auto&& t : c)
156  result.push_back (Invoke (f, t));
157  return result;
158  }
159 #endif
160 
161  template<typename T, template<typename U> class Container, typename F>
162  auto Map (const Container<T>& c, F f) -> typename std::enable_if<std::is_same<void, decltype (Invoke (f, std::declval<T> ()))>::value, void>::type
163  {
164  for (auto&& t : c)
165  Invoke (f, t);
166  }
167 
168  template<typename T, template<typename U> class Container, typename F>
169  auto Filter (const Container<T>& c, F f) -> Container<T>
170  {
171  Container<T> result;
172  std::copy_if (c.begin (), c.end (), std::back_inserter (result), f);
173  return result;
174  }
175 
176  template<template<typename> class Container, typename T>
177  Container<T> Concat (const Container<Container<T>>& containers)
178  {
179  Container<T> result;
180  for (const auto& cont : containers)
181  std::copy (cont.begin (), cont.end (), std::back_inserter (result));
182  return result;
183  }
184 
185  template<template<typename...> class Container, typename... ContArgs>
186  auto Concat (const Container<ContArgs...>& containers) -> typename std::decay<decltype (*containers.begin ())>::type
187  {
188  typename std::decay<decltype (*containers.begin ())>::type result;
189  for (const auto& cont : containers)
190  std::copy (cont.begin (), cont.end (), std::back_inserter (result));
191  return result;
192  }
193 
194  template<template<typename> class Container, typename T>
195  Container<Container<T>> SplitInto (size_t numChunks, const Container<T>& container)
196  {
197  Container<Container<T>> result;
198 
199  const size_t chunkSize = container.size () / numChunks;
200  for (size_t i = 0; i < numChunks; ++i)
201  {
202  Container<T> subcont;
203  const auto start = container.begin () + chunkSize * i;
204  const auto end = start + chunkSize;
205  std::copy (start, end, std::back_inserter (subcont));
206  result.push_back (subcont);
207  }
208 
209  const auto lastStart = container.begin () + chunkSize * numChunks;
210  const auto lastEnd = container.end ();
211  std::copy (lastStart, lastEnd, std::back_inserter (result.front ()));
212 
213  return result;
214  }
215 
216  template<template<typename Pair, typename... Rest> class Cont, template<typename K, typename V> class Pair, typename K, typename V, typename KV, typename... Rest>
217  boost::optional<V> Lookup (const KV& key, const Cont<Pair<K, V>, Rest...>& cont)
218  {
219  for (const auto& pair : cont)
220  if (pair.first == key)
221  return pair.second;
222 
223  return {};
224  }
225 
226 #ifdef USE_CPP14
227  template<typename R>
228  auto ComparingBy (R r)
229  {
230  return [r] (const auto& left, const auto& right) { return r (left) < r (right); };
231  }
232 
233  auto Apply = [] (const auto& t) { return t (); };
234 #else
235  namespace detail
236  {
237  template<typename R>
239  {
240  const R R_;
241 
242  template<typename T>
243  bool operator() (const T& left, const T& right) const
244  {
245  return R_ (left) < R_ (right);
246  }
247  };
248  }
249 
250  template<typename R>
252  {
253  return detail::ComparingByClosure<R> { r };
254  }
255 
256  struct
257  {
258  template<typename T>
259  typename std::result_of<T ()>::type operator() (const T& t) const
260  {
261  return t ();
262  }
263  } Apply;
264 #endif
265 }
266 }
auto ZipWith(const Container< T1 > &c1, const Container< T2 > &c2, F f) -> Container< typename std::result_of< F(T1, T2)>::type >
Definition: prelude.h:44
auto Zip(const Container< T1 > &c1, const Container< T2 > &c2) -> Container< Pair< T1, T2 >>
Definition: prelude.h:61
boost::optional< V > Lookup(const KV &key, const Cont< Pair< K, V >, Rest...> &cont)
Definition: prelude.h:217
auto Filter(const Container< T > &c, F f) -> Container< T >
Definition: prelude.h:169
Container< T > Concat(const Container< Container< T >> &containers)
Definition: prelude.h:177
auto Map(const Container< T > &c, F f) -> typename std::enable_if<!std::is_same< void, decltype(Invoke(f, std::declval< T >()))>::value, WrapType_t< Container< typename std::decay< decltype(Invoke(f, std::declval< T >()))>::type >>>::type
Definition: prelude.h:117
detail::ComparingByClosure< R > ComparingBy(R r)
Definition: prelude.h:251
bool operator()(const T &left, const T &right) const
Definition: prelude.h:243
constexpr bool IsInvokableWithConstImpl(typename std::result_of< F(const T &)>::type *)
Definition: prelude.h:98
void Append(Res &result, T &&val, decltype(result.push_back(std::forward< T >(val)))*=nullptr)
Definition: prelude.h:86
struct LeechCraft::Util::@0 Apply
auto Invoke(F &&f, Args &&...args) -> decltype(std::forward< F >(f)(std::forward< Args >(args)...))
Definition: oldcppkludges.h:39
typename WrapType< T >::type WrapType_t
Definition: prelude.h:75
constexpr bool IsInvokableWithConst()
Definition: prelude.h:110
Container< Container< T > > SplitInto(size_t numChunks, const Container< T > &container)
Definition: prelude.h:195