summaryrefslogtreecommitdiff
path: root/boost/move/algo/detail/adaptive_sort_merge.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/move/algo/detail/adaptive_sort_merge.hpp')
-rw-r--r--boost/move/algo/detail/adaptive_sort_merge.hpp95
1 files changed, 53 insertions, 42 deletions
diff --git a/boost/move/algo/detail/adaptive_sort_merge.hpp b/boost/move/algo/detail/adaptive_sort_merge.hpp
index 63b3f45979..60b5e7b06c 100644
--- a/boost/move/algo/detail/adaptive_sort_merge.hpp
+++ b/boost/move/algo/detail/adaptive_sort_merge.hpp
@@ -154,20 +154,20 @@ typename iterator_traits<ForwardIt>::size_type
return count;
}
-template<class T>
+template<class T, class RandRawIt = T*>
class adaptive_xbuf
{
adaptive_xbuf(const adaptive_xbuf &);
adaptive_xbuf & operator=(const adaptive_xbuf &);
public:
- typedef T* iterator;
+ typedef RandRawIt iterator;
adaptive_xbuf()
- : m_ptr(0), m_size(0), m_capacity(0)
+ : m_ptr(), m_size(0), m_capacity(0)
{}
- adaptive_xbuf(T *raw_memory, std::size_t capacity)
+ adaptive_xbuf(RandRawIt raw_memory, std::size_t capacity)
: m_ptr(raw_memory), m_size(0), m_capacity(capacity)
{}
@@ -183,7 +183,7 @@ class adaptive_xbuf
m_size = n;
}
else{
- T *result = boost::move(first, first+m_size, m_ptr);
+ RandRawIt result = boost::move(first, first+m_size, m_ptr);
boost::uninitialized_move(first+m_size, first+n, result);
m_size = n;
}
@@ -201,8 +201,8 @@ class adaptive_xbuf
iterator add(RandIt it)
{
BOOST_ASSERT(m_size < m_capacity);
- T * p_ret = m_ptr + m_size;
- ::new(p_ret) T(::boost::move(*it));
+ RandRawIt p_ret = m_ptr + m_size;
+ ::new(&*p_ret) T(::boost::move(*it));
++m_size;
return p_ret;
}
@@ -249,14 +249,26 @@ class adaptive_xbuf
}
}
+ private:
+ template<class RIt>
+ static bool is_raw_ptr(RIt)
+ {
+ return false;
+ }
+
+ static bool is_raw_ptr(T*)
+ {
+ return true;
+ }
+
+ public:
template<class U>
bool supports_aligned_trailing(std::size_t size, std::size_t trail_count) const
{
- if(this->data()){
- uintptr_t u_addr_sz = uintptr_t(this->data()+size);
- uintptr_t u_addr_cp = uintptr_t(this->data()+this->capacity());
+ if(this->is_raw_ptr(this->data()) && m_capacity){
+ uintptr_t u_addr_sz = uintptr_t(&*(this->data()+size));
+ uintptr_t u_addr_cp = uintptr_t(&*(this->data()+this->capacity()));
u_addr_sz = ((u_addr_sz + sizeof(U)-1)/sizeof(U))*sizeof(U);
-
return (u_addr_cp >= u_addr_sz) && ((u_addr_cp - u_addr_sz)/sizeof(U) >= trail_count);
}
return false;
@@ -271,7 +283,7 @@ class adaptive_xbuf
template<class U>
U *aligned_trailing(std::size_t 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);
return (U*)u_addr;
}
@@ -302,7 +314,7 @@ class adaptive_xbuf
}
private:
- T *m_ptr;
+ RandRawIt m_ptr;
std::size_t m_size;
std::size_t m_capacity;
};
@@ -458,7 +470,7 @@ RandIt partial_merge_bufferless_impl
if(first1 != last1 && comp(*last1, last1[-1])){
do{
RandIt const old_last1 = last1;
- last1 = lower_bound(last1, last2, *first1, comp);
+ last1 = boost::movelib::lower_bound(last1, last2, *first1, comp);
first1 = rotate_gcd(first1, old_last1, last1);//old_last1 == last1 supported
if(last1 == last2){
return first1;
@@ -604,13 +616,13 @@ void op_buffered_merge
size_type const len1 = size_type(middle-first);
size_type const len2 = size_type(last-middle);
if(len1 <= len2){
- first = upper_bound(first, middle, *middle, comp);
+ first = boost::movelib::upper_bound(first, middle, *middle, comp);
xbuf.move_assign(first, size_type(middle-first));
op_merge_with_right_placed
(xbuf.data(), xbuf.end(), first, middle, last, comp, op);
}
else{
- last = lower_bound(middle, last, middle[-1], comp);
+ last = boost::movelib::lower_bound(middle, last, middle[-1], comp);
xbuf.move_assign(middle, size_type(last-middle));
op_merge_with_left_placed
(first, middle, last, xbuf.data(), xbuf.end(), comp, op);
@@ -618,11 +630,11 @@ void op_buffered_merge
}
}
-template<class RandIt, class Compare>
+template<class RandIt, class Compare, class XBuf>
void buffered_merge
( RandIt first, RandIt const middle, RandIt last
, Compare comp
- , adaptive_xbuf<typename iterator_traits<RandIt>::value_type> &xbuf)
+ , XBuf &xbuf)
{
op_buffered_merge(first, middle, last, comp, move_op(), xbuf);
}
@@ -633,15 +645,14 @@ void buffered_merge
// in the begining of the range, and ordered according to comp
//
// Returns the number of collected keys
-template<class RandIt, class Compare>
+template<class RandIt, class Compare, class XBuf>
typename iterator_traits<RandIt>::size_type
collect_unique
( RandIt const first, RandIt const last
, typename iterator_traits<RandIt>::size_type const max_collected, Compare comp
- , adaptive_xbuf<typename iterator_traits<RandIt>::value_type> & xbuf)
+ , XBuf & xbuf)
{
typedef typename iterator_traits<RandIt>::size_type size_type;
- typedef typename iterator_traits<RandIt>::value_type value_type;
size_type h = 0;
if(max_collected){
++h; // first key is always here
@@ -650,9 +661,9 @@ typename iterator_traits<RandIt>::size_type
RandIt search_end = u;
if(xbuf.capacity() >= max_collected){
- value_type *const ph0 = xbuf.add(first);
+ typename XBuf::iterator const ph0 = xbuf.add(first);
while(u != last && h < max_collected){
- value_type * const r = lower_bound(ph0, xbuf.end(), *u, comp);
+ typename XBuf::iterator const r = boost::movelib::lower_bound(ph0, xbuf.end(), *u, comp);
//If key not found add it to [h, h+h0)
if(r == xbuf.end() || comp(*u, *r) ){
RandIt const new_h0 = boost::move(search_end, u, h0);
@@ -669,7 +680,7 @@ typename iterator_traits<RandIt>::size_type
}
else{
while(u != last && h < max_collected){
- RandIt const r = lower_bound(h0, search_end, *u, comp);
+ RandIt const r = boost::movelib::lower_bound(h0, search_end, *u, comp);
//If key not found add it to [h, h+h0)
if(r == search_end || comp(*u, *r) ){
RandIt const new_h0 = rotate_gcd(h0, search_end, u);
@@ -1666,14 +1677,14 @@ void op_merge_right_step_once
//
// As a last step, if auxiliary memory is available in-place merge is performed.
// until all is merged or auxiliary memory is not large enough.
-template<class RandIt, class Compare>
+template<class RandIt, class Compare, class XBuf>
typename iterator_traits<RandIt>::size_type
adaptive_sort_build_blocks
( RandIt const first
, typename iterator_traits<RandIt>::size_type const len
, typename iterator_traits<RandIt>::size_type const l_base
, typename iterator_traits<RandIt>::size_type const l_build_buf
- , adaptive_xbuf<typename iterator_traits<RandIt>::value_type> & xbuf
+ , XBuf & xbuf
, Compare comp)
{
typedef typename iterator_traits<RandIt>::size_type size_type;
@@ -1820,7 +1831,7 @@ void adaptive_sort_combine_blocks
//Returns true if buffer is placed in
//[buffer+len-l_intbuf, buffer+len). Otherwise, buffer is
//[buffer,buffer+l_intbuf)
-template<class RandIt, class Compare>
+template<class RandIt, class Compare, class XBuf>
bool adaptive_sort_combine_all_blocks
( RandIt keys
, typename iterator_traits<RandIt>::size_type &n_keys
@@ -1828,7 +1839,7 @@ bool adaptive_sort_combine_all_blocks
, typename iterator_traits<RandIt>::size_type const l_buf_plus_data
, typename iterator_traits<RandIt>::size_type l_merged
, typename iterator_traits<RandIt>::size_type &l_intbuf
- , adaptive_xbuf<typename iterator_traits<RandIt>::value_type> & xbuf
+ , XBuf & xbuf
, Compare comp)
{
typedef typename iterator_traits<RandIt>::size_type size_type;
@@ -1916,11 +1927,11 @@ bool adaptive_sort_combine_all_blocks
return buffer_right;
}
-template<class RandIt, class Compare>
+template<class RandIt, class Compare, class XBuf>
void stable_merge
( RandIt first, RandIt const middle, RandIt last
, Compare comp
- , adaptive_xbuf<typename iterator_traits<RandIt>::value_type> &xbuf)
+ , XBuf &xbuf)
{
BOOST_ASSERT(xbuf.empty());
typedef typename iterator_traits<RandIt>::size_type size_type;
@@ -1937,13 +1948,13 @@ void stable_merge
}
-template<class RandIt, class Compare>
+template<class RandIt, class Compare, class XBuf>
void adaptive_sort_final_merge( bool buffer_right
, RandIt const first
, typename iterator_traits<RandIt>::size_type const l_intbuf
, typename iterator_traits<RandIt>::size_type const n_keys
, typename iterator_traits<RandIt>::size_type const len
- , adaptive_xbuf<typename iterator_traits<RandIt>::value_type> & xbuf
+ , XBuf & xbuf
, Compare comp)
{
//BOOST_ASSERT(n_keys || xbuf.size() == l_intbuf);
@@ -1973,11 +1984,11 @@ void adaptive_sort_final_merge( bool buffer_right
BOOST_MOVE_ADAPTIVE_SORT_PRINT(" After final_merge : ", len);
}
-template<class RandIt, class Compare, class Unsigned, class T>
+template<class RandIt, class Compare, class Unsigned, class XBuf>
bool adaptive_sort_build_params
(RandIt first, Unsigned const len, Compare comp
, Unsigned &n_keys, Unsigned &l_intbuf, Unsigned &l_base, Unsigned &l_build_buf
- , adaptive_xbuf<T> & xbuf
+ , XBuf & xbuf
)
{
typedef Unsigned size_type;
@@ -2064,7 +2075,7 @@ bool adaptive_sort_build_params
return true;
}
-template<class RandIt, class Compare>
+template<class RandIt, class Compare, class XBuf>
inline void adaptive_merge_combine_blocks( RandIt first
, typename iterator_traits<RandIt>::size_type len1
, typename iterator_traits<RandIt>::size_type len2
@@ -2074,7 +2085,7 @@ inline void adaptive_merge_combine_blocks( RandIt first
, bool use_internal_buf
, bool xbuf_used
, Compare comp
- , adaptive_xbuf<typename iterator_traits<RandIt>::value_type> & xbuf
+ , XBuf & xbuf
)
{
typedef typename iterator_traits<RandIt>::size_type size_type;
@@ -2135,7 +2146,7 @@ inline void adaptive_merge_combine_blocks( RandIt first
}
}
-template<class RandIt, class Compare>
+template<class RandIt, class Compare, class XBuf>
inline void adaptive_merge_final_merge( RandIt first
, typename iterator_traits<RandIt>::size_type len1
, typename iterator_traits<RandIt>::size_type len2
@@ -2145,7 +2156,7 @@ inline void adaptive_merge_final_merge( RandIt first
, bool use_internal_buf
, bool xbuf_used
, Compare comp
- , adaptive_xbuf<typename iterator_traits<RandIt>::value_type> & xbuf
+ , XBuf & xbuf
)
{
typedef typename iterator_traits<RandIt>::size_type size_type;
@@ -2270,12 +2281,12 @@ inline SizeType adaptive_merge_n_keys_intbuf(SizeType &rl_block, SizeType len1,
//
// * If auxiliary memory is available, the "build_blocks" will be extended to build bigger blocks
// using classic merge.
-template<class RandIt, class Compare>
+template<class RandIt, class Compare, class XBuf>
void adaptive_sort_impl
( RandIt first
, typename iterator_traits<RandIt>::size_type const len
, Compare comp
- , adaptive_xbuf<typename iterator_traits<RandIt>::value_type> & xbuf
+ , XBuf & xbuf
)
{
typedef typename iterator_traits<RandIt>::size_type size_type;
@@ -2368,13 +2379,13 @@ void adaptive_sort_impl
// * If auxiliary memory is more than csqrtlen+n_keys*sizeof(std::size_t),
// then no csqrtlen need to be extracted and "combine_blocks" will use integral
// keys to combine blocks.
-template<class RandIt, class Compare>
+template<class RandIt, class Compare, class XBuf>
void adaptive_merge_impl
( RandIt first
, typename iterator_traits<RandIt>::size_type const len1
, typename iterator_traits<RandIt>::size_type const len2
, Compare comp
- , adaptive_xbuf<typename iterator_traits<RandIt>::value_type> & xbuf
+ , XBuf & xbuf
)
{
typedef typename iterator_traits<RandIt>::size_type size_type;