STXXL  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pq_mergers.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/containers/pq_mergers.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 1999 Peter Sanders <[email protected]>
7  * Copyright (C) 2003, 2004, 2007 Roman Dementiev <[email protected]>
8  * Copyright (C) 2007-2009 Johannes Singler <[email protected]>
9  * Copyright (C) 2007, 2008 Andreas Beckmann <[email protected]>
10  *
11  * Distributed under the Boost Software License, Version 1.0.
12  * (See accompanying file LICENSE_1_0.txt or copy at
13  * http://www.boost.org/LICENSE_1_0.txt)
14  **************************************************************************/
15 
16 #ifndef STXXL_CONTAINERS_PQ_MERGERS_HEADER
17 #define STXXL_CONTAINERS_PQ_MERGERS_HEADER
18 
20 
22 
23 //! \addtogroup stlcontinternals
24 //!
25 //! \{
26 
27 /*! \internal
28  */
29 namespace priority_queue_local {
30 
31 /////////////////////////////////////////////////////////////////////
32 // auxiliary functions
33 
34 // merge length elements from the two sentinel terminated input
35 // sequences source0 and source1 to target
36 // advance source0 and source1 accordingly
37 // require: at least length nonsentinel elements available in source0, source1
38 // require: target may overwrite one of the sources as long as
39 // *(sourcex + length) is before the end of sourcex
40 template <class InputIterator, class OutputIterator, class CompareType>
42  InputIterator& source0,
43  InputIterator& source1,
44  OutputIterator target,
45  unsigned_type length,
46  CompareType& cmp)
47 {
48  OutputIterator done = target + length;
49 
50  while (target != done)
51  {
52  if (cmp(*source0, *source1))
53  {
54  *target = *source1;
55  ++source1;
56  }
57  else
58  {
59  *target = *source0;
60  ++source0;
61  }
62  ++target;
63  }
64 }
65 
66 // merge length elements from the three sentinel terminated input
67 // sequences source0, source1 and source2 to target
68 // advance source0, source1 and source2 accordingly
69 // require: at least length nonsentinel elements available in source0, source1 and source2
70 // require: target may overwrite one of the sources as long as
71 // *(sourcex + length) is before the end of sourcex
72 template <class InputIterator, class OutputIterator, class CompareType>
74  InputIterator& source0,
75  InputIterator& source1,
76  InputIterator& source2,
77  OutputIterator target,
78  unsigned_type length,
79  CompareType& cmp)
80 {
81  OutputIterator done = target + length;
82 
83  if (cmp(*source1, *source0)) {
84  if (cmp(*source2, *source1)) {
85  goto s012;
86  }
87  else {
88  if (cmp(*source0, *source2)) {
89  goto s201;
90  }
91  else {
92  goto s021;
93  }
94  }
95  } else {
96  if (cmp(*source2, *source1)) {
97  if (cmp(*source2, *source0)) {
98  goto s102;
99  }
100  else {
101  goto s120;
102  }
103  } else {
104  goto s210;
105  }
106  }
107 
108 #define Merge3Case(a, b, c) \
109  s ## a ## b ## c : \
110  if (target == done) \
111  return; \
112  *target = *source ## a; \
113  ++target; \
114  ++source ## a; \
115  if (cmp(*source ## b, *source ## a)) \
116  goto s ## a ## b ## c; \
117  if (cmp(*source ## c, *source ## a)) \
118  goto s ## b ## a ## c; \
119  goto s ## b ## c ## a;
120 
121  // the order is chosen in such a way that
122  // four of the trailing gotos can be eliminated by the optimizer
123  Merge3Case(0, 1, 2);
124  Merge3Case(1, 2, 0);
125  Merge3Case(2, 0, 1);
126  Merge3Case(1, 0, 2);
127  Merge3Case(0, 2, 1);
128  Merge3Case(2, 1, 0);
129 
130 #undef Merge3Case
131 }
132 
133 
134 // merge length elements from the four sentinel terminated input
135 // sequences source0, source1, source2 and source3 to target
136 // advance source0, source1, source2 and source3 accordingly
137 // require: at least length nonsentinel elements available in source0, source1, source2 and source3
138 // require: target may overwrite one of the sources as long as
139 // *(sourcex + length) is before the end of sourcex
140 template <class InputIterator, class OutputIterator, class CompareType>
142  InputIterator& source0,
143  InputIterator& source1,
144  InputIterator& source2,
145  InputIterator& source3,
146  OutputIterator target, unsigned_type length, CompareType& cmp)
147 {
148  OutputIterator done = target + length;
149 
150 #define StartMerge4(a, b, c, d) \
151  if ((!cmp(*source ## a, *source ## b)) && (!cmp(*source ## b, *source ## c)) && (!cmp(*source ## c, *source ## d))) \
152  goto s ## a ## b ## c ## d;
153 
154  // b>a c>b d>c
155  // a<b b<c c<d
156  // a<=b b<=c c<=d
157  // !(a>b) !(b>c) !(c>d)
158 
159  StartMerge4(0, 1, 2, 3);
160  StartMerge4(1, 2, 3, 0);
161  StartMerge4(2, 3, 0, 1);
162  StartMerge4(3, 0, 1, 2);
163 
164  StartMerge4(0, 3, 1, 2);
165  StartMerge4(3, 1, 2, 0);
166  StartMerge4(1, 2, 0, 3);
167  StartMerge4(2, 0, 3, 1);
168 
169  StartMerge4(0, 2, 3, 1);
170  StartMerge4(2, 3, 1, 0);
171  StartMerge4(3, 1, 0, 2);
172  StartMerge4(1, 0, 2, 3);
173 
174  StartMerge4(2, 0, 1, 3);
175  StartMerge4(0, 1, 3, 2);
176  StartMerge4(1, 3, 2, 0);
177  StartMerge4(3, 2, 0, 1);
178 
179  StartMerge4(3, 0, 2, 1);
180  StartMerge4(0, 2, 1, 3);
181  StartMerge4(2, 1, 3, 0);
182  StartMerge4(1, 3, 0, 2);
183 
184  StartMerge4(1, 0, 3, 2);
185  StartMerge4(0, 3, 2, 1);
186  StartMerge4(3, 2, 1, 0);
187  StartMerge4(2, 1, 0, 3);
188 
189 #define Merge4Case(a, b, c, d) \
190  s ## a ## b ## c ## d : \
191  if (target == done) \
192  return; \
193  *target = *source ## a; \
194  ++target; \
195  ++source ## a; \
196  if (cmp(*source ## c, *source ## a)) \
197  { \
198  if (cmp(*source ## b, *source ## a)) \
199  goto s ## a ## b ## c ## d; \
200  else \
201  goto s ## b ## a ## c ## d; \
202  } \
203  else \
204  { \
205  if (cmp(*source ## d, *source ## a)) \
206  goto s ## b ## c ## a ## d; \
207  else \
208  goto s ## b ## c ## d ## a; \
209  }
210 
211  Merge4Case(0, 1, 2, 3);
212  Merge4Case(1, 2, 3, 0);
213  Merge4Case(2, 3, 0, 1);
214  Merge4Case(3, 0, 1, 2);
215 
216  Merge4Case(0, 3, 1, 2);
217  Merge4Case(3, 1, 2, 0);
218  Merge4Case(1, 2, 0, 3);
219  Merge4Case(2, 0, 3, 1);
220 
221  Merge4Case(0, 2, 3, 1);
222  Merge4Case(2, 3, 1, 0);
223  Merge4Case(3, 1, 0, 2);
224  Merge4Case(1, 0, 2, 3);
225 
226  Merge4Case(2, 0, 1, 3);
227  Merge4Case(0, 1, 3, 2);
228  Merge4Case(1, 3, 2, 0);
229  Merge4Case(3, 2, 0, 1);
230 
231  Merge4Case(3, 0, 2, 1);
232  Merge4Case(0, 2, 1, 3);
233  Merge4Case(2, 1, 3, 0);
234  Merge4Case(1, 3, 0, 2);
235 
236  Merge4Case(1, 0, 3, 2);
237  Merge4Case(0, 3, 2, 1);
238  Merge4Case(3, 2, 1, 0);
239  Merge4Case(2, 1, 0, 3);
240 
241 #undef StartMerge4
242 #undef Merge4Case
243 }
244 
245 } // namespace priority_queue_local
246 
247 //! \}
248 
250 
251 #endif // !STXXL_CONTAINERS_PQ_MERGERS_HEADER
252 // vim: et:ts=4:sw=4
#define StartMerge4(a, b, c, d)
void merge4_iterator(InputIterator &source0, InputIterator &source1, InputIterator &source2, InputIterator &source3, OutputIterator target, unsigned_type length, CompareType &cmp)
Definition: pq_mergers.h:141
void merge_iterator(InputIterator &source0, InputIterator &source1, OutputIterator target, unsigned_type length, CompareType &cmp)
Definition: pq_mergers.h:41
void merge3_iterator(InputIterator &source0, InputIterator &source1, InputIterator &source2, OutputIterator target, unsigned_type length, CompareType &cmp)
Definition: pq_mergers.h:73
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
choose_int_types< my_pointer_size >::unsigned_type unsigned_type
Definition: types.h:67
#define Merge4Case(a, b, c, d)
#define Merge3Case(a, b, c)
#define STXXL_END_NAMESPACE
Definition: namespace.h:17