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 ArgType,
class DiffType,
class Iterator>
78 DiffType* done_count) {
85 template <
class FType,
class ArgType,
class DestType>
86 void transform1_func(
const FType& func,
93 template <
class ArgType,
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 Arg1Type,
112 class Arg2Type,
class DestType>
113 void transform2_func(
const FType& func,
117 res = func(arg1, arg2);
121 template <
class Arg1Type,
class Arg2Type,
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) noexcept {
152 #endif // DOXYGEN_PARSING
243 template <
class Iterator,
class Func>
249 typedef typename std::iterator_traits<Iterator>::value_type ArgType;
250 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
254 DiffType start_count = 0;
255 DiffType done_count = 0;
261 Cgu::Callback::lambda<ArgType&>(std::forward<Func>(func))
271 for (; first != last; ++first, ++start_count) {
272 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
280 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
281 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
284 tm.
add_task(std::move(task_cb), std::move(fail_cb));
288 while (start_count > done_count) cond.
wait(mutex);
417 template <
class SourceIterator,
class DestIterator,
class Func>
419 SourceIterator first,
424 if (first == last)
return;
426 typedef typename std::iterator_traits<SourceIterator>::value_type ArgType;
427 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
428 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
429 typedef decltype(func(*first)) DestType;
433 DiffType start_count = 0;
434 DiffType done_count = 0;
440 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first, last)]);
446 std::forward<Func>(func))
456 for (; first != last; ++first, ++start_count) {
457 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
458 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgType, DestType, DiffType, SourceIterator>,
467 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
468 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
471 tm.
add_task(std::move(task_cb), std::move(fail_cb));
475 while (start_count > done_count) cond.
wait(mutex);
477 for (DiffType index = 0; index < start_count; ++dest, ++index) {
478 *dest = std::move(results[index]);
612 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
614 SourceIterator1 first1,
615 SourceIterator1 last1,
616 SourceIterator2 first2,
620 if (first1 == last1)
return;
622 typedef typename std::iterator_traits<SourceIterator1>::value_type Arg1Type;
623 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
624 typedef typename std::iterator_traits<SourceIterator2>::value_type Arg2Type;
625 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
626 typedef decltype(func(*first1, *first2)) DestType;
630 DiffType start_count = 0;
631 DiffType done_count = 0;
637 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first1, last1)]);
643 std::forward<Func>(func))
653 for (; first1 != last1; ++first1, ++first2, ++start_count) {
654 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
655 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1Type, Arg2Type, DestType, DiffType, SourceIterator1, SourceIterator2>,
665 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
666 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
669 tm.
add_task(std::move(task_cb), std::move(fail_cb));
673 while (start_count > done_count) cond.
wait(mutex);
675 for (DiffType index = 0; index < start_count; ++dest, ++index) {
676 *dest = std::move(results[index]);
792 template <
class Iterator,
class Func>
799 if (first == last || !max)
return first;
801 typedef typename std::iterator_traits<Iterator>::value_type ArgType;
802 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
806 DiffType start_count = 0;
807 DiffType done_count = 0;
815 const DiffType local_max =
816 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
821 Cgu::Callback::lambda<ArgType&>(std::forward<Func>(func))
831 for (; first != last && start_count < local_max; ++first, ++start_count) {
832 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
840 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
841 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
844 tm.
add_task(std::move(task_cb), std::move(fail_cb));
848 while (start_count > done_count) cond.
wait(mutex);
984 template <
class SourceIterator,
class DestIterator,
class Func>
985 std::pair<SourceIterator, DestIterator>
987 SourceIterator first,
993 if (first == last || !max)
return {first, dest};
995 typedef typename std::iterator_traits<SourceIterator>::value_type ArgType;
996 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
997 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
998 typedef decltype(func(*first)) DestType;
1002 DiffType start_count = 0;
1003 DiffType done_count = 0;
1011 const DiffType local_max =
1012 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1017 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1018 std::distance(first, last))]);
1024 std::forward<Func>(func))
1034 for (; first != last && start_count < local_max; ++first, ++start_count) {
1035 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
1036 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgType, DestType, DiffType, SourceIterator>,
1045 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
1046 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
1049 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1053 while (start_count > done_count) cond.
wait(mutex);
1055 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1056 *dest = std::move(results[index]);
1058 return {first, dest};
1200 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
1201 std::tuple<SourceIterator1, SourceIterator2, DestIterator>
1203 SourceIterator1 first1,
1204 SourceIterator1 last1,
1205 SourceIterator2 first2,
1210 if (first1 == last1 || !max)
return std::make_tuple(first1, first2, dest);
1212 typedef typename std::iterator_traits<SourceIterator1>::value_type Arg1Type;
1213 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
1214 typedef typename std::iterator_traits<SourceIterator2>::value_type Arg2Type;
1215 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1216 typedef decltype(func(*first1, *first2)) DestType;
1220 DiffType start_count = 0;
1221 DiffType done_count = 0;
1229 const DiffType local_max =
1230 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1235 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1236 std::distance(first1, last1))]);
1242 std::forward<Func>(func))
1252 for (; first1 != last1 && start_count < local_max; ++first1, ++first2, ++start_count) {
1253 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
1254 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1Type, Arg2Type, DestType, DiffType, SourceIterator1, SourceIterator2>,
1264 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
1265 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
1268 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1272 while (start_count > done_count) cond.
wait(mutex);
1274 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1275 *dest = std::move(results[index]);
1277 return std::make_tuple(first1, first2, dest);
1284 #endif // CGU_PARALLEL_H