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) noexcept {
152 #endif // DOXYGEN_PARSING
250 template <
class Iterator,
class Func>
256 typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
257 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
261 DiffType start_count = 0;
262 DiffType done_count = 0;
268 Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
278 for (; first != last; ++first, ++start_count) {
279 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
287 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
288 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
291 tm.
add_task(std::move(task_cb), std::move(fail_cb));
295 while (start_count > done_count) cond.
wait(mutex);
432 template <
class SourceIterator,
class DestIterator,
class Func>
434 SourceIterator first,
439 if (first == last)
return;
441 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
442 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
443 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
448 typedef decltype(func(*first)) DestType;
452 DiffType start_count = 0;
453 DiffType done_count = 0;
459 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first, last)]);
465 std::forward<Func>(func))
475 for (; first != last; ++first, ++start_count) {
476 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
477 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
486 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
487 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
490 tm.
add_task(std::move(task_cb), std::move(fail_cb));
494 while (start_count > done_count) cond.
wait(mutex);
496 for (DiffType index = 0; index < start_count; ++dest, ++index) {
497 *dest = std::move(results[index]);
639 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
641 SourceIterator1 first1,
642 SourceIterator1 last1,
643 SourceIterator2 first2,
647 if (first1 == last1)
return;
649 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
650 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
651 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
652 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
657 typedef decltype(func(*first1, *first2)) DestType;
661 DiffType start_count = 0;
662 DiffType done_count = 0;
668 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first1, last1)]);
674 std::forward<Func>(func))
684 for (; first1 != last1; ++first1, ++first2, ++start_count) {
685 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
686 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
696 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
697 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
700 tm.
add_task(std::move(task_cb), std::move(fail_cb));
704 while (start_count > done_count) cond.
wait(mutex);
706 for (DiffType index = 0; index < start_count; ++dest, ++index) {
707 *dest = std::move(results[index]);
827 template <
class Iterator,
class Func>
834 if (first == last || !max)
return first;
836 typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
837 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
841 DiffType start_count = 0;
842 DiffType done_count = 0;
850 const DiffType local_max =
851 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
856 Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
866 for (; first != last && start_count < local_max; ++first, ++start_count) {
867 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
875 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
876 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
879 tm.
add_task(std::move(task_cb), std::move(fail_cb));
883 while (start_count > done_count) cond.
wait(mutex);
1023 template <
class SourceIterator,
class DestIterator,
class Func>
1024 std::pair<SourceIterator, DestIterator>
1026 SourceIterator first,
1027 SourceIterator last,
1032 if (first == last || !max)
return {first, dest};
1034 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
1035 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
1036 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1041 typedef decltype(func(*first)) DestType;
1045 DiffType start_count = 0;
1046 DiffType done_count = 0;
1054 const DiffType local_max =
1055 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1060 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1061 std::distance(first, last))]);
1067 std::forward<Func>(func))
1077 for (; first != last && start_count < local_max; ++first, ++start_count) {
1078 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
1079 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
1088 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
1089 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
1092 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1096 while (start_count > done_count) cond.
wait(mutex);
1098 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1099 *dest = std::move(results[index]);
1101 return {first, dest};
1247 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
1248 std::tuple<SourceIterator1, SourceIterator2, DestIterator>
1250 SourceIterator1 first1,
1251 SourceIterator1 last1,
1252 SourceIterator2 first2,
1257 if (first1 == last1 || !max)
return std::make_tuple(first1, first2, dest);
1259 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
1260 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
1261 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
1262 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1267 typedef decltype(func(*first1, *first2)) DestType;
1271 DiffType start_count = 0;
1272 DiffType done_count = 0;
1280 const DiffType local_max =
1281 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1286 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1287 std::distance(first1, last1))]);
1293 std::forward<Func>(func))
1303 for (; first1 != last1 && start_count < local_max; ++first1, ++first2, ++start_count) {
1304 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
1305 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
1315 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
1316 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
1319 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1323 while (start_count > done_count) cond.
wait(mutex);
1325 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1326 *dest = std::move(results[index]);
1328 return std::make_tuple(first1, first2, dest);
1610 return *iter1 == *iter2;
1630 return !(iter1 == iter2);
1650 return *iter1 < *iter2;
1670 return iter2 < iter1;
1690 return !(iter1 > iter2);
1710 return !(iter1 < iter2);
1730 return *iter1 - *iter2;
1795 #endif // CGU_PARALLEL_H