39 #ifndef CGU_PARALLEL_H
40 #define CGU_PARALLEL_H
47 #include <type_traits>
59 virtual const char*
what()
const throw() {
return "ParallelError\n";}
62 #ifndef DOXYGEN_PARSING
64 namespace ParallelHelper {
66 template <
class ArgType,
class DiffType,
class Iterator>
70 DiffType* remaining) {
77 template <
class FType,
class ArgType,
class DestType>
78 void transform1_func(
const FType& func,
85 template <
class ArgType,
class DestType,
class DiffType,
class SourceIterator>
91 DiffType* remaining) {
98 results[index] = std::move(res);
103 template <
class FType,
class Arg1Type,
104 class Arg2Type,
class DestType>
105 void transform2_func(
const FType& func,
109 res = func(arg1, arg2);
113 template <
class Arg1Type,
class Arg2Type,
class DestType,
114 class DiffType,
class SourceIterator1,
class SourceIterator2>
116 SourceIterator1 iter1,
117 SourceIterator2 iter2,
118 Mutex* m, Cond* cond,
121 DiffType* remaining) {
123 s_task(*iter1, *iter2, res);
128 results[index] = std::move(res);
133 template <
class DiffType>
134 void fail_func(Mutex* m, Cond* cond,
135 bool* error, DiffType* remaining) {
144 #endif // DOXYGEN_PARSING
227 template <
class Iterator,
class Func>
233 typedef typename std::iterator_traits<Iterator>::value_type ArgType;
234 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
236 DiffType remaining = std::distance(first, last);
245 Cgu::Callback::lambda<ArgType&>(std::forward<Func>(func))
255 for (; first != last; ++first) {
256 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
264 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
265 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
268 tm.
add_task(std::move(task_cb), std::move(fail_cb));
272 while (remaining > 0) cond.
wait(mutex);
390 template <
class SourceIterator,
class DestIterator,
class Func>
392 SourceIterator first,
397 if (first == last)
return;
399 typedef typename std::iterator_traits<SourceIterator>::value_type ArgType;
400 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
401 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
402 typedef decltype(func(*first)) DestType;
404 DiffType elts = std::distance(first, last);
405 DiffType remaining = elts;
416 std::forward<Func>(func))
426 for (DiffType index = 0; first != last; ++first, ++index) {
427 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
428 Cgu::Callback::lambda<>(std::bind(&ParallelHelper::transform1_cb_func<ArgType, DestType, DiffType, SourceIterator>,
437 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
438 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
441 tm.
add_task(std::move(task_cb), std::move(fail_cb));
445 while (remaining > 0) cond.
wait(mutex);
447 for (DiffType index = 0; index < elts; ++dest, ++index) {
448 *dest = std::move(results[index]);
571 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
573 SourceIterator1 first1,
574 SourceIterator1 last1,
575 SourceIterator2 first2,
579 if (first1 == last1)
return;
581 typedef typename std::iterator_traits<SourceIterator1>::value_type Arg1Type;
582 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
583 typedef typename std::iterator_traits<SourceIterator2>::value_type Arg2Type;
584 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
585 typedef decltype(func(*first1, *first2)) DestType;
587 DiffType elts = std::distance(first1, last1);
588 DiffType remaining = elts;
599 std::forward<Func>(func))
609 for (DiffType index = 0; first1 != last1; ++first1, ++first2, ++index) {
610 std::unique_ptr<const Cgu::Callback::Callback> task_cb(
611 Cgu::Callback::lambda<>(std::bind(&ParallelHelper::transform2_cb_func<Arg1Type, Arg2Type, DestType, DiffType, SourceIterator1, SourceIterator2>,
621 std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
622 Cgu::Callback::lambda<>([s_fail] () {s_fail();})
625 tm.
add_task(std::move(task_cb), std::move(fail_cb));
629 while (remaining > 0) cond.
wait(mutex);
631 for (DiffType index = 0; index < elts; ++dest, ++index) {
632 *dest = std::move(results[index]);
640 #endif // CGU_PARALLEL_H