3 // Copyright (C) 2007-2018 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the terms
7 // of the GNU General Public License as published by the Free Software
8 // Foundation; either version 3, or (at your option) any later
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file parallel/unique_copy.h
26 * @brief Parallel implementations of std::unique_copy().
27 * This file is a GNU parallel extension to the Standard C++ Library.
30 // Written by Robert Geisberger and Robin Dapp.
32 #ifndef _GLIBCXX_PARALLEL_UNIQUE_COPY_H
33 #define _GLIBCXX_PARALLEL_UNIQUE_COPY_H 1
35 #include <parallel/parallel.h>
36 #include <parallel/multiseq_selection.h>
38 namespace __gnu_parallel
40 /** @brief Parallel std::unique_copy(), w/__o explicit equality predicate.
41 * @param __first Begin iterator of input sequence.
42 * @param __last End iterator of input sequence.
43 * @param __result Begin iterator of result __sequence.
44 * @param __binary_pred Equality predicate.
45 * @return End iterator of result __sequence. */
46 template<typename _IIter
,
47 class _OutputIterator
,
48 class _BinaryPredicate
>
50 __parallel_unique_copy(_IIter __first
, _IIter __last
,
51 _OutputIterator __result
,
52 _BinaryPredicate __binary_pred
)
54 _GLIBCXX_CALL(__last
- __first
)
56 typedef std::iterator_traits
<_IIter
> _TraitsType
;
57 typedef typename
_TraitsType::value_type _ValueType
;
58 typedef typename
_TraitsType::difference_type _DifferenceType
;
60 _DifferenceType __size
= __last
- __first
;
65 // Let the first thread process two parts.
66 _DifferenceType
*__counter
;
67 _DifferenceType
*__borders
;
69 _ThreadIndex __num_threads
= __get_max_threads();
70 // First part contains at least one element.
71 # pragma omp parallel num_threads(__num_threads)
75 __num_threads
= omp_get_num_threads();
76 __borders
= new _DifferenceType
[__num_threads
+ 2];
77 __equally_split(__size
, __num_threads
+ 1, __borders
);
78 __counter
= new _DifferenceType
[__num_threads
+ 1];
81 _ThreadIndex __iam
= omp_get_thread_num();
83 _DifferenceType __begin
, __end
;
85 // Check for length without duplicates
86 // Needed for position in output
87 _DifferenceType __i
= 0;
88 _OutputIterator __out
= __result
;
92 __begin
= __borders
[0] + 1; // == 1
93 __end
= __borders
[__iam
+ 1];
98 for (_IIter __iter
= __first
+ __begin
; __iter
< __first
+ __end
;
101 if (!__binary_pred(*__iter
, *(__iter
- 1)))
110 __begin
= __borders
[__iam
]; //one part
111 __end
= __borders
[__iam
+ 1];
113 for (_IIter __iter
= __first
+ __begin
; __iter
< __first
+ __end
;
116 if (!__binary_pred(*__iter
, *(__iter
- 1)))
120 __counter
[__iam
] = __i
;
122 // Last part still untouched.
123 _DifferenceType __begin_output
;
127 // Store result in output on calculated positions.
132 for (_ThreadIndex __t
= 0; __t
< __num_threads
; ++__t
)
133 __begin_output
+= __counter
[__t
];
137 _OutputIterator __iter_out
= __result
+ __begin_output
;
139 __begin
= __borders
[__num_threads
];
142 for (_IIter __iter
= __first
+ __begin
; __iter
< __first
+ __end
;
145 if (__iter
== __first
146 || !__binary_pred(*__iter
, *(__iter
- 1)))
149 *__iter_out
++ = *__iter
;
153 __counter
[__num_threads
] = __i
;
157 for (_ThreadIndex __t
= 0; __t
< __iam
; __t
++)
158 __begin_output
+= __counter
[__t
];
160 _OutputIterator __iter_out
= __result
+ __begin_output
;
161 for (_IIter __iter
= __first
+ __begin
; __iter
< __first
+ __end
;
164 if (!__binary_pred(*__iter
, *(__iter
- 1)))
165 *__iter_out
++ = *__iter
;
170 _DifferenceType __end_output
= 0;
171 for (_ThreadIndex __t
= 0; __t
< __num_threads
+ 1; __t
++)
172 __end_output
+= __counter
[__t
];
176 return __result
+ __end_output
;
179 /** @brief Parallel std::unique_copy(), without explicit equality predicate
180 * @param __first Begin iterator of input sequence.
181 * @param __last End iterator of input sequence.
182 * @param __result Begin iterator of result __sequence.
183 * @return End iterator of result __sequence. */
184 template<typename _IIter
, class _OutputIterator
>
185 inline _OutputIterator
186 __parallel_unique_copy(_IIter __first
, _IIter __last
,
187 _OutputIterator __result
)
189 typedef typename
std::iterator_traits
<_IIter
>::value_type
191 return __parallel_unique_copy(__first
, __last
, __result
,
192 std::equal_to
<_ValueType
>());
195 }//namespace __gnu_parallel
197 #endif /* _GLIBCXX_PARALLEL_UNIQUE_COPY_H */