algorithm.h 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565
  1. // Copyright (C) 2016 The Qt Company Ltd.
  2. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
  3. #pragma once
  4. #include "predicates.h"
  5. #include <qcompilerdetection.h> // for Q_REQUIRED_RESULT
  6. #include <algorithm>
  7. #include <map>
  8. #include <memory>
  9. #include <set>
  10. #include <tuple>
  11. #include <unordered_map>
  12. #include <unordered_set>
  13. #include <QHash>
  14. #include <QObject>
  15. #include <QSet>
  16. #include <QStringList>
  17. #include <memory>
  18. #include <optional>
  19. #include <tuple>
  20. #include <type_traits>
  21. #include <utility>
  22. namespace Utils
  23. {
  24. /////////////////////////
  25. // anyOf
  26. /////////////////////////
  27. template<typename T, typename F>
  28. bool anyOf(const T &container, F predicate);
  29. template<typename T, typename R, typename S>
  30. bool anyOf(const T &container, R (S::*predicate)() const);
  31. template<typename T, typename R, typename S>
  32. bool anyOf(const T &container, R S::*member);
  33. /////////////////////////
  34. // count
  35. /////////////////////////
  36. template<typename T, typename F>
  37. int count(const T &container, F predicate);
  38. /////////////////////////
  39. // allOf
  40. /////////////////////////
  41. template<typename T, typename F>
  42. bool allOf(const T &container, F predicate);
  43. /////////////////////////
  44. // erase
  45. /////////////////////////
  46. template<typename T, typename F>
  47. void erase(T &container, F predicate);
  48. template<typename T, typename F>
  49. bool eraseOne(T &container, F predicate);
  50. /////////////////////////
  51. // contains
  52. /////////////////////////
  53. template<typename T, typename F>
  54. bool contains(const T &container, F function);
  55. template<typename T, typename R, typename S>
  56. bool contains(const T &container, R (S::*function)() const);
  57. template<typename C, typename R, typename S>
  58. bool contains(const C &container, R S::*member);
  59. /////////////////////////
  60. // findOr
  61. /////////////////////////
  62. template<typename C, typename F>
  63. Q_REQUIRED_RESULT typename C::value_type findOr(const C &container,
  64. typename C::value_type other,
  65. F function);
  66. template<typename T, typename R, typename S>
  67. Q_REQUIRED_RESULT typename T::value_type findOr(const T &container,
  68. typename T::value_type other,
  69. R (S::*function)() const);
  70. template<typename T, typename R, typename S>
  71. Q_REQUIRED_RESULT typename T::value_type findOr(const T &container,
  72. typename T::value_type other,
  73. R S::*member);
  74. template<typename T, typename F>
  75. Q_REQUIRED_RESULT std::optional<typename T::value_type> findOr(const T &container,
  76. std::nullopt_t,
  77. F function);
  78. /////////////////////////
  79. // findOrDefault
  80. /////////////////////////
  81. template<typename C, typename F>
  82. Q_REQUIRED_RESULT typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value,
  83. typename C::value_type>
  84. findOrDefault(const C &container, F function);
  85. template<typename C, typename R, typename S>
  86. Q_REQUIRED_RESULT typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value,
  87. typename C::value_type>
  88. findOrDefault(const C &container, R (S::*function)() const);
  89. template<typename C, typename R, typename S>
  90. Q_REQUIRED_RESULT typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value,
  91. typename C::value_type>
  92. findOrDefault(const C &container, R S::*member);
  93. /////////////////////////
  94. // indexOf
  95. /////////////////////////
  96. template<typename C, typename F>
  97. Q_REQUIRED_RESULT int indexOf(const C &container, F function);
  98. /////////////////////////
  99. // maxElementOr
  100. /////////////////////////
  101. template<typename T>
  102. typename T::value_type maxElementOr(const T &container, typename T::value_type other);
  103. /////////////////////////
  104. // filtered
  105. /////////////////////////
  106. template<typename C, typename F>
  107. Q_REQUIRED_RESULT C filtered(const C &container, F predicate);
  108. template<typename C, typename R, typename S>
  109. Q_REQUIRED_RESULT C filtered(const C &container, R (S::*predicate)() const);
  110. /////////////////////////
  111. // partition
  112. /////////////////////////
  113. // Recommended usage:
  114. // C hit;
  115. // C miss;
  116. // std::tie(hit, miss) = Utils::partition(container, predicate);
  117. template<typename C, typename F>
  118. Q_REQUIRED_RESULT std::tuple<C, C> partition(const C &container, F predicate);
  119. template<typename C, typename R, typename S>
  120. Q_REQUIRED_RESULT std::tuple<C, C> partition(const C &container, R (S::*predicate)() const);
  121. /////////////////////////
  122. // filteredUnique
  123. /////////////////////////
  124. template<typename C>
  125. Q_REQUIRED_RESULT C filteredUnique(const C &container);
  126. /////////////////////////
  127. // qobject_container_cast
  128. /////////////////////////
  129. template<class T, template<typename> class Container, typename Base>
  130. Container<T> qobject_container_cast(const Container<Base> &container);
  131. /////////////////////////
  132. // static_container_cast
  133. /////////////////////////
  134. template<class T, template<typename> class Container, typename Base>
  135. Container<T> static_container_cast(const Container<Base> &container);
  136. /////////////////////////
  137. // sort
  138. /////////////////////////
  139. template<typename Container>
  140. inline void sort(Container &container);
  141. template<typename Container, typename Predicate>
  142. inline void sort(Container &container, Predicate p);
  143. template<typename Container, typename R, typename S>
  144. inline void sort(Container &container, R S::*member);
  145. template<typename Container, typename R, typename S>
  146. inline void sort(Container &container, R (S::*function)() const);
  147. /////////////////////////
  148. // reverseForeach
  149. /////////////////////////
  150. template<typename Container, typename Op>
  151. inline void reverseForeach(const Container &c, const Op &operation);
  152. /////////////////////////
  153. // toReferences
  154. /////////////////////////
  155. template<template<typename...> class ResultContainer, typename SourceContainer>
  156. auto toReferences(SourceContainer &sources);
  157. template<typename SourceContainer>
  158. auto toReferences(SourceContainer &sources);
  159. /////////////////////////
  160. // toConstReferences
  161. /////////////////////////
  162. template<template<typename...> class ResultContainer, typename SourceContainer>
  163. auto toConstReferences(const SourceContainer &sources);
  164. template<typename SourceContainer>
  165. auto toConstReferences(const SourceContainer &sources);
  166. /////////////////////////
  167. // take
  168. /////////////////////////
  169. template<class C, typename P>
  170. Q_REQUIRED_RESULT std::optional<typename C::value_type> take(C &container, P predicate);
  171. template<typename C, typename R, typename S>
  172. Q_REQUIRED_RESULT decltype(auto) take(C &container, R S::*member);
  173. template<typename C, typename R, typename S>
  174. Q_REQUIRED_RESULT decltype(auto) take(C &container, R (S::*function)() const);
  175. /////////////////////////
  176. // setUnionMerge
  177. /////////////////////////
  178. // Works like std::set_union but provides a merge function for items that match
  179. // !(a > b) && !(b > a) which normally means that there is an "equal" match.
  180. // It uses iterators to support move_iterators.
  181. template<class InputIt1, class InputIt2, class OutputIt, class Merge, class Compare>
  182. OutputIt setUnionMerge(InputIt1 first1,
  183. InputIt1 last1,
  184. InputIt2 first2,
  185. InputIt2 last2,
  186. OutputIt d_first,
  187. Merge merge,
  188. Compare comp);
  189. template<class InputIt1, class InputIt2, class OutputIt, class Merge>
  190. OutputIt setUnionMerge(
  191. InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt d_first, Merge merge);
  192. template<class OutputContainer, class InputContainer1, class InputContainer2, class Merge, class Compare>
  193. OutputContainer setUnionMerge(InputContainer1 &&input1,
  194. InputContainer2 &&input2,
  195. Merge merge,
  196. Compare comp);
  197. template<class OutputContainer, class InputContainer1, class InputContainer2, class Merge>
  198. OutputContainer setUnionMerge(InputContainer1 &&input1, InputContainer2 &&input2, Merge merge);
  199. /////////////////////////
  200. // setUnion
  201. /////////////////////////
  202. template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
  203. OutputIterator set_union(InputIterator1 first1,
  204. InputIterator1 last1,
  205. InputIterator2 first2,
  206. InputIterator2 last2,
  207. OutputIterator result,
  208. Compare comp);
  209. template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
  210. OutputIterator set_union(InputIterator1 first1,
  211. InputIterator1 last1,
  212. InputIterator2 first2,
  213. InputIterator2 last2,
  214. OutputIterator result);
  215. /////////////////////////
  216. // transform
  217. /////////////////////////
  218. // function without result type deduction:
  219. template<typename ResultContainer, // complete result container type
  220. typename SC, // input container type
  221. typename F> // function type
  222. Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function);
  223. // function with result type deduction:
  224. template<template<typename> class C, // result container type
  225. typename SC, // input container type
  226. typename F, // function type
  227. typename Value = typename std::decay_t<SC>::value_type,
  228. typename Result = std::decay_t<std::invoke_result_t<F, Value&>>,
  229. typename ResultContainer = C<Result>>
  230. Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function);
  231. #ifdef Q_CC_CLANG
  232. // "Matching of template template-arguments excludes compatible templates"
  233. // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0522r0.html (P0522R0)
  234. // in C++17 makes the above match e.g. C=std::vector even though that takes two
  235. // template parameters. Unfortunately the following one matches too, and there is no additional
  236. // partial ordering rule, resulting in an ambiguous call for this previously valid code.
  237. // GCC and MSVC ignore that issue and follow the standard to the letter, but Clang only
  238. // enables the new behavior when given -frelaxed-template-template-args .
  239. // To avoid requiring everyone using this header to enable that feature, keep the old implementation
  240. // for Clang.
  241. template<template<typename, typename> class C, // result container type
  242. typename SC, // input container type
  243. typename F, // function type
  244. typename Value = typename std::decay_t<SC>::value_type,
  245. typename Result = std::decay_t<std::invoke_result_t<F, Value&>>,
  246. typename ResultContainer = C<Result, std::allocator<Result>>>
  247. Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function);
  248. #endif
  249. // member function without result type deduction:
  250. template<template<typename...> class C, // result container type
  251. typename SC, // input container type
  252. typename R,
  253. typename S>
  254. Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R (S::*p)() const);
  255. // member function with result type deduction:
  256. template<typename ResultContainer, // complete result container type
  257. typename SC, // input container type
  258. typename R,
  259. typename S>
  260. Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R (S::*p)() const);
  261. // member without result type deduction:
  262. template<typename ResultContainer, // complete result container type
  263. typename SC, // input container
  264. typename R,
  265. typename S>
  266. Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R S::*p);
  267. // member with result type deduction:
  268. template<template<typename...> class C, // result container
  269. typename SC, // input container
  270. typename R,
  271. typename S>
  272. Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R S::*p);
  273. // same container types for input and output, const input
  274. // function:
  275. template<template<typename...> class C, // container type
  276. typename F, // function type
  277. typename... CArgs> // Arguments to SC
  278. Q_REQUIRED_RESULT decltype(auto) transform(const C<CArgs...> &container, F function);
  279. // same container types for input and output, const input
  280. // member function:
  281. template<template<typename...> class C, // container type
  282. typename R,
  283. typename S,
  284. typename... CArgs> // Arguments to SC
  285. Q_REQUIRED_RESULT decltype(auto) transform(const C<CArgs...> &container, R (S::*p)() const);
  286. // same container types for input and output, const input
  287. // members:
  288. template<template<typename...> class C, // container
  289. typename R,
  290. typename S,
  291. typename... CArgs> // Arguments to SC
  292. Q_REQUIRED_RESULT decltype(auto) transform(const C<CArgs...> &container, R S::*p);
  293. // same container types for input and output, non-const input
  294. // function:
  295. template<template<typename...> class C, // container type
  296. typename F, // function type
  297. typename... CArgs> // Arguments to SC
  298. Q_REQUIRED_RESULT decltype(auto) transform(C<CArgs...> &container, F function);
  299. // same container types for input and output, non-const input
  300. // member function:
  301. template<template<typename...> class C, // container type
  302. typename R,
  303. typename S,
  304. typename... CArgs> // Arguments to SC
  305. Q_REQUIRED_RESULT decltype(auto) transform(C<CArgs...> &container, R (S::*p)() const);
  306. // same container types for input and output, non-const input
  307. // members:
  308. template<template<typename...> class C, // container
  309. typename R,
  310. typename S,
  311. typename... CArgs> // Arguments to SC
  312. Q_REQUIRED_RESULT decltype(auto) transform(C<CArgs...> &container, R S::*p);
  313. /////////////////////////////////////////////////////////////////////////////
  314. //////// Implementations //////////////////////////////////////////////
  315. /////////////////////////////////////////////////////////////////////////////
  316. //////////////////
  317. // anyOf
  318. /////////////////
  319. template<typename T, typename F>
  320. bool anyOf(const T &container, F predicate)
  321. {
  322. return std::any_of(std::begin(container), std::end(container), predicate);
  323. }
  324. // anyOf taking a member function pointer
  325. template<typename T, typename R, typename S>
  326. bool anyOf(const T &container, R (S::*predicate)() const)
  327. {
  328. return std::any_of(std::begin(container), std::end(container), std::mem_fn(predicate));
  329. }
  330. // anyOf taking a member pointer
  331. template<typename T, typename R, typename S>
  332. bool anyOf(const T &container, R S::*member)
  333. {
  334. return std::any_of(std::begin(container), std::end(container), std::mem_fn(member));
  335. }
  336. //////////////////
  337. // count
  338. /////////////////
  339. template<typename T, typename F>
  340. int count(const T &container, F predicate)
  341. {
  342. return std::count_if(std::begin(container), std::end(container), predicate);
  343. }
  344. //////////////////
  345. // allOf
  346. /////////////////
  347. template<typename T, typename F>
  348. bool allOf(const T &container, F predicate)
  349. {
  350. return std::all_of(std::begin(container), std::end(container), predicate);
  351. }
  352. template<typename T, typename F>
  353. bool allOf(const std::initializer_list<T> &initializerList, F predicate)
  354. {
  355. return std::all_of(std::begin(initializerList), std::end(initializerList), predicate);
  356. }
  357. // allOf taking a member function pointer
  358. template<typename T, typename R, typename S>
  359. bool allOf(const T &container, R (S::*predicate)() const)
  360. {
  361. return std::all_of(std::begin(container), std::end(container), std::mem_fn(predicate));
  362. }
  363. // allOf taking a member pointer
  364. template<typename T, typename R, typename S>
  365. bool allOf(const T &container, R S::*member)
  366. {
  367. return std::all_of(std::begin(container), std::end(container), std::mem_fn(member));
  368. }
  369. //////////////////
  370. // erase
  371. /////////////////
  372. template<typename T, typename F>
  373. void erase(T &container, F predicate)
  374. {
  375. container.erase(std::remove_if(std::begin(container), std::end(container), predicate),
  376. std::end(container));
  377. }
  378. template<typename T, typename F>
  379. bool eraseOne(T &container, F predicate)
  380. {
  381. const auto it = std::find_if(std::begin(container), std::end(container), predicate);
  382. if (it == std::end(container))
  383. return false;
  384. container.erase(it);
  385. return true;
  386. }
  387. //////////////////
  388. // contains
  389. /////////////////
  390. template<typename T, typename F>
  391. bool contains(const T &container, F function)
  392. {
  393. return anyOf(container, function);
  394. }
  395. template<typename T, typename R, typename S>
  396. bool contains(const T &container, R (S::*function)() const)
  397. {
  398. return anyOf(container, function);
  399. }
  400. template<typename C, typename R, typename S>
  401. bool contains(const C &container, R S::*member)
  402. {
  403. return anyOf(container, std::mem_fn(member));
  404. }
  405. //////////////////
  406. // findOr
  407. /////////////////
  408. template<typename C, typename F>
  409. Q_REQUIRED_RESULT
  410. typename C::value_type findOr(const C &container, typename C::value_type other, F function)
  411. {
  412. typename C::const_iterator begin = std::begin(container);
  413. typename C::const_iterator end = std::end(container);
  414. typename C::const_iterator it = std::find_if(begin, end, function);
  415. return it == end ? other : *it;
  416. }
  417. template<typename T, typename R, typename S>
  418. Q_REQUIRED_RESULT
  419. typename T::value_type findOr(const T &container, typename T::value_type other, R (S::*function)() const)
  420. {
  421. return findOr(container, other, std::mem_fn(function));
  422. }
  423. template<typename T, typename R, typename S>
  424. Q_REQUIRED_RESULT
  425. typename T::value_type findOr(const T &container, typename T::value_type other, R S::*member)
  426. {
  427. return findOr(container, other, std::mem_fn(member));
  428. }
  429. template<typename C, typename F>
  430. Q_REQUIRED_RESULT typename std::optional<typename C::value_type> findOr(const C &container,
  431. std::nullopt_t,
  432. F function)
  433. {
  434. typename C::const_iterator begin = std::begin(container);
  435. typename C::const_iterator end = std::end(container);
  436. typename C::const_iterator it = std::find_if(begin, end, function);
  437. if (it == end)
  438. return std::nullopt;
  439. return *it;
  440. }
  441. //////////////////
  442. // findOrDefault
  443. //////////////////
  444. // Default implementation:
  445. template<typename C, typename F>
  446. Q_REQUIRED_RESULT
  447. typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value, typename C::value_type>
  448. findOrDefault(const C &container, F function)
  449. {
  450. return findOr(container, typename C::value_type(), function);
  451. }
  452. template<typename C, typename R, typename S>
  453. Q_REQUIRED_RESULT
  454. typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value, typename C::value_type>
  455. findOrDefault(const C &container, R (S::*function)() const)
  456. {
  457. return findOr(container, typename C::value_type(), std::mem_fn(function));
  458. }
  459. template<typename C, typename R, typename S>
  460. Q_REQUIRED_RESULT
  461. typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value, typename C::value_type>
  462. findOrDefault(const C &container, R S::*member)
  463. {
  464. return findOr(container, typename C::value_type(), std::mem_fn(member));
  465. }
  466. //////////////////
  467. // index of:
  468. //////////////////
  469. template<typename C, typename F>
  470. Q_REQUIRED_RESULT
  471. int indexOf(const C& container, F function)
  472. {
  473. typename C::const_iterator begin = std::begin(container);
  474. typename C::const_iterator end = std::end(container);
  475. typename C::const_iterator it = std::find_if(begin, end, function);
  476. return it == end ? -1 : std::distance(begin, it);
  477. }
  478. //////////////////
  479. // max element
  480. //////////////////
  481. template<typename T>
  482. typename T::value_type maxElementOr(const T &container, typename T::value_type other)
  483. {
  484. typename T::const_iterator begin = std::begin(container);
  485. typename T::const_iterator end = std::end(container);
  486. typename T::const_iterator it = std::max_element(begin, end);
  487. if (it == end)
  488. return other;
  489. return *it;
  490. }
  491. //////////////////
  492. // transform
  493. /////////////////
  494. namespace {
  495. /////////////////
  496. // helper code for transform to use back_inserter and thus push_back for everything
  497. // and insert for QSet<>
  498. //
  499. // SetInsertIterator, straight from the standard for insert_iterator
  500. // just without the additional parameter to insert
  501. template<class Container>
  502. class SetInsertIterator
  503. {
  504. protected:
  505. Container *container;
  506. public:
  507. using iterator_category = std::output_iterator_tag;
  508. using container_type = Container;
  509. explicit SetInsertIterator(Container &x)
  510. : container(&x)
  511. {}
  512. SetInsertIterator<Container> &operator=(const typename Container::value_type &value)
  513. {
  514. container->insert(value);
  515. return *this;
  516. }
  517. SetInsertIterator<Container> &operator=(typename Container::value_type &&value)
  518. {
  519. container->insert(std::move(value));
  520. return *this;
  521. }
  522. SetInsertIterator<Container> &operator*() { return *this; }
  523. SetInsertIterator<Container> &operator++() { return *this; }
  524. SetInsertIterator<Container> operator++(int) { return *this; }
  525. };
  526. // for QMap / QHash, inserting a std::pair / QPair
  527. template<class Container>
  528. class MapInsertIterator
  529. {
  530. protected:
  531. Container *container;
  532. public:
  533. using iterator_category = std::output_iterator_tag;
  534. using container_type = Container;
  535. explicit MapInsertIterator(Container &x)
  536. : container(&x)
  537. {}
  538. MapInsertIterator<Container> &operator=(
  539. const std::pair<const typename Container::key_type, typename Container::mapped_type> &value)
  540. { container->insert(value.first, value.second); return *this; }
  541. MapInsertIterator<Container> &operator=(
  542. const QPair<typename Container::key_type, typename Container::mapped_type> &value)
  543. { container->insert(value.first, value.second); return *this; }
  544. MapInsertIterator<Container> &operator*() { return *this; }
  545. MapInsertIterator<Container> &operator++() { return *this; }
  546. MapInsertIterator<Container> operator++(int) { return *this; }
  547. };
  548. // because Qt container are not implementing the standard interface we need
  549. // this helper functions for generic code
  550. template<typename Type>
  551. void append(QList<Type> *container, QList<Type> &&input)
  552. {
  553. container->append(std::move(input));
  554. }
  555. template<typename Type>
  556. void append(QList<Type> *container, const QList<Type> &input)
  557. {
  558. container->append(input);
  559. }
  560. template<typename Container>
  561. void append(Container *container, Container &&input)
  562. {
  563. container->insert(container->end(),
  564. std::make_move_iterator(input.begin()),
  565. std::make_move_iterator(input.end()));
  566. }
  567. template<typename Container>
  568. void append(Container *container, const Container &input)
  569. {
  570. container->insert(container->end(), input.begin(), input.end());
  571. }
  572. // BackInsertIterator behaves like std::back_insert_iterator except is adds the back insertion for
  573. // container of the same type
  574. template<typename Container>
  575. class BackInsertIterator
  576. {
  577. public:
  578. using iterator_category = std::output_iterator_tag;
  579. using value_type = void;
  580. using difference_type = ptrdiff_t;
  581. using pointer = void;
  582. using reference = void;
  583. using container_type = Container;
  584. explicit constexpr BackInsertIterator(Container &container)
  585. : m_container(std::addressof(container))
  586. {}
  587. constexpr BackInsertIterator &operator=(const typename Container::value_type &value)
  588. {
  589. m_container->push_back(value);
  590. return *this;
  591. }
  592. constexpr BackInsertIterator &operator=(typename Container::value_type &&value)
  593. {
  594. m_container->push_back(std::move(value));
  595. return *this;
  596. }
  597. constexpr BackInsertIterator &operator=(const Container &container)
  598. {
  599. append(m_container, container);
  600. return *this;
  601. }
  602. constexpr BackInsertIterator &operator=(Container &&container)
  603. {
  604. append(m_container, container);
  605. return *this;
  606. }
  607. [[nodiscard]] constexpr BackInsertIterator &operator*() { return *this; }
  608. constexpr BackInsertIterator &operator++() { return *this; }
  609. constexpr BackInsertIterator operator++(int) { return *this; }
  610. private:
  611. Container *m_container;
  612. };
  613. // inserter helper function, returns a BackInsertIterator for most containers
  614. // and is overloaded for QSet<> and other containers without push_back, returning custom inserters
  615. template<typename Container>
  616. inline BackInsertIterator<Container> inserter(Container &container)
  617. {
  618. return BackInsertIterator(container);
  619. }
  620. template<typename X>
  621. inline SetInsertIterator<QSet<X>>
  622. inserter(QSet<X> &container)
  623. {
  624. return SetInsertIterator<QSet<X>>(container);
  625. }
  626. template<typename K, typename C, typename A>
  627. inline SetInsertIterator<std::set<K, C, A>>
  628. inserter(std::set<K, C, A> &container)
  629. {
  630. return SetInsertIterator<std::set<K, C, A>>(container);
  631. }
  632. template<typename K, typename H, typename C, typename A>
  633. inline SetInsertIterator<std::unordered_set<K, H, C, A>>
  634. inserter(std::unordered_set<K, H, C, A> &container)
  635. {
  636. return SetInsertIterator<std::unordered_set<K, H, C, A>>(container);
  637. }
  638. template<typename K, typename V, typename C, typename A>
  639. inline SetInsertIterator<std::map<K, V, C, A>>
  640. inserter(std::map<K, V, C, A> &container)
  641. {
  642. return SetInsertIterator<std::map<K, V, C, A>>(container);
  643. }
  644. template<typename K, typename V, typename H, typename C, typename A>
  645. inline SetInsertIterator<std::unordered_map<K, V, H, C, A>>
  646. inserter(std::unordered_map<K, V, H, C, A> &container)
  647. {
  648. return SetInsertIterator<std::unordered_map<K, V, H, C, A>>(container);
  649. }
  650. template<typename K, typename V>
  651. inline MapInsertIterator<QMap<K, V>>
  652. inserter(QMap<K, V> &container)
  653. {
  654. return MapInsertIterator<QMap<K, V>>(container);
  655. }
  656. template<typename K, typename V>
  657. inline MapInsertIterator<QHash<K, V>>
  658. inserter(QHash<K, V> &container)
  659. {
  660. return MapInsertIterator<QHash<K, V>>(container);
  661. }
  662. // Helper code for container.reserve that makes it possible to effectively disable it for
  663. // specific cases
  664. // default: do reserve
  665. // Template arguments are more specific than the second version below, so this is tried first
  666. template<template<typename...> class C, typename... CArgs,
  667. typename = decltype(&C<CArgs...>::reserve)>
  668. void reserve(C<CArgs...> &c, typename C<CArgs...>::size_type s)
  669. {
  670. c.reserve(s);
  671. }
  672. // containers that don't have reserve()
  673. template<typename C>
  674. void reserve(C &, typename C::size_type) { }
  675. } // anonymous
  676. // --------------------------------------------------------------------
  677. // Different containers for input and output:
  678. // --------------------------------------------------------------------
  679. // different container types for input and output, e.g. transforming a QList into a QSet
  680. // function without result type deduction:
  681. template<typename ResultContainer, // complete result container type
  682. typename SC, // input container type
  683. typename F> // function type
  684. Q_REQUIRED_RESULT
  685. decltype(auto) transform(SC &&container, F function)
  686. {
  687. ResultContainer result;
  688. reserve(result, typename ResultContainer::size_type(container.size()));
  689. std::transform(std::begin(container), std::end(container), inserter(result), function);
  690. return result;
  691. }
  692. // function with result type deduction:
  693. template<template<typename> class C, // result container type
  694. typename SC, // input container type
  695. typename F, // function type
  696. typename Value,
  697. typename Result,
  698. typename ResultContainer>
  699. Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function)
  700. {
  701. return transform<ResultContainer>(std::forward<SC>(container), function);
  702. }
  703. #ifdef Q_CC_CLANG
  704. template<template<typename, typename> class C, // result container type
  705. typename SC, // input container type
  706. typename F, // function type
  707. typename Value,
  708. typename Result,
  709. typename ResultContainer>
  710. Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function)
  711. {
  712. return transform<ResultContainer>(std::forward<SC>(container), function);
  713. }
  714. #endif
  715. // member function without result type deduction:
  716. template<template<typename...> class C, // result container type
  717. typename SC, // input container type
  718. typename R,
  719. typename S>
  720. Q_REQUIRED_RESULT
  721. decltype(auto) transform(SC &&container, R (S::*p)() const)
  722. {
  723. return transform<C>(std::forward<SC>(container), std::mem_fn(p));
  724. }
  725. // member function with result type deduction:
  726. template<typename ResultContainer, // complete result container type
  727. typename SC, // input container type
  728. typename R,
  729. typename S>
  730. Q_REQUIRED_RESULT
  731. decltype(auto) transform(SC &&container, R (S::*p)() const)
  732. {
  733. return transform<ResultContainer>(std::forward<SC>(container), std::mem_fn(p));
  734. }
  735. // member without result type deduction:
  736. template<typename ResultContainer, // complete result container type
  737. typename SC, // input container
  738. typename R,
  739. typename S>
  740. Q_REQUIRED_RESULT
  741. decltype(auto) transform(SC &&container, R S::*p)
  742. {
  743. return transform<ResultContainer>(std::forward<SC>(container), std::mem_fn(p));
  744. }
  745. // member with result type deduction:
  746. template<template<typename...> class C, // result container
  747. typename SC, // input container
  748. typename R,
  749. typename S>
  750. Q_REQUIRED_RESULT
  751. decltype(auto) transform(SC &&container, R S::*p)
  752. {
  753. return transform<C>(std::forward<SC>(container), std::mem_fn(p));
  754. }
  755. // same container types for input and output, const input
  756. // function:
  757. template<template<typename...> class C, // container type
  758. typename F, // function type
  759. typename... CArgs> // Arguments to SC
  760. Q_REQUIRED_RESULT
  761. decltype(auto) transform(const C<CArgs...> &container, F function)
  762. {
  763. return transform<C, const C<CArgs...> &>(container, function);
  764. }
  765. // member function:
  766. template<template<typename...> class C, // container type
  767. typename R,
  768. typename S,
  769. typename... CArgs> // Arguments to SC
  770. Q_REQUIRED_RESULT
  771. decltype(auto) transform(const C<CArgs...> &container, R (S::*p)() const)
  772. {
  773. return transform<C, const C<CArgs...> &>(container, std::mem_fn(p));
  774. }
  775. // members:
  776. template<template<typename...> class C, // container
  777. typename R,
  778. typename S,
  779. typename... CArgs> // Arguments to SC
  780. Q_REQUIRED_RESULT
  781. decltype(auto) transform(const C<CArgs...> &container, R S::*p)
  782. {
  783. return transform<C, const C<CArgs...> &>(container, std::mem_fn(p));
  784. }
  785. // same container types for input and output, non-const input
  786. // function:
  787. template<template<typename...> class C, // container type
  788. typename F, // function type
  789. typename... CArgs> // Arguments to SC
  790. Q_REQUIRED_RESULT
  791. auto transform(C<CArgs...> &container, F function) -> decltype(auto)
  792. {
  793. return transform<C, C<CArgs...> &>(container, function);
  794. }
  795. // member function:
  796. template<template<typename...> class C, // container type
  797. typename R,
  798. typename S,
  799. typename... CArgs> // Arguments to SC
  800. Q_REQUIRED_RESULT
  801. decltype(auto) transform(C<CArgs...> &container, R (S::*p)() const)
  802. {
  803. return transform<C, C<CArgs...> &>(container, std::mem_fn(p));
  804. }
  805. // members:
  806. template<template<typename...> class C, // container
  807. typename R,
  808. typename S,
  809. typename... CArgs> // Arguments to SC
  810. Q_REQUIRED_RESULT
  811. decltype(auto) transform(C<CArgs...> &container, R S::*p)
  812. {
  813. return transform<C, C<CArgs...> &>(container, std::mem_fn(p));
  814. }
  815. // Specialization for QStringList:
  816. template<template<typename...> class C = QList, // result container
  817. typename F> // Arguments to C
  818. Q_REQUIRED_RESULT
  819. auto transform(const QStringList &container, F function)
  820. {
  821. return transform<C, const QList<QString> &>(static_cast<QList<QString>>(container), function);
  822. }
  823. // member function:
  824. template<template<typename...> class C = QList, // result container type
  825. typename R,
  826. typename S>
  827. Q_REQUIRED_RESULT
  828. decltype(auto) transform(const QStringList &container, R (S::*p)() const)
  829. {
  830. return transform<C, const QList<QString> &>(static_cast<QList<QString>>(container), std::mem_fn(p));
  831. }
  832. // members:
  833. template<template<typename...> class C = QList, // result container
  834. typename R,
  835. typename S>
  836. Q_REQUIRED_RESULT
  837. decltype(auto) transform(const QStringList &container, R S::*p)
  838. {
  839. return transform<C, const QList<QString> &>(static_cast<QList<QString>>(container), std::mem_fn(p));
  840. }
  841. //////////////////
  842. // filtered
  843. /////////////////
  844. template<typename C, typename F>
  845. Q_REQUIRED_RESULT
  846. C filtered(const C &container, F predicate)
  847. {
  848. C out;
  849. std::copy_if(std::begin(container), std::end(container),
  850. inserter(out), predicate);
  851. return out;
  852. }
  853. template<typename C, typename R, typename S>
  854. Q_REQUIRED_RESULT
  855. C filtered(const C &container, R (S::*predicate)() const)
  856. {
  857. C out;
  858. std::copy_if(std::begin(container), std::end(container),
  859. inserter(out), std::mem_fn(predicate));
  860. return out;
  861. }
  862. template<typename C, typename R, typename S>
  863. Q_REQUIRED_RESULT C filtered(const C &container, R S::*predicate)
  864. {
  865. C out;
  866. std::copy_if(std::begin(container), std::end(container), inserter(out), std::mem_fn(predicate));
  867. return out;
  868. }
  869. //////////////////
  870. // filteredCast
  871. /////////////////
  872. template<typename R, typename C, typename F>
  873. Q_REQUIRED_RESULT R filteredCast(const C &container, F predicate)
  874. {
  875. R out;
  876. std::copy_if(std::begin(container), std::end(container), inserter(out), predicate);
  877. return out;
  878. }
  879. //////////////////
  880. // partition
  881. /////////////////
  882. // Recommended usage:
  883. // C hit;
  884. // C miss;
  885. // std::tie(hit, miss) = Utils::partition(container, predicate);
  886. template<typename C, typename F>
  887. Q_REQUIRED_RESULT
  888. std::tuple<C, C> partition(const C &container, F predicate)
  889. {
  890. C hit;
  891. C miss;
  892. reserve(hit, container.size());
  893. reserve(miss, container.size());
  894. auto hitIns = inserter(hit);
  895. auto missIns = inserter(miss);
  896. for (const auto &i : container) {
  897. if (predicate(i))
  898. hitIns = i;
  899. else
  900. missIns = i;
  901. }
  902. return std::make_tuple(hit, miss);
  903. }
  904. template<typename C, typename R, typename S>
  905. Q_REQUIRED_RESULT
  906. std::tuple<C, C> partition(const C &container, R (S::*predicate)() const)
  907. {
  908. return partition(container, std::mem_fn(predicate));
  909. }
  910. //////////////////
  911. // filteredUnique
  912. /////////////////
  913. template<typename C>
  914. Q_REQUIRED_RESULT
  915. C filteredUnique(const C &container)
  916. {
  917. C result;
  918. auto ins = inserter(result);
  919. QSet<typename C::value_type> seen;
  920. int setSize = 0;
  921. auto endIt = std::end(container);
  922. for (auto it = std::begin(container); it != endIt; ++it) {
  923. seen.insert(*it);
  924. if (setSize == seen.size()) // unchanged size => was already seen
  925. continue;
  926. ++setSize;
  927. ins = *it;
  928. }
  929. return result;
  930. }
  931. //////////////////
  932. // qobject_container_cast
  933. /////////////////
  934. template <class T, template<typename> class Container, typename Base>
  935. Container<T> qobject_container_cast(const Container<Base> &container)
  936. {
  937. Container<T> result;
  938. auto ins = inserter(result);
  939. for (Base val : container) {
  940. if (T target = qobject_cast<T>(val))
  941. ins = target;
  942. }
  943. return result;
  944. }
  945. //////////////////
  946. // static_container_cast
  947. /////////////////
  948. template <class T, template<typename> class Container, typename Base>
  949. Container<T> static_container_cast(const Container<Base> &container)
  950. {
  951. Container<T> result;
  952. reserve(result, container.size());
  953. auto ins = inserter(result);
  954. for (Base val : container)
  955. ins = static_cast<T>(val);
  956. return result;
  957. }
  958. //////////////////
  959. // sort
  960. /////////////////
  961. template <typename Container>
  962. inline void sort(Container &container)
  963. {
  964. std::stable_sort(std::begin(container), std::end(container));
  965. }
  966. template <typename Container, typename Predicate>
  967. inline void sort(Container &container, Predicate p)
  968. {
  969. std::stable_sort(std::begin(container), std::end(container), p);
  970. }
  971. // const lvalue
  972. template<typename Container>
  973. inline Container sorted(const Container &container)
  974. {
  975. Container c = container;
  976. sort(c);
  977. return c;
  978. }
  979. // non-const lvalue
  980. // This is needed because otherwise the "universal" reference below is used, modifying the input
  981. // container.
  982. template<typename Container>
  983. inline Container sorted(Container &container)
  984. {
  985. Container c = container;
  986. sort(c);
  987. return c;
  988. }
  989. // non-const rvalue (actually rvalue or lvalue, but lvalue is handled above)
  990. template<typename Container>
  991. inline Container sorted(Container &&container)
  992. {
  993. sort(container);
  994. return std::move(container);
  995. }
  996. // const rvalue
  997. template<typename Container>
  998. inline Container sorted(const Container &&container)
  999. {
  1000. return sorted(container);
  1001. }
  1002. // const lvalue
  1003. template<typename Container, typename Predicate>
  1004. inline Container sorted(const Container &container, Predicate p)
  1005. {
  1006. Container c = container;
  1007. sort(c, p);
  1008. return c;
  1009. }
  1010. // non-const lvalue
  1011. // This is needed because otherwise the "universal" reference below is used, modifying the input
  1012. // container.
  1013. template<typename Container, typename Predicate>
  1014. inline Container sorted(Container &container, Predicate p)
  1015. {
  1016. Container c = container;
  1017. sort(c, p);
  1018. return c;
  1019. }
  1020. // non-const rvalue (actually rvalue or lvalue, but lvalue is handled above)
  1021. template<typename Container, typename Predicate>
  1022. inline Container sorted(Container &&container, Predicate p)
  1023. {
  1024. sort(container, p);
  1025. return std::move(container);
  1026. }
  1027. // const rvalue
  1028. template<typename Container, typename Predicate>
  1029. inline Container sorted(const Container &&container, Predicate p)
  1030. {
  1031. return sorted(container, p);
  1032. }
  1033. // pointer to member
  1034. template<typename Container, typename R, typename S>
  1035. inline void sort(Container &container, R S::*member)
  1036. {
  1037. auto f = std::mem_fn(member);
  1038. using const_ref = typename Container::const_reference;
  1039. std::stable_sort(std::begin(container), std::end(container),
  1040. [&f](const_ref a, const_ref b) {
  1041. return f(a) < f(b);
  1042. });
  1043. }
  1044. // const lvalue
  1045. template<typename Container, typename R, typename S>
  1046. inline Container sorted(const Container &container, R S::*member)
  1047. {
  1048. Container c = container;
  1049. sort(c, member);
  1050. return c;
  1051. }
  1052. // non-const lvalue
  1053. // This is needed because otherwise the "universal" reference below is used, modifying the input
  1054. // container.
  1055. template<typename Container, typename R, typename S>
  1056. inline Container sorted(Container &container, R S::*member)
  1057. {
  1058. Container c = container;
  1059. sort(c, member);
  1060. return c;
  1061. }
  1062. // non-const rvalue (actually rvalue or lvalue, but lvalue is handled above)
  1063. template<typename Container, typename R, typename S>
  1064. inline Container sorted(Container &&container, R S::*member)
  1065. {
  1066. sort(container, member);
  1067. return std::move(container);
  1068. }
  1069. // const rvalue
  1070. template<typename Container, typename R, typename S>
  1071. inline Container sorted(const Container &&container, R S::*member)
  1072. {
  1073. return sorted(container, member);
  1074. }
  1075. // pointer to member function
  1076. template<typename Container, typename R, typename S>
  1077. inline void sort(Container &container, R (S::*function)() const)
  1078. {
  1079. auto f = std::mem_fn(function);
  1080. using const_ref = typename Container::const_reference;
  1081. std::stable_sort(std::begin(container), std::end(container),
  1082. [&f](const_ref a, const_ref b) {
  1083. return f(a) < f(b);
  1084. });
  1085. }
  1086. // const lvalue
  1087. template<typename Container, typename R, typename S>
  1088. inline Container sorted(const Container &container, R (S::*function)() const)
  1089. {
  1090. Container c = container;
  1091. sort(c, function);
  1092. return c;
  1093. }
  1094. // non-const lvalue
  1095. // This is needed because otherwise the "universal" reference below is used, modifying the input
  1096. // container.
  1097. template<typename Container, typename R, typename S>
  1098. inline Container sorted(Container &container, R (S::*function)() const)
  1099. {
  1100. Container c = container;
  1101. sort(c, function);
  1102. return c;
  1103. }
  1104. // non-const rvalue (actually rvalue or lvalue, but lvalue is handled above)
  1105. template<typename Container, typename R, typename S>
  1106. inline Container sorted(Container &&container, R (S::*function)() const)
  1107. {
  1108. sort(container, function);
  1109. return std::move(container);
  1110. }
  1111. // const rvalue
  1112. template<typename Container, typename R, typename S>
  1113. inline Container sorted(const Container &&container, R (S::*function)() const)
  1114. {
  1115. return sorted(container, function);
  1116. }
  1117. //////////////////
  1118. // reverseForeach
  1119. /////////////////
  1120. template <typename Container, typename Op>
  1121. inline void reverseForeach(const Container &c, const Op &operation)
  1122. {
  1123. auto rend = c.rend();
  1124. for (auto it = c.rbegin(); it != rend; ++it)
  1125. operation(*it);
  1126. }
  1127. //////////////////
  1128. // toReferences
  1129. /////////////////
  1130. template <template<typename...> class ResultContainer,
  1131. typename SourceContainer>
  1132. auto toReferences(SourceContainer &sources)
  1133. {
  1134. return transform<ResultContainer>(sources, [] (auto &value) { return std::ref(value); });
  1135. }
  1136. template <typename SourceContainer>
  1137. auto toReferences(SourceContainer &sources)
  1138. {
  1139. return transform(sources, [] (auto &value) { return std::ref(value); });
  1140. }
  1141. //////////////////
  1142. // toConstReferences
  1143. /////////////////
  1144. template <template<typename...> class ResultContainer,
  1145. typename SourceContainer>
  1146. auto toConstReferences(const SourceContainer &sources)
  1147. {
  1148. return transform<ResultContainer>(sources, [] (const auto &value) { return std::cref(value); });
  1149. }
  1150. template <typename SourceContainer>
  1151. auto toConstReferences(const SourceContainer &sources)
  1152. {
  1153. return transform(sources, [] (const auto &value) { return std::cref(value); });
  1154. }
  1155. //////////////////
  1156. // take:
  1157. /////////////////
  1158. template<class C, typename P>
  1159. Q_REQUIRED_RESULT std::optional<typename C::value_type> take(C &container, P predicate)
  1160. {
  1161. const auto end = std::end(container);
  1162. const auto it = std::find_if(std::begin(container), end, predicate);
  1163. if (it == end)
  1164. return std::nullopt;
  1165. std::optional<typename C::value_type> result = std::make_optional(std::move(*it));
  1166. container.erase(it);
  1167. return result;
  1168. }
  1169. // pointer to member
  1170. template <typename C, typename R, typename S>
  1171. Q_REQUIRED_RESULT decltype(auto) take(C &container, R S::*member)
  1172. {
  1173. return take(container, std::mem_fn(member));
  1174. }
  1175. // pointer to member function
  1176. template <typename C, typename R, typename S>
  1177. Q_REQUIRED_RESULT decltype(auto) take(C &container, R (S::*function)() const)
  1178. {
  1179. return take(container, std::mem_fn(function));
  1180. }
  1181. //////////////////
  1182. // setUnionMerge: Works like std::set_union but provides a merge function for items that match
  1183. // !(a > b) && !(b > a) which normally means that there is an "equal" match.
  1184. // It uses iterators to support move_iterators.
  1185. /////////////////
  1186. template<class InputIt1,
  1187. class InputIt2,
  1188. class OutputIt,
  1189. class Merge,
  1190. class Compare>
  1191. OutputIt setUnionMerge(InputIt1 first1,
  1192. InputIt1 last1,
  1193. InputIt2 first2,
  1194. InputIt2 last2,
  1195. OutputIt d_first,
  1196. Merge merge,
  1197. Compare comp)
  1198. {
  1199. for (; first1 != last1; ++d_first) {
  1200. if (first2 == last2)
  1201. return std::copy(first1, last1, d_first);
  1202. if (comp(*first2, *first1)) {
  1203. *d_first = *first2++;
  1204. } else {
  1205. if (comp(*first1, *first2)) {
  1206. *d_first = *first1;
  1207. } else {
  1208. *d_first = merge(*first1, *first2);
  1209. ++first2;
  1210. }
  1211. ++first1;
  1212. }
  1213. }
  1214. return std::copy(first2, last2, d_first);
  1215. }
  1216. template<class InputIt1,
  1217. class InputIt2,
  1218. class OutputIt,
  1219. class Merge>
  1220. OutputIt setUnionMerge(InputIt1 first1,
  1221. InputIt1 last1,
  1222. InputIt2 first2,
  1223. InputIt2 last2,
  1224. OutputIt d_first,
  1225. Merge merge)
  1226. {
  1227. return setUnionMerge(first1,
  1228. last1,
  1229. first2,
  1230. last2,
  1231. d_first,
  1232. merge,
  1233. std::less<std::decay_t<decltype(*first1)>>{});
  1234. }
  1235. template<class OutputContainer,
  1236. class InputContainer1,
  1237. class InputContainer2,
  1238. class Merge,
  1239. class Compare>
  1240. OutputContainer setUnionMerge(InputContainer1 &&input1,
  1241. InputContainer2 &&input2,
  1242. Merge merge,
  1243. Compare comp)
  1244. {
  1245. OutputContainer results;
  1246. results.reserve(input1.size() + input2.size());
  1247. setUnionMerge(std::make_move_iterator(std::begin(input1)),
  1248. std::make_move_iterator(std::end(input1)),
  1249. std::make_move_iterator(std::begin(input2)),
  1250. std::make_move_iterator(std::end(input2)),
  1251. std::back_inserter(results),
  1252. merge,
  1253. comp);
  1254. return results;
  1255. }
  1256. template<class OutputContainer,
  1257. class InputContainer1,
  1258. class InputContainer2,
  1259. class Merge>
  1260. OutputContainer setUnionMerge(InputContainer1 &&input1,
  1261. InputContainer2 &&input2,
  1262. Merge merge)
  1263. {
  1264. return setUnionMerge<OutputContainer>(std::forward<InputContainer1>(input1),
  1265. std::forward<InputContainer2>(input2),
  1266. merge,
  1267. std::less<std::decay_t<decltype(*std::begin(input1))>>{});
  1268. }
  1269. template<typename Container>
  1270. constexpr auto usize(const Container &container)
  1271. {
  1272. return static_cast<std::make_unsigned_t<decltype(std::size(container))>>(std::size(container));
  1273. }
  1274. template<typename Container>
  1275. constexpr auto ssize(const Container &container)
  1276. {
  1277. return static_cast<std::make_signed_t<decltype(std::size(container))>>(std::size(container));
  1278. }
  1279. template<typename Compare>
  1280. struct CompareIter
  1281. {
  1282. Compare compare;
  1283. explicit constexpr CompareIter(Compare compare)
  1284. : compare(std::move(compare))
  1285. {}
  1286. template<typename Iterator1, typename Iterator2>
  1287. constexpr bool operator()(Iterator1 it1, Iterator2 it2)
  1288. {
  1289. return bool(compare(*it1, *it2));
  1290. }
  1291. };
  1292. template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
  1293. OutputIterator set_union_impl(InputIterator1 first1,
  1294. InputIterator1 last1,
  1295. InputIterator2 first2,
  1296. InputIterator2 last2,
  1297. OutputIterator result,
  1298. Compare comp)
  1299. {
  1300. auto compare = CompareIter<Compare>(comp);
  1301. while (first1 != last1 && first2 != last2) {
  1302. if (compare(first1, first2)) {
  1303. *result = *first1;
  1304. ++first1;
  1305. } else if (compare(first2, first1)) {
  1306. *result = *first2;
  1307. ++first2;
  1308. } else {
  1309. *result = *first1;
  1310. ++first1;
  1311. ++first2;
  1312. }
  1313. ++result;
  1314. }
  1315. return std::copy(first2, last2, std::copy(first1, last1, result));
  1316. }
  1317. template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
  1318. OutputIterator set_union(InputIterator1 first1,
  1319. InputIterator1 last1,
  1320. InputIterator2 first2,
  1321. InputIterator2 last2,
  1322. OutputIterator result,
  1323. Compare comp)
  1324. {
  1325. return Utils::set_union_impl(first1, last1, first2, last2, result, comp);
  1326. }
  1327. template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
  1328. OutputIterator set_union(InputIterator1 first1,
  1329. InputIterator1 last1,
  1330. InputIterator2 first2,
  1331. InputIterator2 last2,
  1332. OutputIterator result)
  1333. {
  1334. return Utils::set_union_impl(
  1335. first1, last1, first2, last2, result, std::less<typename InputIterator1::value_type>{});
  1336. }
  1337. // Replacement for deprecated Qt functionality
  1338. template <class T>
  1339. QSet<T> toSet(const QList<T> &list)
  1340. {
  1341. return QSet<T>(list.begin(), list.end());
  1342. }
  1343. template<class T>
  1344. QList<T> toList(const QSet<T> &set)
  1345. {
  1346. return QList<T>(set.begin(), set.end());
  1347. }
  1348. template <class Key, class T>
  1349. void addToHash(QHash<Key, T> *result, const QHash<Key, T> &additionalContents)
  1350. {
  1351. result->insert(additionalContents);
  1352. }
  1353. template <typename Tuple, std::size_t... I>
  1354. static std::size_t tupleHashHelper(uint seed, const Tuple &tuple, std::index_sequence<I...>)
  1355. {
  1356. return qHashMulti(seed, (std::get<I>(tuple), ...));
  1357. }
  1358. template<typename... T> std::size_t qHash(const std::tuple<T...> &tuple, uint seed = 0)
  1359. {
  1360. return tupleHashHelper(seed, tuple, std::make_index_sequence<sizeof...(T)>());
  1361. }
  1362. // Workaround for missing information from QSet::insert()
  1363. // Return type could be a pair like for std::set, but we never use the iterator anyway.
  1364. template<typename T, typename U> [[nodiscard]] bool insert(QSet<T> &s, const U &v)
  1365. {
  1366. const int oldSize = s.size();
  1367. s.insert(v);
  1368. return s.size() > oldSize;
  1369. }
  1370. } // namespace Utils