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) {
156 #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 #ifdef CGU_USE_AUTO_PTR
280 typedef std::auto_ptr<const Callback::Callback> CbPtr;
282 typedef std::unique_ptr<const Callback::Callback> CbPtr;
297 tm.
add_task(std::move(task_cb), std::move(fail_cb));
301 while (start_count > done_count) cond.
wait(mutex);
433 template <
class SourceIterator,
class DestIterator,
class Func>
435 SourceIterator first,
440 if (first == last)
return;
442 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
443 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
444 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
445 typedef decltype(func(*first)) DestType;
449 DiffType start_count = 0;
450 DiffType done_count = 0;
456 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first, last)]);
462 std::forward<Func>(func))
472 for (; first != last; ++first, ++start_count) {
473 #ifdef CGU_USE_AUTO_PTR
474 typedef std::auto_ptr<const Callback::Callback> CbPtr;
476 typedef std::unique_ptr<const Callback::Callback> CbPtr;
479 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
492 tm.
add_task(std::move(task_cb), std::move(fail_cb));
496 while (start_count > done_count) cond.
wait(mutex);
498 for (DiffType index = 0; index < start_count; ++dest, ++index) {
499 *dest = std::move(results[index]);
636 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
638 SourceIterator1 first1,
639 SourceIterator1 last1,
640 SourceIterator2 first2,
644 if (first1 == last1)
return;
646 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
647 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
648 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
649 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
650 typedef decltype(func(*first1, *first2)) DestType;
654 DiffType start_count = 0;
655 DiffType done_count = 0;
661 std::unique_ptr<DestType[]> results(
new DestType[std::distance(first1, last1)]);
667 std::forward<Func>(func))
677 for (; first1 != last1; ++first1, ++first2, ++start_count) {
678 #ifdef CGU_USE_AUTO_PTR
679 typedef std::auto_ptr<const Callback::Callback> CbPtr;
681 typedef std::unique_ptr<const Callback::Callback> CbPtr;
684 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
698 tm.
add_task(std::move(task_cb), std::move(fail_cb));
702 while (start_count > done_count) cond.
wait(mutex);
704 for (DiffType index = 0; index < start_count; ++dest, ++index) {
705 *dest = std::move(results[index]);
824 template <
class Iterator,
class Func>
831 if (first == last || !max)
return first;
833 typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
834 typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
838 DiffType start_count = 0;
839 DiffType done_count = 0;
847 const DiffType local_max =
848 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
853 Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
863 for (; first != last && start_count < local_max; ++first, ++start_count) {
864 #ifdef CGU_USE_AUTO_PTR
865 typedef std::auto_ptr<const Callback::Callback> CbPtr;
867 typedef std::unique_ptr<const Callback::Callback> CbPtr;
881 tm.
add_task(std::move(task_cb), std::move(fail_cb));
885 while (start_count > done_count) cond.
wait(mutex);
1024 template <
class SourceIterator,
class DestIterator,
class Func>
1025 std::pair<SourceIterator, DestIterator>
1027 SourceIterator first,
1028 SourceIterator last,
1033 if (first == last || !max)
return {first, dest};
1035 typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
1036 typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
1037 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1038 typedef decltype(func(*first)) DestType;
1042 DiffType start_count = 0;
1043 DiffType done_count = 0;
1051 const DiffType local_max =
1052 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1057 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1058 std::distance(first, last))]);
1064 std::forward<Func>(func))
1074 for (; first != last && start_count < local_max; ++first, ++start_count) {
1075 #ifdef CGU_USE_AUTO_PTR
1076 typedef std::auto_ptr<const Callback::Callback> CbPtr;
1078 typedef std::unique_ptr<const Callback::Callback> CbPtr;
1081 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
1094 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1098 while (start_count > done_count) cond.
wait(mutex);
1100 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1101 *dest = std::move(results[index]);
1103 return {first, dest};
1248 template <
class SourceIterator1,
class SourceIterator2,
class DestIterator,
class Func>
1249 std::tuple<SourceIterator1, SourceIterator2, DestIterator>
1251 SourceIterator1 first1,
1252 SourceIterator1 last1,
1253 SourceIterator2 first2,
1258 if (first1 == last1 || !max)
return std::make_tuple(first1, first2, dest);
1260 typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
1261 typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
1262 typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
1263 typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1264 typedef decltype(func(*first1, *first2)) DestType;
1268 DiffType start_count = 0;
1269 DiffType done_count = 0;
1277 const DiffType local_max =
1278 (max >= 0) ? max : std::numeric_limits<DiffType>::max();
1283 std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
1284 std::distance(first1, last1))]);
1290 std::forward<Func>(func))
1300 for (; first1 != last1 && start_count < local_max; ++first1, ++first2, ++start_count) {
1301 #ifdef CGU_USE_AUTO_PTR
1302 typedef std::auto_ptr<const Callback::Callback> CbPtr;
1304 typedef std::unique_ptr<const Callback::Callback> CbPtr;
1307 Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
1321 tm.
add_task(std::move(task_cb), std::move(fail_cb));
1325 while (start_count > done_count) cond.
wait(mutex);
1327 for (DiffType index = 0; index < start_count; ++dest, ++index) {
1328 *dest = std::move(results[index]);
1330 return std::make_tuple(first1, first2, dest);
1601 return *iter1 == *iter2;
1621 return !(iter1 == iter2);
1641 return *iter1 < *iter2;
1661 return iter2 < iter1;
1681 return !(iter1 > iter2);
1701 return !(iter1 < iter2);
1721 return *iter1 - *iter2;
1786 #endif // CGU_PARALLEL_H