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
247 template <
class Iterator,
class Func>
253 typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
254 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
258 DiffType start_count = 0;
259 DiffType done_count = 0;
265 Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
275 for (; first != last; ++first, ++start_count) {
276 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
284 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
285 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
288 tm.
add_task(std::move(task_cb), std::move(fail_cb));
292 while (start_count > done_count) cond.
wait(mutex);
425 template <
class SourceIterator,
class DestIterator,
class Func>
427 SourceIterator first,
432 if (first == last)
return;
434 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
435 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
436 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
437 typedef decltype(func(*first)) DestType;
441 DiffType start_count = 0;
442 DiffType done_count = 0;
448 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first, last)]);
454 std::forward<Func>(func))
464 for (; first != last; ++first, ++start_count) {
465 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
466 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
475 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
476 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
479 tm.
add_task(std::move(task_cb), std::move(fail_cb));
483 while (start_count > done_count) cond.
wait(mutex);
485 for (DiffType index = 0; index < start_count; ++dest, ++index) {
486 *dest = std::move(results[index]);
624 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
626 SourceIterator1 first1,
627 SourceIterator1 last1,
628 SourceIterator2 first2,
632 if (first1 == last1)
return;
634 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
635 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
636 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
637 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
638 typedef decltype(func(*first1, *first2)) DestType;
642 DiffType start_count = 0;
643 DiffType done_count = 0;
649 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first1, last1)]);
655 std::forward<Func>(func))
665 for (; first1 != last1; ++first1, ++first2, ++start_count) {
666 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
667 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
677 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
678 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
681 tm.
add_task(std::move(task_cb), std::move(fail_cb));
685 while (start_count > done_count) cond.
wait(mutex);
687 for (DiffType index = 0; index < start_count; ++dest, ++index) {
688 *dest = std::move(results[index]);
808 template <
class Iterator,
class Func>
815 if (first == last || !max)
return first;
817 typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
818 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
822 DiffType start_count = 0;
823 DiffType done_count = 0;
831 const DiffType local_max =
832 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
837 Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
847 for (; first != last && start_count < local_max; ++first, ++start_count) {
848 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
856 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
857 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
860 tm.
add_task(std::move(task_cb), std::move(fail_cb));
864 while (start_count > done_count) cond.
wait(mutex);
1004 template <
class SourceIterator,
class DestIterator,
class Func>
1005 std::pair<SourceIterator, DestIterator>
1007 SourceIterator first,
1008 SourceIterator last,
1013 if (first == last || !max)
return {first, dest};
1015 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
1016 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
1017 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1018 typedef decltype(func(*first)) DestType;
1022 DiffType start_count = 0;
1023 DiffType done_count = 0;
1031 const DiffType local_max =
1032 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1037 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1038 std::distance(first, last))]);
1044 std::forward<Func>(func))
1054 for (; first != last && start_count < local_max; ++first, ++start_count) {
1055 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
1056 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
1065 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
1066 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
1069 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1073 while (start_count > done_count) cond.
wait(mutex);
1075 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1076 *dest = std::move(results[index]);
1078 return {first, dest};
1224 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
1225 std::tuple<SourceIterator1, SourceIterator2, DestIterator>
1227 SourceIterator1 first1,
1228 SourceIterator1 last1,
1229 SourceIterator2 first2,
1234 if (first1 == last1 || !max)
return std::make_tuple(first1, first2, dest);
1236 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
1237 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
1238 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
1239 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1240 typedef decltype(func(*first1, *first2)) DestType;
1244 DiffType start_count = 0;
1245 DiffType done_count = 0;
1253 const DiffType local_max =
1254 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1259 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1260 std::distance(first1, last1))]);
1266 std::forward<Func>(func))
1276 for (; first1 != last1 && start_count < local_max; ++first1, ++first2, ++start_count) {
1277 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
1278 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
1288 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
1289 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
1292 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1296 while (start_count > done_count) cond.
wait(mutex);
1298 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1299 *dest = std::move(results[index]);
1301 return std::make_tuple(first1, first2, dest);
1574 return *iter1 == *iter2;
1594 return !(iter1 == iter2);
1614 return *iter1 < *iter2;
1634 return iter2 < iter1;
1654 return !(iter1 > iter2);
1674 return !(iter1 < iter2);
1694 return *iter1 - *iter2;
1759 #endif // CGU_PARALLEL_H