Fixes Issue #25

This commit is contained in:
Ion Gaztañaga
2019-04-08 00:32:28 +02:00
parent 2d00bc5d74
commit bfdfca0b88
9 changed files with 267 additions and 130 deletions

View File

@@ -806,7 +806,8 @@ Special thanks to:
* Removed support for deprecated GCC compilers. * Removed support for deprecated GCC compilers.
* Fixed bugs: * Fixed bugs:
* [@https://github.com/boostorg/move/pull/23 Git Pull #23: ['"Add minimal cmake file "]]. * [@https://github.com/boostorg/move/pull/23 Git Pull #23: ['"Add minimal cmake file"]].
* [@https://github.com/boostorg/move/issues/25 Git Pull #25: ['"daptive_merge is broken for iterator_traits<RandIt>::size_type != std::size_t"]].
[endsect] [endsect]

View File

@@ -309,7 +309,7 @@ void adaptive_merge_impl
template<class RandIt, class Compare> template<class RandIt, class Compare>
void adaptive_merge( RandIt first, RandIt middle, RandIt last, Compare comp void adaptive_merge( RandIt first, RandIt middle, RandIt last, Compare comp
, typename iterator_traits<RandIt>::value_type* uninitialized = 0 , typename iterator_traits<RandIt>::value_type* uninitialized = 0
, std::size_t uninitialized_len = 0) , typename iterator_traits<RandIt>::size_type uninitialized_len = 0)
{ {
typedef typename iterator_traits<RandIt>::size_type size_type; typedef typename iterator_traits<RandIt>::size_type size_type;
typedef typename iterator_traits<RandIt>::value_type value_type; typedef typename iterator_traits<RandIt>::value_type value_type;
@@ -340,7 +340,7 @@ void adaptive_merge( RandIt first, RandIt middle, RandIt last, Compare comp
return; return;
} while(1); } while(1);
::boost::movelib::adaptive_xbuf<value_type> xbuf(uninitialized, uninitialized_len); ::boost::movelib::adaptive_xbuf<value_type, value_type*, size_type> xbuf(uninitialized, size_type(uninitialized_len));
::boost::movelib::detail_adaptive::adaptive_merge_impl(first, size_type(middle - first), size_type(last - middle), comp, xbuf); ::boost::movelib::detail_adaptive::adaptive_merge_impl(first, size_type(middle - first), size_type(last - middle), comp, xbuf);
} }

View File

@@ -148,7 +148,7 @@ typename iterator_traits<RandIt>::size_type
} }
xbuf.clear(); xbuf.clear();
//2*l_build_buf or total already merged //2*l_build_buf or total already merged
return min_value(elements_in_blocks, 2*l_build_buf); return min_value<size_type>(elements_in_blocks, 2*l_build_buf);
} }
template<class RandItKeys, class KeyCompare, class RandIt, class Compare, class XBuf> template<class RandItKeys, class KeyCompare, class RandIt, class Compare, class XBuf>
@@ -185,14 +185,14 @@ void adaptive_sort_combine_blocks
bool const is_last = combined_i==n_reg_combined; bool const is_last = combined_i==n_reg_combined;
size_type const l_cur_combined = is_last ? l_irreg_combined : l_reg_combined; size_type const l_cur_combined = is_last ? l_irreg_combined : l_reg_combined;
range_xbuf<RandIt, move_op> rbuf( (use_buf && xbuf_used) ? (combined_first-l_block) : combined_first, combined_first); range_xbuf<RandIt, size_type, move_op> rbuf( (use_buf && xbuf_used) ? (combined_first-l_block) : combined_first, combined_first);
size_type n_block_a, n_block_b, l_irreg1, l_irreg2; size_type n_block_a, n_block_b, l_irreg1, l_irreg2;
combine_params( keys, key_comp, l_cur_combined combine_params( keys, key_comp, l_cur_combined
, l_prev_merged, l_block, rbuf , l_prev_merged, l_block, rbuf
, n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs , n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" 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(boost::movelib::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)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::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){ if(!use_buf){
merge_blocks_bufferless merge_blocks_bufferless
(keys, key_comp, combined_first, l_block, 0u, n_block_a, n_block_b, l_irreg2, comp); (keys, key_comp, combined_first, l_block, 0u, n_block_a, n_block_b, l_irreg2, comp);
@@ -211,14 +211,14 @@ void adaptive_sort_combine_blocks
size_type const l_cur_combined = is_last ? l_irreg_combined : l_reg_combined; size_type const l_cur_combined = is_last ? l_irreg_combined : l_reg_combined;
RandIt const combined_last(combined_first+l_cur_combined); RandIt const combined_last(combined_first+l_cur_combined);
range_xbuf<RandIt, move_op> rbuf(combined_last, xbuf_used ? (combined_last+l_block) : combined_last); range_xbuf<RandIt, size_type, move_op> rbuf(combined_last, xbuf_used ? (combined_last+l_block) : combined_last);
size_type n_block_a, n_block_b, l_irreg1, l_irreg2; size_type n_block_a, n_block_b, l_irreg1, l_irreg2;
combine_params( keys, key_comp, l_cur_combined combine_params( keys, key_comp, l_cur_combined
, l_prev_merged, l_block, rbuf , l_prev_merged, l_block, rbuf
, n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs , n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" 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(boost::movelib::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)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::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 merge_blocks_right
(keys, key_comp, combined_first, l_block, n_block_a, n_block_b, l_irreg2, comp, xbuf_used); (keys, key_comp, combined_first, l_block, n_block_a, n_block_b, l_irreg2, comp, xbuf_used);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" After merge_blocks_R: ", len + l_block); BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" After merge_blocks_R: ", len + l_block);
@@ -263,7 +263,7 @@ bool adaptive_sort_combine_all_blocks
// Implies l_block == n_keys/2 && use_internal_buf == true // Implies l_block == n_keys/2 && use_internal_buf == true
//Otherwise, just give up and and use all keys to merge using rotations (use_internal_buf = false) //Otherwise, just give up and and use all keys to merge using rotations (use_internal_buf = false)
bool use_internal_buf = false; bool use_internal_buf = false;
size_type const l_block = lblock_for_combine(l_intbuf, n_keys, 2*l_merged, use_internal_buf); size_type const l_block = lblock_for_combine(l_intbuf, n_keys, size_type(2*l_merged), use_internal_buf);
BOOST_ASSERT(!l_intbuf || (l_block == l_intbuf)); BOOST_ASSERT(!l_intbuf || (l_block == l_intbuf));
BOOST_ASSERT(n == 0 || (!use_internal_buf || prev_use_internal_buf) ); BOOST_ASSERT(n == 0 || (!use_internal_buf || prev_use_internal_buf) );
BOOST_ASSERT(n == 0 || (!use_internal_buf || l_prev_block == l_block) ); BOOST_ASSERT(n == 0 || (!use_internal_buf || l_prev_block == l_block) );
@@ -607,12 +607,12 @@ void adaptive_sort_impl
template<class RandIt, class RandRawIt, class Compare> template<class RandIt, class RandRawIt, class Compare>
void adaptive_sort( RandIt first, RandIt last, Compare comp void adaptive_sort( RandIt first, RandIt last, Compare comp
, RandRawIt uninitialized , RandRawIt uninitialized
, std::size_t uninitialized_len) , typename iterator_traits<RandIt>::size_type uninitialized_len)
{ {
typedef typename iterator_traits<RandIt>::size_type size_type; typedef typename iterator_traits<RandIt>::size_type size_type;
typedef typename iterator_traits<RandIt>::value_type value_type; typedef typename iterator_traits<RandIt>::value_type value_type;
::boost::movelib::adaptive_xbuf<value_type, RandRawIt> xbuf(uninitialized, uninitialized_len); ::boost::movelib::adaptive_xbuf<value_type, RandRawIt, size_type> xbuf(uninitialized, uninitialized_len);
::boost::movelib::detail_adaptive::adaptive_sort_impl(first, size_type(last - first), comp, xbuf); ::boost::movelib::detail_adaptive::adaptive_sort_impl(first, size_type(last - first), comp, xbuf);
} }

View File

@@ -328,11 +328,11 @@ void merge_blocks_bufferless
RandItKeys key_range2(key_first); RandItKeys key_range2(key_first);
size_type min_check = n_block_a == n_block_left ? 0u : n_block_a; size_type min_check = n_block_a == n_block_left ? 0u : n_block_a;
size_type max_check = min_value(min_check+1, n_block_left); size_type max_check = min_value<size_type>(min_check+1, n_block_left);
for (RandIt f = first+l_irreg1; n_block_left; --n_block_left, ++key_range2, f += l_block, min_check -= min_check != 0, max_check -= max_check != 0) { for (RandIt f = first+l_irreg1; n_block_left; --n_block_left, ++key_range2, f += l_block, min_check -= min_check != 0, max_check -= max_check != 0) {
size_type const next_key_idx = find_next_block(key_range2, key_comp, f, l_block, min_check, max_check, comp); size_type const next_key_idx = find_next_block(key_range2, key_comp, f, l_block, min_check, max_check, comp);
RandItKeys const key_next(key_range2 + next_key_idx); RandItKeys const key_next(key_range2 + next_key_idx);
max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left); max_check = min_value<size_type>(max_value<size_type>(max_check, next_key_idx+size_type(2)), n_block_left);
RandIt const first_min = f + next_key_idx*l_block; RandIt const first_min = f + next_key_idx*l_block;
@@ -344,12 +344,12 @@ void merge_blocks_bufferless
n_bef_irreg2 += l_irreg_pos_count; n_bef_irreg2 += l_irreg_pos_count;
swap_and_update_key(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(boost::movelib::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(boost::movelib::is_sorted(first_min, first_min + l_block, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((f == (first+l_irreg1)) || !comp(*f, *(f-l_block))); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((f == (first+l_irreg1)) || !comp(*f, *(f-l_block)));
} }
} }
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first+l_irreg1+n_bef_irreg2*l_block, first_irr2, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first+l_irreg1+n_bef_irreg2*l_block, first_irr2, comp));
RandIt first1 = first; RandIt first1 = first;
RandIt last1 = first+l_irreg1; RandIt last1 = first+l_irreg1;
@@ -361,11 +361,11 @@ void merge_blocks_bufferless
first1 = is_range1_A == is_range2_A first1 = is_range1_A == is_range2_A
? last1 : partial_merge_bufferless(first1, last1, last1 + l_block, &is_range1_A, comp); ? last1 : partial_merge_bufferless(first1, last1, last1 + l_block, &is_range1_A, comp);
last1 += l_block; last1 += l_block;
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, first1, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, first1, comp));
} }
merge_bufferless(is_range1_A ? first1 : last1, first_irr2, last_irr2, comp); merge_bufferless(is_range1_A ? first1 : last1, first_irr2, last_irr2, comp);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, last_irr2, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, last_irr2, comp));
} }
// Complexity: 2*distance(first, last)+max_collected^2/2 // Complexity: 2*distance(first, last)+max_collected^2/2
@@ -615,7 +615,7 @@ void stable_merge
typedef typename iterator_traits<RandIt>::size_type size_type; typedef typename iterator_traits<RandIt>::size_type size_type;
size_type const len1 = size_type(middle-first); size_type const len1 = size_type(middle-first);
size_type const len2 = size_type(last-middle); size_type const len2 = size_type(last-middle);
size_type const l_min = min_value(len1, len2); size_type const l_min = min_value<size_type>(len1, len2);
if(xbuf.capacity() >= l_min){ if(xbuf.capacity() >= l_min){
buffered_merge(first, middle, last, comp, xbuf); buffered_merge(first, middle, last, comp, xbuf);
xbuf.clear(); xbuf.clear();
@@ -624,6 +624,7 @@ void stable_merge
//merge_bufferless(first, middle, last, comp); //merge_bufferless(first, middle, last, comp);
merge_adaptive_ONlogN(first, middle, last, comp, xbuf.begin(), xbuf.capacity()); merge_adaptive_ONlogN(first, middle, last, comp, xbuf.begin(), xbuf.capacity());
} }
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, last, boost::movelib::unantistable(comp)));
} }
template<class RandIt, class Comp, class XBuf> template<class RandIt, class Comp, class XBuf>
@@ -939,19 +940,19 @@ OutputIt op_merge_blocks_with_irreg
for(; n_block_left; --n_block_left, ++key_first, min_check -= min_check != 0, max_check -= max_check != 0){ for(; n_block_left; --n_block_left, ++key_first, min_check -= min_check != 0, max_check -= max_check != 0){
size_type next_key_idx = find_next_block(key_first, key_comp, first_reg, l_block, min_check, max_check, comp); size_type next_key_idx = find_next_block(key_first, key_comp, first_reg, l_block, min_check, max_check, comp);
max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left); max_check = min_value<size_type>(max_value<size_type>(max_check, next_key_idx+size_type(2)), n_block_left);
RandIt const last_reg = first_reg + l_block; RandIt const last_reg = first_reg + l_block;
RandIt first_min = first_reg + next_key_idx*l_block; RandIt first_min = first_reg + next_key_idx*l_block;
RandIt const last_min = first_min + l_block; (void)last_min; RandIt const last_min = first_min + l_block; (void)last_min;
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_reg, last_reg, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_reg, last_reg, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!next_key_idx || is_sorted(first_min, last_min, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!next_key_idx || boost::movelib::is_sorted(first_min, last_min, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((!next_key_idx || !comp(*first_reg, *first_min ))); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((!next_key_idx || !comp(*first_reg, *first_min )));
OutputIt orig_dest = dest; (void)orig_dest; 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) 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)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(orig_dest, dest, comp));
if(first_reg == dest){ if(first_reg == dest){
dest = next_key_idx ? ::boost::adl_move_swap_ranges(first_min, last_min, first_reg) dest = next_key_idx ? ::boost::adl_move_swap_ranges(first_min, last_min, first_reg)
@@ -965,7 +966,7 @@ OutputIt op_merge_blocks_with_irreg
RandItKeys const key_next(key_first + next_key_idx); RandItKeys const key_next(key_first + next_key_idx);
swap_and_update_key(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)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(orig_dest, dest, comp));
first_reg = last_reg; first_reg = last_reg;
} }
return dest; return dest;
@@ -1017,17 +1018,17 @@ void op_merge_blocks_left
//Process all regular blocks before the irregular B block //Process all regular blocks before the irregular B block
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
size_type min_check = n_block_a == n_block_left ? 0u : n_block_a; size_type min_check = n_block_a == n_block_left ? 0u : n_block_a;
size_type max_check = min_value(min_check+1, n_block_left); size_type max_check = min_value<size_type>(min_check+size_type(1), n_block_left);
for (; n_block_left; --n_block_left, ++key_range2, min_check -= min_check != 0, max_check -= max_check != 0) { for (; n_block_left; --n_block_left, ++key_range2, min_check -= min_check != 0, max_check -= max_check != 0) {
size_type const next_key_idx = find_next_block(key_range2, key_comp, first2, l_block, min_check, max_check, comp); size_type const next_key_idx = find_next_block(key_range2, key_comp, first2, l_block, min_check, max_check, comp);
max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left); max_check = min_value<size_type>(max_value<size_type>(max_check, next_key_idx+size_type(2)), n_block_left);
RandIt const first_min = first2 + next_key_idx*l_block; RandIt const first_min = first2 + next_key_idx*l_block;
RandIt const last_min = first_min + l_block; (void)last_min; RandIt const last_min = first_min + l_block; (void)last_min;
RandIt const last2 = first2 + l_block; RandIt const last2 = first2 + l_block;
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first1, last1, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first1, last1, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first2, last2, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first2, last2, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || is_sorted(first_min, last_min, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || boost::movelib::is_sorted(first_min, last_min, comp));
//Check if irregular b block should go here. //Check if irregular b block should go here.
//If so, break to the special code handling the irregular block //If so, break to the special code handling the irregular block
@@ -1068,7 +1069,7 @@ void op_merge_blocks_left
(buffer, buffer+(last1-first1), first2, last2, first_min, buf_beg, buf_end, comp, op, is_range1_A); (buffer, buffer+(last1-first1), first2, last2, first_min, buf_beg, buf_end, comp, op, is_range1_A);
} }
(void)unmerged; (void)unmerged;
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first-l_block, unmerged, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first-l_block, unmerged, comp));
swap_and_update_key( 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)); , last_min - size_type(last2 - first2));
@@ -1117,7 +1118,7 @@ void op_merge_blocks_left
else if(!is_buffer_middle){ else if(!is_buffer_middle){
buffer = op(forward_t(), first1, last1, buffer); buffer = op(forward_t(), first1, last1, buffer);
} }
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first-l_block, buffer, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first-l_block, buffer, comp));
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
//Process irregular B block and remaining A blocks //Process irregular B block and remaining A blocks
@@ -1126,7 +1127,7 @@ void op_merge_blocks_left
( key_range2, key_mid, key_comp, first2, first_irr2, last_irr2 ( key_range2, key_mid, key_comp, first2, first_irr2, last_irr2
, buffer, l_block, n_block_left, min_check, max_check, comp, false, op); , buffer, l_block, n_block_left, min_check, max_check, comp, false, op);
buffer = op(forward_t(), first_irr2, last_irr2, buffer);(void)buffer; buffer = op(forward_t(), first_irr2, last_irr2, buffer);(void)buffer;
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first-l_block, buffer, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first-l_block, buffer, comp));
} }
// first - first element to merge. // first - first element to merge.
@@ -1240,18 +1241,18 @@ void op_merge_blocks_with_buf
//Process all regular blocks before the irregular B block //Process all regular blocks before the irregular B block
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
size_type min_check = n_block_a == n_block_left ? 0u : n_block_a; size_type min_check = n_block_a == n_block_left ? 0u : n_block_a;
size_type max_check = min_value(min_check+1, n_block_left); size_type max_check = min_value<size_type>(min_check+size_type(1), n_block_left);
for (; n_block_left; --n_block_left, ++key_range2, min_check -= min_check != 0, max_check -= max_check != 0) { for (; n_block_left; --n_block_left, ++key_range2, min_check -= min_check != 0, max_check -= max_check != 0) {
size_type const next_key_idx = find_next_block(key_range2, key_comp, first2, l_block, min_check, max_check, comp); size_type const next_key_idx = find_next_block(key_range2, key_comp, first2, l_block, min_check, max_check, comp);
max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left); max_check = min_value<size_type>(max_value<size_type>(max_check, next_key_idx+size_type(2)), n_block_left);
RandIt first_min = first2 + next_key_idx*l_block; RandIt first_min = first2 + next_key_idx*l_block;
RandIt const last_min = first_min + l_block; (void)last_min; RandIt const last_min = first_min + l_block; (void)last_min;
RandIt const last2 = first2 + l_block; RandIt const last2 = first2 + l_block;
bool const buffer_empty = buffer == buffer_end; (void)buffer_empty; bool const buffer_empty = buffer == buffer_end; (void)buffer_empty;
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(buffer_empty ? is_sorted(first1, last1, comp) : is_sorted(buffer, buffer_end, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(buffer_empty ? boost::movelib::is_sorted(first1, last1, comp) : boost::movelib::is_sorted(buffer, buffer_end, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first2, last2, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first2, last2, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || is_sorted(first_min, last_min, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || boost::movelib::is_sorted(first_min, last_min, comp));
//Check if irregular b block should go here. //Check if irregular b block should go here.
//If so, break to the special code handling the irregular block //If so, break to the special code handling the irregular block
@@ -1273,10 +1274,10 @@ void op_merge_blocks_with_buf
//swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min); //swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min);
buffer_end = buffer_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min, buffer = buf_first, op); buffer_end = buffer_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min, buffer = buf_first, op);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_swp: ", len); BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_swp: ", len);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first2, last2, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first2, last2, comp));
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_min, last_min, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_min, last_min, comp));
first1 = first2; first1 = first2;
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, first1, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, first1, comp));
} }
else { else {
RandIt const unmerged = op_partial_merge_and_save(first1, last1, first2, last2, first_min, buffer, buffer_end, comp, op, is_range1_A); RandIt const unmerged = op_partial_merge_and_save(first1, last1, first2, last2, first_min, buffer, buffer_end, comp, op, is_range1_A);
@@ -1296,10 +1297,10 @@ void op_merge_blocks_with_buf
} }
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!is_range_1_empty || (last_min-first_min) == (last2-unmerged)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!is_range_1_empty || (last_min-first_min) == (last2-unmerged));
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_swp: ", len); BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_swp: ", len);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_min, last_min, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_min, last_min, comp));
is_range1_A ^= is_range_1_empty; is_range1_A ^= is_range_1_empty;
first1 = unmerged; first1 = unmerged;
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, unmerged, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, unmerged, comp));
} }
BOOST_ASSERT( (is_range2_A && n_block_a_left) || (!is_range2_A && n_block_b_left)); BOOST_ASSERT( (is_range2_A && n_block_a_left) || (!is_range2_A && n_block_b_left));
is_range2_A ? --n_block_a_left : --n_block_b_left; is_range2_A ? --n_block_a_left : --n_block_b_left;
@@ -1307,7 +1308,7 @@ void op_merge_blocks_with_buf
first2 = last2; first2 = last2;
} }
RandIt res = op(forward_t(), buffer, buffer_end, first1); (void)res; RandIt res = op(forward_t(), buffer, buffer_end, first1); (void)res;
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, res, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, res, comp));
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_fwd: ", len); BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_fwd: ", len);
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -1325,14 +1326,14 @@ void op_merge_blocks_with_buf
, (make_reverse_iterator)(first_irr2), rbuf_beg, (make_reverse_iterator)(buffer), (make_reverse_iterator)(last_irr2) , (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 , l_block, n_block_left, 0, n_block_left
, inverse<Compare>(comp), true, op).base(); , inverse<Compare>(comp), true, op).base();
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(dest, last_irr2, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(dest, last_irr2, comp));
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_irg: ", len); BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_irg: ", len);
buffer_end = rbuf_beg.base(); buffer_end = rbuf_beg.base();
BOOST_ASSERT((dest-last1) == (buffer_end-buffer)); BOOST_ASSERT((dest-last1) == (buffer_end-buffer));
op_merge_with_left_placed(is_range1_A ? first1 : last1, last1, dest, buffer, buffer_end, comp, op); op_merge_with_left_placed(is_range1_A ? first1 : last1, last1, dest, buffer, buffer_end, comp, op);
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_with_left_plc:", len); BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_with_left_plc:", len);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, last_irr2, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, last_irr2, comp));
} }
////////////////////////////////// //////////////////////////////////
@@ -1446,17 +1447,17 @@ typename iterator_traits<RandIt>::size_type
RandIt pos = first_block; RandIt pos = first_block;
while((elements_in_blocks - p0) > 2*l_merged) { while((elements_in_blocks - p0) > 2*l_merged) {
op_merge_left(pos-l_merged, pos, pos+l_merged, pos+2*l_merged, comp, op); op_merge_left(pos-l_merged, pos, pos+l_merged, pos+2*l_merged, comp, op);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(pos-l_merged, pos+l_merged, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(pos-l_merged, pos+l_merged, comp));
p0 += 2*l_merged; p0 += 2*l_merged;
pos = first_block+p0; pos = first_block+p0;
} }
if((elements_in_blocks-p0) > l_merged) { if((elements_in_blocks-p0) > l_merged) {
op_merge_left(pos-l_merged, pos, pos+l_merged, first_block+elements_in_blocks, comp, op); op_merge_left(pos-l_merged, pos, pos+l_merged, first_block+elements_in_blocks, comp, op);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(pos-l_merged, pos-l_merged+(first_block+elements_in_blocks-pos), comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(pos-l_merged, pos-l_merged+(first_block+elements_in_blocks-pos), comp));
} }
else { else {
op(forward_t(), pos, first_block+elements_in_blocks, pos-l_merged); op(forward_t(), pos, first_block+elements_in_blocks, pos-l_merged);
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(pos-l_merged, first_block+elements_in_blocks-l_merged, comp)); BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(pos-l_merged, first_block+elements_in_blocks-l_merged, comp));
} }
first_block -= l_merged; first_block -= l_merged;
l_left_space -= l_merged; l_left_space -= l_merged;

