STXXL  1.4.1
 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,
41  class CompareType, typename SizeType>
43  InputIterator& source0,
44  InputIterator& source1,
45  OutputIterator target,
46  SizeType length,
47  CompareType& cmp)
48 {
49  OutputIterator done = target + length;
50 
51  while (target != done)
52  {
53  if (cmp(*source0, *source1))
54  {
55  *target = *source1;
56  ++source1;
57  }
58  else
59  {
60  *target = *source0;
61  ++source0;
62  }
63  ++target;
64  }
65 }
66 
67 // merge length elements from the three sentinel terminated input
68 // sequences source0, source1 and source2 to target
69 // advance source0, source1 and source2 accordingly
70 // require: at least length nonsentinel elements available in source0, source1 and source2
71 // require: target may overwrite one of the sources as long as
72 // *(sourcex + length) is before the end of sourcex
73 template <class InputIterator, class OutputIterator,
74  class CompareType, typename SizeType>
76  InputIterator& source0,
77  InputIterator& source1,
78  InputIterator& source2,
79  OutputIterator target,
80  SizeType length,
81  CompareType& cmp)
82 {
83  OutputIterator done = target + length;
84 
85  if (cmp(*source1, *source0)) {
86  if (cmp(*source2, *source1)) {
87  goto s012;
88  }
89  else {
90  if (cmp(*source0, *source2)) {
91  goto s201;
92  }
93  else {
94  goto s021;
95  }
96  }
97  } else {
98  if (cmp(*source2, *source1)) {
99  if (cmp(*source2, *source0)) {
100  goto s102;
101  }
102  else {
103  goto s120;
104  }
105  } else {
106  goto s210;
107  }
108  }
109 
110 #define Merge3Case(a, b, c) \
111  s ## a ## b ## c : \
112  if (target == done) \
113  return; \
114  *target = *source ## a; \
115  ++target; \
116  ++source ## a; \
117  if (cmp(*source ## b, *source ## a)) \
118  goto s ## a ## b ## c; \
119  if (cmp(*source ## c, *source ## a)) \
120  goto s ## b ## a ## c; \
121  goto s ## b ## c ## a;
122 
123  // the order is chosen in such a way that
124  // four of the trailing gotos can be eliminated by the optimizer
125  Merge3Case(0, 1, 2);
126  Merge3Case(1, 2, 0);
127  Merge3Case(2, 0, 1);
128  Merge3Case(1, 0, 2);
129  Merge3Case(0, 2, 1);
130  Merge3Case(2, 1, 0);
131 
132 #undef Merge3Case
133 }
134 
135 // merge length elements from the four sentinel terminated input
136 // sequences source0, source1, source2 and source3 to target
137 // advance source0, source1, source2 and source3 accordingly
138 // require: at least length nonsentinel elements available in source0, source1, source2 and source3
139 // require: target may overwrite one of the sources as long as
140 // *(sourcex + length) is before the end of sourcex
141 template <class InputIterator, class OutputIterator,
142  class CompareType, typename SizeType>
144  InputIterator& source0,
145  InputIterator& source1,
146  InputIterator& source2,
147  InputIterator& source3,
148  OutputIterator target, SizeType length, CompareType& cmp)
149 {
150  OutputIterator done = target + length;
151 
152 #define StartMerge4(a, b, c, d) \
153  if ((!cmp(*source ## a, *source ## b)) && \
154  (!cmp(*source ## b, *source ## c)) && \
155  (!cmp(*source ## c, *source ## d))) \
156  goto s ## a ## b ## c ## d;
157 
158  // b>a c>b d>c
159  // a<b b<c c<d
160  // a<=b b<=c c<=d
161  // !(a>b) !(b>c) !(c>d)
162 
163  StartMerge4(0, 1, 2, 3);
164  StartMerge4(1, 2, 3, 0);
165  StartMerge4(2, 3, 0, 1);
166  StartMerge4(3, 0, 1, 2);
167 
168  StartMerge4(0, 3, 1, 2);
169  StartMerge4(3, 1, 2, 0);
170  StartMerge4(1, 2, 0, 3);
171  StartMerge4(2, 0, 3, 1);
172 
173  StartMerge4(0, 2, 3, 1);
174  StartMerge4(2, 3, 1, 0);
175  StartMerge4(3, 1, 0, 2);
176  StartMerge4(1, 0, 2, 3);
177 
178  StartMerge4(2, 0, 1, 3);
179  StartMerge4(0, 1, 3, 2);
180  StartMerge4(1, 3, 2, 0);
181  StartMerge4(3, 2, 0, 1);
182 
183  StartMerge4(3, 0, 2, 1);
184  StartMerge4(0, 2, 1, 3);
185  StartMerge4(2, 1, 3, 0);
186  StartMerge4(1, 3, 0, 2);
187 
188  StartMerge4(1, 0, 3, 2);
189  StartMerge4(0, 3, 2, 1);
190  StartMerge4(3, 2, 1, 0);
191  StartMerge4(2, 1, 0, 3);
192 
193 #define Merge4Case(a, b, c, d) \
194  s ## a ## b ## c ## d : \
195  if (target == done) \
196  return; \
197  *target = *source ## a; \
198  ++target; \
199  ++source ## a; \
200  if (cmp(*source ## c, *source ## a)) \
201  { \
202  if (cmp(*source ## b, *source ## a)) \
203  goto s ## a ## b ## c ## d; \
204  else \
205  goto s ## b ## a ## c ## d; \
206  } \
207  else \
208  { \
209  if (cmp(*source ## d, *source ## a)) \
210  goto s ## b ## c ## a ## d; \
211  else \
212  goto s ## b ## c ## d ## a; \
213  }
214 
215  Merge4Case(0, 1, 2, 3);
216  Merge4Case(1, 2, 3, 0);
217  Merge4Case(2, 3, 0, 1);
218  Merge4Case(3, 0, 1, 2);
219 
220  Merge4Case(0, 3, 1, 2);
221  Merge4Case(3, 1, 2, 0);
222  Merge4Case(1, 2, 0, 3);
223  Merge4Case(2, 0, 3, 1);
224 
225  Merge4Case(0, 2, 3, 1);
226  Merge4Case(2, 3, 1, 0);
227  Merge4Case(3, 1, 0, 2);
228  Merge4Case(1, 0, 2, 3);
229 
230  Merge4Case(2, 0, 1, 3);
231  Merge4Case(0, 1, 3, 2);
232  Merge4Case(1, 3, 2, 0);
233  Merge4Case(3, 2, 0, 1);
234 
235  Merge4Case(3, 0, 2, 1);
236  Merge4Case(0, 2, 1, 3);
237  Merge4Case(2, 1, 3, 0);
238  Merge4Case(1, 3, 0, 2);
239 
240  Merge4Case(1, 0, 3, 2);
241  Merge4Case(0, 3, 2, 1);
242  Merge4Case(3, 2, 1, 0);
243  Merge4Case(2, 1, 0, 3);
244 
245 #undef StartMerge4
246 #undef Merge4Case
247 }
248 
249 } // namespace priority_queue_local
250 
251 //! \}
252 
254 
255 #endif // !STXXL_CONTAINERS_PQ_MERGERS_HEADER
256 // vim: et:ts=4:sw=4
#define StartMerge4(a, b, c, d)
void merge3_iterator(InputIterator &source0, InputIterator &source1, InputIterator &source2, OutputIterator target, SizeType length, CompareType &cmp)
Definition: pq_mergers.h:75
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
#define Merge4Case(a, b, c, d)
void merge_iterator(InputIterator &source0, InputIterator &source1, OutputIterator target, SizeType length, CompareType &cmp)
Definition: pq_mergers.h:42
#define Merge3Case(a, b, c)
#define STXXL_END_NAMESPACE
Definition: namespace.h:17
void merge4_iterator(InputIterator &source0, InputIterator &source1, InputIterator &source2, InputIterator &source3, OutputIterator target, SizeType length, CompareType &cmp)
Definition: pq_mergers.h:143