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) {
154 #endif // DOXYGEN_PARSING
254 template <
class Iterator,
class Func>
260 typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
261 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
265 DiffType start_count = 0;
266 DiffType done_count = 0;
272 Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
282 for (; first != last; ++first, ++start_count) {
283 #ifdef CGU_USE_AUTO_PTR
284 typedef std::auto_ptr<const Callback::Callback> CbPtr;
286 typedef std::unique_ptr<const Callback::Callback> CbPtr;
301 tm.
add_task(std::move(task_cb), std::move(fail_cb));
305 while (start_count > done_count) cond.
wait(mutex);
444 template <
class SourceIterator,
class DestIterator,
class Func>
446 SourceIterator first,
451 if (first == last)
return;
453 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
454 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
455 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
460 typedef decltype(func(*first)) DestType;
464 DiffType start_count = 0;
465 DiffType done_count = 0;
471 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first, last)]);
477 std::forward<Func>(func))
487 for (; first != last; ++first, ++start_count) {
488 #ifdef CGU_USE_AUTO_PTR
489 typedef std::auto_ptr<const Callback::Callback> CbPtr;
491 typedef std::unique_ptr<const Callback::Callback> CbPtr;
494 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
500 results.get() + start_count))
506 tm.
add_task(std::move(task_cb), std::move(fail_cb));
510 while (start_count > done_count) cond.
wait(mutex);
512 for (DiffType index = 0; index < start_count; ++dest, ++index) {
513 *dest = std::move(results[index]);
657 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
659 SourceIterator1 first1,
660 SourceIterator1 last1,
661 SourceIterator2 first2,
665 if (first1 == last1)
return;
667 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
668 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
669 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
670 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
675 typedef decltype(func(*first1, *first2)) DestType;
679 DiffType start_count = 0;
680 DiffType done_count = 0;
686 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first1, last1)]);
692 std::forward<Func>(func))
702 for (; first1 != last1; ++first1, ++first2, ++start_count) {
703 #ifdef CGU_USE_AUTO_PTR
704 typedef std::auto_ptr<const Callback::Callback> CbPtr;
706 typedef std::unique_ptr<const Callback::Callback> CbPtr;
709 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
716 results.get() + start_count))
722 tm.
add_task(std::move(task_cb), std::move(fail_cb));
726 while (start_count > done_count) cond.
wait(mutex);
728 for (DiffType index = 0; index < start_count; ++dest, ++index) {
729 *dest = std::move(results[index]);
851 template <
class Iterator,
class Func>
858 if (first == last || !max)
return first;
860 typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
861 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
865 DiffType start_count = 0;
866 DiffType done_count = 0;
874 const DiffType local_max =
875 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
880 Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
890 for (; first != last && start_count < local_max; ++first, ++start_count) {
891 #ifdef CGU_USE_AUTO_PTR
892 typedef std::auto_ptr<const Callback::Callback> CbPtr;
894 typedef std::unique_ptr<const Callback::Callback> CbPtr;
908 tm.
add_task(std::move(task_cb), std::move(fail_cb));
912 while (start_count > done_count) cond.
wait(mutex);
1054 template <
class SourceIterator,
class DestIterator,
class Func>
1055 std::pair<SourceIterator, DestIterator>
1057 SourceIterator first,
1058 SourceIterator last,
1063 if (first == last || !max)
return {first, dest};
1065 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
1066 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
1067 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1072 typedef decltype(func(*first)) DestType;
1076 DiffType start_count = 0;
1077 DiffType done_count = 0;
1085 const DiffType local_max =
1086 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1091 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1092 std::distance(first, last))]);
1098 std::forward<Func>(func))
1108 for (; first != last && start_count < local_max; ++first, ++start_count) {
1109 #ifdef CGU_USE_AUTO_PTR
1110 typedef std::auto_ptr<const Callback::Callback> CbPtr;
1112 typedef std::unique_ptr<const Callback::Callback> CbPtr;
1115 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
1121 results.get() + start_count))
1127 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1131 while (start_count > done_count) cond.
wait(mutex);
1133 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1134 *dest = std::move(results[index]);
1136 return {first, dest};
1284 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
1285 std::tuple<SourceIterator1, SourceIterator2, DestIterator>
1287 SourceIterator1 first1,
1288 SourceIterator1 last1,
1289 SourceIterator2 first2,
1294 if (first1 == last1 || !max)
return std::make_tuple(first1, first2, dest);
1296 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
1297 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
1298 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
1299 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1304 typedef decltype(func(*first1, *first2)) DestType;
1308 DiffType start_count = 0;
1309 DiffType done_count = 0;
1317 const DiffType local_max =
1318 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1323 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1324 std::distance(first1, last1))]);
1330 std::forward<Func>(func))
1340 for (; first1 != last1 && start_count < local_max; ++first1, ++first2, ++start_count) {
1341 #ifdef CGU_USE_AUTO_PTR
1342 typedef std::auto_ptr<const Callback::Callback> CbPtr;
1344 typedef std::unique_ptr<const Callback::Callback> CbPtr;
1347 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
1354 results.get() + start_count))
1360 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1364 while (start_count > done_count) cond.
wait(mutex);
1366 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1367 *dest = std::move(results[index]);
1369 return std::make_tuple(first1, first2, dest);
1649 return *iter1 == *iter2;
1669 return !(iter1 == iter2);
1689 return *iter1 < *iter2;
1709 return iter2 < iter1;
1729 return !(iter1 > iter2);
1749 return !(iter1 < iter2);
1769 return *iter1 - *iter2;
1834 #endif // CGU_PARALLEL_H