1 | /**************************************************************************** |
---|---|

2 | ** |

3 | ** Copyright (C) 2016 The Qt Company Ltd. |

4 | ** Contact: https://www.qt.io/licensing/ |

5 | ** |

6 | ** This file is part of the QtConcurrent module of the Qt Toolkit. |

7 | ** |

8 | ** $QT_BEGIN_LICENSE:LGPL$ |

9 | ** Commercial License Usage |

10 | ** Licensees holding valid commercial Qt licenses may use this file in |

11 | ** accordance with the commercial license agreement provided with the |

12 | ** Software or, alternatively, in accordance with the terms contained in |

13 | ** a written agreement between you and The Qt Company. For licensing terms |

14 | ** and conditions see https://www.qt.io/terms-conditions. For further |

15 | ** information use the contact form at https://www.qt.io/contact-us. |

16 | ** |

17 | ** GNU Lesser General Public License Usage |

18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |

19 | ** General Public License version 3 as published by the Free Software |

20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |

21 | ** packaging of this file. Please review the following information to |

22 | ** ensure the GNU Lesser General Public License version 3 requirements |

23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |

24 | ** |

25 | ** GNU General Public License Usage |

26 | ** Alternatively, this file may be used under the terms of the GNU |

27 | ** General Public License version 2.0 or (at your option) the GNU General |

28 | ** Public license version 3 or any later version approved by the KDE Free |

29 | ** Qt Foundation. The licenses are as published by the Free Software |

30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |

31 | ** included in the packaging of this file. Please review the following |

32 | ** information to ensure the GNU General Public License requirements will |

33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |

34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |

35 | ** |

36 | ** $QT_END_LICENSE$ |

37 | ** |

38 | ****************************************************************************/ |

39 | |

40 | #ifndef QTCONCURRENT_FUNCTIONWRAPPERS_H |

41 | #define QTCONCURRENT_FUNCTIONWRAPPERS_H |

42 | |

43 | #include <QtConcurrent/qtconcurrentcompilertest.h> |

44 | #include <QtCore/QStringList> |

45 | |

46 | #if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC) |

47 | |

48 | QT_BEGIN_NAMESPACE |

49 | |

50 | namespace QtConcurrent { |

51 | |

52 | template <typename T> |

53 | class FunctionWrapper0 |

54 | { |

55 | public: |

56 | typedef T (*FunctionPointerType)(); |

57 | typedef T result_type; |

58 | inline FunctionWrapper0(FunctionPointerType _functionPointer) |

59 | :functionPointer(_functionPointer) { } |

60 | |

61 | inline T operator()() |

62 | { |

63 | return functionPointer(); |

64 | } |

65 | private: |

66 | FunctionPointerType functionPointer; |

67 | }; |

68 | |

69 | template <typename T, typename U> |

70 | class FunctionWrapper1 |

71 | { |

72 | public: |

73 | typedef T (*FunctionPointerType)(U u); |

74 | typedef T result_type; |

75 | inline FunctionWrapper1(FunctionPointerType _functionPointer) |

76 | :functionPointer(_functionPointer) { } |

77 | |

78 | inline T operator()(U u) |

79 | { |

80 | return functionPointer(u); |

81 | } |

82 | |

83 | private: |

84 | FunctionPointerType functionPointer; |

85 | }; |

86 | |

87 | template <typename T, typename U, typename V> |

88 | class FunctionWrapper2 |

89 | { |

90 | public: |

91 | typedef T (*FunctionPointerType)(U u, V v); |

92 | typedef T result_type; |

93 | inline FunctionWrapper2(FunctionPointerType _functionPointer) |

94 | :functionPointer(_functionPointer) { } |

95 | |

96 | inline T operator()(U u, V v) |

97 | { |

98 | return functionPointer(u, v); |

99 | } |

100 | private: |

101 | FunctionPointerType functionPointer; |

102 | }; |

103 | |

104 | template <typename T, typename C> |

105 | class MemberFunctionWrapper |

106 | { |

107 | public: |

108 | typedef T (C::*FunctionPointerType)(); |

109 | typedef T result_type; |

110 | inline MemberFunctionWrapper(FunctionPointerType _functionPointer) |

111 | :functionPointer(_functionPointer) { } |

112 | |

113 | inline T operator()(C &c) |

114 | { |

115 | return (c.*functionPointer)(); |

116 | } |

117 | private: |

118 | FunctionPointerType functionPointer; |

119 | }; |

120 | |

121 | template <typename T, typename C, typename U> |

122 | class MemberFunctionWrapper1 |

123 | { |

124 | public: |

125 | typedef T (C::*FunctionPointerType)(U); |

126 | typedef T result_type; |

127 | |

128 | inline MemberFunctionWrapper1(FunctionPointerType _functionPointer) |

129 | : functionPointer(_functionPointer) |

130 | { } |

131 | |

132 | inline T operator()(C &c, U u) |

133 | { |

134 | return (c.*functionPointer)(u); |

135 | } |

136 | |

137 | private: |

138 | FunctionPointerType functionPointer; |

139 | }; |

140 | |

141 | template <typename T, typename C> |

142 | class ConstMemberFunctionWrapper |

143 | { |

144 | public: |

145 | typedef T (C::*FunctionPointerType)() const; |

146 | typedef T result_type; |

147 | inline ConstMemberFunctionWrapper(FunctionPointerType _functionPointer) |

148 | :functionPointer(_functionPointer) { } |

149 | |

150 | inline T operator()(const C &c) const |

151 | { |

152 | return (c.*functionPointer)(); |

153 | } |

154 | private: |

155 | FunctionPointerType functionPointer; |

156 | }; |

157 | |

158 | } // namespace QtConcurrent. |

