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) noexcept {
 
  150 #endif // DOXYGEN_PARSING 
  251 template <
class Iterator, 
class Func>
 
  257   typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
 
  258   typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
 
  262   DiffType start_count = 0;
 
  263   DiffType done_count = 0;
 
  269     Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
 
  279   for (; first != last; ++first, ++start_count) {
 
  280     std::unique_ptr<const Cgu::Callback::Callback> task_cb(
 
  288     std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
 
  289       Cgu::Callback::lambda<>([s_fail] () {s_fail();})
 
  292     tm.
add_task(std::move(task_cb), std::move(fail_cb));
 
  296   while (start_count > done_count) cond.
wait(mutex);
 
  436 template <
class SourceIterator, 
class DestIterator, 
class Func>
 
  438             SourceIterator first,
 
  443   if (first == last) 
return;
 
  445   typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
 
  446   typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
 
  447   typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
 
  452   typedef decltype(func(*first)) DestType;
 
  456   DiffType start_count = 0;
 
  457   DiffType done_count = 0;
 
  463   std::unique_ptr<DestType[]> results(
new DestType[std::distance(first, last)]);
 
  469                 std::forward<Func>(func))
 
  479   for (; first != last; ++first, ++start_count) {
 
  480     std::unique_ptr<const Cgu::Callback::Callback> task_cb(
 
  481       Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
 
  487                     results.get() + start_count))
 
  489     std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
 
  490       Cgu::Callback::lambda<>([s_fail] () {s_fail();})
 
  493     tm.
add_task(std::move(task_cb), std::move(fail_cb));
 
  497   while (start_count > done_count) cond.
wait(mutex);
 
  499   for (DiffType index = 0; index < start_count; ++dest, ++index) {
 
  500     *dest = std::move(results[index]);
 
  645 template <
class SourceIterator1, 
class SourceIterator2, 
class DestIterator, 
class Func>
 
  647             SourceIterator1 first1,
 
  648             SourceIterator1 last1,
 
  649             SourceIterator2 first2,
 
  653   if (first1 == last1) 
return;
 
  655   typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
 
  656   typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
 
  657   typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
 
  658   typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
 
  663   typedef decltype(func(*first1, *first2)) DestType;
 
  667   DiffType start_count = 0;
 
  668   DiffType done_count = 0;
 
  674   std::unique_ptr<DestType[]> results(
new DestType[std::distance(first1, last1)]);
 
  680                 std::forward<Func>(func))
 
  690   for (; first1 != last1; ++first1, ++first2, ++start_count) {
 
  691     std::unique_ptr<const Cgu::Callback::Callback> task_cb(
 
  692       Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
 
  699                     results.get() + start_count))
 
  701     std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
 
  702       Cgu::Callback::lambda<>([s_fail] () {s_fail();})
 
  705     tm.
add_task(std::move(task_cb), std::move(fail_cb));
 
  709   while (start_count > done_count) cond.
wait(mutex);
 
  711   for (DiffType index = 0; index < start_count; ++dest, ++index) {
 
  712     *dest = std::move(results[index]);
 
  835 template <
class Iterator, 
class Func>
 
  842   if (first == last || !max) 
return first;
 
  844   typedef typename std::iterator_traits<Iterator>::reference ArgRefType;
 
  845   typedef typename std::iterator_traits<Iterator>::difference_type DiffType;
 
  849   DiffType start_count = 0;
 
  850   DiffType done_count = 0;
 
  858   const DiffType local_max =
 
  859     (max >= 0) ? max : std::numeric_limits<DiffType>::max();
 
  864     Cgu::Callback::lambda<ArgRefType>(std::forward<Func>(func))
 
  874   for (; first != last && start_count < local_max; ++first, ++start_count) {
 
  875     std::unique_ptr<const Cgu::Callback::Callback> task_cb(
 
  883     std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
 
  884       Cgu::Callback::lambda<>([s_fail] () {s_fail();})
 
  887     tm.
add_task(std::move(task_cb), std::move(fail_cb));
 
  891   while (start_count > done_count) cond.
wait(mutex);
 
 1034 template <
class SourceIterator, 
class DestIterator, 
class Func>
 
 1035 std::pair<SourceIterator, DestIterator>
 
 1037                  SourceIterator first,
 
 1038                  SourceIterator last,
 
 1043   if (first == last || !max) 
return {first, dest};
 
 1045   typedef typename std::iterator_traits<SourceIterator>::reference ArgRefType;
 
 1046   typedef typename std::iterator_traits<SourceIterator>::difference_type DiffType;
 
 1047   typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
 
 1052   typedef decltype(func(*first)) DestType;
 
 1056   DiffType start_count = 0;
 
 1057   DiffType done_count = 0;
 
 1065   const DiffType local_max =
 
 1066     (max >= 0) ? max : std::numeric_limits<DiffType>::max();
 
 1071   std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
 
 1072                                 std::distance(first, last))]);
 
 1078                 std::forward<Func>(func))
 
 1088   for (; first != last && start_count < local_max; ++first, ++start_count) {
 
 1089     std::unique_ptr<const Cgu::Callback::Callback> task_cb(
 
 1090       Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform1_cb_func<ArgRefType, DestType, DiffType, SourceIterator>,
 
 1096                     results.get() + start_count))
 
 1098     std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
 
 1099       Cgu::Callback::lambda<>([s_fail] () {s_fail();})
 
 1102     tm.
add_task(std::move(task_cb), std::move(fail_cb));
 
 1106   while (start_count > done_count) cond.
wait(mutex);
 
 1108   for (DiffType index = 0; index < start_count; ++dest, ++index) {
 
 1109     *dest = std::move(results[index]);
 
 1111   return {first, dest};
 
 1260 template <
class SourceIterator1, 
class SourceIterator2, 
class DestIterator, 
class Func>
 
 1261 std::tuple<SourceIterator1, SourceIterator2, DestIterator>
 
 1263                  SourceIterator1 first1,
 
 1264                  SourceIterator1 last1,
 
 1265                  SourceIterator2 first2,
 
 1270   if (first1 == last1 || !max) 
return std::make_tuple(first1, first2, dest);
 
 1272   typedef typename std::iterator_traits<SourceIterator1>::reference Arg1RefType;
 
 1273   typedef typename std::iterator_traits<SourceIterator1>::difference_type DiffType;
 
 1274   typedef typename std::iterator_traits<SourceIterator2>::reference Arg2RefType;
 
 1275   typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
 
 1280   typedef decltype(func(*first1, *first2)) DestType;
 
 1284   DiffType start_count = 0;
 
 1285   DiffType done_count = 0;
 
 1293   const DiffType local_max =
 
 1294     (max >= 0) ? max : std::numeric_limits<DiffType>::max();
 
 1299   std::unique_ptr<DestType[]> results(
new DestType[std::min(local_max,
 
 1300                                 std::distance(first1, last1))]);
 
 1306                 std::forward<Func>(func))
 
 1316   for (; first1 != last1 && start_count < local_max; ++first1, ++first2, ++start_count) {
 
 1317     std::unique_ptr<const Cgu::Callback::Callback> task_cb(
 
 1318       Cgu::Callback::lambda<>(std::bind(&ParallelHelper2::transform2_cb_func<Arg1RefType, Arg2RefType, DestType, DiffType, SourceIterator1, SourceIterator2>,
 
 1325                     results.get() + start_count))
 
 1327     std::unique_ptr<const Cgu::Callback::Callback> fail_cb(
 
 1328       Cgu::Callback::lambda<>([s_fail] () {s_fail();})
 
 1331     tm.
add_task(std::move(task_cb), std::move(fail_cb));
 
 1335   while (start_count > done_count) cond.
wait(mutex);
 
 1337   for (DiffType index = 0; index < start_count; ++dest, ++index) {
 
 1338     *dest = std::move(results[index]);
 
 1340   return std::make_tuple(first1, first2, dest);
 
 1622   return *iter1 == *iter2;
 
 1642   return !(iter1 == iter2);
 
 1662   return *iter1 < *iter2;
 
 1682   return iter2 < iter1;
 
 1702   return !(iter1 > iter2);
 
 1722   return !(iter1 < iter2);
 
 1742   return *iter1 - *iter2;
 
 1807 #endif // CGU_PARALLEL_H