123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495 |
- #ifndef __BOOST_SORT_COMMON_UTIL_MERGE_HPP
- #define __BOOST_SORT_COMMON_UTIL_MERGE_HPP
- #include <ciso646>
- #include <algorithm>
- #include <functional>
- #include <iterator>
- #include <memory>
- #include <boost/sort/common/util/algorithm.hpp>
- #include <boost/sort/common/util/traits.hpp>
- #include <boost/sort/common/util/circular_buffer.hpp>
- namespace boost
- {
- namespace sort
- {
- namespace common
- {
- namespace util
- {
- namespace here = boost::sort::common::util;
- template<class Iter1_t, class Iter2_t, class Iter3_t, class Compare>
- static Iter3_t merge(Iter1_t buf1, const Iter1_t end_buf1, Iter2_t buf2,
- const Iter2_t end_buf2, Iter3_t buf_out, Compare comp)
- {
-
-
-
- typedef value_iter<Iter1_t> value1_t;
- typedef value_iter<Iter2_t> value2_t;
- typedef value_iter<Iter3_t> value3_t;
- static_assert (std::is_same< value1_t, value2_t >::value,
- "Incompatible iterators\n");
- static_assert (std::is_same< value3_t, value2_t >::value,
- "Incompatible iterators\n");
-
-
-
- const size_t MIN_CHECK = 1024;
- if (size_t((end_buf1 - buf1) + (end_buf2 - buf2)) >= MIN_CHECK)
- {
- if (buf1 == end_buf1) return move_forward(buf_out, buf2, end_buf2);
- if (buf2 == end_buf2) return move_forward(buf_out, buf1, end_buf1);
- if (not comp(*buf2, *(end_buf1 - 1)))
- {
- Iter3_t mid = move_forward(buf_out, buf1, end_buf1);
- return move_forward(mid, buf2, end_buf2);
- };
- if (comp(*(end_buf2 - 1), *buf1))
- {
- Iter3_t mid = move_forward(buf_out, buf2, end_buf2);
- return move_forward(mid, buf1, end_buf1);
- };
- };
- while ((buf1 != end_buf1) and (buf2 != end_buf2))
- {
- *(buf_out++) = (not comp(*buf2, *buf1)) ?
- std::move(*(buf1++)) : std::move(*(buf2++));
- };
- return (buf1 == end_buf1) ?
- move_forward(buf_out, buf2, end_buf2) :
- move_forward(buf_out, buf1, end_buf1);
- }
- ;
- template<class Iter1_t, class Iter2_t, class Value_t, class Compare>
- static Value_t *merge_construct(Iter1_t first1, const Iter1_t last1,
- Iter2_t first2, const Iter2_t last2,
- Value_t *it_out, Compare comp)
- {
-
-
-
- typedef value_iter<Iter1_t> type1;
- typedef value_iter<Iter2_t> type2;
- static_assert (std::is_same< Value_t, type1 >::value,
- "Incompatible iterators\n");
- static_assert (std::is_same< Value_t, type2 >::value,
- "Incompatible iterators\n");
-
-
-
- const size_t MIN_CHECK = 1024;
- if (size_t((last1 - first1) + (last2 - first2)) >= MIN_CHECK)
- {
- if (first1 == last1) return move_construct(it_out, first2, last2);
- if (first2 == last2) return move_construct(it_out, first1, last1);
- if (not comp(*first2, *(last1 - 1)))
- {
- Value_t* mid = move_construct(it_out, first1, last1);
- return move_construct(mid, first2, last2);
- };
- if (comp(*(last2 - 1), *first1))
- {
- Value_t* mid = move_construct(it_out, first2, last2);
- return move_construct(mid, first1, last1);
- };
- };
- while (first1 != last1 and first2 != last2)
- {
- construct_object((it_out++),
- (not comp(*first2, *first1)) ?
- std::move(*(first1++)) :
- std::move(*(first2++)));
- };
- return (first1 == last1) ?
- move_construct(it_out, first2, last2) :
- move_construct(it_out, first1, last1);
- };
- template<class Iter1_t, class Iter2_t, class Compare>
- static Iter2_t merge_half(Iter1_t buf1, const Iter1_t end_buf1, Iter2_t buf2,
- const Iter2_t end_buf2, Iter2_t buf_out, Compare comp)
- {
-
-
-
- typedef value_iter<Iter1_t> value1_t;
- typedef value_iter<Iter2_t> value2_t;
- static_assert (std::is_same< value1_t, value2_t >::value,
- "Incompatible iterators\n");
-
-
-
- #ifdef __BS_DEBUG
- assert ( (buf2 - buf_out) == ( end_buf1 - buf1));
- #endif
- const size_t MIN_CHECK = 1024;
- if (size_t((end_buf1 - buf1) + (end_buf2 - buf2)) >= MIN_CHECK)
- {
- if (buf1 == end_buf1) return end_buf2;
- if (buf2 == end_buf2) return move_forward(buf_out, buf1, end_buf1);
- if (not comp(*buf2, *(end_buf1 - 1)))
- {
- move_forward(buf_out, buf1, end_buf1);
- return end_buf2;
- };
- if (comp(*(end_buf2 - 1), *buf1))
- {
- Iter2_t mid = move_forward(buf_out, buf2, end_buf2);
- return move_forward(mid, buf1, end_buf1);
- };
- };
- while ((buf1 != end_buf1) and (buf2 != end_buf2))
- {
- *(buf_out++) = (not comp(*buf2, *buf1)) ?
- std::move(*(buf1++)) : std::move(*(buf2++));
- };
- return (buf2 == end_buf2)? move_forward(buf_out, buf1, end_buf1) : end_buf2;
- };
- template<class Iter1_t, class Iter2_t, class Compare>
- static Iter2_t merge_half_backward(Iter1_t buf1, Iter1_t end_buf1, Iter2_t buf2,
- Iter2_t end_buf2, Iter1_t end_buf_out,
- Compare comp)
- {
-
-
-
- typedef value_iter<Iter1_t> value1_t;
- typedef value_iter<Iter2_t> value2_t;
- static_assert (std::is_same< value1_t, value2_t >::value,
- "Incompatible iterators\n");
-
-
-
- #ifdef __BS_DEBUG
- assert ((end_buf_out - end_buf1) == (end_buf2 - buf2) );
- #endif
- const size_t MIN_CHECK = 1024;
- if (size_t((end_buf1 - buf1) + (end_buf2 - buf2)) >= MIN_CHECK)
- {
- if (buf2 == end_buf2) return buf1;
- if (buf1 == end_buf1)
- return here::move_backward(end_buf_out, buf2, end_buf2);
- if (not comp(*buf2, *(end_buf1 - 1)))
- {
- here::move_backward(end_buf_out, buf2, end_buf2);
- return buf1;
- };
- if (comp(*(end_buf2 - 1), *buf1))
- {
- Iter1_t mid = here::move_backward(end_buf_out, buf1, end_buf1);
- return here::move_backward(mid, buf2, end_buf2);
- };
- };
- while ((buf1 != end_buf1) and (buf2 != end_buf2))
- {
- *(--end_buf_out) =
- (not comp(*(end_buf2 - 1), *(end_buf1 - 1))) ?
- std::move(*(--end_buf2)):
- std::move(*(--end_buf1));
- };
- return (buf1 == end_buf1) ?
- here::move_backward(end_buf_out, buf2, end_buf2) : buf1;
- };
- template<class Iter1_t, class Iter2_t, class Iter3_t, class Compare>
- static bool merge_uncontiguous(Iter1_t src1, const Iter1_t end_src1,
- Iter2_t src2, const Iter2_t end_src2,
- Iter3_t aux, Compare comp)
- {
-
-
-
- typedef value_iter<Iter1_t> type1;
- typedef value_iter<Iter2_t> type2;
- typedef value_iter<Iter3_t> type3;
- static_assert (std::is_same< type1, type2 >::value,
- "Incompatible iterators\n");
- static_assert (std::is_same< type3, type2 >::value,
- "Incompatible iterators\n");
-
-
-
- if (src1 == end_src1 or src2 == end_src2
- or not comp(*src2, *(end_src1 - 1))) return true;
- while (src1 != end_src1 and not comp(*src2, *src1))
- ++src1;
- Iter3_t const end_aux = aux + (end_src1 - src1);
- Iter2_t src2_first = src2;
- move_forward(aux, src1, end_src1);
- while ((src1 != end_src1) and (src2 != end_src2))
- {
- *(src1++) = std::move((not comp(*src2, *aux)) ? *(aux++) : *(src2++));
- }
- if (src2 == end_src2)
- {
- while (src1 != end_src1)
- *(src1++) = std::move(*(aux++));
- move_forward(src2_first, aux, end_aux);
- }
- else
- {
- merge_half(aux, end_aux, src2, end_src2, src2_first, comp);
- };
- return false;
- };
- template<class Iter1_t, class Iter2_t, class Compare>
- static bool merge_contiguous(Iter1_t src1, Iter1_t src2, Iter1_t end_src2,
- Iter2_t buf, Compare comp)
- {
-
-
-
- typedef value_iter<Iter1_t> type1;
- typedef value_iter<Iter2_t> type2;
- static_assert (std::is_same< type1, type2 >::value,
- "Incompatible iterators\n");
-
-
-
- if (src1 == src2 or src2 == end_src2 or not comp(*src2, *(src2 - 1)))
- return true;
- Iter1_t end_src1 = src2;
- while (src1 != end_src1 and not comp(*src2, *src1))
- ++src1;
- if (src1 == end_src1) return false;
- size_t nx = end_src1 - src1;
- move_forward(buf, src1, end_src1);
- merge_half(buf, buf + nx, src2, end_src2, src1, comp);
- return false;
- };
- template<class Iter1_t, class Iter2_t, class Circular, class Compare>
- static bool merge_circular(Iter1_t buf1, Iter1_t end_buf1, Iter2_t buf2,
- Iter2_t end_buf2, Circular &circ, Compare comp,
- Iter1_t &it1_out, Iter2_t &it2_out)
- {
-
-
-
- typedef value_iter<Iter1_t> type1;
- typedef value_iter<Iter2_t> type2;
- static_assert (std::is_same< type1, type2 >::value,
- "Incompatible iterators\n");
- typedef typename Circular::value_t type3;
- static_assert (std::is_same<type1, type3>::value,
- "Incompatible iterators\n");
-
-
-
- #ifdef __BS_DEBUG
- assert ( circ.free_size() >= size_t ((end_buf1-buf1) + (end_buf2-buf2)));
- #endif
- if (not comp(*buf2, *(end_buf1 - 1)))
- {
- circ.push_move_back(buf1, (end_buf1 - buf1));
- it1_out = end_buf1;
- it2_out = buf2;
- return true;
- };
- if (comp(*(end_buf2 - 1), *buf1))
- {
- circ.push_move_back(buf2, (end_buf2 - buf2));
- it1_out = buf1;
- it2_out = end_buf2;
- return false;
- }
- while (buf1 != end_buf1 and buf2 != end_buf2)
- {
- circ.push_back(comp(*buf2, *buf1) ? std::move(*(buf2++))
- : std::move(*(buf1++)));
- };
- it2_out = buf2;
- it1_out = buf1;
- bool ret = (buf1 == end_buf1);
- return ret;
- };
- };
- };
- };
- };
- #endif
|