39 #ifndef CGU_PARALLEL_H
40 #define CGU_PARALLEL_H
47 #include <type_traits>
61 virtual const char*
what()
const throw() {
return "ParallelError\n";}
64 #ifndef DOXYGEN_PARSING
71 namespace ParallelHelper2 {
73 template <
class ArgType,
class DiffType,
class Iterator>
77 DiffType* done_count) {
84 template <
class FType,
class ArgType,
class DestType>
85 void transform1_func(
const FType& func,
92 template <
class ArgType,
class DestType,
class DiffType,
class SourceIterator>
94 SourceIterator source_iter,
100 s_task(*source_iter, res);
105 results[index] = std::move(res);
110 template <
class FType,
class Arg1Type,
111 class Arg2Type,
class DestType>
112 void transform2_func(
const FType& func,
116 res = func(arg1, arg2);
120 template <
class Arg1Type,
class Arg2Type,
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,
130 s_task(*source_iter1, *source_iter2, res);
135 results[index] = std::move(res);
140 template <
class DiffType>
141 void fail_func(Mutex* m, Cond* cond,
142 bool* error, DiffType* done_count) noexcept {
151 #endif // DOXYGEN_PARSING
237 template <
class Iterator,
class Func>
243 typedef typename std::iterator_traits<Iterator>::value_type ArgType;
244 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
248 DiffType start_count = 0;
249 DiffType done_count = 0;
255 Cgu::Callback::lambda<ArgType&>(std::forward<Func>(func))
265 for (; first != last; ++first, ++start_count) {
266 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
274 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
275 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
278 tm.
add_task(std::move(task_cb), std::move(fail_cb));
282 while (start_count > done_count) cond.
wait(mutex);
407 template <
class SourceIterator,
class DestIterator,
class Func>
409 SourceIterator first,
414 if (first == last)
return;
416 typedef typename std::iterator_traits<SourceIterator>::value_type ArgType;
417 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
418 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
419 typedef decltype(func(*first)) DestType;
423 DiffType start_count = 0;
424 DiffType done_count = 0;
430 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first, last)]);
436 std::forward<Func>(func))
446 for (; first != last; ++first, ++start_count) {
447 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
448 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgType, DestType, DiffType, SourceIterator>,
457 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
458 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
461 tm.
add_task(std::move(task_cb), std::move(fail_cb));
465 while (start_count > done_count) cond.
wait(mutex);
467 for (DiffType index = 0; index < start_count; ++dest, ++index) {
468 *dest = std::move(results[index]);
598 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
600 SourceIterator1 first1,
601 SourceIterator1 last1,
602 SourceIterator2 first2,
606 if (first1 == last1)
return;
608 typedef typename std::iterator_traits<SourceIterator1>::value_type Arg1Type;
609 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
610 typedef typename std::iterator_traits<SourceIterator2>::value_type Arg2Type;
611 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
612 typedef decltype(func(*first1, *first2)) DestType;
616 DiffType start_count = 0;
617 DiffType done_count = 0;
623 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first1, last1)]);
629 std::forward<Func>(func))
639 for (; first1 != last1; ++first1, ++first2, ++start_count) {
640 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
641 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1Type, Arg2Type, DestType, DiffType, SourceIterator1, SourceIterator2>,
651 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
652 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
655 tm.
add_task(std::move(task_cb), std::move(fail_cb));
659 while (start_count > done_count) cond.
wait(mutex);
661 for (DiffType index = 0; index < start_count; ++dest, ++index) {
662 *dest = std::move(results[index]);
778 template <
class Iterator,
class Func>
785 if (first == last || !max)
return first;
787 typedef typename std::iterator_traits<Iterator>::value_type ArgType;
788 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
792 DiffType start_count = 0;
793 DiffType done_count = 0;
801 const DiffType local_max =
802 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
807 Cgu::Callback::lambda<ArgType&>(std::forward<Func>(func))
817 for (; first != last && start_count < local_max; ++first, ++start_count) {
818 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
826 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
827 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
830 tm.
add_task(std::move(task_cb), std::move(fail_cb));
834 while (start_count > done_count) cond.
wait(mutex);
970 template <
class SourceIterator,
class DestIterator,
class Func>
971 std::pair<SourceIterator, DestIterator>
973 SourceIterator first,
979 if (first == last || !max)
return {first, dest};
981 typedef typename std::iterator_traits<SourceIterator>::value_type ArgType;
982 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
983 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
984 typedef decltype(func(*first)) DestType;
988 DiffType start_count = 0;
989 DiffType done_count = 0;
997 const DiffType local_max =
998 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1003 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1004 std::distance(first, last))]);
1010 std::forward<Func>(func))
1020 for (; first != last && start_count < local_max; ++first, ++start_count) {
1021 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
1022 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgType, DestType, DiffType, SourceIterator>,
1031 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
1032 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
1035 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1039 while (start_count > done_count) cond.
wait(mutex);
1041 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1042 *dest = std::move(results[index]);
1044 return {first, dest};
1186 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
1187 std::tuple<SourceIterator1, SourceIterator2, DestIterator>
1189 SourceIterator1 first1,
1190 SourceIterator1 last1,
1191 SourceIterator2 first2,
1196 if (first1 == last1 || !max)
return std::make_tuple(first1, first2, dest);
1198 typedef typename std::iterator_traits<SourceIterator1>::value_type Arg1Type;
1199 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
1200 typedef typename std::iterator_traits<SourceIterator2>::value_type Arg2Type;
1201 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1202 typedef decltype(func(*first1, *first2)) DestType;
1206 DiffType start_count = 0;
1207 DiffType done_count = 0;
1215 const DiffType local_max =
1216 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1221 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1222 std::distance(first1, last1))]);
1228 std::forward<Func>(func))
1238 for (; first1 != last1 && start_count < local_max; ++first1, ++first2, ++start_count) {
1239 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
1240 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1Type, Arg2Type, DestType, DiffType, SourceIterator1, SourceIterator2>,
1250 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
1251 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
1254 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1258 while (start_count > done_count) cond.
wait(mutex);
1260 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1261 *dest = std::move(results[index]);
1263 return std::make_tuple(first1, first2, dest);
1270 #endif // CGU_PARALLEL_H