libstdc++

algobase.h
Go to the documentation of this file.
1 // -*- C++ -*-
2
3 // Copyright (C) 2007-2013 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 3, 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 // 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.
19
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/>.
24
25 /** @file parallel/algobase.h
26 * @brief Parallel STL function calls corresponding to the
27 * stl_algobase.h header. The functions defined here mainly do case
28 * switches and call the actual parallelized versions in other files.
29 * Inlining policy: Functions that basically only contain one
30 * function call, are declared inline.
31 * This file is a GNU parallel extension to the Standard C++ Library.
32 */
33
34 // Written by Johannes Singler and Felix Putze.
35
36 #ifndef _GLIBCXX_PARALLEL_ALGOBASE_H
37 #define _GLIBCXX_PARALLEL_ALGOBASE_H 1
38
39 #include <bits/stl_algobase.h>
40 #include <parallel/base.h>
41 #include <parallel/algorithmfwd.h>
42 #include <parallel/find.h>
43 #include <parallel/find_selectors.h>
44
45 namespace std _GLIBCXX_VISIBILITY(default)
46 {
47 namespace __parallel
48 {
49 // NB: equal and lexicographical_compare require mismatch.
50
51 // Sequential fallback
52 template<typename _IIter1, typename _IIter2>
53 inline pair<_IIter1, _IIter2>
54 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
55 __gnu_parallel::sequential_tag)
56 { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2); }
57
58 // Sequential fallback
59 template<typename _IIter1, typename _IIter2, typename _Predicate>
60 inline pair<_IIter1, _IIter2>
61 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
62 _Predicate __pred, __gnu_parallel::sequential_tag)
63 { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); }
64
65 // Sequential fallback for input iterator case
66 template<typename _IIter1, typename _IIter2,
67 typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
68 inline pair<_IIter1, _IIter2>
69 __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
70 _Predicate __pred, _IteratorTag1, _IteratorTag2)
71 { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); }
72
73 // Parallel mismatch for random access iterators
74 template<typename _RAIter1, typename _RAIter2, typename _Predicate>
75 pair<_RAIter1, _RAIter2>
76 __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1,
77 _RAIter2 __begin2, _Predicate __pred,
78 random_access_iterator_tag, random_access_iterator_tag)
79 {
80 if (_GLIBCXX_PARALLEL_CONDITION(true))
81 {
82 _RAIter1 __res =
83 __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred,
84 __gnu_parallel::
85 __mismatch_selector()).first;
86 return make_pair(__res , __begin2 + (__res - __begin1));
87 }
88 else
89 return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred);
90 }
91
92 // Public interface
93 template<typename _IIter1, typename _IIter2>
94 inline pair<_IIter1, _IIter2>
95 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
96 {
97 typedef std::iterator_traits<_IIter1> _Iterator1Traits;
98 typedef std::iterator_traits<_IIter2> _Iterator2Traits;
99 typedef typename _Iterator1Traits::value_type _ValueType1;
100 typedef typename _Iterator2Traits::value_type _ValueType2;
101 typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
102 typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
103
104 typedef __gnu_parallel::_EqualTo<_ValueType1, _ValueType2> _EqualTo;
105
106 return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(),
107 _IteratorCategory1(), _IteratorCategory2());
108 }
109
110 // Public interface
111 template<typename _IIter1, typename _IIter2, typename _Predicate>
112 inline pair<_IIter1, _IIter2>
113 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
114 _Predicate __pred)
115 {
116 typedef std::iterator_traits<_IIter1> _Iterator1Traits;
117 typedef std::iterator_traits<_IIter2> _Iterator2Traits;
118 typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
119 typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
120
121 return __mismatch_switch(__begin1, __end1, __begin2, __pred,
122 _IteratorCategory1(), _IteratorCategory2());
123 }
124
125 // Sequential fallback
126 template<typename _IIter1, typename _IIter2>
127 inline bool
128 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
129 __gnu_parallel::sequential_tag)
130 { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2); }
131
132 // Sequential fallback
133 template<typename _IIter1, typename _IIter2, typename _Predicate>
134 inline bool
135 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
136 _Predicate __pred, __gnu_parallel::sequential_tag)
137 { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __pred); }
138
139 // Public interface
140 template<typename _IIter1, typename _IIter2>
141 inline bool
142 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
143 {
144 return __gnu_parallel::mismatch(__begin1, __end1, __begin2).first
145 == __end1;
146 }
147
148 // Public interface
149 template<typename _IIter1, typename _IIter2, typename _Predicate>
150 inline bool
151 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
152 _Predicate __pred)
153 {
154 return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __pred).first
155 == __end1;
156 }
157
158 // Sequential fallback
159 template<typename _IIter1, typename _IIter2>
160 inline bool
161 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
162 _IIter2 __begin2, _IIter2 __end2,
163 __gnu_parallel::sequential_tag)
164 { return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1,
165 __begin2, __end2); }
166
167 // Sequential fallback
168 template<typename _IIter1, typename _IIter2, typename _Predicate>
169 inline bool
170 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
171 _IIter2 __begin2, _IIter2 __end2,
172 _Predicate __pred, __gnu_parallel::sequential_tag)
173 { return _GLIBCXX_STD_A::lexicographical_compare(
174 __begin1, __end1, __begin2, __end2, __pred); }
175
176 // Sequential fallback for input iterator case
177 template<typename _IIter1, typename _IIter2,
178 typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
179 inline bool
180 __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1,
181 _IIter2 __begin2, _IIter2 __end2,
182 _Predicate __pred,
183 _IteratorTag1, _IteratorTag2)
184 { return _GLIBCXX_STD_A::lexicographical_compare(
185 __begin1, __end1, __begin2, __end2, __pred); }
186
187 // Parallel lexicographical_compare for random access iterators
188 // Limitation: Both valuetypes must be the same
189 template<typename _RAIter1, typename _RAIter2, typename _Predicate>
190 bool
191 __lexicographical_compare_switch(_RAIter1 __begin1, _RAIter1 __end1,
192 _RAIter2 __begin2, _RAIter2 __end2,
193 _Predicate __pred,
194 random_access_iterator_tag,
195 random_access_iterator_tag)
196 {
197 if (_GLIBCXX_PARALLEL_CONDITION(true))
198 {
199 typedef iterator_traits<_RAIter1> _TraitsType1;
200 typedef typename _TraitsType1::value_type _ValueType1;
201
202 typedef iterator_traits<_RAIter2> _TraitsType2;
203 typedef typename _TraitsType2::value_type _ValueType2;
204
205 typedef __gnu_parallel::
206 _EqualFromLess<_ValueType1, _ValueType2, _Predicate>
207 _EqualFromLessCompare;
208
209 // Longer sequence in first place.
210 if ((__end1 - __begin1) < (__end2 - __begin2))
211 {
212 typedef pair<_RAIter1, _RAIter2> _SpotType;
213 _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2,
214 _EqualFromLessCompare(__pred),
215 random_access_iterator_tag(),
216 random_access_iterator_tag());
217
218 return (__mm.first == __end1)
219 || bool(__pred(*__mm.first, *__mm.second));
220 }
221 else
222 {
223 typedef pair<_RAIter2, _RAIter1> _SpotType;
224 _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1,
225 _EqualFromLessCompare(__pred),
226 random_access_iterator_tag(),
227 random_access_iterator_tag());
228
229 return (__mm.first != __end2)
230 && bool(__pred(*__mm.second, *__mm.first));
231 }
232 }
233 else
234 return _GLIBCXX_STD_A::lexicographical_compare(
235 __begin1, __end1, __begin2, __end2, __pred);
236 }
237
238 // Public interface
239 template<typename _IIter1, typename _IIter2>
240 inline bool
241 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
242 _IIter2 __begin2, _IIter2 __end2)
243 {
244 typedef iterator_traits<_IIter1> _TraitsType1;
245 typedef typename _TraitsType1::value_type _ValueType1;
246 typedef typename _TraitsType1::iterator_category _IteratorCategory1;
247
248 typedef iterator_traits<_IIter2> _TraitsType2;
249 typedef typename _TraitsType2::value_type _ValueType2;
250 typedef typename _TraitsType2::iterator_category _IteratorCategory2;
251 typedef __gnu_parallel::_Less<_ValueType1, _ValueType2> _LessType;
252
253 return __lexicographical_compare_switch(
254 __begin1, __end1, __begin2, __end2, _LessType(),
255 _IteratorCategory1(), _IteratorCategory2());
256 }
257
258 // Public interface
259 template<typename _IIter1, typename _IIter2, typename _Predicate>
260 inline bool
261 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
262 _IIter2 __begin2, _IIter2 __end2,
263 _Predicate __pred)
264 {
265 typedef iterator_traits<_IIter1> _TraitsType1;
266 typedef typename _TraitsType1::iterator_category _IteratorCategory1;
267
268 typedef iterator_traits<_IIter2> _TraitsType2;
269 typedef typename _TraitsType2::iterator_category _IteratorCategory2;
270
271 return __lexicographical_compare_switch(
272 __begin1, __end1, __begin2, __end2, __pred,
273 _IteratorCategory1(), _IteratorCategory2());
274 }
275 } // end namespace
276 } // end namespace
277
278 #endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */