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 | #include <tuple> |

47 | |

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

49 | |

50 | QT_BEGIN_NAMESPACE |

51 | |

52 | namespace QtPrivate { |

53 | |

54 | struct PushBackWrapper |

55 | { |

56 | template <class C, class U> |

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

58 | { |

59 | return c.push_back(u); |

60 | } |

61 | |

62 | template <class C, class U> |

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

64 | { |

65 | return c.push_back(u); |

66 | } |

67 | }; |

68 | |

69 | // -- MapResultType |

70 | |

71 | template <class T, class Enable = void> |

72 | struct Argument |

73 | { |

74 | using Type = void; |

75 | }; |

76 | |

77 | template <class Sequence> |

78 | struct Argument<Sequence, typename std::enable_if<IsIterableValue<Sequence>>::type> |

79 | { |

80 | using Type = std::decay_t<decltype(*std::declval<Sequence>().begin())>; |

81 | }; |

82 | |

83 | template <class Iterator> |

84 | struct Argument<Iterator, typename std::enable_if<IsDereferenceableValue<Iterator>>::type> |

85 | { |

86 | using Type = std::decay_t<decltype(*std::declval<Iterator>())>; |

87 | }; |

88 | |

89 | template <class T> |

90 | using ArgumentType = typename Argument<T>::Type; |

91 | |

92 | template <class T, class MapFunctor> |

93 | struct MapResult |

94 | { |

95 | static_assert(std::is_invocable_v<std::decay_t<MapFunctor>, ArgumentType<T>>, |

96 | "It's not possible to invoke the function with passed argument."); |

97 | using Type = std::invoke_result_t<std::decay_t<MapFunctor>, ArgumentType<T>>; |

98 | }; |

99 | |

100 | template <class T, class MapFunctor> |

101 | using MapResultType = typename MapResult<T, MapFunctor>::Type; |

102 | |

103 | // -- ReduceResultType |

104 | |

105 | template <class T> |

106 | struct ReduceResultType; |

107 | |

108 | template <class U, class V> |

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

110 | { |

111 | using ResultType = U; |

112 | }; |

113 | |

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

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

116 | { |

117 | using ResultType = C; |

118 | }; |

119 | |

120 | template <class U, class V> |

121 | struct ReduceResultType<std::function<void(U&, V)>> |

122 | { |

123 | using ResultType = U; |

124 | }; |

125 | |

126 | template <typename R, typename ...A> |

127 | struct ReduceResultType<R(*)(A...)> |

128 | { |

129 | using ResultType = typename std::tuple_element<0, std::tuple<A...>>::type; |

130 | }; |

131 | |

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

133 | template <class U, class V> |

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

135 | { |

136 | using ResultType = U; |

137 | }; |

138 | |

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

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

141 | { |

142 | using ResultType = C; |

143 | }; |

144 | #endif |

145 | |

146 | // -- MapSequenceResultType |

147 | |

148 | template <class InputSequence, class MapFunctor> |

149 | struct MapSequenceResultType |

150 | { |

151 | static_assert(std::is_same_v<typename InputSequence::value_type, |

152 | QtPrivate::MapResultType<InputSequence, MapFunctor>>, |

153 | "Couldn't deduce the output sequence type, you must specify it explicitly."); |

154 | typedef InputSequence ResultType; |

155 | }; |

156 | |

157 | template <class MapFunctor> |

158 | struct MapSequenceResultType<QStringList, MapFunctor> |

159 | { |

160 | typedef QList<QtPrivate::MapResultType<QStringList, MapFunctor>> ResultType; |

161 | }; |

162 | |

163 | #ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS |

164 | |

165 | template <template <typename...> class InputSequence, typename MapFunctor, typename ...T> |

166 | struct MapSequenceResultType<InputSequence<T...>, MapFunctor> |

167 | { |

168 | typedef InputSequence<QtPrivate::MapResultType<InputSequence<T...>, MapFunctor>> ResultType; |

169 | }; |

170 | |

171 | #endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER |

172 | |

173 | template<typename Sequence> |

174 | struct SequenceHolder |

175 | { |

176 | SequenceHolder(const Sequence &s) : sequence(s) { } |

177 | SequenceHolder(Sequence &&s) : sequence(std::move(s)) { } |

178 | Sequence sequence; |

179 | }; |

180 | |

181 | } // namespace QtPrivate. |

182 | |

183 | |

184 | QT_END_NAMESPACE |

185 | |

186 | #endif // QT_NO_CONCURRENT |

187 | |

188 | #endif |

189 |