libstdc++
algobase.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 // Copyright (C) 2007, 2008, 2009, 2010 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/tags.h>
42 #include <parallel/settings.h>
43 #include <parallel/find.h>
45 
46 namespace std _GLIBCXX_VISIBILITY(default)
47 {
48 namespace __parallel
49 {
50  // NB: equal and lexicographical_compare require mismatch.
51 
52  // Sequential fallback
53  template<typename _IIter1, typename _IIter2>
54  inline pair<_IIter1, _IIter2>
55  mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
57  { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2); }
58 
59  // Sequential fallback
60  template<typename _IIter1, typename _IIter2, typename _Predicate>
61  inline pair<_IIter1, _IIter2>
62  mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
63  _Predicate __pred, __gnu_parallel::sequential_tag)
64  { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); }
65 
66  // Sequential fallback for input iterator case
67  template<typename _IIter1, typename _IIter2,
68  typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
69  inline pair<_IIter1, _IIter2>
70  __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
71  _Predicate __pred, _IteratorTag1, _IteratorTag2)
72  { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); }
73 
74  // Parallel mismatch for random access iterators
75  template<typename _RAIter1, typename _RAIter2, typename _Predicate>
76  pair<_RAIter1, _RAIter2>
77  __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1,
78  _RAIter2 __begin2, _Predicate __pred,
79  random_access_iterator_tag, random_access_iterator_tag)
80  {
82  {
83  _RAIter1 __res =
84  __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred,
85  __gnu_parallel::
86  __mismatch_selector()).first;
87  return make_pair(__res , __begin2 + (__res - __begin1));
88  }
89  else
90  return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred);
91  }
92 
93  // Public interface
94  template<typename _IIter1, typename _IIter2>
95  inline pair<_IIter1, _IIter2>
96  mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
97  {
98  typedef std::iterator_traits<_IIter1> _Iterator1Traits;
99  typedef std::iterator_traits<_IIter2> _Iterator2Traits;
100  typedef typename _Iterator1Traits::value_type _ValueType1;
101  typedef typename _Iterator2Traits::value_type _ValueType2;
102  typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
103  typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
104 
106 
107  return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(),
108  _IteratorCategory1(), _IteratorCategory2());
109  }
110 
111  // Public interface
112  template<typename _IIter1, typename _IIter2, typename _Predicate>
113  inline pair<_IIter1, _IIter2>
114  mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
115  _Predicate __pred)
116  {
117  typedef std::iterator_traits<_IIter1> _Iterator1Traits;
118  typedef std::iterator_traits<_IIter2> _Iterator2Traits;
119  typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
120  typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
121 
122  return __mismatch_switch(__begin1, __end1, __begin2, __pred,
123  _IteratorCategory1(), _IteratorCategory2());
124  }
125 
126  // Sequential fallback
127  template<typename _IIter1, typename _IIter2>
128  inline bool
129  equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
131  { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2); }
132 
133  // Sequential fallback
134  template<typename _IIter1, typename _IIter2, typename _Predicate>
135  inline bool
136  equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
137  _Predicate __pred, __gnu_parallel::sequential_tag)
138  { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __pred); }
139 
140  // Public interface
141  template<typename _IIter1, typename _IIter2>
142  inline bool
143  equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
144  {
145  return __gnu_parallel::mismatch(__begin1, __end1, __begin2).first
146  == __end1;
147  }
148 
149  // Public interface
150  template<typename _IIter1, typename _IIter2, typename _Predicate>
151  inline bool
152  equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
153  _Predicate __pred)
154  {
155  return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __pred).first
156  == __end1;
157  }
158 
159  // Sequential fallback
160  template<typename _IIter1, typename _IIter2>
161  inline bool
162  lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
163  _IIter2 __begin2, _IIter2 __end2,
165  { return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1,
166  __begin2, __end2); }
167 
168  // Sequential fallback
169  template<typename _IIter1, typename _IIter2, typename _Predicate>
170  inline bool
171  lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
172  _IIter2 __begin2, _IIter2 __end2,
173  _Predicate __pred, __gnu_parallel::sequential_tag)
174  { return _GLIBCXX_STD_A::lexicographical_compare(
175  __begin1, __end1, __begin2, __end2, __pred); }
176 
177  // Sequential fallback for input iterator case
178  template<typename _IIter1, typename _IIter2,
179  typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
180  inline bool
181  __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1,
182  _IIter2 __begin2, _IIter2 __end2,
183  _Predicate __pred,
184  _IteratorTag1, _IteratorTag2)
185  { return _GLIBCXX_STD_A::lexicographical_compare(
186  __begin1, __end1, __begin2, __end2, __pred); }
187 
188  // Parallel lexicographical_compare for random access iterators
189  // Limitation: Both valuetypes must be the same
190  template<typename _RAIter1, typename _RAIter2, typename _Predicate>
191  bool
192  __lexicographical_compare_switch(_RAIter1 __begin1, _RAIter1 __end1,
193  _RAIter2 __begin2, _RAIter2 __end2,
194  _Predicate __pred,
195  random_access_iterator_tag,
196  random_access_iterator_tag)
197  {
198  if (_GLIBCXX_PARALLEL_CONDITION(true))
199  {
200  typedef iterator_traits<_RAIter1> _TraitsType1;
201  typedef typename _TraitsType1::value_type _ValueType1;
202 
203  typedef iterator_traits<_RAIter2> _TraitsType2;
204  typedef typename _TraitsType2::value_type _ValueType2;
205 
206  typedef __gnu_parallel::
208  _EqualFromLessCompare;
209 
210  // Longer sequence in first place.
211  if ((__end1 - __begin1) < (__end2 - __begin2))
212  {
213  typedef pair<_RAIter1, _RAIter2> _SpotType;
214  _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2,
215  _EqualFromLessCompare(__pred),
216  random_access_iterator_tag(),
217  random_access_iterator_tag());
218 
219  return (__mm.first == __end1)
220  || bool(__pred(*__mm.first, *__mm.second));
221  }
222  else
223  {
224  typedef pair<_RAIter2, _RAIter1> _SpotType;
225  _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1,
226  _EqualFromLessCompare(__pred),
227  random_access_iterator_tag(),
228  random_access_iterator_tag());
229 
230  return (__mm.first != __end2)
231  && bool(__pred(*__mm.second, *__mm.first));
232  }
233  }
234  else
235  return _GLIBCXX_STD_A::lexicographical_compare(
236  __begin1, __end1, __begin2, __end2, __pred);
237  }
238 
239  // Public interface
240  template<typename _IIter1, typename _IIter2>
241  inline bool
242  lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
243  _IIter2 __begin2, _IIter2 __end2)
244  {
245  typedef iterator_traits<_IIter1> _TraitsType1;
246  typedef typename _TraitsType1::value_type _ValueType1;
247  typedef typename _TraitsType1::iterator_category _IteratorCategory1;
248 
249  typedef iterator_traits<_IIter2> _TraitsType2;
250  typedef typename _TraitsType2::value_type _ValueType2;
251  typedef typename _TraitsType2::iterator_category _IteratorCategory2;
253 
254  return __lexicographical_compare_switch(
255  __begin1, __end1, __begin2, __end2, _LessType(),
256  _IteratorCategory1(), _IteratorCategory2());
257  }
258 
259  // Public interface
260  template<typename _IIter1, typename _IIter2, typename _Predicate>
261  inline bool
262  lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
263  _IIter2 __begin2, _IIter2 __end2,
264  _Predicate __pred)
265  {
266  typedef iterator_traits<_IIter1> _TraitsType1;
267  typedef typename _TraitsType1::iterator_category _IteratorCategory1;
268 
269  typedef iterator_traits<_IIter2> _TraitsType2;
270  typedef typename _TraitsType2::iterator_category _IteratorCategory2;
271 
272  return __lexicographical_compare_switch(
273  __begin1, __end1, __begin2, __end2, __pred,
274  _IteratorCategory1(), _IteratorCategory2());
275  }
276 } // end namespace
277 } // end namespace
278 
279 #endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */
Similar to std::equal_to, but allows two different types.
Constructs predicate for equality from strict weak ordering predicate.
Runtime settings and tuning parameters, heuristics to decide whether to use parallelized algorithms...
Forces sequential execution at compile time.
Definition: tags.h:42
Parallel implementation base for std::find(), std::equal() and related functions. This file is a GNU ...
pair< typename __decay_and_strip< _T1 >::__type, typename __decay_and_strip< _T2 >::__type > make_pair(_T1 &&__x, _T2 &&__y)
A convenience wrapper for creating a pair from two objects.
Definition: stl_pair.h:262
std::pair< _RAIter1, _RAIter2 > __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector)
Parallel std::find, switch for different algorithms.
Definition: find.h:60
Similar to std::less, but allows two different types.
#define _GLIBCXX_PARALLEL_CONDITION(__c)
Determine at compile(?)-time if the parallel variant of an algorithm should be called.
Definition: settings.h:95
Sequential helper functions. This file is a GNU parallel extension to the Standard C++ Library...
_Function objects representing different tasks to be plugged into the parallel find algorithm...
Tags for compile-time selection. This file is a GNU parallel extension to the Standard C++ Library...