View File

@@ -19,11 +19,12 @@
#include <boost/move/algo/predicate.hpp> #include <boost/move/algo/predicate.hpp>
#include <boost/move/detail/iterator_to_raw_pointer.hpp> #include <boost/move/detail/iterator_to_raw_pointer.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <cstddef>
namespace boost { namespace boost {
namespace movelib { namespace movelib {
template<class T, class RandRawIt = T*> template<class T, class RandRawIt = T*, class SizeType = typename iterator_traits<RandRawIt>::size_type>
class adaptive_xbuf class adaptive_xbuf
{ {
adaptive_xbuf(const adaptive_xbuf &); adaptive_xbuf(const adaptive_xbuf &);
@@ -35,21 +36,22 @@ class adaptive_xbuf
public: public:
typedef RandRawIt iterator; typedef RandRawIt iterator;
typedef SizeType size_type;
adaptive_xbuf() adaptive_xbuf()
: m_ptr(), m_size(0), m_capacity(0) : m_ptr(), m_size(0), m_capacity(0)
{} {}
adaptive_xbuf(RandRawIt raw_memory, std::size_t capacity) adaptive_xbuf(RandRawIt raw_memory, size_type capacity)
: m_ptr(raw_memory), m_size(0), m_capacity(capacity) : m_ptr(raw_memory), m_size(0), m_capacity(capacity)
{} {}
template<class RandIt> template<class RandIt>
void move_assign(RandIt first, std::size_t n) void move_assign(RandIt first, size_type n)
{ {
if(n <= m_size){ if(n <= m_size){
boost::move(first, first+n, m_ptr); boost::move(first, first+n, m_ptr);
std::size_t size = m_size; size_type size = m_size;
while(size-- != n){ while(size-- != n){
m_ptr[size].~T(); m_ptr[size].~T();
} }
@@ -63,7 +65,7 @@ class adaptive_xbuf
} }
template<class RandIt> template<class RandIt>
void push_back(RandIt first, std::size_t n) void push_back(RandIt first, size_type n)
{ {
BOOST_ASSERT(m_capacity - m_size >= n); BOOST_ASSERT(m_capacity - m_size >= n);
boost::uninitialized_move(first, first+n, m_ptr+m_size); boost::uninitialized_move(first, first+n, m_ptr+m_size);
@@ -94,22 +96,22 @@ class adaptive_xbuf
} }
} }
void set_size(std::size_t size) void set_size(size_type size)
{ {
m_size = size; m_size = size;
} }
void shrink_to_fit(std::size_t const size) void shrink_to_fit(size_type const size)
{ {
if(m_size > size){ if(m_size > size){
for(std::size_t szt_i = size; szt_i != m_size; ++szt_i){ for(size_type szt_i = size; szt_i != m_size; ++szt_i){
m_ptr[szt_i].~T(); m_ptr[szt_i].~T();
} }
m_size = size; m_size = size;
} }
} }
void initialize_until(std::size_t const size, T &t) void initialize_until(size_type const size, T &t)
{ {
BOOST_ASSERT(m_size < m_capacity); BOOST_ASSERT(m_size < m_capacity);
if(m_size < size){ if(m_size < size){
@@ -148,7 +150,7 @@ class adaptive_xbuf
public: public:
template<class U> template<class U>
bool supports_aligned_trailing(std::size_t size, std::size_t trail_count) const bool supports_aligned_trailing(size_type size, size_type trail_count) const
{ {
if(this->is_raw_ptr(this->data()) && m_capacity){ if(this->is_raw_ptr(this->data()) && m_capacity){
uintptr_t u_addr_sz = uintptr_t(&*(this->data()+size)); uintptr_t u_addr_sz = uintptr_t(&*(this->data()+size));
@@ -166,7 +168,7 @@ class adaptive_xbuf
} }
template<class U> template<class U>
U *aligned_trailing(std::size_t pos) const U *aligned_trailing(size_type pos) const
{ {
uintptr_t u_addr = uintptr_t(&*(this->data()+pos)); uintptr_t u_addr = uintptr_t(&*(this->data()+pos));
u_addr = ((u_addr + sizeof(U)-1)/sizeof(U))*sizeof(U); u_addr = ((u_addr + sizeof(U)-1)/sizeof(U))*sizeof(U);
@@ -178,7 +180,7 @@ class adaptive_xbuf
this->clear(); this->clear();
} }
std::size_t capacity() const size_type capacity() const
{ return m_capacity; } { return m_capacity; }
iterator data() const iterator data() const
@@ -190,7 +192,7 @@ class adaptive_xbuf
iterator end() const iterator end() const
{ return m_ptr+m_size; } { return m_ptr+m_size; }
std::size_t size() const size_type size() const
{ return m_size; } { return m_size; }
bool empty() const bool empty() const
@@ -203,18 +205,18 @@ class adaptive_xbuf
private: private:
RandRawIt m_ptr; RandRawIt m_ptr;
std::size_t m_size; size_type m_size;
std::size_t m_capacity; size_type m_capacity;
}; };
template<class Iterator, class Op> template<class Iterator, class SizeType, class Op>
class range_xbuf class range_xbuf
{ {
range_xbuf(const range_xbuf &); range_xbuf(const range_xbuf &);
range_xbuf & operator=(const range_xbuf &); range_xbuf & operator=(const range_xbuf &);
public: public:
typedef typename iterator_traits<Iterator>::size_type size_type; typedef SizeType size_type;
typedef Iterator iterator; typedef Iterator iterator;
range_xbuf(Iterator first, Iterator last) range_xbuf(Iterator first, Iterator last)
@@ -222,7 +224,7 @@ class range_xbuf
{} {}
template<class RandIt> template<class RandIt>
void move_assign(RandIt first, std::size_t n) void move_assign(RandIt first, size_type n)
{ {
BOOST_ASSERT(size_type(n) <= size_type(m_cap-m_first)); BOOST_ASSERT(size_type(n) <= size_type(m_cap-m_first));
m_last = Op()(forward_t(), first, first+n, m_first); m_last = Op()(forward_t(), first, first+n, m_first);
@@ -231,7 +233,7 @@ class range_xbuf
~range_xbuf() ~range_xbuf()
{} {}
std::size_t capacity() const size_type capacity() const
{ return m_cap-m_first; } { return m_cap-m_first; }
Iterator data() const Iterator data() const
@@ -240,7 +242,7 @@ class range_xbuf
Iterator end() const Iterator end() const
{ return m_last; } { return m_last; }
std::size_t size() const size_type size() const
{ return m_last-m_first; } { return m_last-m_first; }
bool empty() const bool empty() const
@@ -260,7 +262,7 @@ class range_xbuf
return pos; return pos;
} }
void set_size(std::size_t size) void set_size(size_type size)
{ {
m_last = m_first; m_last = m_first;
m_last += size; m_last += size;
@@ -581,11 +583,14 @@ void merge_bufferless_ON2(RandIt first, RandIt middle, RandIt last, Compare comp
static const std::size_t MergeBufferlessONLogNRotationThreshold = 16u; static const std::size_t MergeBufferlessONLogNRotationThreshold = 16u;
template <class RandIt, class SizeType, class Compare> template <class RandIt, class Compare>
void merge_bufferless_ONlogN_recursive void merge_bufferless_ONlogN_recursive
(RandIt first, RandIt middle, RandIt last, SizeType len1, SizeType len2, Compare comp) ( RandIt first, RandIt middle, RandIt last
, typename iterator_traits<RandIt>::size_type len1
, typename iterator_traits<RandIt>::size_type len2
, Compare comp)
{ {
typedef SizeType size_type; typedef typename iterator_traits<RandIt>::size_type size_type;
while(1) { while(1) {
//trivial cases //trivial cases
@@ -841,15 +846,15 @@ void uninitialized_merge_with_left_placed
/// This is a helper function for the merge routines. /// This is a helper function for the merge routines.
template<typename BidirectionalIterator1, typename BidirectionalIterator2, template<typename BidirectionalIterator1, typename BidirectionalIterator2>
typename SizeType>
BidirectionalIterator1 BidirectionalIterator1
rotate_adaptive(BidirectionalIterator1 first, rotate_adaptive(BidirectionalIterator1 first,
BidirectionalIterator1 middle, BidirectionalIterator1 middle,
BidirectionalIterator1 last, BidirectionalIterator1 last,
SizeType len1, SizeType len2, typename iterator_traits<BidirectionalIterator1>::size_type len1,
typename iterator_traits<BidirectionalIterator1>::size_type len2,
BidirectionalIterator2 buffer, BidirectionalIterator2 buffer,
SizeType buffer_size) typename iterator_traits<BidirectionalIterator1>::size_type buffer_size)
{ {
if (len1 > len2 && len2 <= buffer_size) if (len1 > len2 && len2 <= buffer_size)
{ {
@@ -878,70 +883,64 @@ template<typename BidirectionalIterator1, typename BidirectionalIterator2,
return rotate_gcd(first, middle, last); return rotate_gcd(first, middle, last);
} }
template<typename BidirectionalIterator, typename SizeType, template<typename BidirectionalIterator,
typename Pointer, typename Compare> typename Pointer, typename Compare>
void merge_adaptive_ONlogN_recursive void merge_adaptive_ONlogN_recursive
(BidirectionalIterator first, (BidirectionalIterator first,
BidirectionalIterator middle, BidirectionalIterator middle,
BidirectionalIterator last, BidirectionalIterator last,
SizeType len1, SizeType len2, typename iterator_traits<BidirectionalIterator>::size_type len1,
Pointer buffer, SizeType buffer_size, typename iterator_traits<BidirectionalIterator>::size_type len2,
Pointer buffer,
typename iterator_traits<BidirectionalIterator>::size_type buffer_size,
Compare comp) Compare comp)
{ {
typedef typename iterator_traits<BidirectionalIterator>::size_type size_type; typedef typename iterator_traits<BidirectionalIterator>::size_type size_type;
if (len1 <= buffer_size || len2 <= buffer_size) //trivial cases
if (!len2 || !len1) {
return;
}
else if (len1 <= buffer_size || len2 <= buffer_size)
{ {
range_xbuf<Pointer, move_op> rxbuf(buffer, buffer + buffer_size); range_xbuf<Pointer, size_type, move_op> rxbuf(buffer, buffer + buffer_size);
buffered_merge(first, middle, last, comp, rxbuf); buffered_merge(first, middle, last, comp, rxbuf);
} }
else if (size_type(len1 + len2) == 2u) {
if (comp(*middle, *first))
adl_move_swap(*first, *middle);
return;
}
else if (size_type(len1 + len2) < MergeBufferlessONLogNRotationThreshold) {
merge_bufferless_ON2(first, middle, last, comp);
return;
}
BidirectionalIterator first_cut = first;
BidirectionalIterator second_cut = middle;
size_type len11 = 0;
size_type len22 = 0;
if (len1 > len2) //(len1 < len2)
{
len11 = len1 / 2;
first_cut += len11;
second_cut = boost::movelib::lower_bound(middle, last, *first_cut, comp);
len22 = second_cut - middle;
}
else else
{ {
//trivial cases len22 = len2 / 2;
if (!len2) { second_cut += len22;
return; first_cut = boost::movelib::upper_bound(first, middle, *second_cut, comp);
} len11 = first_cut - first;
else if (!len1) {
return;
}
else if (size_type(len1 | len2) == 1u) {
if (comp(*middle, *first))
adl_move_swap(*first, *middle);
return;
}
else if (size_type(len1 + len2) < MergeBufferlessONLogNRotationThreshold) {
merge_bufferless_ON2(first, middle, last, comp);
return;
}
BidirectionalIterator first_cut = first;
BidirectionalIterator second_cut = middle;
size_type len11 = 0;
size_type len22 = 0;
if (len1 > len2) //(len1 < len2)
{
len11 = len1 / 2;
//len11 = buffer_size;
first_cut += len11;
second_cut = boost::movelib::lower_bound(middle, last, *first_cut, comp);
len22 = second_cut - middle;
}
else
{
//len22 = len2 / 2;
len22 = buffer_size;
second_cut += len22;
first_cut = boost::movelib::upper_bound(first, middle, *second_cut, comp);
len11 = first_cut - first;
}
BidirectionalIterator new_middle
= rotate_adaptive(first_cut, middle, second_cut,
len1 - len11, len22, buffer,
buffer_size);
merge_adaptive_ONlogN_recursive(first, first_cut, new_middle, len11,
len22, buffer, buffer_size, comp);
merge_adaptive_ONlogN_recursive(new_middle, second_cut, last,
len1 - len11, len2 - len22, buffer, buffer_size, comp);
} }
BidirectionalIterator new_middle
= rotate_adaptive(first_cut, middle, second_cut,
size_type(len1 - len11), len22, buffer,
buffer_size);
merge_adaptive_ONlogN_recursive(first, first_cut, new_middle, len11,
len22, buffer, buffer_size, comp);
merge_adaptive_ONlogN_recursive(new_middle, second_cut, last,
len1 - len11, len2 - len22, buffer, buffer_size, comp);
} }
@@ -951,7 +950,7 @@ void merge_adaptive_ONlogN(BidirectionalIterator first,
BidirectionalIterator last, BidirectionalIterator last,
Compare comp, Compare comp,
RandRawIt uninitialized, RandRawIt uninitialized,
std::size_t uninitialized_len) typename iterator_traits<BidirectionalIterator>::size_type uninitialized_len)
{ {
typedef typename iterator_traits<BidirectionalIterator>::value_type value_type; typedef typename iterator_traits<BidirectionalIterator>::value_type value_type;
typedef typename iterator_traits<BidirectionalIterator>::size_type size_type; typedef typename iterator_traits<BidirectionalIterator>::size_type size_type;

View File

@@ -36,11 +36,22 @@ struct antistable
bool operator()(const U &u, const V & v) bool operator()(const U &u, const V & v)
{ return !m_comp(v, u); } { return !m_comp(v, u); }
const Comp &get() const
{ return m_comp; }
private: private:
antistable & operator=(const antistable &); antistable & operator=(const antistable &);
Comp &m_comp; Comp &m_comp;
}; };
template<class Comp>
Comp unantistable(Comp comp)
{ return comp; }
template<class Comp>
Comp unantistable(antistable<Comp> comp)
{ return comp.get(); }
template <class Comp> template <class Comp>
class negate class negate
{ {

View File

@@ -66,8 +66,19 @@ bool test_random_shuffled(std::size_t const element_count, std::size_t const num
return true; return true;
} }
void instantiate_smalldiff_iterators()
{
typedef randit<int, short> short_rand_it_t;
boost::movelib::adaptive_merge(short_rand_it_t(), short_rand_it_t(), short_rand_it_t(), less_int());
typedef randit<int, signed char> schar_rand_it_t;
boost::movelib::adaptive_merge(schar_rand_it_t(), schar_rand_it_t(), schar_rand_it_t(), less_int());
}
int main() int main()
{ {
instantiate_smalldiff_iterators();
const std::size_t NIter = 100; const std::size_t NIter = 100;
test_random_shuffled<order_move_type>(10001, 3, NIter); 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, 65, NIter);

View File

@@ -38,7 +38,7 @@ bool test_random_shuffled(std::size_t const element_count, std::size_t const num
std::srand(0); std::srand(0);
for (std::size_t i = 0; i != num_iter; ++i) for (std::size_t it = 0; it != num_iter; ++it)
{ {
::random_shuffle(elements.get(), elements.get() + element_count); ::random_shuffle(elements.get(), elements.get() + element_count);
for(std::size_t i = 0; i < (num_keys ? num_keys : element_count); ++i){ for(std::size_t i = 0; i < (num_keys ? num_keys : element_count); ++i){
@@ -59,8 +59,19 @@ bool test_random_shuffled(std::size_t const element_count, std::size_t const num
return true; return true;
} }
void instantiate_smalldiff_iterators()
{
typedef randit<int, short> short_rand_it_t;
boost::movelib::adaptive_sort(short_rand_it_t(), short_rand_it_t(), less_int());
typedef randit<int, signed char> schar_rand_it_t;
boost::movelib::adaptive_sort(schar_rand_it_t(), schar_rand_it_t(), less_int());
}
int main() int main()
{ {
instantiate_smalldiff_iterators();
const std::size_t NIter = 100; const std::size_t NIter = 100;
test_random_shuffled<order_move_type>(10001, 3, NIter); 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, 65, NIter);

View File

@@ -14,6 +14,7 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/move/core.hpp> #include <boost/move/core.hpp>
#include <boost/move/detail/iterator_traits.hpp>
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>
@@ -169,4 +170,106 @@ inline bool is_buffer(T *elements, std::size_t element_count)
} }
//size_type iterator
template <class T, class D>
class randit
{
public:
typedef std::random_access_iterator_tag iterator_category;
typedef T value_type;
typedef D difference_type;
typedef T* pointer;
typedef T& reference;
private:
T* m_ptr;
public:
explicit randit(T* ptr)
: m_ptr(ptr)
{}
public:
//Constructors
randit()
: m_ptr() //Value initialization to achieve "null iterators" (N3644)
{}
randit(const randit& other)
: m_ptr(other.m_ptr)
{}
randit & operator=(const randit& other)
{ m_ptr = other.m_ptr; return *this; }
//T* like operators
reference operator*() const
{ return *m_ptr; }
pointer operator->() const
{ return m_ptr; }
reference operator[](difference_type off) const
{ return m_ptr[off]; }
//Increment / Decrement
randit& operator++()
{ ++m_ptr; return *this; }
randit operator++(int)
{ return randit(m_ptr++); }
randit& operator--()
{ --m_ptr; return *this; }
randit operator--(int)
{ return randit(m_ptr--); }
//Arithmetic
randit& operator+=(difference_type off)
{ m_ptr += off; return *this; }
randit& operator-=(difference_type off)
{ m_ptr -= off; return *this; }
friend randit operator+(const randit &x, difference_type off)
{ return randit(x.m_ptr+off); }
friend randit operator+(difference_type off, randit right)
{ right.m_ptr += off; return right; }
friend randit operator-(randit left, difference_type off)
{ left.m_ptr -= off; return left; }
friend difference_type operator-(const randit &left, const randit& right)
{ return difference_type(left.m_ptr - right.m_ptr); }
//Comparison operators
friend bool operator== (const randit& l, const randit& r)
{ return l.m_ptr == r.m_ptr; }
friend bool operator!= (const randit& l, const randit& r)
{ return l.m_ptr != r.m_ptr; }
friend bool operator< (const randit& l, const randit& r)
{ return l.m_ptr < r.m_ptr; }
friend bool operator<= (const randit& l, const randit& r)
{ return l.m_ptr <= r.m_ptr; }
friend bool operator> (const randit& l, const randit& r)
{ return l.m_ptr > r.m_ptr; }
friend bool operator>= (const randit& l, const randit& r)
{ return l.m_ptr >= r.m_ptr; }
};
struct less_int
{
bool operator()(int l, int r)
{ return l < r; }
};
#endif //BOOST_MOVE_TEST_ORDER_TYPE_HPP #endif //BOOST_MOVE_TEST_ORDER_TYPE_HPP