39 #ifndef CGU_PARALLEL_H
40 #define CGU_PARALLEL_H
47 #include <type_traits>
62 virtual const char*
what()
const throw() {
return "ParallelError\n";}
65 #ifndef DOXYGEN_PARSING
72 namespace ParallelHelper2 {
74 template <
class ArgRefType,
class DiffType,
class Iterator>
78 DiffType* done_count) {
85 template <
class FType,
class ArgRefType,
class DestType>
86 void transform1_func(
const FType& func,
93 template <
class ArgRefType,
class DestType,
class DiffType,
class SourceIterator>
95 SourceIterator source_iter,
101 s_task(*source_iter, res);
106 results[index] = std::move(res);
111 template <
class FType,
class Arg1RefType,
112 class Arg2RefType,
class DestType>
113 void transform2_func(
const FType& func,
117 res = func(arg1, arg2);
121 template <
class Arg1RefType,
class Arg2RefType,
class DestType,
122 class DiffType,
class SourceIterator1,
class SourceIterator2>
124 SourceIterator1 source_iter1,
125 SourceIterator2 source_iter2,
126 Mutex* m, Cond* cond,
127 DiffType* done_count,
131 s_task(*source_iter1, *source_iter2, res);
136 results[index] = std::move(res);
141 template <
class DiffType>
142 void fail_func(Mutex* m, Cond* cond,
143 bool* error, DiffType* done_count) {
156 #endif // DOXYGEN_PARSING
253 template <
class Iterator,
class Func>
259 typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
260 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
264 DiffType start_count = 0;
265 DiffType done_count = 0;
271 Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
281 for (; first != last; ++first, ++start_count) {
282 #ifdef CGU_USE_AUTO_PTR
283 typedef std::auto_ptr<const Callback::Callback> CbPtr;
285 typedef std::unique_ptr<const Callback::Callback> CbPtr;
300 tm.
add_task(std::move(task_cb), std::move(fail_cb));
304 while (start_count > done_count) cond.
wait(mutex);
440 template <
class SourceIterator,
class DestIterator,
class Func>
442 SourceIterator first,
447 if (first == last)
return;
449 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
450 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
451 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
456 typedef decltype(func(*first)) DestType;
460 DiffType start_count = 0;
461 DiffType done_count = 0;
467 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first, last)]);
473 std::forward<Func>(func))
483 for (; first != last; ++first, ++start_count) {
484 #ifdef CGU_USE_AUTO_PTR
485 typedef std::auto_ptr<const Callback::Callback> CbPtr;
487 typedef std::unique_ptr<const Callback::Callback> CbPtr;
490 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
503 tm.
add_task(std::move(task_cb), std::move(fail_cb));
507 while (start_count > done_count) cond.
wait(mutex);
509 for (DiffType index = 0; index < start_count; ++dest, ++index) {
510 *dest = std::move(results[index]);
651 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
653 SourceIterator1 first1,
654 SourceIterator1 last1,
655 SourceIterator2 first2,
659 if (first1 == last1)
return;
661 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
662 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
663 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
664 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
669 typedef decltype(func(*first1, *first2)) DestType;
673 DiffType start_count = 0;
674 DiffType done_count = 0;
680 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first1, last1)]);
686 std::forward<Func>(func))
696 for (; first1 != last1; ++first1, ++first2, ++start_count) {
697 #ifdef CGU_USE_AUTO_PTR
698 typedef std::auto_ptr<const Callback::Callback> CbPtr;
700 typedef std::unique_ptr<const Callback::Callback> CbPtr;
703 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
717 tm.
add_task(std::move(task_cb), std::move(fail_cb));
721 while (start_count > done_count) cond.
wait(mutex);
723 for (DiffType index = 0; index < start_count; ++dest, ++index) {
724 *dest = std::move(results[index]);
843 template <
class Iterator,
class Func>
850 if (first == last || !max)
return first;
852 typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
853 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
857 DiffType start_count = 0;
858 DiffType done_count = 0;
866 const DiffType local_max =
867 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
872 Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
882 for (; first != last && start_count < local_max; ++first, ++start_count) {
883 #ifdef CGU_USE_AUTO_PTR
884 typedef std::auto_ptr<const Callback::Callback> CbPtr;
886 typedef std::unique_ptr<const Callback::Callback> CbPtr;
900 tm.
add_task(std::move(task_cb), std::move(fail_cb));
904 while (start_count > done_count) cond.
wait(mutex);
1043 template <
class SourceIterator,
class DestIterator,
class Func>
1044 std::pair<SourceIterator, DestIterator>
1046 SourceIterator first,
1047 SourceIterator last,
1052 if (first == last || !max)
return {first, dest};
1054 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
1055 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
1056 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1061 typedef decltype(func(*first)) DestType;
1065 DiffType start_count = 0;
1066 DiffType done_count = 0;
1074 const DiffType local_max =
1075 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1080 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1081 std::distance(first, last))]);
1087 std::forward<Func>(func))
1097 for (; first != last && start_count < local_max; ++first, ++start_count) {
1098 #ifdef CGU_USE_AUTO_PTR
1099 typedef std::auto_ptr<const Callback::Callback> CbPtr;
1101 typedef std::unique_ptr<const Callback::Callback> CbPtr;
1104 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
1117 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1121 while (start_count > done_count) cond.
wait(mutex);
1123 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1124 *dest = std::move(results[index]);
1126 return {first, dest};
1271 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
1272 std::tuple<SourceIterator1, SourceIterator2, DestIterator>
1274 SourceIterator1 first1,
1275 SourceIterator1 last1,
1276 SourceIterator2 first2,
1281 if (first1 == last1 || !max)
return std::make_tuple(first1, first2, dest);
1283 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
1284 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
1285 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
1286 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1291 typedef decltype(func(*first1, *first2)) DestType;
1295 DiffType start_count = 0;
1296 DiffType done_count = 0;
1304 const DiffType local_max =
1305 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1310 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1311 std::distance(first1, last1))]);
1317 std::forward<Func>(func))
1327 for (; first1 != last1 && start_count < local_max; ++first1, ++first2, ++start_count) {
1328 #ifdef CGU_USE_AUTO_PTR
1329 typedef std::auto_ptr<const Callback::Callback> CbPtr;
1331 typedef std::unique_ptr<const Callback::Callback> CbPtr;
1334 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
1348 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1352 while (start_count > done_count) cond.
wait(mutex);
1354 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1355 *dest = std::move(results[index]);
1357 return std::make_tuple(first1, first2, dest);
1637 return *iter1 == *iter2;
1657 return !(iter1 == iter2);
1677 return *iter1 < *iter2;
1697 return iter2 < iter1;
1717 return !(iter1 > iter2);
1737 return !(iter1 < iter2);
1757 return *iter1 - *iter2;
1822 #endif // CGU_PARALLEL_H