File indexing completed on 2025-01-18 09:51:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef __BOOST_SORT_PARALLEL_DETAIL_UTIL_MERGE_FOUR_HPP
0014 #define __BOOST_SORT_PARALLEL_DETAIL_UTIL_MERGE_FOUR_HPP
0015
0016 #include <ciso646>
0017 #include <functional>
0018 #include <iterator>
0019 #include <memory>
0020 #include <vector>
0021 #include <boost/sort/common/util/traits.hpp>
0022 #include <boost/sort/common/range.hpp>
0023
0024
0025 namespace boost
0026 {
0027 namespace sort
0028 {
0029 namespace common
0030 {
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 template<class Iter_t, class Compare = typename util::compare_iter<Iter_t> >
0055 inline bool less_range(Iter_t it1, uint32_t pos1, Iter_t it2, uint32_t pos2,
0056 Compare comp = Compare())
0057 {
0058 return (comp(*it1, *it2)) ? true :
0059 (pos2 < pos1) ? false : not (comp(*it2, *it1));
0060 };
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 template<class Iter1_t, class Iter2_t, class Compare>
0075 range<Iter1_t> full_merge4(const range<Iter1_t> &rdest,
0076 range<Iter2_t> vrange_input[4],
0077 uint32_t nrange_input, Compare comp)
0078 {
0079 using std::swap;
0080 typedef range<Iter1_t> range1_t;
0081 typedef util::value_iter<Iter1_t> type1;
0082 typedef util::value_iter<Iter2_t> type2;
0083 static_assert (std::is_same< type1, type2 >::value,
0084 "Incompatible iterators\n");
0085
0086 size_t ndest = 0;
0087 uint32_t i = 0;
0088 while (i < nrange_input)
0089 {
0090 if (vrange_input[i].size() != 0)
0091 {
0092 ndest += vrange_input[i++].size();
0093 }
0094 else
0095 {
0096 for (uint32_t k = i + 1; k < nrange_input; ++k)
0097 {
0098 vrange_input[k - 1] = vrange_input[k];
0099 };
0100 --nrange_input;
0101 };
0102 };
0103
0104 if (nrange_input == 0) return range1_t(rdest.first, rdest.first);
0105 if (nrange_input == 1) return move_forward(rdest, vrange_input[0]);
0106 if (nrange_input == 2)
0107 {
0108 return merge(rdest, vrange_input[0], vrange_input[1], comp);
0109 };
0110
0111
0112
0113
0114 uint32_t pos[4] =
0115 { 0, 1, 2, 3 }, npos = nrange_input;
0116
0117
0118
0119
0120
0121 if (less_range(vrange_input[pos[1]].first, pos[1],
0122 vrange_input[pos[0]].first, pos[0], comp))
0123 {
0124 swap(pos[0], pos[1]);
0125 };
0126 if (npos == 4 and less_range(vrange_input[pos[3]].first, pos[3],
0127 vrange_input[pos[2]].first, pos[2], comp))
0128 {
0129 swap(pos[3], pos[2]);
0130 };
0131 if (less_range (vrange_input[pos[2]].first, pos[2],
0132 vrange_input[pos[0]].first, pos[0], comp))
0133 {
0134 swap(pos[0], pos[2]);
0135 };
0136 if (npos == 4
0137 and less_range (vrange_input[pos[3]].first, pos[3],
0138 vrange_input[pos[1]].first, pos[1], comp))
0139 {
0140 swap(pos[1], pos[3]);
0141 };
0142 if (less_range (vrange_input[pos[2]].first, pos[2],
0143 vrange_input[pos[1]].first, pos[1], comp))
0144 {
0145 swap(pos[1], pos[2]);
0146 };
0147
0148 Iter1_t it_dest = rdest.first;
0149 while (npos > 2)
0150 {
0151 *(it_dest++) = std::move(*(vrange_input[pos[0]].first++));
0152 if (vrange_input[pos[0]].size() == 0)
0153 {
0154 pos[0] = pos[1];
0155 pos[1] = pos[2];
0156 pos[2] = pos[3];
0157 --npos;
0158 }
0159 else
0160 {
0161 if (less_range(vrange_input[pos[1]].first, pos[1],
0162 vrange_input[pos[0]].first, pos[0], comp))
0163 {
0164 swap(pos[0], pos[1]);
0165 if (less_range(vrange_input[pos[2]].first, pos[2],
0166 vrange_input[pos[1]].first, pos[1], comp))
0167 {
0168 swap(pos[1], pos[2]);
0169 if (npos == 4
0170 and less_range(vrange_input[pos[3]].first,
0171 pos[3],
0172 vrange_input[pos[2]].first,
0173 pos[2], comp))
0174 {
0175 swap(pos[2], pos[3]);
0176 };
0177 };
0178 };
0179 };
0180 };
0181
0182 range1_t raux1(rdest.first, it_dest), raux2(it_dest, rdest.last);
0183 if (pos[0] < pos[1])
0184 {
0185 return concat(raux1,merge(raux2, vrange_input[pos[0]],
0186 vrange_input[pos[1]], comp));
0187 }
0188 else
0189 {
0190 return concat(raux1, merge (raux2, vrange_input[pos[1]],
0191 vrange_input[pos[0]], comp));
0192 };
0193 };
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207 template<class Value_t, class Iter_t, class Compare>
0208 range<Value_t *> uninit_full_merge4(const range<Value_t *> &dest,
0209 range<Iter_t> vrange_input[4],
0210 uint32_t nrange_input, Compare comp)
0211 {
0212 using std::swap;
0213 typedef util::value_iter<Iter_t> type1;
0214 static_assert (std::is_same< type1, Value_t >::value,
0215 "Incompatible iterators\n");
0216
0217 size_t ndest = 0;
0218 uint32_t i = 0;
0219 while (i < nrange_input)
0220 {
0221 if (vrange_input[i].size() != 0)
0222 {
0223 ndest += vrange_input[i++].size();
0224 }
0225 else
0226 {
0227 for (uint32_t k = i + 1; k < nrange_input; ++k)
0228 {
0229 vrange_input[k - 1] = vrange_input[k];
0230 };
0231 --nrange_input;
0232 };
0233 };
0234 if (nrange_input == 0) return range<Value_t *>(dest.first, dest.first);
0235 if (nrange_input == 1) return move_construct(dest, vrange_input[0]);
0236 if (nrange_input == 2)
0237 {
0238 return merge_construct(dest, vrange_input[0], vrange_input[1], comp);
0239 };
0240
0241
0242
0243
0244 uint32_t pos[4] = { 0, 1, 2, 3 }, npos = nrange_input;
0245
0246
0247
0248
0249
0250 if (less_range(vrange_input[pos[1]].first, pos[1],
0251 vrange_input[pos[0]].first, pos[0], comp))
0252 {
0253 swap(pos[0], pos[1]);
0254 };
0255 if (npos == 4 and less_range(vrange_input[pos[3]].first, pos[3],
0256 vrange_input[pos[2]].first, pos[2], comp))
0257 {
0258 swap(pos[3], pos[2]);
0259 };
0260 if (less_range(vrange_input[pos[2]].first, pos[2],
0261 vrange_input[pos[0]].first, pos[0], comp))
0262 {
0263 swap(pos[0], pos[2]);
0264 };
0265 if (npos == 4 and less_range(vrange_input[pos[3]].first, pos[3],
0266 vrange_input[pos[1]].first, pos[1], comp))
0267 {
0268 swap(pos[1], pos[3]);
0269 };
0270 if (less_range(vrange_input[pos[2]].first, pos[2],
0271 vrange_input[pos[1]].first, pos[1], comp))
0272 {
0273 swap(pos[1], pos[2]);
0274 };
0275
0276 Value_t *it_dest = dest.first;
0277 while (npos > 2)
0278 {
0279 util::construct_object(&(*(it_dest++)),
0280 std::move(*(vrange_input[pos[0]].first++)));
0281 if (vrange_input[pos[0]].size() == 0)
0282 {
0283 pos[0] = pos[1];
0284 pos[1] = pos[2];
0285 pos[2] = pos[3];
0286 --npos;
0287 }
0288 else
0289 {
0290 if (less_range (vrange_input[pos[1]].first, pos[1],
0291 vrange_input[pos[0]].first, pos[0], comp))
0292 {
0293 swap(pos[0], pos[1]);
0294 if (less_range (vrange_input[pos[2]].first, pos[2],
0295 vrange_input[pos[1]].first, pos[1], comp))
0296 {
0297 swap(pos[1], pos[2]);
0298 if (npos == 4 and less_range(vrange_input[pos[3]].first,
0299 pos[3],
0300 vrange_input[pos[2]].first,
0301 pos[2], comp))
0302 {
0303 swap(pos[2], pos[3]);
0304 };
0305 };
0306 };
0307 };
0308 };
0309
0310 range<Value_t *> raux1(dest.first, it_dest), raux2(it_dest, dest.last);
0311 if (pos[0] < pos[1])
0312 {
0313 return concat(raux1,
0314 merge_construct(raux2, vrange_input[pos[0]],
0315 vrange_input[pos[1]], comp));
0316 }
0317 else
0318 {
0319 return concat(raux1,
0320 merge_construct(raux2, vrange_input[pos[1]],
0321 vrange_input[pos[0]], comp));
0322 };
0323 };
0324
0325
0326 };
0327 };
0328 };
0329
0330
0331 #endif