Install gcc-4.4.0-tdm-1-core-2.tar.gz
[msysgit.git] / mingw / lib / gcc / mingw32 / 4.3.3 / include / c++ / parallel / unique_copy.h
blob7f51e2603fde2a2af1977ae6af10d333a2e1772d
1 // -*- C++ -*-
3 // Copyright (C) 2007, 2008 Free Software Foundation, Inc.
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.
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 // 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.
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.
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.
36 // Written by Robert Geisberger and Robin Dapp.
38 #ifndef _GLIBCXX_PARALLEL_UNIQUE_H
39 #define _GLIBCXX_PARALLEL_UNIQUE_H 1
41 #include <parallel/parallel.h>
42 #include <parallel/multiseq_selection.h>
44 namespace __gnu_parallel
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. */
53 template<typename InputIterator,
54 class OutputIterator,
55 class BinaryPredicate>
56 OutputIterator
57 parallel_unique_copy(InputIterator first, InputIterator last,
58 OutputIterator result, BinaryPredicate binary_pred)
60 _GLIBCXX_CALL(last - first)
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;
66 difference_type size = last - first;
68 if (size == 0)
69 return result;
71 // Let the first thread process two parts.
72 difference_type *counter;
73 difference_type *borders;
75 thread_index_t num_threads = get_max_threads();
76 // First part contains at least one element.
77 # pragma omp parallel num_threads(num_threads)
79 # pragma omp single
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];
87 thread_index_t iam = omp_get_thread_num();
89 difference_type begin, end;
91 // Check for length without duplicates
92 // Needed for position in output
93 difference_type i = 0;
94 OutputIterator out = result;
96 if (iam == 0)
98 begin = borders[0] + 1; // == 1
99 end = borders[iam + 1];
101 ++i;
102 *out++ = *first;
104 for (InputIterator iter = first + begin; iter < first + end; ++iter)
106 if (!binary_pred(*iter, *(iter-1)))
108 ++i;
109 *out++ = *iter;
113 else
115 begin = borders[iam]; //one part
116 end = borders[iam + 1];
118 for (InputIterator iter = first + begin; iter < first + end; ++iter)
120 if (!binary_pred(*iter, *(iter - 1)))
121 ++i;
124 counter[iam] = i;
126 // Last part still untouched.
127 difference_type begin_output;
129 # pragma omp barrier
131 // Store result in output on calculated positions.
132 begin_output = 0;
134 if (iam == 0)
136 for (int t = 0; t < num_threads; ++t)
137 begin_output += counter[t];
139 i = 0;
141 OutputIterator iter_out = result + begin_output;
143 begin = borders[num_threads];
144 end = size;
146 for (InputIterator iter = first + begin; iter < first + end; ++iter)
148 if (iter == first || !binary_pred(*iter, *(iter - 1)))
150 ++i;
151 *iter_out++ = *iter;
155 counter[num_threads] = i;
157 else
159 for (int t = 0; t < iam; t++)
160 begin_output += counter[t];
162 OutputIterator iter_out = result + begin_output;
163 for (InputIterator iter = first + begin; iter < first + end; ++iter)
165 if (!binary_pred(*iter, *(iter-1)))
166 *iter_out++ = *iter;
171 difference_type end_output = 0;
172 for (int t = 0; t < num_threads + 1; t++)
173 end_output += counter[t];
175 delete[] borders;
177 return result + end_output;
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. */
185 template<typename InputIterator, class OutputIterator>
186 inline OutputIterator
187 parallel_unique_copy(InputIterator first, InputIterator last,
188 OutputIterator result)
190 typedef typename std::iterator_traits<InputIterator>::value_type
191 value_type;
192 return parallel_unique_copy(first, last, result,
193 std::equal_to<value_type>());
196 }//namespace __gnu_parallel
198 #endif