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>
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,
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  {
81  {
82  _RAIter1 __res =
83  __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred,
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 
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,
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,
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::
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;
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 */
_Function objects representing different tasks to be plugged into the parallel find algorithm...
GNU parallel code for public use.
Sequential helper functions. This file is a GNU parallel extension to the Standard C++ Library...
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 ...
constexpr 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:276
Similar to std::equal_to, but allows two different types.
ISO C++ entities toplevel namespace is std.
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
Constructs predicate for equality from strict weak ordering predicate.
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