merging move from develop

This commit is contained in:
Ion Gaztañaga
2017-11-01 11:50:48 +01:00
6 changed files with 132 additions and 95 deletions

View File

@@ -788,6 +788,15 @@ Many thanks to all boosters that have tested, reviewed and improved the library.
[section:release_notes Release Notes]
[section:release_notes_boost_1_66 Boost 1.66 Release]
* Fixed bugs:
* [@https://github.com/boostorg/move/pull/14 Git Pull #14: ['"Workaround for bogus [-Wignored-attributes] warning on GCC 6.x/7.x"]].
* [@https://github.com/boostorg/move/issues/15 Git Issue #15: ['"Incorrect merge in adaptive_merge when the number of unique items is limited"]].
[endsect]
[section:release_notes_boost_1_65 Boost 1.65 Release]
* Fixed bug:

View File

@@ -53,12 +53,29 @@
#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
#ifndef BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL
#define BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL 1
#endif
#ifdef BOOST_MOVE_ADAPTIVE_SORT_STATS
#define BOOST_MOVE_ADAPTIVE_SORT_PRINT(STR, L) \
print_stats(STR, L)\
//
#if BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL == 2
#define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(STR, L) \
print_stats(STR, L)\
//
#define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(STR, L) \
print_stats(STR, L)\
//
#else
#define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(STR, L) \
print_stats(STR, L)\
//
#define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(STR, L)
#endif
#else
#define BOOST_MOVE_ADAPTIVE_SORT_PRINT(STR, L)
#define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(STR, L)
#define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(STR, L)
#endif
#ifdef BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS
@@ -421,7 +438,12 @@ RandItB op_buffered_partial_merge_to_range1_and_buffer
lastb = op(forward_t(), first1, last1, firstb);
break;
}
op(three_way_t(), comp(*first2, *firstb) ? first2++ : firstb++, first1++, lastb++);
if (comp(*first2, *firstb)) {
op(three_way_t(), first2++, first1++, lastb++);
}
else {
op(three_way_t(), firstb++, first1++, lastb++);
}
}
rfirst2 = first2;
rfirstb = firstb;
@@ -432,15 +454,14 @@ RandItB op_buffered_partial_merge_to_range1_and_buffer
template<class RandItKeys, class RandIt>
void swap_and_update_key
( bool is_next_far_away
, RandItKeys const key_next
( RandItKeys const key_next
, RandItKeys const key_range2
, RandItKeys &key_mid
, RandIt const begin
, RandIt const end
, RandIt const with)
{
if(is_next_far_away){
if(begin != with){
::boost::adl_move_swap_ranges(begin, end, with);
::boost::adl_move_swap(*key_next, *key_range2);
if(key_next == key_mid){
@@ -575,7 +596,7 @@ void merge_blocks_bufferless
}
n_bef_irreg2 += l_irreg_pos_count;
swap_and_update_key(next_key_idx != 0, key_next, key_range2, key_mid, f, f + l_block, first_min);
swap_and_update_key(key_next, key_range2, key_mid, f, f + l_block, first_min);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(f, f+l_block, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_min, first_min + l_block, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((f == (first+l_irreg1)) || !comp(*f, *(f-l_block)));
@@ -995,9 +1016,8 @@ RandItB op_buffered_partial_merge_and_swap_to_range1_and_buffer
lastb = op(forward_t(), first1, last1, firstb);
break;
}
bool const min_less = comp(*first_min, *firstb);
if(min_less){
if(comp(*first_min, *firstb)){
op( four_way_t(), first2++, first_min++, first1++, lastb++);
}
else{
@@ -1084,8 +1104,8 @@ OutputIt op_partial_merge_and_swap_impl
}
template<class RandIt, class InputIt2, class OutputIt, class Compare, class Op>
RandIt op_partial_merge_and_swap
(RandIt &r_first1, RandIt const last1, RandIt &r_first2, RandIt const last2, InputIt2 &r_first_min, OutputIt d_first, Compare comp, Op op, bool is_stable)
OutputIt op_partial_merge_and_swap
(RandIt &r_first1, RandIt const last1, InputIt2 &r_first2, InputIt2 const last2, InputIt2 &r_first_min, OutputIt d_first, Compare comp, Op op, bool is_stable)
{
return is_stable ? op_partial_merge_and_swap_impl(r_first1, last1, r_first2, last2, r_first_min, d_first, comp, op)
: op_partial_merge_and_swap_impl(r_first1, last1, r_first2, last2, r_first_min, d_first, antistable<Compare>(comp), op);
@@ -1174,7 +1194,7 @@ OutputIt op_merge_blocks_with_irreg
OutputIt orig_dest = dest; (void)orig_dest;
dest = next_key_idx ? op_partial_merge_and_swap(first_irr, last_irr, first_reg, last_reg, first_min, dest, comp, op, is_stable)
: op_partial_merge (first_irr, last_irr, first_reg, last_reg, dest, comp, op, is_stable);
: op_partial_merge (first_irr, last_irr, first_reg, last_reg, dest, comp, op, is_stable);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(orig_dest, dest, comp));
if(first_reg == dest){
@@ -1187,7 +1207,7 @@ OutputIt op_merge_blocks_with_irreg
}
RandItKeys const key_next(key_first + next_key_idx);
swap_and_update_key(next_key_idx != 0, key_next, key_first, key_mid, last_reg, last_reg, first_min);
swap_and_update_key(key_next, key_first, key_mid, last_reg, last_reg, first_min);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(orig_dest, dest, comp));
first_reg = last_reg;
@@ -1262,7 +1282,7 @@ void op_merge_blocks_left
if(!is_buffer_middle){
buffer = op(forward_t(), first1, last1, buffer);
}
swap_and_update_key(next_key_idx != 0, key_next, key_range2, key_mid, first2, last2, first_min);
swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min);
first1 = first2;
last1 = last2;
}
@@ -1284,7 +1304,7 @@ void op_merge_blocks_left
(void)unmerged;
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first-l_block, unmerged, comp));
swap_and_update_key( next_key_idx != 0, key_next, key_range2, key_mid, first2, last2
swap_and_update_key( key_next, key_range2, key_mid, first2, last2
, last_min - size_type(last2 - first2));
if(buf_beg != buf_end){ //range2 exhausted: is_buffer_middle for the next iteration
@@ -1395,9 +1415,9 @@ void merge_blocks_right
, bool const xbuf_used)
{
merge_blocks_left
( make_reverse_iterator(key_first + needed_keys_count(n_block_a, n_block_b))
( (make_reverse_iterator)(key_first + needed_keys_count(n_block_a, n_block_b))
, inverse<KeyCompare>(key_comp)
, make_reverse_iterator(first + ((n_block_a+n_block_b)*l_block+l_irreg2))
, (make_reverse_iterator)(first + ((n_block_a+n_block_b)*l_block+l_irreg2))
, l_block
, l_irreg2
, n_block_b
@@ -1474,7 +1494,7 @@ void op_merge_blocks_with_buf
RandIt res = op(forward_t(), buffer, buffer_end, first1);
buffer = buffer_end = buf_first;
BOOST_ASSERT(buffer_empty || res == last1); (void)res;
swap_and_update_key(next_key_idx != 0, key_next, key_range2, key_mid, first2, last2, first_min);
swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first2, last2, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_min, last_min, comp));
first1 = first2;
@@ -1492,7 +1512,7 @@ void op_merge_blocks_with_buf
first_min = last_min;
}
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!is_range_1_empty || (last_min-first_min) == (last2-unmerged));
swap_and_update_key(next_key_idx != 0, key_next, key_range2, key_mid, first2, last2, first_min);
swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_min, last_min, comp));
is_range1_A ^= is_range_1_empty;
@@ -1518,9 +1538,9 @@ void op_merge_blocks_with_buf
reverse_iterator<RandItBuf> rbuf_beg(buffer_end);
RandIt dest = op_merge_blocks_with_irreg
( make_reverse_iterator(key_first + n_block_b + n_block_a), make_reverse_iterator(key_mid), inverse<KeyCompare>(key_comp)
, make_reverse_iterator(first_irr2), rbuf_beg
, make_reverse_iterator(buffer), make_reverse_iterator(last_irr2)
((make_reverse_iterator)(key_first + n_block_b + n_block_a), (make_reverse_iterator)(key_mid), inverse<KeyCompare>(key_comp)
, (make_reverse_iterator)(first_irr2), rbuf_beg
, (make_reverse_iterator)(buffer), (make_reverse_iterator)(last_irr2)
, l_block, n_block_left, 0, n_block_left
, inverse<Compare>(comp), true, op).base();
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(dest, last_irr2, comp));
@@ -1792,7 +1812,7 @@ void adaptive_sort_combine_blocks
combine_params( keys, key_comp, l_cur_combined
, l_prev_merged, l_block, rbuf
, n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A combpar: ", len + l_block);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A combpar: ", len + l_block);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(combined_first, combined_first + n_block_a*l_block+l_irreg1, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(combined_first + n_block_a*l_block+l_irreg1, combined_first + n_block_a*l_block+l_irreg1+n_block_b*l_block+l_irreg2, comp));
if(!use_buf){
@@ -1803,7 +1823,7 @@ void adaptive_sort_combine_blocks
merge_blocks_left
(keys, key_comp, combined_first, l_block, 0u, n_block_a, n_block_b, l_irreg2, comp, xbuf_used);
}
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" After merge_blocks_l: ", len + l_block);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" After merge_blocks_L: ", len + l_block);
}
}
else{
@@ -1818,12 +1838,12 @@ void adaptive_sort_combine_blocks
combine_params( keys, key_comp, l_cur_combined
, l_prev_merged, l_block, rbuf
, n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A combpar: ", len + l_block);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A combpar: ", len + l_block);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(combined_first, combined_first + n_block_a*l_block+l_irreg1, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(combined_first + n_block_a*l_block+l_irreg1, combined_first + n_block_a*l_block+l_irreg1+n_block_b*l_block+l_irreg2, comp));
merge_blocks_right
(keys, key_comp, combined_first, l_block, n_block_a, n_block_b, l_irreg2, comp, xbuf_used);
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" After merge_blocks_r: ", len + l_block);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" After merge_blocks_R: ", len + l_block);
}
}
}
@@ -1889,7 +1909,7 @@ bool adaptive_sort_combine_all_blocks
move_data_forward(buf_end, l_diff, buf_beg, common_xbuf);
}
}
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" After move_data : ", l_data + l_intbuf);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" After move_data : ", l_data + l_intbuf);
}
//Combine to form l_merged*2 segments
@@ -1904,7 +1924,8 @@ bool adaptive_sort_combine_all_blocks
( uint_keys, less(), !use_internal_buf || is_merge_left ? first : first-l_block
, l_data, l_merged, l_block, use_internal_buf, common_xbuf, xbuf, comp, is_merge_left);
}
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" After combine_blocks: ", l_data + l_intbuf);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(is_merge_left ? " After comb blocks L: " : " After comb blocks R: ", l_data + l_intbuf);
prev_merge_left = is_merge_left;
l_prev_total_combined = l_total_combined;
l_prev_block = l_block;
@@ -1981,7 +2002,7 @@ void adaptive_sort_final_merge( bool buffer_right
merge_bufferless(first, first+n_key_plus_buf, first+len, comp);
}
}
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" After final_merge : ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" After final_merge : ", len);
}
template<class RandIt, class Compare, class Unsigned, class XBuf>
@@ -2096,7 +2117,7 @@ inline void adaptive_merge_combine_blocks( RandIt first
if(n_keys){
RandIt const first_data = first+collected;
RandIt const keys = first;
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A combine: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A combine: ", len);
if(xbuf_used){
if(xbuf.size() < l_block){
xbuf.initialize_until(l_block, *first);
@@ -2108,7 +2129,7 @@ inline void adaptive_merge_combine_blocks( RandIt first
, n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs
merge_blocks_with_buf
(keys, comp, first_data, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, xbuf.data(), xbuf_used);
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A mrg xbf: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" A mrg xbf: ", len);
}
else{
size_type n_block_a, n_block_b, l_irreg1, l_irreg2;
@@ -2118,12 +2139,12 @@ inline void adaptive_merge_combine_blocks( RandIt first
if(use_internal_buf){
merge_blocks_with_buf
(keys, comp, first_data, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, first_data-l_block, xbuf_used);
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A mrg buf: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A mrg buf: ", len);
}
else{
merge_blocks_bufferless
(keys, comp, first_data, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp);
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A mrg nbf: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" A mrg nbf: ", len);
}
}
}
@@ -2137,12 +2158,12 @@ inline void adaptive_merge_combine_blocks( RandIt first
combine_params( uint_keys, less(), l_combine
, l_combine1, l_block, xbuf
, n_block_a, n_block_b, l_irreg1, l_irreg2, true); //Outputs
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A combine: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A combine: ", len);
BOOST_ASSERT(xbuf.size() >= l_block);
merge_blocks_with_buf
(uint_keys, less(), first, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, xbuf.data(), true);
xbuf.clear();
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A mrg buf: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" A mrg buf: ", len);
}
}
@@ -2170,24 +2191,25 @@ inline void adaptive_merge_final_merge( RandIt first
if(n_keys){
stable_sort(first, first+n_keys, comp, xbuf);
stable_merge(first, first+n_keys, first+len, comp, xbuf);
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A key mrg: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A key mrg: ", len);
}
}
else{
xbuf.clear();
stable_sort(first, first+collected, comp, xbuf);
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A k/b srt: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b srt: ", len);
stable_merge(first, first+collected, first+len, comp, xbuf);
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A k/b mrg: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b mrg: ", len);
}
}
else{
xbuf.clear();
stable_sort(first, first+collected, comp, xbuf);
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A k/b srt: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b srt: ", len);
stable_merge(first, first+collected, first+len1+len2, comp, xbuf);
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" A k/b mrg: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b mrg: ", len);
}
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" A fin mrg: ", len);
}
template<class SizeType, class Xbuf>
@@ -2250,8 +2272,8 @@ inline SizeType adaptive_merge_n_keys_intbuf(SizeType &rl_block, SizeType len1,
// Iteratively for each pair of previously merged block:
// * Blocks are divided groups of csqrtlen elements and
// 2*merged_block/csqrtlen keys are sorted to be used as markers
// * Groups are selection-sorted by first or last element (depending wheter they
// merged to left or right) and keys are reordered accordingly as an imitation-buffer.
// * Groups are selection-sorted by first or last element (depending whether they are going
// to be merged to left or right) and keys are reordered accordingly as an imitation-buffer.
// * Elements of each block pair are merged using the csqrtlen buffer taking into account
// if they belong to the first half or second half (marked by the key).
//
@@ -2280,7 +2302,7 @@ inline SizeType adaptive_merge_n_keys_intbuf(SizeType &rl_block, SizeType len1,
// keys to combine blocks.
//
// * If auxiliary memory is available, the "build_blocks" will be extended to build bigger blocks
// using classic merge.
// using classic merge and "combine_blocks" will use bigger blocks when merging.
template<class RandIt, class Compare, class XBuf>
void adaptive_sort_impl
( RandIt first
@@ -2294,46 +2316,45 @@ void adaptive_sort_impl
//Small sorts go directly to insertion sort
if(len <= size_type(AdaptiveSortInsertionSortThreshold)){
insertion_sort(first, first + len, comp);
return;
}
if((len-len/2) <= xbuf.capacity()){
else if((len-len/2) <= xbuf.capacity()){
merge_sort(first, first+len, comp, xbuf.data());
return;
}
else{
//Make sure it is at least four
BOOST_STATIC_ASSERT(AdaptiveSortInsertionSortThreshold >= 4);
//Make sure it is at least four
BOOST_STATIC_ASSERT(AdaptiveSortInsertionSortThreshold >= 4);
size_type l_base = 0;
size_type l_intbuf = 0;
size_type n_keys = 0;
size_type l_build_buf = 0;
size_type l_base = 0;
size_type l_intbuf = 0;
size_type n_keys = 0;
size_type l_build_buf = 0;
//Calculate and extract needed unique elements. If a minimum is not achieved
//fallback to a slow stable sort
if(!adaptive_sort_build_params(first, len, comp, n_keys, l_intbuf, l_base, l_build_buf, xbuf)){
stable_sort(first, first+len, comp, xbuf);
}
else{
BOOST_ASSERT(l_build_buf);
//Otherwise, continue the adaptive_sort
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("\n After collect_unique: ", len);
size_type const n_key_plus_buf = l_intbuf+n_keys;
//l_build_buf is always power of two if l_intbuf is zero
BOOST_ASSERT(l_intbuf || (0 == (l_build_buf & (l_build_buf-1))));
//Calculate and extract needed unique elements. If a minimum is not achieved
//fallback to rotation-based merge
if(!adaptive_sort_build_params(first, len, comp, n_keys, l_intbuf, l_base, l_build_buf, xbuf)){
stable_sort(first, first+len, comp, xbuf);
return;
//Classic merge sort until internal buffer and xbuf are exhausted
size_type const l_merged = adaptive_sort_build_blocks
(first+n_key_plus_buf-l_build_buf, len-n_key_plus_buf+l_build_buf, l_base, l_build_buf, xbuf, comp);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" After build_blocks: ", len);
//Non-trivial merge
bool const buffer_right = adaptive_sort_combine_all_blocks
(first, n_keys, first+n_keys, len-n_keys, l_merged, l_intbuf, xbuf, comp);
//Sort keys and buffer and merge the whole sequence
adaptive_sort_final_merge(buffer_right, first, l_intbuf, n_keys, len, xbuf, comp);
}
}
BOOST_ASSERT(l_build_buf);
//Otherwise, continue the adaptive_sort
BOOST_MOVE_ADAPTIVE_SORT_PRINT("\n After collect_unique: ", len);
size_type const n_key_plus_buf = l_intbuf+n_keys;
//l_build_buf is always power of two if l_intbuf is zero
BOOST_ASSERT(l_intbuf || (0 == (l_build_buf & (l_build_buf-1))));
//Classic merge sort until internal buffer and xbuf are exhausted
size_type const l_merged = adaptive_sort_build_blocks
(first+n_key_plus_buf-l_build_buf, len-n_key_plus_buf+l_build_buf, l_base, l_build_buf, xbuf, comp);
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" After build_blocks: ", len);
//Non-trivial merge
bool const buffer_right = adaptive_sort_combine_all_blocks
(first, n_keys, first+n_keys, len-n_keys, l_merged, l_intbuf, xbuf, comp);
//Sort keys and buffer and merge the whole sequence
adaptive_sort_final_merge(buffer_right, first, l_intbuf, n_keys, len, xbuf, comp);
}
// Main explanation of the merge algorithm.
@@ -2353,8 +2374,8 @@ void adaptive_sort_impl
// * Trailing [first+len1, first+len1+len2) elements are divided in groups of cqrtlen elements.
// Remaining elements that can't form a group are grouped in the back of those elements.
// * In parallel the following two steps are performed:
// * Groups are selection-sorted by first or last element (depending wheter they
// merged to left or right) and keys are reordered accordingly as an imitation-buffer.
// * Groups are selection-sorted by first or last element (depending whether they are going
// to be merged to left or right) and keys are reordered accordingly as an imitation-buffer.
// * Elements of each block pair are merged using the csqrtlen buffer taking into account
// if they belong to the first half or second half (marked by the key).
//
@@ -2412,11 +2433,12 @@ void adaptive_merge_impl
size_type const to_collect = l_intbuf+n_keys;
//Try to extract needed unique values from the first range
size_type const collected = collect_unique(first, first+len1, to_collect, comp, xbuf);
BOOST_MOVE_ADAPTIVE_SORT_PRINT("\n A collect: ", len);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("\n A collect: ", len);
//Not the minimum number of keys is not available on the first range, so fallback to rotations
if(collected != to_collect && collected < 4){
merge_bufferless(first, first+len1, first+len1+len2, comp);
merge_bufferless(first, first+collected, first+len1, comp);
merge_bufferless(first, first + len1, first + len1 + len2, comp);
return;
}

View File

@@ -64,15 +64,7 @@
#endif
//Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
#if defined(__GNUC__) && (__GNUC__ >= 4) && \
(\
defined(BOOST_GCC) || \
(defined(BOOST_INTEL) && (BOOST_INTEL_CXX_VERSION >= 1300)) \
)
#define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
#else
#define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS
#endif
#define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS BOOST_MAY_ALIAS
namespace boost {

View File

@@ -967,14 +967,13 @@ typedef union max_align max_align_t;
#if !defined(BOOST_NO_ALIGNMENT)
template<std::size_t Len, std::size_t Align>
struct aligned_storage_impl;
struct aligned_struct;
#define BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(A)\
template<std::size_t Len>\
struct BOOST_ALIGNMENT(A) aligned_storage_impl<Len, A>\
struct BOOST_ALIGNMENT(A) aligned_struct<Len, A>\
{\
char dummy[Len];\
typedef aligned_storage_impl<Len, A> type;\
};\
//
@@ -995,6 +994,20 @@ BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1000)
#undef BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT
// Workaround for bogus [-Wignored-attributes] warning on GCC 6.x/7.x: don't use a type that "directly" carries the alignment attribute.
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82270
template<std::size_t Len, std::size_t Align>
struct aligned_struct_wrapper
{
aligned_struct<Len, Align> dummy;
};
template<std::size_t Len, std::size_t Align>
struct aligned_storage_impl
{
typedef aligned_struct_wrapper<Len, Align> type;
};
#else //BOOST_NO_ALIGNMENT
template<class T, std::size_t Len>

View File

@@ -69,6 +69,7 @@ bool test_random_shuffled(std::size_t const element_count, std::size_t const num
int main()
{
const std::size_t NIter = 100;
test_random_shuffled<order_move_type>(10001, 3, NIter);
test_random_shuffled<order_move_type>(10001, 65, NIter);
test_random_shuffled<order_move_type>(10001, 101, NIter);
test_random_shuffled<order_move_type>(10001, 1023, NIter);

View File

@@ -16,7 +16,6 @@
#include <boost/move/unique_ptr.hpp>
#include <boost/container/vector.hpp>
#include <boost/timer/timer.hpp>
#include "order_type.hpp"
#include "random_shuffle.hpp"
@@ -63,6 +62,7 @@ bool test_random_shuffled(std::size_t const element_count, std::size_t const num
int main()
{
const std::size_t NIter = 100;
test_random_shuffled<order_move_type>(10001, 3, NIter);
test_random_shuffled<order_move_type>(10001, 65, NIter);
test_random_shuffled<order_move_type>(10001, 101, NIter);
test_random_shuffled<order_move_type>(10001, 1023, NIter);