]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/parallel/unique_copy.h
multiway_merge.h: Reformat to 80 columns; adjust some inline specifiers; other minor...
[thirdparty/gcc.git] / libstdc++-v3 / include / parallel / unique_copy.h
CommitLineData
c2ba9709
JS
1// -*- C++ -*-
2
5817ff8e 3// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
c2ba9709
JS
4//
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 2, or (at your option) any later
9// version.
10
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.
15
16// You should have received a copy of the GNU General Public License
17// along with this library; see the file COPYING. If not, write to
18// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19// MA 02111-1307, USA.
20
21// As a special exception, you may use this file as part of a free
22// software library without restriction. Specifically, if other files
23// instantiate templates or use macros or inline functions from this
24// file, or you compile this file and link it with other files to
25// produce an executable, this file does not by itself cause the
26// resulting executable to be covered by the GNU General Public
27// License. This exception does not however invalidate any other
28// reasons why the executable file might be covered by the GNU General
29// Public License.
30
31/** @file parallel/unique_copy.h
32 * @brief Parallel implementations of std::unique_copy().
33 * This file is a GNU parallel extension to the Standard C++ Library.
34 */
35
36// Written by Robert Geisberger and Robin Dapp.
37
38#ifndef _GLIBCXX_PARALLEL_UNIQUE_H
39#define _GLIBCXX_PARALLEL_UNIQUE_H 1
40
41#include <parallel/parallel.h>
42#include <parallel/multiseq_selection.h>
43
44namespace __gnu_parallel
45{
46
e683ee2a
JS
47/** @brief Parallel std::unique_copy(), w/o explicit equality predicate.
48 * @param first Begin iterator of input sequence.
49 * @param last End iterator of input sequence.
50 * @param result Begin iterator of result sequence.
51 * @param binary_pred Equality predicate.
52 * @return End iterator of result sequence. */
5817ff8e
PC
53template<typename InputIterator,
54 class OutputIterator,
55 class BinaryPredicate>
56 OutputIterator
c2ba9709 57 parallel_unique_copy(InputIterator first, InputIterator last,
e683ee2a 58 OutputIterator result, BinaryPredicate binary_pred)
c2ba9709
JS
59 {
60 _GLIBCXX_CALL(last - first)
61
62 typedef std::iterator_traits<InputIterator> traits_type;
63 typedef typename traits_type::value_type value_type;
64 typedef typename traits_type::difference_type difference_type;
65
66 difference_type size = last - first;
c2ba9709
JS
67
68 if (size == 0)
69 return result;
70
71 // Let the first thread process two parts.
e683ee2a
JS
72 difference_type *counter;
73 difference_type *borders;
c2ba9709 74
e683ee2a 75 thread_index_t num_threads = get_max_threads();
c2ba9709 76 // First part contains at least one element.
e683ee2a
JS
77# pragma omp parallel num_threads(num_threads)
78 {
79# pragma omp single
80 {
5817ff8e
PC
81 num_threads = omp_get_num_threads();
82 borders = new difference_type[num_threads + 2];
83 equally_split(size, num_threads + 1, borders);
84 counter = new difference_type[num_threads + 1];
e683ee2a
JS
85 }
86
87 thread_index_t iam = omp_get_thread_num();
88
89 difference_type begin, end;
90
91 // Check for length without duplicates
92 // Needed for position in output
93 difference_type i = 0;
94 OutputIterator out = result;
95
96 if (iam == 0)
97 {
98 begin = borders[0] + 1; // == 1
99 end = borders[iam + 1];
100
5817ff8e 101 ++i;
1661473b 102 *out++ = *first;
e683ee2a
JS
103
104 for (InputIterator iter = first + begin; iter < first + end; ++iter)
105 {
106 if (!binary_pred(*iter, *(iter-1)))
107 {
5817ff8e 108 ++i;
1661473b 109 *out++ = *iter;
e683ee2a
JS
110 }
111 }
112 }
c2ba9709 113 else
e683ee2a
JS
114 {
115 begin = borders[iam]; //one part
116 end = borders[iam + 1];
117
118 for (InputIterator iter = first + begin; iter < first + end; ++iter)
119 {
5817ff8e
PC
120 if (!binary_pred(*iter, *(iter - 1)))
121 ++i;
122 }
e683ee2a 123 }
c2ba9709
JS
124 counter[iam] = i;
125
126 // Last part still untouched.
127 difference_type begin_output;
128
e683ee2a 129# pragma omp barrier
c2ba9709
JS
130
131 // Store result in output on calculated positions.
132 begin_output = 0;
133
134 if (iam == 0)
e683ee2a 135 {
5817ff8e 136 for (int t = 0; t < num_threads; ++t)
e683ee2a 137 begin_output += counter[t];
c2ba9709 138
e683ee2a 139 i = 0;
c2ba9709 140
e683ee2a 141 OutputIterator iter_out = result + begin_output;
c2ba9709 142
e683ee2a
JS
143 begin = borders[num_threads];
144 end = size;
c2ba9709 145
e683ee2a
JS
146 for (InputIterator iter = first + begin; iter < first + end; ++iter)
147 {
5817ff8e 148 if (iter == first || !binary_pred(*iter, *(iter - 1)))
e683ee2a 149 {
5817ff8e 150 ++i;
1661473b 151 *iter_out++ = *iter;
e683ee2a
JS
152 }
153 }
c2ba9709 154
e683ee2a
JS
155 counter[num_threads] = i;
156 }
c2ba9709 157 else
e683ee2a
JS
158 {
159 for (int t = 0; t < iam; t++)
160 begin_output += counter[t];
161
162 OutputIterator iter_out = result + begin_output;
163 for (InputIterator iter = first + begin; iter < first + end; ++iter)
164 {
165 if (!binary_pred(*iter, *(iter-1)))
5817ff8e
PC
166 *iter_out++ = *iter;
167 }
e683ee2a 168 }
c2ba9709
JS
169 }
170
171 difference_type end_output = 0;
172 for (int t = 0; t < num_threads + 1; t++)
173 end_output += counter[t];
174
e683ee2a
JS
175 delete[] borders;
176
c2ba9709
JS
177 return result + end_output;
178 }
179
e683ee2a
JS
180/** @brief Parallel std::unique_copy(), without explicit equality predicate
181 * @param first Begin iterator of input sequence.
182 * @param last End iterator of input sequence.
183 * @param result Begin iterator of result sequence.
184 * @return End iterator of result sequence. */
185template<typename InputIterator, class OutputIterator>
c2ba9709
JS
186 inline OutputIterator
187 parallel_unique_copy(InputIterator first, InputIterator last,
e683ee2a 188 OutputIterator result)
c2ba9709
JS
189 {
190 typedef typename std::iterator_traits<InputIterator>::value_type value_type;
5817ff8e
PC
191 return parallel_unique_copy(first, last, result,
192 std::equal_to<value_type>());
c2ba9709
JS
193 }
194
195}//namespace __gnu_parallel
196
197#endif