159 | |

160 | namespace QtPrivate { |

161 | |

162 | template <typename T> |

163 | const T& createFunctionWrapper(const T& t) |

164 | { |

165 | return t; |

166 | } |

167 | |

168 | template <typename T, typename U> |

169 | QtConcurrent::FunctionWrapper1<T, U> createFunctionWrapper(T (*func)(U)) |

170 | { |

171 | return QtConcurrent::FunctionWrapper1<T, U>(func); |

172 | } |

173 | |

174 | template <typename T, typename C> |

175 | QtConcurrent::MemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)()) |

176 | { |

177 | return QtConcurrent::MemberFunctionWrapper<T, C>(func); |

178 | } |

179 | |

180 | template <typename T, typename C, typename U> |

181 | QtConcurrent::MemberFunctionWrapper1<T, C, U> createFunctionWrapper(T (C::*func)(U)) |

182 | { |

183 | return QtConcurrent::MemberFunctionWrapper1<T, C, U>(func); |

184 | } |

185 | |

186 | template <typename T, typename C> |

187 | QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() const) |

188 | { |

189 | return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func); |

190 | } |

191 | |

192 | #if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 |

193 | template <typename T, typename U> |

194 | QtConcurrent::FunctionWrapper1<T, U> createFunctionWrapper(T (*func)(U) noexcept) |

195 | { |

196 | return QtConcurrent::FunctionWrapper1<T, U>(func); |

197 | } |

198 | |

199 | template <typename T, typename C> |

200 | QtConcurrent::MemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() noexcept) |

201 | { |

202 | return QtConcurrent::MemberFunctionWrapper<T, C>(func); |

203 | } |

204 | |

205 | template <typename T, typename C, typename U> |

206 | QtConcurrent::MemberFunctionWrapper1<T, C, U> createFunctionWrapper(T (C::*func)(U) noexcept) |

207 | { |

208 | return QtConcurrent::MemberFunctionWrapper1<T, C, U>(func); |

209 | } |

210 | |

211 | template <typename T, typename C> |

212 | QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() const noexcept) |

213 | { |

214 | return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func); |

215 | } |

216 | #endif |

217 | |

218 | struct PushBackWrapper |

219 | { |

220 | typedef void result_type; |

221 | |

222 | template <class C, class U> |

223 | inline void operator()(C &c, const U &u) const |

224 | { |

225 | return c.push_back(u); |

226 | } |

227 | |

228 | template <class C, class U> |

229 | inline void operator()(C &c, U &&u) const |

230 | { |

231 | return c.push_back(u); |

232 | } |

233 | }; |

234 | |

235 | template <typename Functor, bool foo = HasResultType<Functor>::Value> |

236 | struct LazyResultType { typedef typename Functor::result_type Type; }; |

237 | template <typename Functor> |

238 | struct LazyResultType<Functor, false> { typedef void Type; }; |

239 | |

240 | template <class T> |

241 | struct ReduceResultType; |

242 | |

243 | template <class U, class V> |

244 | struct ReduceResultType<void(*)(U&,V)> |

