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,
100 s_task(*source_iter, res);
105 *result = std::move(res);
110 template <
class FType,
class Arg1RefType,
111 class Arg2RefType,
class DestType>
112 void transform2_func(
const FType& func,
116 res = func(arg1, arg2);
120 template <
class Arg1RefType,
class Arg2RefType,
class DestType,
121 class DiffType,
class SourceIterator1,
class SourceIterator2>
123 SourceIterator1 source_iter1,
124 SourceIterator2 source_iter2,
125 Mutex* m, Cond* cond,
126 DiffType* done_count,
129 s_task(*source_iter1, *source_iter2, res);
134 *result = std::move(res);
139 template <
class DiffType>
140 void fail_func(Mutex* m, Cond* cond,
141 bool* error, DiffType* done_count) noexcept {
150 #endif // DOXYGEN_PARSING
251 template <
class Iterator,
class Func>
257 typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
258 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
262 DiffType start_count = 0;
263 DiffType done_count = 0;
269 Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
279 for (; first != last; ++first, ++start_count) {
280 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
288 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
289 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
292 tm.
add_task(std::move(task_cb), std::move(fail_cb));
296 while (start_count > done_count) cond.
wait(mutex);
441 template <
class SourceIterator,
class DestIterator,
class Func>
443 SourceIterator first,
448 if (first == last)
return;
450 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
451 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
452 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
457 typedef decltype(func(*first)) DestType;
461 DiffType start_count = 0;
462 DiffType done_count = 0;
468 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first, last)]);
474 std::forward<Func>(func))
484 for (; first != last; ++first, ++start_count) {
485 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
486 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
492 results.get() + start_count))
494 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
495 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
498 tm.
add_task(std::move(task_cb), std::move(fail_cb));
502 while (start_count > done_count) cond.
wait(mutex);
504 for (DiffType index = 0; index < start_count; ++dest, ++index) {
505 *dest = std::move(results[index]);
655 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
657 SourceIterator1 first1,
658 SourceIterator1 last1,
659 SourceIterator2 first2,
663 if (first1 == last1)
return;
665 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
666 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
667 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
668 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
673 typedef decltype(func(*first1, *first2)) DestType;
677 DiffType start_count = 0;
678 DiffType done_count = 0;
684 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first1, last1)]);
690 std::forward<Func>(func))
700 for (; first1 != last1; ++first1, ++first2, ++start_count) {
701 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
702 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
709 results.get() + start_count))
711 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
712 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
715 tm.
add_task(std::move(task_cb), std::move(fail_cb));
719 while (start_count > done_count) cond.
wait(mutex);
721 for (DiffType index = 0; index < start_count; ++dest, ++index) {
722 *dest = std::move(results[index]);
845 template <
class Iterator,
class Func>
852 if (first == last || !max)
return first;
854 typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
855 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
859 DiffType start_count = 0;
860 DiffType done_count = 0;
868 const DiffType local_max =
869 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
874 Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
884 for (; first != last && start_count < local_max; ++first, ++start_count) {
885 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
893 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
894 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
897 tm.
add_task(std::move(task_cb), std::move(fail_cb));
901 while (start_count > done_count) cond.
wait(mutex);
1044 template <
class SourceIterator,
class DestIterator,
class Func>
1045 std::pair<SourceIterator, DestIterator>
1047 SourceIterator first,
1048 SourceIterator last,
1053 if (first == last || !max)
return {first, dest};
1055 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
1056 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
1057 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1062 typedef decltype(func(*first)) DestType;
1066 DiffType start_count = 0;
1067 DiffType done_count = 0;
1075 const DiffType local_max =
1076 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1081 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1082 std::distance(first, last))]);
1088 std::forward<Func>(func))
1098 for (; first != last && start_count < local_max; ++first, ++start_count) {
1099 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
1100 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
1106 results.get() + start_count))
1108 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
1109 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
1112 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1116 while (start_count > done_count) cond.
wait(mutex);
1118 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1119 *dest = std::move(results[index]);
1121 return {first, dest};
1270 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
1271 std::tuple<SourceIterator1, SourceIterator2, DestIterator>
1273 SourceIterator1 first1,
1274 SourceIterator1 last1,
1275 SourceIterator2 first2,
1280 if (first1 == last1 || !max)
return std::make_tuple(first1, first2, dest);
1282 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
1283 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
1284 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
1285 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1290 typedef decltype(func(*first1, *first2)) DestType;
1294 DiffType start_count = 0;
1295 DiffType done_count = 0;
1303 const DiffType local_max =
1304 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1309 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1310 std::distance(first1, last1))]);
1316 std::forward<Func>(func))
1326 for (; first1 != last1 && start_count < local_max; ++first1, ++first2, ++start_count) {
1327 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
1328 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
1335 results.get() + start_count))
1337 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
1338 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
1341 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1345 while (start_count > done_count) cond.
wait(mutex);
1347 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1348 *dest = std::move(results[index]);
1350 return std::make_tuple(first1, first2, dest);
1632 return *iter1 == *iter2;
1652 return !(iter1 == iter2);
1672 return *iter1 < *iter2;
1692 return iter2 < iter1;
1712 return !(iter1 > iter2);
1732 return !(iter1 < iter2);
1752 return *iter1 - *iter2;
1817 #endif // CGU_PARALLEL_H