Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * include/stxxl/bits/containers/pq_mergers.h 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 1999 Peter Sanders <sanders@mpi-sb.mpg.de> 00007 * Copyright (C) 2003, 2004, 2007 Roman Dementiev <dementiev@mpi-sb.mpg.de> 00008 * Copyright (C) 2007-2009 Johannes Singler <singler@ira.uka.de> 00009 * Copyright (C) 2007, 2008 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00010 * 00011 * Distributed under the Boost Software License, Version 1.0. 00012 * (See accompanying file LICENSE_1_0.txt or copy at 00013 * http://www.boost.org/LICENSE_1_0.txt) 00014 **************************************************************************/ 00015 00016 #ifndef STXXL_PQ_MERGERS_HEADER 00017 #define STXXL_PQ_MERGERS_HEADER 00018 00019 __STXXL_BEGIN_NAMESPACE 00020 00021 //! \addtogroup stlcontinternals 00022 //! 00023 //! \{ 00024 00025 /*! \internal 00026 */ 00027 namespace priority_queue_local 00028 { 00029 ///////////////////////////////////////////////////////////////////// 00030 // auxiliary functions 00031 00032 // merge length elements from the two sentinel terminated input 00033 // sequences source0 and source1 to target 00034 // advance source0 and source1 accordingly 00035 // require: at least length nonsentinel elements available in source0, source1 00036 // require: target may overwrite one of the sources as long as 00037 // *(sourcex + length) is before the end of sourcex 00038 template <class InputIterator, class OutputIterator, class Cmp_> 00039 void merge_iterator( 00040 InputIterator & source0, 00041 InputIterator & source1, 00042 OutputIterator target, 00043 unsigned_type length, 00044 Cmp_& cmp) 00045 { 00046 OutputIterator done = target + length; 00047 00048 while (target != done) 00049 { 00050 if (cmp(*source0, *source1)) 00051 { 00052 *target = *source1; 00053 ++source1; 00054 } 00055 else 00056 { 00057 *target = *source0; 00058 ++source0; 00059 } 00060 ++target; 00061 } 00062 } 00063 00064 // merge length elements from the three sentinel terminated input 00065 // sequences source0, source1 and source2 to target 00066 // advance source0, source1 and source2 accordingly 00067 // require: at least length nonsentinel elements available in source0, source1 and source2 00068 // require: target may overwrite one of the sources as long as 00069 // *(sourcex + length) is before the end of sourcex 00070 template <class InputIterator, class OutputIterator, class Cmp_> 00071 void merge3_iterator( 00072 InputIterator & source0, 00073 InputIterator & source1, 00074 InputIterator & source2, 00075 OutputIterator target, 00076 unsigned_type length, 00077 Cmp_& cmp) 00078 { 00079 OutputIterator done = target + length; 00080 00081 if (cmp(*source1, *source0)) { 00082 if (cmp(*source2, *source1)) { 00083 goto s012; 00084 } 00085 else { 00086 if (cmp(*source0, *source2)) { 00087 goto s201; 00088 } 00089 else { 00090 goto s021; 00091 } 00092 } 00093 } else { 00094 if (cmp(*source2, *source1)) { 00095 if (cmp(*source2, *source0)) { 00096 goto s102; 00097 } 00098 else { 00099 goto s120; 00100 } 00101 } else { 00102 goto s210; 00103 } 00104 } 00105 00106 #define Merge3Case(a, b, c) \ 00107 s ## a ## b ## c : \ 00108 if (target == done) \ 00109 return; \ 00110 *target = *source ## a; \ 00111 ++target; \ 00112 ++source ## a; \ 00113 if (cmp(*source ## b, *source ## a)) \ 00114 goto s ## a ## b ## c; \ 00115 if (cmp(*source ## c, *source ## a)) \ 00116 goto s ## b ## a ## c; \ 00117 goto s ## b ## c ## a; 00118 00119 // the order is chosen in such a way that 00120 // four of the trailing gotos can be eliminated by the optimizer 00121 Merge3Case(0, 1, 2); 00122 Merge3Case(1, 2, 0); 00123 Merge3Case(2, 0, 1); 00124 Merge3Case(1, 0, 2); 00125 Merge3Case(0, 2, 1); 00126 Merge3Case(2, 1, 0); 00127 00128 #undef Merge3Case 00129 } 00130 00131 00132 // merge length elements from the four sentinel terminated input 00133 // sequences source0, source1, source2 and source3 to target 00134 // advance source0, source1, source2 and source3 accordingly 00135 // require: at least length nonsentinel elements available in source0, source1, source2 and source3 00136 // require: target may overwrite one of the sources as long as 00137 // *(sourcex + length) is before the end of sourcex 00138 template <class InputIterator, class OutputIterator, class Cmp_> 00139 void merge4_iterator( 00140 InputIterator & source0, 00141 InputIterator & source1, 00142 InputIterator & source2, 00143 InputIterator & source3, 00144 OutputIterator target, unsigned_type length, Cmp_& cmp) 00145 { 00146 OutputIterator done = target + length; 00147 00148 #define StartMerge4(a, b, c, d) \ 00149 if ((!cmp(*source ## a, *source ## b)) && (!cmp(*source ## b, *source ## c)) && (!cmp(*source ## c, *source ## d))) \ 00150 goto s ## a ## b ## c ## d; 00151 00152 // b>a c>b d>c 00153 // a<b b<c c<d 00154 // a<=b b<=c c<=d 00155 // !(a>b) !(b>c) !(c>d) 00156 00157 StartMerge4(0, 1, 2, 3); 00158 StartMerge4(1, 2, 3, 0); 00159 StartMerge4(2, 3, 0, 1); 00160 StartMerge4(3, 0, 1, 2); 00161 00162 StartMerge4(0, 3, 1, 2); 00163 StartMerge4(3, 1, 2, 0); 00164 StartMerge4(1, 2, 0, 3); 00165 StartMerge4(2, 0, 3, 1); 00166 00167 StartMerge4(0, 2, 3, 1); 00168 StartMerge4(2, 3, 1, 0); 00169 StartMerge4(3, 1, 0, 2); 00170 StartMerge4(1, 0, 2, 3); 00171 00172 StartMerge4(2, 0, 1, 3); 00173 StartMerge4(0, 1, 3, 2); 00174 StartMerge4(1, 3, 2, 0); 00175 StartMerge4(3, 2, 0, 1); 00176 00177 StartMerge4(3, 0, 2, 1); 00178 StartMerge4(0, 2, 1, 3); 00179 StartMerge4(2, 1, 3, 0); 00180 StartMerge4(1, 3, 0, 2); 00181 00182 StartMerge4(1, 0, 3, 2); 00183 StartMerge4(0, 3, 2, 1); 00184 StartMerge4(3, 2, 1, 0); 00185 StartMerge4(2, 1, 0, 3); 00186 00187 #define Merge4Case(a, b, c, d) \ 00188 s ## a ## b ## c ## d : \ 00189 if (target == done) \ 00190 return; \ 00191 *target = *source ## a; \ 00192 ++target; \ 00193 ++source ## a; \ 00194 if (cmp(*source ## c, *source ## a)) \ 00195 { \ 00196 if (cmp(*source ## b, *source ## a)) \ 00197 goto s ## a ## b ## c ## d; \ 00198 else \ 00199 goto s ## b ## a ## c ## d; \ 00200 } \ 00201 else \ 00202 { \ 00203 if (cmp(*source ## d, *source ## a)) \ 00204 goto s ## b ## c ## a ## d; \ 00205 else \ 00206 goto s ## b ## c ## d ## a; \ 00207 } 00208 00209 Merge4Case(0, 1, 2, 3); 00210 Merge4Case(1, 2, 3, 0); 00211 Merge4Case(2, 3, 0, 1); 00212 Merge4Case(3, 0, 1, 2); 00213 00214 Merge4Case(0, 3, 1, 2); 00215 Merge4Case(3, 1, 2, 0); 00216 Merge4Case(1, 2, 0, 3); 00217 Merge4Case(2, 0, 3, 1); 00218 00219 Merge4Case(0, 2, 3, 1); 00220 Merge4Case(2, 3, 1, 0); 00221 Merge4Case(3, 1, 0, 2); 00222 Merge4Case(1, 0, 2, 3); 00223 00224 Merge4Case(2, 0, 1, 3); 00225 Merge4Case(0, 1, 3, 2); 00226 Merge4Case(1, 3, 2, 0); 00227 Merge4Case(3, 2, 0, 1); 00228 00229 Merge4Case(3, 0, 2, 1); 00230 Merge4Case(0, 2, 1, 3); 00231 Merge4Case(2, 1, 3, 0); 00232 Merge4Case(1, 3, 0, 2); 00233 00234 Merge4Case(1, 0, 3, 2); 00235 Merge4Case(0, 3, 2, 1); 00236 Merge4Case(3, 2, 1, 0); 00237 Merge4Case(2, 1, 0, 3); 00238 00239 #undef StartMerge4 00240 #undef Merge4Case 00241 } 00242 } //priority_queue_local 00243 00244 //! \} 00245 00246 __STXXL_END_NAMESPACE 00247 00248 #endif // !STXXL_PQ_MERGERS_HEADER 00249 // vim: et:ts=4:sw=4