245 | { |

246 | typedef U ResultType; |

247 | }; |

248 | |

249 | template <class T, class C, class U> |

250 | struct ReduceResultType<T(C::*)(U)> |

251 | { |

252 | typedef C ResultType; |

253 | }; |

254 | |

255 | #if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 |

256 | template <class U, class V> |

257 | struct ReduceResultType<void(*)(U&,V) noexcept> |

258 | { |

259 | typedef U ResultType; |

260 | }; |

261 | |

262 | template <class T, class C, class U> |

263 | struct ReduceResultType<T(C::*)(U) noexcept> |

264 | { |

265 | typedef C ResultType; |

266 | }; |

267 | #endif |

268 | |

269 | template <class InputSequence, class MapFunctor> |

270 | struct MapResultType |

271 | { |

272 | typedef typename LazyResultType<MapFunctor>::Type ResultType; |

273 | }; |

274 | |

275 | template <class U, class V> |

276 | struct MapResultType<void, U (*)(V)> |

277 | { |

278 | typedef U ResultType; |

279 | }; |

280 | |

281 | template <class T, class C> |

282 | struct MapResultType<void, T(C::*)() const> |

283 | { |

284 | typedef T ResultType; |

285 | }; |

286 | |

287 | #if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 |

288 | template <class U, class V> |

289 | struct MapResultType<void, U (*)(V) noexcept> |

290 | { |

291 | typedef U ResultType; |

292 | }; |

293 | |

294 | template <class T, class C> |

295 | struct MapResultType<void, T(C::*)() const noexcept> |

296 | { |

297 | typedef T ResultType; |

298 | }; |

299 | #endif |

300 | |

301 | #ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS |

302 | |

303 | template <template <typename> class InputSequence, typename MapFunctor, typename T> |

304 | struct MapResultType<InputSequence<T>, MapFunctor> |

305 | { |

306 | typedef InputSequence<typename LazyResultType<MapFunctor>::Type> ResultType; |

307 | }; |

308 | |

309 | template <template <typename> class InputSequence, class T, class U, class V> |

310 | struct MapResultType<InputSequence<T>, U (*)(V)> |

311 | { |

312 | typedef InputSequence<U> ResultType; |

313 | }; |

314 | |

315 | template <template <typename> class InputSequence, class T, class U, class C> |

316 | struct MapResultType<InputSequence<T>, U(C::*)() const> |

317 | { |

318 | typedef InputSequence<U> ResultType; |

319 | }; |

320 | |

321 | #if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 |

322 | |

323 | template <template <typename> class InputSequence, class T, class U, class V> |

324 | struct MapResultType<InputSequence<T>, U (*)(V) noexcept> |

325 | { |

326 | typedef InputSequence<U> ResultType; |

327 | }; |

328 | |

329 | template <template <typename> class InputSequence, class T, class U, class C> |

330 | struct MapResultType<InputSequence<T>, U(C::*)() const noexcept> |

331 | { |

332 | typedef InputSequence<U> ResultType; |

333 | }; |

334 | #endif |

335 | |

336 | #endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER |

337 | |

338 | template <class MapFunctor> |

339 | struct MapResultType<QStringList, MapFunctor> |

340 | { |

341 | typedef QList<typename LazyResultType<MapFunctor>::Type> ResultType; |

342 | }; |

343 | |

344 | template <class U, class V> |

345 | struct MapResultType<QStringList, U (*)(V)> |

346 | { |

347 | typedef QList<U> ResultType; |

348 | }; |

349 | |

350 | template <class U, class C> |

351 | struct MapResultType<QStringList, U(C::*)() const> |

352 | { |

353 | typedef QList<U> ResultType; |

354 | }; |

355 | |

356 | #if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 |

357 | |

358 | template <class U, class V> |

359 | struct MapResultType<QStringList, U (*)(V) noexcept> |

360 | { |

361 | typedef QList<U> ResultType; |

362 | }; |

363 | |

364 | template <class U, class C> |

365 | struct MapResultType<QStringList, U(C::*)() const noexcept> |

366 | { |

367 | typedef QList<U> ResultType; |

368 | }; |

369 | #endif |

370 | |

371 | } // namespace QtPrivate. |

372 | |

373 | |

374 | QT_END_NAMESPACE |

375 | |

376 | #endif // QT_NO_CONCURRENT |

377 | |

378 | #endif |

379 |