mirror of
https://github.com/boostorg/move.git
synced 2025-07-31 12:57:14 +02:00
Fixes Issue #25
This commit is contained in:
@ -806,7 +806,8 @@ Special thanks to:
|
||||
|
||||
* Removed support for deprecated GCC compilers.
|
||||
* 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]
|
||||
|
||||
|
@ -309,7 +309,7 @@ void adaptive_merge_impl
|
||||
template<class RandIt, class Compare>
|
||||
void adaptive_merge( RandIt first, RandIt middle, RandIt last, Compare comp
|
||||
, 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>::value_type value_type;
|
||||
@ -340,7 +340,7 @@ void adaptive_merge( RandIt first, RandIt middle, RandIt last, Compare comp
|
||||
return;
|
||||
} 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);
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ typename iterator_traits<RandIt>::size_type
|
||||
}
|
||||
xbuf.clear();
|
||||
//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>
|
||||
@ -185,14 +185,14 @@ void adaptive_sort_combine_blocks
|
||||
bool const is_last = combined_i==n_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;
|
||||
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_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));
|
||||
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(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){
|
||||
merge_blocks_bufferless
|
||||
(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;
|
||||
|
||||
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;
|
||||
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_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));
|
||||
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(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
|
||||
(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);
|
||||
@ -263,7 +263,7 @@ bool adaptive_sort_combine_all_blocks
|
||||
// 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)
|
||||
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(n == 0 || (!use_internal_buf || prev_use_internal_buf) );
|
||||
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>
|
||||
void adaptive_sort( RandIt first, RandIt last, Compare comp
|
||||
, 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>::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);
|
||||
}
|
||||
|
||||
|
@ -328,11 +328,11 @@ void merge_blocks_bufferless
|
||||
RandItKeys key_range2(key_first);
|
||||
|
||||
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) {
|
||||
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);
|
||||
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;
|
||||
|
||||
@ -344,12 +344,12 @@ void merge_blocks_bufferless
|
||||
n_bef_irreg2 += l_irreg_pos_count;
|
||||
|
||||
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(boost::movelib::is_sorted(f, f+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(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 last1 = first+l_irreg1;
|
||||
@ -361,11 +361,11 @@ void merge_blocks_bufferless
|
||||
first1 = is_range1_A == is_range2_A
|
||||
? last1 : partial_merge_bufferless(first1, last1, last1 + l_block, &is_range1_A, comp);
|
||||
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);
|
||||
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
|
||||
@ -615,7 +615,7 @@ void stable_merge
|
||||
typedef typename iterator_traits<RandIt>::size_type size_type;
|
||||
size_type const len1 = size_type(middle-first);
|
||||
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){
|
||||
buffered_merge(first, middle, last, comp, xbuf);
|
||||
xbuf.clear();
|
||||
@ -624,6 +624,7 @@ void stable_merge
|
||||
//merge_bufferless(first, middle, last, comp);
|
||||
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>
|
||||
@ -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){
|
||||
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 first_min = first_reg + next_key_idx*l_block;
|
||||
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(!next_key_idx || is_sorted(first_min, last_min, comp));
|
||||
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_reg, last_reg, 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 )));
|
||||
|
||||
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);
|
||||
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){
|
||||
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);
|
||||
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;
|
||||
}
|
||||
return dest;
|
||||
@ -1017,17 +1018,17 @@ void op_merge_blocks_left
|
||||
//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 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) {
|
||||
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 last_min = first_min + l_block; (void)last_min;
|
||||
RandIt const last2 = first2 + l_block;
|
||||
|
||||
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first1, last1, comp));
|
||||
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(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(boost::movelib::is_sorted(first1, last1, comp));
|
||||
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first2, last2, 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.
|
||||
//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);
|
||||
}
|
||||
(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
|
||||
, last_min - size_type(last2 - first2));
|
||||
@ -1117,7 +1118,7 @@ void op_merge_blocks_left
|
||||
else if(!is_buffer_middle){
|
||||
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
|
||||
@ -1126,7 +1127,7 @@ void op_merge_blocks_left
|
||||
( 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 = 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.
|
||||
@ -1240,18 +1241,18 @@ void op_merge_blocks_with_buf
|
||||
//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 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) {
|
||||
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 const last_min = first_min + l_block; (void)last_min;
|
||||
RandIt const last2 = first2 + l_block;
|
||||
|
||||
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(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(buffer_empty ? boost::movelib::is_sorted(first1, last1, comp) : boost::movelib::is_sorted(buffer, buffer_end, comp));
|
||||
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first2, last2, 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.
|
||||
//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);
|
||||
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_INVARIANT(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(first2, last2, comp));
|
||||
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_min, last_min, comp));
|
||||
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 {
|
||||
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_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;
|
||||
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));
|
||||
is_range2_A ? --n_block_a_left : --n_block_b_left;
|
||||
@ -1307,7 +1308,7 @@ void op_merge_blocks_with_buf
|
||||
first2 = last2;
|
||||
}
|
||||
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);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@ -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)
|
||||
, 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));
|
||||
BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(dest, last_irr2, comp));
|
||||
BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_irg: ", len);
|
||||
|
||||
buffer_end = rbuf_beg.base();
|
||||
BOOST_ASSERT((dest-last1) == (buffer_end-buffer));
|
||||
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_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;
|
||||
while((elements_in_blocks - p0) > 2*l_merged) {
|
||||
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;
|
||||
pos = first_block+p0;
|
||||
}
|
||||
if((elements_in_blocks-p0) > l_merged) {
|
||||
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 {
|
||||
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;
|
||||
l_left_space -= l_merged;
|
||||
|
@ -19,11 +19,12 @@
|
||||
#include <boost/move/algo/predicate.hpp>
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
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
|
||||
{
|
||||
adaptive_xbuf(const adaptive_xbuf &);
|
||||
@ -35,21 +36,22 @@ class adaptive_xbuf
|
||||
|
||||
public:
|
||||
typedef RandRawIt iterator;
|
||||
typedef SizeType size_type;
|
||||
|
||||
adaptive_xbuf()
|
||||
: 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)
|
||||
{}
|
||||
|
||||
template<class RandIt>
|
||||
void move_assign(RandIt first, std::size_t n)
|
||||
void move_assign(RandIt first, size_type n)
|
||||
{
|
||||
if(n <= m_size){
|
||||
boost::move(first, first+n, m_ptr);
|
||||
std::size_t size = m_size;
|
||||
size_type size = m_size;
|
||||
while(size-- != n){
|
||||
m_ptr[size].~T();
|
||||
}
|
||||
@ -63,7 +65,7 @@ class adaptive_xbuf
|
||||
}
|
||||
|
||||
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::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;
|
||||
}
|
||||
|
||||
void shrink_to_fit(std::size_t const size)
|
||||
void shrink_to_fit(size_type const 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_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);
|
||||
if(m_size < size){
|
||||
@ -148,7 +150,7 @@ class adaptive_xbuf
|
||||
|
||||
public:
|
||||
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){
|
||||
uintptr_t u_addr_sz = uintptr_t(&*(this->data()+size));
|
||||
@ -166,7 +168,7 @@ class adaptive_xbuf
|
||||
}
|
||||
|
||||
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));
|
||||
u_addr = ((u_addr + sizeof(U)-1)/sizeof(U))*sizeof(U);
|
||||
@ -178,7 +180,7 @@ class adaptive_xbuf
|
||||
this->clear();
|
||||
}
|
||||
|
||||
std::size_t capacity() const
|
||||
size_type capacity() const
|
||||
{ return m_capacity; }
|
||||
|
||||
iterator data() const
|
||||
@ -190,7 +192,7 @@ class adaptive_xbuf
|
||||
iterator end() const
|
||||
{ return m_ptr+m_size; }
|
||||
|
||||
std::size_t size() const
|
||||
size_type size() const
|
||||
{ return m_size; }
|
||||
|
||||
bool empty() const
|
||||
@ -203,18 +205,18 @@ class adaptive_xbuf
|
||||
|
||||
private:
|
||||
RandRawIt m_ptr;
|
||||
std::size_t m_size;
|
||||
std::size_t m_capacity;
|
||||
size_type m_size;
|
||||
size_type m_capacity;
|
||||
};
|
||||
|
||||
template<class Iterator, class Op>
|
||||
template<class Iterator, class SizeType, class Op>
|
||||
class range_xbuf
|
||||
{
|
||||
range_xbuf(const range_xbuf &);
|
||||
range_xbuf & operator=(const range_xbuf &);
|
||||
|
||||
public:
|
||||
typedef typename iterator_traits<Iterator>::size_type size_type;
|
||||
typedef SizeType size_type;
|
||||
typedef Iterator iterator;
|
||||
|
||||
range_xbuf(Iterator first, Iterator last)
|
||||
@ -222,7 +224,7 @@ class range_xbuf
|
||||
{}
|
||||
|
||||
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));
|
||||
m_last = Op()(forward_t(), first, first+n, m_first);
|
||||
@ -231,7 +233,7 @@ class range_xbuf
|
||||
~range_xbuf()
|
||||
{}
|
||||
|
||||
std::size_t capacity() const
|
||||
size_type capacity() const
|
||||
{ return m_cap-m_first; }
|
||||
|
||||
Iterator data() const
|
||||
@ -240,7 +242,7 @@ class range_xbuf
|
||||
Iterator end() const
|
||||
{ return m_last; }
|
||||
|
||||
std::size_t size() const
|
||||
size_type size() const
|
||||
{ return m_last-m_first; }
|
||||
|
||||
bool empty() const
|
||||
@ -260,7 +262,7 @@ class range_xbuf
|
||||
return pos;
|
||||
}
|
||||
|
||||
void set_size(std::size_t size)
|
||||
void set_size(size_type size)
|
||||
{
|
||||
m_last = m_first;
|
||||
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;
|
||||
|
||||
template <class RandIt, class SizeType, class Compare>
|
||||
template <class RandIt, class Compare>
|
||||
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) {
|
||||
//trivial cases
|
||||
@ -841,15 +846,15 @@ void uninitialized_merge_with_left_placed
|
||||
|
||||
|
||||
/// This is a helper function for the merge routines.
|
||||
template<typename BidirectionalIterator1, typename BidirectionalIterator2,
|
||||
typename SizeType>
|
||||
template<typename BidirectionalIterator1, typename BidirectionalIterator2>
|
||||
BidirectionalIterator1
|
||||
rotate_adaptive(BidirectionalIterator1 first,
|
||||
BidirectionalIterator1 middle,
|
||||
BidirectionalIterator1 last,
|
||||
SizeType len1, SizeType len2,
|
||||
typename iterator_traits<BidirectionalIterator1>::size_type len1,
|
||||
typename iterator_traits<BidirectionalIterator1>::size_type len2,
|
||||
BidirectionalIterator2 buffer,
|
||||
SizeType buffer_size)
|
||||
typename iterator_traits<BidirectionalIterator1>::size_type buffer_size)
|
||||
{
|
||||
if (len1 > len2 && len2 <= buffer_size)
|
||||
{
|
||||
@ -878,70 +883,64 @@ template<typename BidirectionalIterator1, typename BidirectionalIterator2,
|
||||
return rotate_gcd(first, middle, last);
|
||||
}
|
||||
|
||||
template<typename BidirectionalIterator, typename SizeType,
|
||||
template<typename BidirectionalIterator,
|
||||
typename Pointer, typename Compare>
|
||||
void merge_adaptive_ONlogN_recursive
|
||||
(BidirectionalIterator first,
|
||||
BidirectionalIterator middle,
|
||||
BidirectionalIterator last,
|
||||
SizeType len1, SizeType len2,
|
||||
Pointer buffer, SizeType buffer_size,
|
||||
typename iterator_traits<BidirectionalIterator>::size_type len1,
|
||||
typename iterator_traits<BidirectionalIterator>::size_type len2,
|
||||
Pointer buffer,
|
||||
typename iterator_traits<BidirectionalIterator>::size_type buffer_size,
|
||||
Compare comp)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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
|
||||
{
|
||||
//trivial cases
|
||||
if (!len2) {
|
||||
return;
|
||||
}
|
||||
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);
|
||||
len22 = len2 / 2;
|
||||
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,
|
||||
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,
|
||||
Compare comp,
|
||||
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>::size_type size_type;
|
||||
|
@ -36,11 +36,22 @@ struct antistable
|
||||
bool operator()(const U &u, const V & v)
|
||||
{ return !m_comp(v, u); }
|
||||
|
||||
const Comp &get() const
|
||||
{ return m_comp; }
|
||||
|
||||
private:
|
||||
antistable & operator=(const antistable &);
|
||||
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>
|
||||
class negate
|
||||
{
|
||||
|
@ -66,8 +66,19 @@ bool test_random_shuffled(std::size_t const element_count, std::size_t const num
|
||||
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()
|
||||
{
|
||||
instantiate_smalldiff_iterators();
|
||||
|
||||
const std::size_t NIter = 100;
|
||||
test_random_shuffled<order_move_type>(10001, 3, NIter);
|
||||
test_random_shuffled<order_move_type>(10001, 65, NIter);
|
||||
|
@ -38,7 +38,7 @@ bool test_random_shuffled(std::size_t const element_count, std::size_t const num
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
instantiate_smalldiff_iterators();
|
||||
|
||||
const std::size_t NIter = 100;
|
||||
test_random_shuffled<order_move_type>(10001, 3, NIter);
|
||||
test_random_shuffled<order_move_type>(10001, 65, NIter);
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/detail/iterator_traits.hpp>
|
||||
#include <cstddef>
|
||||
#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
|
||||
|
Reference in New Issue
Block a user