Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef _GLIBCXX_PARALLEL_UNIQUE_COPY_H
00033 #define _GLIBCXX_PARALLEL_UNIQUE_COPY_H 1
00034
00035 #include <parallel/parallel.h>
00036 #include <parallel/multiseq_selection.h>
00037
00038 namespace __gnu_parallel
00039 {
00040
00041
00042
00043
00044
00045
00046 template<typename _IIter,
00047 class _OutputIterator,
00048 class _BinaryPredicate>
00049 _OutputIterator
00050 __parallel_unique_copy(_IIter __first, _IIter __last,
00051 _OutputIterator __result,
00052 _BinaryPredicate __binary_pred)
00053 {
00054 _GLIBCXX_CALL(__last - __first)
00055
00056 typedef std::iterator_traits<_IIter> _TraitsType;
00057 typedef typename _TraitsType::value_type _ValueType;
00058 typedef typename _TraitsType::difference_type _DifferenceType;
00059
00060 _DifferenceType __size = __last - __first;
00061
00062 if (__size == 0)
00063 return __result;
00064
00065
00066 _DifferenceType *__counter;
00067 _DifferenceType *__borders;
00068
00069 _ThreadIndex __num_threads = __get_max_threads();
00070
00071 # pragma omp parallel num_threads(__num_threads)
00072 {
00073 # pragma omp single
00074 {
00075 __num_threads = omp_get_num_threads();
00076 __borders = new _DifferenceType[__num_threads + 2];
00077 equally_split(__size, __num_threads + 1, __borders);
00078 __counter = new _DifferenceType[__num_threads + 1];
00079 }
00080
00081 _ThreadIndex __iam = omp_get_thread_num();
00082
00083 _DifferenceType __begin, __end;
00084
00085
00086
00087 _DifferenceType __i = 0;
00088 _OutputIterator __out = __result;
00089
00090 if (__iam == 0)
00091 {
00092 __begin = __borders[0] + 1;
00093 __end = __borders[__iam + 1];
00094
00095 ++__i;
00096 *__out++ = *__first;
00097
00098 for (_IIter __iter = __first + __begin; __iter < __first + __end;
00099 ++__iter)
00100 {
00101 if (!__binary_pred(*__iter, *(__iter - 1)))
00102 {
00103 ++__i;
00104 *__out++ = *__iter;
00105 }
00106 }
00107 }
00108 else
00109 {
00110 __begin = __borders[__iam];
00111 __end = __borders[__iam + 1];
00112
00113 for (_IIter __iter = __first + __begin; __iter < __first + __end;
00114 ++__iter)
00115 {
00116 if (!__binary_pred(*__iter, *(__iter - 1)))
00117 ++__i;
00118 }
00119 }
00120 __counter[__iam] = __i;
00121
00122
00123 _DifferenceType __begin_output;
00124
00125 # pragma omp barrier
00126
00127
00128 __begin_output = 0;
00129
00130 if (__iam == 0)
00131 {
00132 for (_ThreadIndex __t = 0; __t < __num_threads; ++__t)
00133 __begin_output += __counter[__t];
00134
00135 __i = 0;
00136
00137 _OutputIterator __iter_out = __result + __begin_output;
00138
00139 __begin = __borders[__num_threads];
00140 __end = __size;
00141
00142 for (_IIter __iter = __first + __begin; __iter < __first + __end;
00143 ++__iter)
00144 {
00145 if (__iter == __first
00146 || !__binary_pred(*__iter, *(__iter - 1)))
00147 {
00148 ++__i;
00149 *__iter_out++ = *__iter;
00150 }
00151 }
00152
00153 __counter[__num_threads] = __i;
00154 }
00155 else
00156 {
00157 for (_ThreadIndex __t = 0; __t < __iam; __t++)
00158 __begin_output += __counter[__t];
00159
00160 _OutputIterator __iter_out = __result + __begin_output;
00161 for (_IIter __iter = __first + __begin; __iter < __first + __end;
00162 ++__iter)
00163 {
00164 if (!__binary_pred(*__iter, *(__iter - 1)))
00165 *__iter_out++ = *__iter;
00166 }
00167 }
00168 }
00169
00170 _DifferenceType __end_output = 0;
00171 for (_ThreadIndex __t = 0; __t < __num_threads + 1; __t++)
00172 __end_output += __counter[__t];
00173
00174 delete[] __borders;
00175
00176 return __result + __end_output;
00177 }
00178
00179
00180
00181
00182
00183
00184 template<typename _IIter, class _OutputIterator>
00185 inline _OutputIterator
00186 __parallel_unique_copy(_IIter __first, _IIter __last,
00187 _OutputIterator __result)
00188 {
00189 typedef typename std::iterator_traits<_IIter>::value_type
00190 _ValueType;
00191 return __parallel_unique_copy(__first, __last, __result,
00192 std::equal_to<_ValueType>());
00193 }
00194
00195 }
00196
00197 #endif