mirror of
https://github.com/boostorg/move.git
synced 2025-08-01 05:14:27 +02:00
Merge branch 'develop'
This commit is contained in:
34
doc/move.qbk
34
doc/move.qbk
@@ -661,6 +661,32 @@ An alternative is to implement a single `operator =()` for copyable and movable
|
||||
However, "pass by value" is not optimal for classes (like containers, strings, etc.) that reuse resources
|
||||
(like previously allocated memory) when x is assigned from a lvalue.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:templated_assignment_operator Templated assignment operator in copyable and movable types]
|
||||
|
||||
|
||||
[import ../example/doc_template_assign.cpp]
|
||||
|
||||
Given a movable and copyable class, if a templated assignment operator (*) is added:
|
||||
|
||||
[template_assign_example_foo_bar]
|
||||
|
||||
C++98 and C++11 compilers will behave different when assigning from a `[const] Foo` lvalue:
|
||||
|
||||
[template_assign_example_main]
|
||||
|
||||
This different behaviour is a side-effect of the move emulation that can't be easily avoided by
|
||||
[*Boost.Move]. One workaround is to SFINAE-out the templated assignment operator with `disable_if`:
|
||||
|
||||
[c++]
|
||||
|
||||
template<class U> // Modified templated assignment
|
||||
typename boost::disable_if<boost::is_same<U, Foo>, Foo&>::type
|
||||
operator=(const U& rhs)
|
||||
{ i = -rhs.i; return *this; } //(2)
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
@@ -762,6 +788,14 @@ Many thanks to all boosters that have tested, reviewed and improved the library.
|
||||
|
||||
[section:release_notes Release Notes]
|
||||
|
||||
[section:release_notes_boost_1_62 Boost 1.62 Release]
|
||||
|
||||
* Documented new limitations reported in Trac tickets
|
||||
[@https://svn.boost.org/trac/boost/ticket/12194 #12194 ['"Copy assignment on moveable and copyable classes uses wrong type"]] and
|
||||
[@https://svn.boost.org/trac/boost/ticket/12307 #12307 ['"Copy assignment on moveable and copyable classes uses wrong type"]].
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:release_notes_boost_1_61 Boost 1.61 Release]
|
||||
|
||||
* Experimental: asymptotically optimal bufferless merge and sort algorithms: [funcref boost::movelib::adaptive_merge adaptive_merge]
|
||||
|
98
example/doc_template_assign.cpp
Normal file
98
example/doc_template_assign.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/move for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
#include <boost/move/detail/meta_utils_core.hpp>
|
||||
|
||||
#include <boost/move/move.hpp>
|
||||
|
||||
//[template_assign_example_foo_bar
|
||||
|
||||
class Foo
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(Foo)
|
||||
|
||||
public:
|
||||
int i;
|
||||
explicit Foo(int val) : i(val) {}
|
||||
|
||||
Foo(BOOST_RV_REF(Foo) obj) : i(obj.i) {}
|
||||
|
||||
Foo& operator=(BOOST_RV_REF(Foo) rhs)
|
||||
{ i = rhs.i; rhs.i = 0; return *this; }
|
||||
|
||||
Foo& operator=(BOOST_COPY_ASSIGN_REF(Foo) rhs)
|
||||
{ i = rhs.i; return *this; } //(1)
|
||||
|
||||
template<class U> //(*) TEMPLATED ASSIGNMENT, potential problem
|
||||
//<-
|
||||
#if 1
|
||||
typename ::boost::move_detail::disable_if_same<U, Foo, Foo&>::type
|
||||
operator=(const U& rhs)
|
||||
#else
|
||||
//->
|
||||
Foo& operator=(const U& rhs)
|
||||
//<-
|
||||
#endif
|
||||
//->
|
||||
{ i = -rhs.i; return *this; } //(2)
|
||||
};
|
||||
//]
|
||||
|
||||
struct Bar
|
||||
{
|
||||
int i;
|
||||
explicit Bar(int val) : i(val) {}
|
||||
};
|
||||
|
||||
|
||||
//<-
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
//->
|
||||
#include <cassert>
|
||||
|
||||
int main()
|
||||
{
|
||||
//[template_assign_example_main
|
||||
Foo foo1(1);
|
||||
//<-
|
||||
assert(foo1.i == 1);
|
||||
//->
|
||||
Foo foo2(2);
|
||||
//<-
|
||||
assert(foo2.i == 2);
|
||||
Bar bar(3);
|
||||
assert(bar.i == 3);
|
||||
//->
|
||||
foo2 = foo1; // Calls (1) in C++11 but (2) in C++98
|
||||
//<-
|
||||
assert(foo2.i == 1);
|
||||
assert(foo1.i == 1); //Fails in C++98 unless workaround is applied
|
||||
foo1 = bar;
|
||||
assert(foo1.i == -3);
|
||||
foo2 = boost::move(foo1);
|
||||
assert(foo1.i == 0);
|
||||
assert(foo2.i == -3);
|
||||
//->
|
||||
const Foo foo5(5);
|
||||
foo2 = foo5; // Calls (1) in C++11 but (2) in C++98
|
||||
//<-
|
||||
assert(foo2.i == 5); //Fails in C++98 unless workaround is applied
|
||||
assert(foo5.i == 5);
|
||||
//->
|
||||
//]
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
@@ -231,8 +231,8 @@ BOOST_MOVE_FORCEINLINE void adl_move_swap(T& x, T& y)
|
||||
//! using boost::adl_move_swap.
|
||||
//!
|
||||
//! Parameters:
|
||||
//! first1, last1 - the first range of elements to swap
|
||||
//! first2 - beginning of the second range of elements to swap
|
||||
//! first1, last1 - the first range of elements to swap
|
||||
//! first2 - beginning of the second range of elements to swap
|
||||
//!
|
||||
//! Type requirements:
|
||||
//! - ForwardIt1, ForwardIt2 must meet the requirements of ForwardIterator.
|
||||
|
@@ -56,7 +56,7 @@ void adaptive_merge( RandIt first, RandIt middle, RandIt last, Compare comp
|
||||
typedef typename iterator_traits<RandIt>::value_type value_type;
|
||||
|
||||
::boost::movelib::detail_adaptive::adaptive_xbuf<value_type> xbuf(uninitialized, 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);
|
||||
}
|
||||
|
||||
} //namespace movelib {
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -21,12 +21,14 @@
|
||||
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#include <boost/move/detail/iterator_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace movelib {
|
||||
|
||||
struct forward_t{};
|
||||
struct backward_t{};
|
||||
struct three_way_t{};
|
||||
|
||||
struct move_op
|
||||
{
|
||||
@@ -41,6 +43,13 @@ struct move_op
|
||||
template <class SourceIt, class DestinationIt>
|
||||
DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_last)
|
||||
{ return ::boost::move_backward(first, last, dest_last); }
|
||||
|
||||
template <class SourceIt, class DestinationIt1, class DestinationIt2>
|
||||
void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it)
|
||||
{
|
||||
*dest2it = boost::move(*dest1it);
|
||||
*dest1it = boost::move(*srcit);
|
||||
}
|
||||
};
|
||||
|
||||
struct swap_op
|
||||
@@ -56,6 +65,15 @@ struct swap_op
|
||||
template <class SourceIt, class DestinationIt>
|
||||
DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_begin)
|
||||
{ return boost::adl_move_swap_ranges_backward(first, last, dest_begin); }
|
||||
|
||||
template <class SourceIt, class DestinationIt1, class DestinationIt2>
|
||||
void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it)
|
||||
{
|
||||
typename ::boost::movelib::iterator_traits<SourceIt>::value_type tmp(boost::move(*dest2it));
|
||||
*dest2it = boost::move(*dest1it);
|
||||
*dest1it = boost::move(*srcit);
|
||||
*srcit = boost::move(tmp);
|
||||
}
|
||||
};
|
||||
|
||||
}} //namespace boost::movelib
|
||||
|
@@ -167,7 +167,7 @@ void op_merge_left( RandIt buf_first
|
||||
op(forward_t(), first2, last2, buf_first);
|
||||
return;
|
||||
}
|
||||
else if(comp(*first2, *first1)){
|
||||
else if(comp(*first2, *first1)){
|
||||
op(first2, buf_first);
|
||||
++first2;
|
||||
}
|
||||
@@ -214,7 +214,7 @@ void op_merge_right
|
||||
{
|
||||
RandIt const first2 = last1;
|
||||
while(first1 != last1){
|
||||
if(last2 == first2){
|
||||
if(last2 == first2){
|
||||
op(backward_t(), first1, last1, buf_last);
|
||||
return;
|
||||
}
|
||||
@@ -230,7 +230,7 @@ void op_merge_right
|
||||
++last1;
|
||||
}
|
||||
}
|
||||
if(last2 != buf_last){ //In case all remaining elements are in the same place
|
||||
if(last2 != buf_last){ //In case all remaining elements are in the same place
|
||||
//(e.g. buffer is exactly the size of the first half
|
||||
//and all elements from the second half are less)
|
||||
op(backward_t(), first2, last2, buf_last);
|
||||
@@ -257,9 +257,104 @@ void swap_merge_right
|
||||
op_merge_right(first1, last1, last2, buf_last, comp, swap_op());
|
||||
}
|
||||
|
||||
// cost: min(L1,L2)^2+max(L1,L2)
|
||||
template <class BidirIt, class Distance, class Compare>
|
||||
void merge_bufferless_ONlogN_recursive
|
||||
(BidirIt first, BidirIt middle, BidirIt last, Distance len1, Distance len2, Compare comp)
|
||||
{
|
||||
typedef typename iterator_traits<BidirIt>::size_type size_type;
|
||||
while(1) {
|
||||
//#define MERGE_BUFFERLESS_RECURSIVE_OPT
|
||||
#ifndef MERGE_BUFFERLESS_RECURSIVE_OPT
|
||||
if (len2 == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!len1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((len1 | len2) == 1) {
|
||||
if (comp(*middle, *first))
|
||||
adl_move_swap(*first, *middle);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (len2 == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!len1) {
|
||||
return;
|
||||
}
|
||||
BidirIt middle_prev = middle; --middle_prev;
|
||||
if(!comp(*middle, *middle_prev))
|
||||
return;
|
||||
|
||||
while(true) {
|
||||
if (comp(*middle, *first))
|
||||
break;
|
||||
++first;
|
||||
if(--len1 == 1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (len1 == 1 && len2 == 1) {
|
||||
//comp(*middle, *first) == true already tested in the loop
|
||||
adl_move_swap(*first, *middle);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
BidirIt first_cut = first;
|
||||
BidirIt second_cut = middle;
|
||||
Distance len11 = 0;
|
||||
Distance len22 = 0;
|
||||
if (len1 > len2) {
|
||||
len11 = len1 / 2;
|
||||
first_cut += len11;
|
||||
second_cut = lower_bound(middle, last, *first_cut, comp);
|
||||
len22 = size_type(second_cut - middle);
|
||||
}
|
||||
else {
|
||||
len22 = len2 / 2;
|
||||
second_cut += len22;
|
||||
first_cut = upper_bound(first, middle, *second_cut, comp);
|
||||
len11 = size_type(first_cut - first);
|
||||
}
|
||||
BidirIt new_middle = rotate_gcd(first_cut, middle, second_cut);
|
||||
|
||||
//Avoid one recursive call doing a manual tail call elimination on the biggest range
|
||||
const Distance len_internal = len11+len22;
|
||||
if( len_internal < (len1 + len2 - len_internal) ) {
|
||||
merge_bufferless_ONlogN_recursive(first, first_cut, new_middle, len11, len22, comp);
|
||||
//merge_bufferless_recursive(new_middle, second_cut, last, len1 - len11, len2 - len22, comp);
|
||||
first = new_middle;
|
||||
middle = second_cut;
|
||||
len1 -= len11;
|
||||
len2 -= len22;
|
||||
}
|
||||
else {
|
||||
//merge_bufferless_recursive(first, first_cut, new_middle, len11, len22, comp);
|
||||
merge_bufferless_ONlogN_recursive(new_middle, second_cut, last, len1 - len11, len2 - len22, comp);
|
||||
middle = first_cut;
|
||||
last = new_middle;
|
||||
len1 = len11;
|
||||
len2 = len22;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Complexity: NlogN
|
||||
template<class BidirIt, class Compare>
|
||||
void merge_bufferless_ONlogN(BidirIt first, BidirIt middle, BidirIt last, Compare comp)
|
||||
{
|
||||
merge_bufferless_ONlogN_recursive
|
||||
(first, middle, last, middle - first, last - middle, comp);
|
||||
}
|
||||
|
||||
//Complexity: min(len1,len2)^2 + max(len1,len2)
|
||||
template<class RandIt, class Compare>
|
||||
void merge_bufferless(RandIt first, RandIt middle, RandIt last, Compare comp)
|
||||
void merge_bufferless_ON2(RandIt first, RandIt middle, RandIt last, Compare comp)
|
||||
{
|
||||
if((middle - first) < (last - middle)){
|
||||
while(first != middle){
|
||||
@@ -271,12 +366,12 @@ void merge_bufferless(RandIt first, RandIt middle, RandIt last, Compare comp)
|
||||
}
|
||||
do{
|
||||
++first;
|
||||
} while(first != middle && !comp(*middle, *first));
|
||||
} while(first != middle && !comp(*middle, *first));
|
||||
}
|
||||
}
|
||||
else{
|
||||
while(middle != last){
|
||||
RandIt p = upper_bound(first, middle, last[-1], comp);
|
||||
RandIt p = upper_bound(first, middle, last[-1], comp);
|
||||
last = rotate_gcd(p, middle, last);
|
||||
middle = p;
|
||||
if(middle == first){
|
||||
@@ -290,10 +385,21 @@ void merge_bufferless(RandIt first, RandIt middle, RandIt last, Compare comp)
|
||||
}
|
||||
}
|
||||
|
||||
template<class RandIt, class Compare>
|
||||
void merge_bufferless(RandIt first, RandIt middle, RandIt last, Compare comp)
|
||||
{
|
||||
//#define BOOST_ADAPTIVE_MERGE_NLOGN_MERGE
|
||||
#ifdef BOOST_ADAPTIVE_MERGE_NLOGN_MERGE
|
||||
merge_bufferless_ONlogN(first, middle, last, comp);
|
||||
#else
|
||||
merge_bufferless_ON2(first, middle, last, comp);
|
||||
#endif //BOOST_ADAPTIVE_MERGE_NLOGN_MERGE
|
||||
}
|
||||
|
||||
template<class Comp>
|
||||
struct antistable
|
||||
{
|
||||
antistable(Comp &comp)
|
||||
explicit antistable(Comp &comp)
|
||||
: m_comp(comp)
|
||||
{}
|
||||
|
||||
@@ -306,6 +412,49 @@ struct antistable
|
||||
Comp &m_comp;
|
||||
};
|
||||
|
||||
template <class Comp>
|
||||
class negate
|
||||
{
|
||||
public:
|
||||
negate()
|
||||
{}
|
||||
|
||||
explicit negate(Comp comp)
|
||||
: m_comp(comp)
|
||||
{}
|
||||
|
||||
template <class T1, class T2>
|
||||
bool operator()(const T1& l, const T2& r)
|
||||
{
|
||||
return !m_comp(l, r);
|
||||
}
|
||||
|
||||
private:
|
||||
Comp m_comp;
|
||||
};
|
||||
|
||||
|
||||
template <class Comp>
|
||||
class inverse
|
||||
{
|
||||
public:
|
||||
inverse()
|
||||
{}
|
||||
|
||||
explicit inverse(Comp comp)
|
||||
: m_comp(comp)
|
||||
{}
|
||||
|
||||
template <class T1, class T2>
|
||||
bool operator()(const T1& l, const T2& r)
|
||||
{
|
||||
return m_comp(r, l);
|
||||
}
|
||||
|
||||
private:
|
||||
Comp m_comp;
|
||||
};
|
||||
|
||||
// [r_first, r_last) are already in the right part of the destination range.
|
||||
template <class Compare, class InputIterator, class InputOutIterator, class Op>
|
||||
void op_merge_with_right_placed
|
||||
|
@@ -41,6 +41,21 @@ namespace movelib {
|
||||
|
||||
static const unsigned MergeSortInsertionSortThreshold = 16;
|
||||
|
||||
template <class RandIt, class Compare>
|
||||
void inplace_stable_sort(RandIt first, RandIt last, Compare comp)
|
||||
{
|
||||
typedef typename iterator_traits<RandIt>::size_type size_type;
|
||||
if (size_type(last - first) <= size_type(MergeSortInsertionSortThreshold)) {
|
||||
insertion_sort(first, last, comp);
|
||||
return;
|
||||
}
|
||||
RandIt middle = first + (last - first) / 2;
|
||||
inplace_stable_sort(first, middle, comp);
|
||||
inplace_stable_sort(middle, last, comp);
|
||||
merge_bufferless_ONlogN_recursive
|
||||
(first, middle, last, size_type(middle - first), size_type(last - middle), comp);
|
||||
}
|
||||
|
||||
// @endcond
|
||||
|
||||
template<class RandIt, class RandIt2, class Compare>
|
||||
|
@@ -125,10 +125,10 @@ F uninitialized_move(I f, I l, F r
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
for (; back != r; ++back){
|
||||
back->~input_value_type();
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return r;
|
||||
|
@@ -260,8 +260,8 @@
|
||||
|
||||
#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
|
||||
public:\
|
||||
TYPE& operator=(TYPE &t)\
|
||||
{ this->operator=(const_cast<const TYPE &>(t)); return *this;}\
|
||||
BOOST_MOVE_FORCEINLINE TYPE& operator=(TYPE &t)\
|
||||
{ this->operator=(const_cast<const TYPE&>(t)); return *this;}\
|
||||
public:\
|
||||
BOOST_MOVE_FORCEINLINE operator ::boost::rv<TYPE>&() \
|
||||
{ return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this); }\
|
||||
|
@@ -114,6 +114,18 @@ struct is_same<T, T>
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// enable_if_same
|
||||
//////////////////////////////////////
|
||||
template <class T, class U, class R = void>
|
||||
struct enable_if_same : enable_if<is_same<T, U>, R> {};
|
||||
|
||||
//////////////////////////////////////
|
||||
// disable_if_same
|
||||
//////////////////////////////////////
|
||||
template <class T, class U, class R = void>
|
||||
struct disable_if_same : disable_if<is_same<T, U>, R> {};
|
||||
|
||||
} //namespace move_detail {
|
||||
} //namespace boost {
|
||||
|
||||
|
171
include/boost/move/detail/reverse_iterator.hpp
Normal file
171
include/boost/move/detail/reverse_iterator.hpp
Normal file
@@ -0,0 +1,171 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/move for documentation.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_MOVE_DETAIL_REVERSE_ITERATOR_HPP
|
||||
#define BOOST_MOVE_DETAIL_REVERSE_ITERATOR_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
#include <boost/move/detail/iterator_traits.hpp>
|
||||
#include <boost/move/detail/meta_utils.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace movelib {
|
||||
|
||||
template<class It>
|
||||
class reverse_iterator
|
||||
{
|
||||
public:
|
||||
typedef typename boost::movelib::iterator_traits<It>::pointer pointer;
|
||||
typedef typename boost::movelib::iterator_traits<It>::reference reference;
|
||||
typedef typename boost::movelib::iterator_traits<It>::difference_type difference_type;
|
||||
typedef typename boost::movelib::iterator_traits<It>::iterator_category iterator_category;
|
||||
typedef typename boost::movelib::iterator_traits<It>::value_type value_type;
|
||||
|
||||
|
||||
typedef It iterator_type;
|
||||
|
||||
reverse_iterator()
|
||||
: m_current() //Value initialization to achieve "null iterators" (N3644)
|
||||
{}
|
||||
|
||||
explicit reverse_iterator(It r)
|
||||
: m_current(r)
|
||||
{}
|
||||
|
||||
reverse_iterator(const reverse_iterator& r)
|
||||
: m_current(r.base())
|
||||
{}
|
||||
|
||||
template<class OtherIt>
|
||||
reverse_iterator( const reverse_iterator<OtherIt>& r
|
||||
, typename boost::move_detail::enable_if_convertible<OtherIt, It>::type* =0
|
||||
)
|
||||
: m_current(r.base())
|
||||
{}
|
||||
|
||||
reverse_iterator & operator=( const reverse_iterator& r)
|
||||
{ m_current = r.base(); return *this; }
|
||||
|
||||
template<class OtherIt>
|
||||
typename boost::move_detail::enable_if_convertible<OtherIt, It, reverse_iterator &>::type
|
||||
operator=( const reverse_iterator<OtherIt>& r)
|
||||
{ m_current = r.base(); return *this; }
|
||||
|
||||
It base() const
|
||||
{ return m_current; }
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
It temp(m_current);
|
||||
--temp;
|
||||
reference r = *temp;
|
||||
return r;
|
||||
}
|
||||
|
||||
pointer operator->() const
|
||||
{
|
||||
It temp(m_current);
|
||||
--temp;
|
||||
return iterator_arrow_result(temp);
|
||||
}
|
||||
|
||||
reference operator[](difference_type off) const
|
||||
{
|
||||
return this->m_current[-off - 1];
|
||||
}
|
||||
|
||||
reverse_iterator& operator++()
|
||||
{
|
||||
--m_current;
|
||||
return *this;
|
||||
}
|
||||
|
||||
reverse_iterator operator++(int)
|
||||
{
|
||||
reverse_iterator temp((*this));
|
||||
--m_current;
|
||||
return temp;
|
||||
}
|
||||
|
||||
reverse_iterator& operator--()
|
||||
{
|
||||
++m_current;
|
||||
return *this;
|
||||
}
|
||||
|
||||
reverse_iterator operator--(int)
|
||||
{
|
||||
reverse_iterator temp((*this));
|
||||
++m_current;
|
||||
return temp;
|
||||
}
|
||||
|
||||
friend bool operator==(const reverse_iterator& l, const reverse_iterator& r)
|
||||
{ return l.m_current == r.m_current; }
|
||||
|
||||
friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r)
|
||||
{ return l.m_current != r.m_current; }
|
||||
|
||||
friend bool operator<(const reverse_iterator& l, const reverse_iterator& r)
|
||||
{ return l.m_current > r.m_current; }
|
||||
|
||||
friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r)
|
||||
{ return l.m_current >= r.m_current; }
|
||||
|
||||
friend bool operator>(const reverse_iterator& l, const reverse_iterator& r)
|
||||
{ return l.m_current < r.m_current; }
|
||||
|
||||
friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r)
|
||||
{ return l.m_current <= r.m_current; }
|
||||
|
||||
reverse_iterator& operator+=(difference_type off)
|
||||
{ m_current -= off; return *this; }
|
||||
|
||||
reverse_iterator& operator-=(difference_type off)
|
||||
{ m_current += off; return *this; }
|
||||
|
||||
friend reverse_iterator operator+(reverse_iterator l, difference_type off)
|
||||
{ return (l += off); }
|
||||
|
||||
friend reverse_iterator operator+(difference_type off, reverse_iterator r)
|
||||
{ return (r += off); }
|
||||
|
||||
friend reverse_iterator operator-(reverse_iterator l, difference_type off)
|
||||
{ return (l-= off); }
|
||||
|
||||
friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r)
|
||||
{ return r.m_current - l.m_current; }
|
||||
|
||||
private:
|
||||
It m_current; // the wrapped iterator
|
||||
};
|
||||
|
||||
template< class Iterator >
|
||||
reverse_iterator<Iterator> make_reverse_iterator( Iterator i )
|
||||
{
|
||||
return reverse_iterator<Iterator>(i);
|
||||
}
|
||||
|
||||
} //namespace movelib {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_MOVE_DETAIL_REVERSE_ITERATOR_HPP
|
@@ -55,8 +55,10 @@
|
||||
// BOOST_MOVE_IS_POD(T) should evaluate to true if T is a POD type
|
||||
// BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) should evaluate to true if "T x;" has no effect
|
||||
// BOOST_MOVE_HAS_TRIVIAL_COPY(T) should evaluate to true if T(t) <==> memcpy
|
||||
// (Note: this trait does not guarantee T is copy constructible, the copy constructor could be deleted but still be trivial)
|
||||
// BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) should evaluate to true if T(boost::move(t)) <==> memcpy
|
||||
// BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) should evaluate to true if t = u <==> memcpy
|
||||
// (Note: this trait does not guarantee T is assignable , the copy assignmen could be deleted but still be trivial)
|
||||
// BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) should evaluate to true if t = boost::move(u) <==> memcpy
|
||||
// BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) should evaluate to true if ~T() has no effect
|
||||
// BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) should evaluate to true if "T x;" can not throw
|
||||
@@ -117,9 +119,7 @@
|
||||
# define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
|
||||
# endif
|
||||
# if __has_feature(has_trivial_copy)
|
||||
# //There are problems with deleted copy constructors detected as trivially copyable.
|
||||
# //http://stackoverflow.com/questions/12754886/has-trivial-copy-behaves-differently-in-clang-and-gcc-whos-right
|
||||
# define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) && ::boost::move_detail::is_copy_constructible<T>::value)
|
||||
# define BOOST_MOVE_HAS_TRIVIAL_COPY(T) __has_trivial_copy(T)
|
||||
# endif
|
||||
# if __has_feature(has_trivial_assign)
|
||||
# define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) )
|
||||
@@ -235,7 +235,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MOVE_HAS_TRIVIAL_COPY
|
||||
#define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_TRIVIAL_COPY(T)
|
||||
#define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) ::boost::move_detail::is_pod<T>::value ||\
|
||||
(::boost::move_detail::is_copy_constructible<T>::value &&\
|
||||
BOOST_MOVE_HAS_TRIVIAL_COPY(T))
|
||||
#else
|
||||
#define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) ::boost::move_detail::is_pod<T>::value
|
||||
#endif
|
||||
@@ -246,12 +248,6 @@
|
||||
#define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T) ::boost::move_detail::is_pod<T>::value
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MOVE_HAS_TRIVIAL_COPY
|
||||
#define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_TRIVIAL_COPY(T)
|
||||
#else
|
||||
#define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) ::boost::move_detail::is_pod<T>::value
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR
|
||||
#define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T)
|
||||
#else
|
||||
@@ -259,7 +255,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MOVE_HAS_TRIVIAL_ASSIGN
|
||||
#define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T)
|
||||
#define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value ||\
|
||||
( ::boost::move_detail::is_copy_assignable<T>::value &&\
|
||||
BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T))
|
||||
#else
|
||||
#define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value
|
||||
#endif
|
||||
@@ -821,9 +819,7 @@ struct is_trivially_copy_constructible
|
||||
{
|
||||
//In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with
|
||||
//deleted copy constructors so make sure the type is copy constructible.
|
||||
static const bool value = ::boost::move_detail::is_pod<T>::value ||
|
||||
( ::boost::move_detail::is_copy_constructible<T>::value &&
|
||||
BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) );
|
||||
static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T);
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
@@ -831,7 +827,7 @@ struct is_trivially_copy_constructible
|
||||
//////////////////////////////////////
|
||||
template<class T>
|
||||
struct is_trivially_move_constructible
|
||||
{ static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T); };
|
||||
{ static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T); };
|
||||
|
||||
//////////////////////////////////////
|
||||
// is_trivially_copy_assignable
|
||||
@@ -841,9 +837,7 @@ struct is_trivially_copy_assignable
|
||||
{
|
||||
//In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with
|
||||
//deleted copy constructors so make sure the type is copy constructible.
|
||||
static const bool value = ::boost::move_detail::is_pod<T>::value ||
|
||||
( ::boost::move_detail::is_copy_assignable<T>::value &&
|
||||
BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) );
|
||||
static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T);
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
@@ -1005,7 +999,7 @@ BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1000)
|
||||
|
||||
template<class T, std::size_t Len>
|
||||
union aligned_union
|
||||
{
|
||||
{
|
||||
T aligner;
|
||||
char dummy[Len];
|
||||
};
|
||||
@@ -1023,7 +1017,7 @@ struct aligned_next<Len, Align, T, true>
|
||||
//End of search defaults to max_align_t
|
||||
template<std::size_t Len, std::size_t Align>
|
||||
struct aligned_next<Len, Align, max_align_t, false>
|
||||
{ typedef aligned_union<max_align_t, Len> type; };
|
||||
{ typedef aligned_union<max_align_t, Len> type; };
|
||||
|
||||
//Now define a search list through types
|
||||
#define BOOST_MOVE_ALIGNED_NEXT_STEP(TYPE, NEXT_TYPE)\
|
||||
|
@@ -119,6 +119,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_merge", "bench_merge.
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adaptive_sort_test", "adaptive_sort_test.vcproj", "{CD617A28-6217-B79E-4CE2-6BA035379A6A}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adaptive_merge_test", "adaptive_merge_test.vcproj", "{CD617A28-6217-B79E-4CE2-6BA035379A6A}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_template_assign", "doc_template_assign.vcproj", "{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@@ -247,6 +259,18 @@ Global
|
||||
{CD2617A8-6217-9EB7-24CE-6C9AA035376A}.Debug.Build.0 = Debug|Win32
|
||||
{CD2617A8-6217-9EB7-24CE-6C9AA035376A}.Release.ActiveCfg = Release|Win32
|
||||
{CD2617A8-6217-9EB7-24CE-6C9AA035376A}.Release.Build.0 = Release|Win32
|
||||
{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Debug.ActiveCfg = Debug|Win32
|
||||
{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Debug.Build.0 = Debug|Win32
|
||||
{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Release.ActiveCfg = Release|Win32
|
||||
{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Release.Build.0 = Release|Win32
|
||||
{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Debug.ActiveCfg = Debug|Win32
|
||||
{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Debug.Build.0 = Debug|Win32
|
||||
{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Release.ActiveCfg = Release|Win32
|
||||
{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Release.Build.0 = Release|Win32
|
||||
{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Debug.ActiveCfg = Debug|Win32
|
||||
{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Debug.Build.0 = Debug|Win32
|
||||
{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Release.ActiveCfg = Release|Win32
|
||||
{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionItems) = postSolution
|
||||
..\..\..\..\boost\move\algo\adaptive_merge.hpp = ..\..\..\..\boost\move\algo\adaptive_merge.hpp
|
||||
@@ -267,8 +291,8 @@ Global
|
||||
..\..\..\..\boost\move\detail\iterator_traits.hpp = ..\..\..\..\boost\move\detail\iterator_traits.hpp
|
||||
..\..\doc\Jamfile.v2 = ..\..\doc\Jamfile.v2
|
||||
..\..\..\..\boost\move\make_unique.hpp = ..\..\..\..\boost\move\make_unique.hpp
|
||||
..\..\..\..\boost\move\algo\merge.hpp = ..\..\..\..\boost\move\algo\merge.hpp
|
||||
..\..\..\..\boost\move\algo\merge_sort.hpp = ..\..\..\..\boost\move\algo\merge_sort.hpp
|
||||
..\..\..\..\boost\move\algo\detail\merge.hpp = ..\..\..\..\boost\move\algo\detail\merge.hpp
|
||||
..\..\..\..\boost\move\algo\detail\merge_sort.hpp = ..\..\..\..\boost\move\algo\detail\merge_sort.hpp
|
||||
..\..\..\..\boost\move\detail\meta_utils.hpp = ..\..\..\..\boost\move\detail\meta_utils.hpp
|
||||
..\..\..\..\boost\move\detail\meta_utils_core.hpp = ..\..\..\..\boost\move\detail\meta_utils_core.hpp
|
||||
..\..\..\..\boost\move\move.hpp = ..\..\..\..\boost\move\move.hpp
|
||||
|
134
proj/vc7ide/adaptive_merge_test.vcproj
Normal file
134
proj/vc7ide/adaptive_merge_test.vcproj
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="adaptive_merge_test"
|
||||
ProjectGUID="{CD617A28-6217-B79E-4CE2-6BA035379A6A}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/adaptive_merge_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
DisableLanguageExtensions="FALSE"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/adaptive_merge_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/adaptive_merge_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/adaptive_merge_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/adaptive_merge_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{163D8753-0546-A605-5C56-3B0FEAD7A52A}">
|
||||
<File
|
||||
RelativePath="..\..\test\adaptive_merge_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
134
proj/vc7ide/adaptive_sort_test.vcproj
Normal file
134
proj/vc7ide/adaptive_sort_test.vcproj
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="adaptive_sort_test"
|
||||
ProjectGUID="{CD617A28-6217-B79E-4CE2-6BA035379A6A}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/adaptive_sort_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
DisableLanguageExtensions="FALSE"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/adaptive_sort_test_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/adaptive_sort_test.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/adaptive_sort_test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/adaptive_sort_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{163D8753-0546-A605-5C56-3B0FEAD7A52A}">
|
||||
<File
|
||||
RelativePath="..\..\test\adaptive_sort_test.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
134
proj/vc7ide/doc_template_assign.vcproj
Normal file
134
proj/vc7ide/doc_template_assign.vcproj
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="doc_template_assign"
|
||||
ProjectGUID="{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/doc_template_assign"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
DisableLanguageExtensions="FALSE"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_template_assign_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/doc_template_assign.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/doc_template_assign"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_template_assign.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{475F3C87-6465-7BC5-05A6-2454C0A2A2CF}">
|
||||
<File
|
||||
RelativePath="..\..\example\doc_template_assign.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
87
test/adaptive_merge_test.cpp
Normal file
87
test/adaptive_merge_test.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2016.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/move for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cstdlib> //std::srand
|
||||
#include <algorithm> //std::next_permutation
|
||||
#include <iostream> //std::cout
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/move/unique_ptr.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/timer/timer.hpp>
|
||||
|
||||
using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
#include "order_type.hpp"
|
||||
|
||||
#include <boost/move/algo/adaptive_merge.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
|
||||
|
||||
template<class T>
|
||||
bool test_random_shuffled(std::size_t const element_count, std::size_t const num_keys, std::size_t const num_iter)
|
||||
{
|
||||
boost::movelib::unique_ptr<T[]> elements(new T[element_count]);
|
||||
boost::movelib::unique_ptr<std::size_t[]> key_reps(new std::size_t[num_keys ? num_keys : element_count]);
|
||||
std::cout << "- - N: " << element_count << ", Keys: " << num_keys << ", It: " << num_iter << " \n";
|
||||
|
||||
//Initialize keys
|
||||
for(std::size_t i=0; i < element_count; ++i){
|
||||
std::size_t key = num_keys ? (i % num_keys) : i;
|
||||
elements[i].key=key;
|
||||
}
|
||||
|
||||
std::srand(0);
|
||||
|
||||
for (std::size_t i = 0; i != num_iter; ++i)
|
||||
{
|
||||
std::random_shuffle(elements.get(), elements.get() + element_count);
|
||||
for(std::size_t i = 0; i < (num_keys ? num_keys : element_count); ++i){
|
||||
key_reps[i]=0;
|
||||
}
|
||||
for(std::size_t i = 0; i < element_count; ++i){
|
||||
elements[i].val = key_reps[elements[i].key]++;
|
||||
}
|
||||
|
||||
boost::container::vector<order_type> tmp(elements.get(), elements.get()+element_count);
|
||||
std::size_t const split = std::size_t(std::rand()) % element_count;
|
||||
std::stable_sort(tmp.data(), tmp.data()+split, order_type_less<order_type>());
|
||||
std::stable_sort(tmp.data()+split, tmp.data()+element_count, order_type_less<order_type>());
|
||||
|
||||
boost::movelib::adaptive_merge(tmp.data(), tmp.data()+split, tmp.data()+element_count, order_type_less<order_type>());
|
||||
|
||||
if (!is_order_type_ordered(tmp.data(), element_count))
|
||||
{
|
||||
std::cout << "\n ERROR\n";
|
||||
throw int(0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
const std::size_t NIter = 100;
|
||||
#else
|
||||
const std::size_t NIter = 10;
|
||||
#endif
|
||||
test_random_shuffled<order_type>(10001, 65, NIter);
|
||||
test_random_shuffled<order_type>(10001, 101, NIter);
|
||||
test_random_shuffled<order_type>(10001, 1023, NIter);
|
||||
test_random_shuffled<order_type>(10001, 4095, NIter);
|
||||
test_random_shuffled<order_type>(10001, 0, NIter);
|
||||
|
||||
return 0;
|
||||
}
|
83
test/adaptive_sort_test.cpp
Normal file
83
test/adaptive_sort_test.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2016.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/move for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cstdlib> //std::srand
|
||||
#include <algorithm> //std::next_permutation
|
||||
#include <iostream> //std::cout
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/move/unique_ptr.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/timer/timer.hpp>
|
||||
|
||||
using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
#include "order_type.hpp"
|
||||
|
||||
#include <boost/move/algo/adaptive_sort.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
|
||||
template<class T>
|
||||
bool test_random_shuffled(std::size_t const element_count, std::size_t const num_keys, std::size_t const num_iter)
|
||||
{
|
||||
boost::movelib::unique_ptr<T[]> elements(new T[element_count]);
|
||||
boost::movelib::unique_ptr<std::size_t[]> key_reps(new std::size_t[num_keys ? num_keys : element_count]);
|
||||
std::cout << "- - N: " << element_count << ", Keys: " << num_keys << ", It: " << num_iter << " \n";
|
||||
|
||||
//Initialize keys
|
||||
for(std::size_t i=0; i < element_count; ++i){
|
||||
std::size_t key = num_keys ? (i % num_keys) : i;
|
||||
elements[i].key=key;
|
||||
}
|
||||
|
||||
std::srand(0);
|
||||
|
||||
for (std::size_t i = 0; i != num_iter; ++i)
|
||||
{
|
||||
std::random_shuffle(elements.get(), elements.get() + element_count);
|
||||
for(std::size_t i = 0; i < (num_keys ? num_keys : element_count); ++i){
|
||||
key_reps[i]=0;
|
||||
}
|
||||
for(std::size_t i = 0; i < element_count; ++i){
|
||||
elements[i].val = key_reps[elements[i].key]++;
|
||||
}
|
||||
|
||||
boost::container::vector<order_type> tmp(elements.get(), elements.get()+element_count);
|
||||
|
||||
boost::movelib::adaptive_sort(tmp.data(), tmp.data()+element_count, order_type_less<order_type>());
|
||||
|
||||
if (!is_order_type_ordered(tmp.data(), element_count))
|
||||
{
|
||||
std::cout << "\n ERROR\n";
|
||||
throw int(0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
const std::size_t NIter = 100;
|
||||
#else
|
||||
const std::size_t NIter = 10;
|
||||
#endif
|
||||
test_random_shuffled<order_type>(10001, 65, NIter);
|
||||
test_random_shuffled<order_type>(10001, 101, NIter);
|
||||
test_random_shuffled<order_type>(10001, 1023, NIter);
|
||||
test_random_shuffled<order_type>(10001, 4095, NIter);
|
||||
test_random_shuffled<order_type>(10001, 0, NIter);
|
||||
|
||||
return 0;
|
||||
}
|
@@ -18,62 +18,18 @@
|
||||
#include <boost/move/unique_ptr.hpp>
|
||||
#include <boost/timer/timer.hpp>
|
||||
|
||||
#include "order_type.hpp"
|
||||
|
||||
using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
|
||||
boost::ulong_long_type num_copy;
|
||||
boost::ulong_long_type num_elements;
|
||||
|
||||
struct merged_type
|
||||
{
|
||||
public:
|
||||
std::size_t key;
|
||||
std::size_t val;
|
||||
|
||||
merged_type()
|
||||
{
|
||||
++num_elements;
|
||||
}
|
||||
|
||||
merged_type(const merged_type& other)
|
||||
: key(other.key), val(other.val)
|
||||
{
|
||||
++num_elements;
|
||||
++num_copy;
|
||||
}
|
||||
|
||||
merged_type & operator=(const merged_type& other)
|
||||
{
|
||||
++num_copy;
|
||||
key = other.key;
|
||||
val = other.val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~merged_type ()
|
||||
{
|
||||
--num_elements;
|
||||
}
|
||||
};
|
||||
|
||||
boost::ulong_long_type num_compare;
|
||||
|
||||
//#define BOOST_MOVE_ADAPTIVE_SORT_STATS
|
||||
void print_stats(const char *str, boost::ulong_long_type element_count)
|
||||
{
|
||||
std::printf("%sCmp:%8.04f Cpy:%9.04f\n", str, double(num_compare)/element_count, double(num_copy)/element_count );
|
||||
std::printf("%sCmp:%8.04f Cpy:%9.04f\n", str, double(order_type::num_compare)/element_count, double(order_type::num_copy)/element_count );
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
struct counted_less
|
||||
{
|
||||
bool operator()(const T &a,T const &b) const
|
||||
{ ++num_compare; return a.key < b.key; }
|
||||
};
|
||||
|
||||
#include <boost/move/algo/adaptive_merge.hpp>
|
||||
#include <boost/move/algo/detail/merge.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
@@ -101,21 +57,7 @@ std::size_t generate_elements(T elements[], std::size_t element_count, std::size
|
||||
return split_count;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool test_order(T *elements, std::size_t element_count, bool stable = true)
|
||||
{
|
||||
for(std::size_t i = 1; i < element_count; ++i){
|
||||
if(counted_less<T>()(elements[i], elements[i-1])){
|
||||
std::printf("\n Ord KO !!!!");
|
||||
return false;
|
||||
}
|
||||
if( stable && !(counted_less<T>()(elements[i-1], elements[i])) && (elements[i-1].val > elements[i].val) ){
|
||||
std::printf("\n Stb KO !!!! ");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Compare>
|
||||
void adaptive_merge_buffered(T *elements, T *mid, T *last, Compare comp, std::size_t BufLen)
|
||||
@@ -126,23 +68,23 @@ void adaptive_merge_buffered(T *elements, T *mid, T *last, Compare comp, std::si
|
||||
|
||||
enum AlgoType
|
||||
{
|
||||
InplaceMerge,
|
||||
StdMerge,
|
||||
AdaptiveMerge,
|
||||
SqrtHAdaptiveMerge,
|
||||
SqrtAdaptiveMerge,
|
||||
Sqrt2AdaptiveMerge,
|
||||
QuartAdaptiveMerge,
|
||||
BuflessMerge,
|
||||
StdInplaceMerge,
|
||||
MaxMerge
|
||||
};
|
||||
|
||||
const char *AlgoNames [] = { "InplaceMerge "
|
||||
const char *AlgoNames [] = { "StdMerge "
|
||||
, "AdaptMerge "
|
||||
, "SqrtHAdaptMerge "
|
||||
, "SqrtAdaptMerge "
|
||||
, "Sqrt2AdaptMerge "
|
||||
, "QuartAdaptMerge "
|
||||
, "BuflessMerge "
|
||||
, "StdInplaceMerge "
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT((sizeof(AlgoNames)/sizeof(*AlgoNames)) == MaxMerge);
|
||||
@@ -150,53 +92,53 @@ BOOST_STATIC_ASSERT((sizeof(AlgoNames)/sizeof(*AlgoNames)) == MaxMerge);
|
||||
template<class T>
|
||||
bool measure_algo(T *elements, std::size_t key_reps[], std::size_t element_count, std::size_t key_len, unsigned alg, nanosecond_type &prev_clock)
|
||||
{
|
||||
std::size_t const split_pos = generate_elements(elements, element_count, key_reps, key_len, counted_less<T>());
|
||||
std::size_t const split_pos = generate_elements(elements, element_count, key_reps, key_len, order_type_less<T>());
|
||||
|
||||
std::printf("%s ", AlgoNames[alg]);
|
||||
num_compare=0;
|
||||
num_copy=0;
|
||||
num_elements = element_count;
|
||||
order_type::num_compare=0;
|
||||
order_type::num_copy=0;
|
||||
order_type::num_elements = element_count;
|
||||
cpu_timer timer;
|
||||
timer.resume();
|
||||
switch(alg)
|
||||
{
|
||||
case InplaceMerge:
|
||||
std::inplace_merge(elements, elements+split_pos, elements+element_count, counted_less<T>());
|
||||
case StdMerge:
|
||||
std::inplace_merge(elements, elements+split_pos, elements+element_count, order_type_less<T>());
|
||||
break;
|
||||
case AdaptiveMerge:
|
||||
boost::movelib::adaptive_merge(elements, elements+split_pos, elements+element_count, counted_less<T>());
|
||||
boost::movelib::adaptive_merge(elements, elements+split_pos, elements+element_count, order_type_less<T>());
|
||||
break;
|
||||
case SqrtHAdaptiveMerge:
|
||||
adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, counted_less<T>()
|
||||
adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less<T>()
|
||||
, boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count)/2+1);
|
||||
break;
|
||||
case SqrtAdaptiveMerge:
|
||||
adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, counted_less<T>()
|
||||
adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less<T>()
|
||||
, boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
|
||||
break;
|
||||
case Sqrt2AdaptiveMerge:
|
||||
adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, counted_less<T>()
|
||||
adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less<T>()
|
||||
, 2*boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
|
||||
break;
|
||||
case QuartAdaptiveMerge:
|
||||
adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, counted_less<T>()
|
||||
adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less<T>()
|
||||
, (element_count-1)/4+1);
|
||||
break;
|
||||
case BuflessMerge:
|
||||
boost::movelib::merge_bufferless(elements, elements+split_pos, elements+element_count, counted_less<T>());
|
||||
case StdInplaceMerge:
|
||||
boost::movelib::merge_bufferless_ONlogN(elements, elements+split_pos, elements+element_count, order_type_less<T>());
|
||||
break;
|
||||
}
|
||||
timer.stop();
|
||||
|
||||
if(num_elements == element_count){
|
||||
if(order_type::num_elements == element_count){
|
||||
std::printf(" Tmp Ok ");
|
||||
} else{
|
||||
std::printf(" Tmp KO ");
|
||||
}
|
||||
nanosecond_type new_clock = timer.elapsed().wall;
|
||||
|
||||
//std::cout << "Cmp:" << num_compare << " Cpy:" << num_copy; //for old compilers without ll size argument
|
||||
std::printf("Cmp:%8.04f Cpy:%9.04f", double(num_compare)/element_count, double(num_copy)/element_count );
|
||||
//std::cout << "Cmp:" << order_type::num_compare << " Cpy:" << order_type::num_copy; //for old compilers without ll size argument
|
||||
std::printf("Cmp:%8.04f Cpy:%9.04f", double(order_type::num_compare)/element_count, double(order_type::num_copy)/element_count );
|
||||
|
||||
double time = double(new_clock);
|
||||
|
||||
@@ -219,7 +161,7 @@ bool measure_algo(T *elements, std::size_t key_reps[], std::size_t element_count
|
||||
, units
|
||||
, prev_clock ? double(new_clock)/double(prev_clock): 1.0);
|
||||
prev_clock = new_clock;
|
||||
bool res = test_order(elements, element_count, true);
|
||||
bool res = is_order_type_ordered(elements, element_count, true);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -235,7 +177,7 @@ bool measure_all(std::size_t L, std::size_t NK)
|
||||
nanosecond_type prev_clock = 0;
|
||||
nanosecond_type back_clock;
|
||||
bool res = true;
|
||||
res = res && measure_algo(A,Keys,L,NK,InplaceMerge, prev_clock);
|
||||
res = res && measure_algo(A,Keys,L,NK,StdMerge, prev_clock);
|
||||
back_clock = prev_clock;/*
|
||||
//
|
||||
prev_clock = back_clock;
|
||||
@@ -253,70 +195,74 @@ bool measure_all(std::size_t L, std::size_t NK)
|
||||
prev_clock = back_clock;
|
||||
res = res && measure_algo(A,Keys,L,NK,AdaptiveMerge, prev_clock);
|
||||
//
|
||||
//prev_clock = back_clock;
|
||||
//res = res && measure_algo(A,Keys,L,NK,BuflessMerge, prev_clock);
|
||||
prev_clock = back_clock;
|
||||
res = res && measure_algo(A,Keys,L,NK,StdInplaceMerge, prev_clock);
|
||||
//
|
||||
if(!res)
|
||||
throw int(0);
|
||||
return res;
|
||||
}
|
||||
|
||||
struct less
|
||||
{
|
||||
template<class T, class U>
|
||||
bool operator()(const T &t, const U &u)
|
||||
{ return t < u; }
|
||||
};
|
||||
|
||||
//Undef it to run the long test
|
||||
#define BENCH_MERGE_SHORT
|
||||
#define BENCH_SORT_UNIQUE_VALUES
|
||||
|
||||
int main()
|
||||
{
|
||||
try{
|
||||
measure_all<merged_type>(101,1);
|
||||
measure_all<merged_type>(101,7);
|
||||
measure_all<merged_type>(101,31);
|
||||
measure_all<merged_type>(101,0);
|
||||
#ifndef BENCH_SORT_UNIQUE_VALUES
|
||||
measure_all<order_type>(101,1);
|
||||
measure_all<order_type>(101,7);
|
||||
measure_all<order_type>(101,31);
|
||||
#endif
|
||||
measure_all<order_type>(101,0);
|
||||
|
||||
//
|
||||
measure_all<merged_type>(1101,1);
|
||||
measure_all<merged_type>(1001,7);
|
||||
measure_all<merged_type>(1001,31);
|
||||
measure_all<merged_type>(1001,127);
|
||||
measure_all<merged_type>(1001,511);
|
||||
measure_all<merged_type>(1001,0);
|
||||
#ifndef BENCH_SORT_UNIQUE_VALUES
|
||||
measure_all<order_type>(1101,1);
|
||||
measure_all<order_type>(1001,7);
|
||||
measure_all<order_type>(1001,31);
|
||||
measure_all<order_type>(1001,127);
|
||||
measure_all<order_type>(1001,511);
|
||||
#endif
|
||||
measure_all<order_type>(1001,0);
|
||||
//
|
||||
#ifndef BENCH_MERGE_SHORT
|
||||
measure_all<merged_type>(10001,65);
|
||||
measure_all<merged_type>(10001,255);
|
||||
measure_all<merged_type>(10001,1023);
|
||||
measure_all<merged_type>(10001,4095);
|
||||
measure_all<merged_type>(10001,0);
|
||||
#ifndef BENCH_SORT_UNIQUE_VALUES
|
||||
measure_all<order_type>(10001,65);
|
||||
measure_all<order_type>(10001,255);
|
||||
measure_all<order_type>(10001,1023);
|
||||
measure_all<order_type>(10001,4095);
|
||||
#endif
|
||||
measure_all<order_type>(10001,0);
|
||||
|
||||
//
|
||||
measure_all<merged_type>(100001,511);
|
||||
measure_all<merged_type>(100001,2047);
|
||||
measure_all<merged_type>(100001,8191);
|
||||
measure_all<merged_type>(100001,32767);
|
||||
measure_all<merged_type>(100001,0);
|
||||
#ifndef BENCH_SORT_UNIQUE_VALUES
|
||||
measure_all<order_type>(100001,511);
|
||||
measure_all<order_type>(100001,2047);
|
||||
measure_all<order_type>(100001,8191);
|
||||
measure_all<order_type>(100001,32767);
|
||||
#endif
|
||||
measure_all<order_type>(100001,0);
|
||||
|
||||
//
|
||||
#ifdef NDEBUG
|
||||
measure_all<merged_type>(1000001,1);
|
||||
measure_all<merged_type>(1000001,1024);
|
||||
measure_all<merged_type>(1000001,32768);
|
||||
measure_all<merged_type>(1000001,524287);
|
||||
measure_all<merged_type>(1000001,0);
|
||||
measure_all<merged_type>(1500001,0);
|
||||
//measure_all<merged_type>(10000001,0);
|
||||
//measure_all<merged_type>(15000001,0);
|
||||
//measure_all<merged_type>(100000001,0);
|
||||
#ifndef BENCH_SORT_UNIQUE_VALUES
|
||||
measure_all<order_type>(1000001,1);
|
||||
measure_all<order_type>(1000001,1024);
|
||||
measure_all<order_type>(1000001,32768);
|
||||
measure_all<order_type>(1000001,524287);
|
||||
#endif
|
||||
measure_all<order_type>(1000001,0);
|
||||
measure_all<order_type>(1500001,0);
|
||||
//measure_all<order_type>(10000001,0);
|
||||
//measure_all<order_type>(15000001,0);
|
||||
//measure_all<order_type>(100000001,0);
|
||||
#endif //NDEBUG
|
||||
|
||||
#endif //#ifndef BENCH_MERGE_SHORT
|
||||
|
||||
//measure_all<merged_type>(100000001,0);
|
||||
//measure_all<order_type>(100000001,0);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@@ -23,58 +23,15 @@ using boost::timer::cpu_timer;
|
||||
using boost::timer::cpu_times;
|
||||
using boost::timer::nanosecond_type;
|
||||
|
||||
|
||||
boost::ulong_long_type num_copy;
|
||||
boost::ulong_long_type num_elements;
|
||||
|
||||
struct sorted_type
|
||||
{
|
||||
public:
|
||||
std::size_t key;
|
||||
std::size_t val;
|
||||
|
||||
sorted_type()
|
||||
{
|
||||
++num_elements;
|
||||
}
|
||||
|
||||
sorted_type(const sorted_type& other)
|
||||
: key(other.key), val(other.val)
|
||||
{
|
||||
++num_elements;
|
||||
++num_copy;
|
||||
}
|
||||
|
||||
sorted_type & operator=(const sorted_type& other)
|
||||
{
|
||||
++num_copy;
|
||||
key = other.key;
|
||||
val = other.val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~sorted_type ()
|
||||
{
|
||||
--num_elements;
|
||||
}
|
||||
};
|
||||
|
||||
boost::ulong_long_type num_compare;
|
||||
#include "order_type.hpp"
|
||||
|
||||
//#define BOOST_MOVE_ADAPTIVE_SORT_STATS
|
||||
void print_stats(const char *str, boost::ulong_long_type element_count)
|
||||
{
|
||||
std::printf("%sCmp:%7.03f Cpy:%8.03f\n", str, double(num_compare)/element_count, double(num_copy)/element_count );
|
||||
std::printf("%sCmp:%7.03f Cpy:%8.03f\n", str, double(order_type::num_compare)/element_count, double(order_type::num_copy)/element_count );
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
struct counted_less
|
||||
{
|
||||
bool operator()(const T &a,T const &b) const
|
||||
{ ++num_compare; return a.key < b.key; }
|
||||
};
|
||||
|
||||
#include <boost/move/algo/adaptive_sort.hpp>
|
||||
#include <boost/move/algo/detail/merge_sort.hpp>
|
||||
#include <boost/move/algo/detail/bufferless_merge_sort.hpp>
|
||||
@@ -99,22 +56,6 @@ void generate_elements(T elements[], std::size_t element_count, std::size_t key_
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool test_order(T *elements, std::size_t element_count, bool stable = true)
|
||||
{
|
||||
for(std::size_t i = 1; i < element_count; ++i){
|
||||
if(counted_less<T>()(elements[i], elements[i-1])){
|
||||
std::printf("\n Ord KO !!!!");
|
||||
return false;
|
||||
}
|
||||
if( stable && !(counted_less<T>()(elements[i-1], elements[i])) && (elements[i-1].val > elements[i].val) ){
|
||||
std::printf("\n Stb KO !!!! ");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T, class Compare>
|
||||
void adaptive_sort_buffered(T *elements, std::size_t element_count, Compare comp, std::size_t BufLen)
|
||||
{
|
||||
@@ -139,6 +80,7 @@ enum AlgoType
|
||||
Sqrt2AdaptiveSort,
|
||||
QuartAdaptiveSort,
|
||||
NoBufMergeSort,
|
||||
InplaceStableSort,
|
||||
SlowStableSort,
|
||||
HeapSort,
|
||||
MaxSort
|
||||
@@ -152,6 +94,7 @@ const char *AlgoNames [] = { "MergeSort "
|
||||
, "Sqrt2AdaptSort "
|
||||
, "QuartAdaptSort "
|
||||
, "NoBufMergeSort "
|
||||
, "InplStableSort "
|
||||
, "SlowSort "
|
||||
, "HeapSort "
|
||||
};
|
||||
@@ -164,60 +107,63 @@ bool measure_algo(T *elements, std::size_t key_reps[], std::size_t element_count
|
||||
generate_elements(elements, element_count, key_reps, key_len);
|
||||
|
||||
std::printf("%s ", AlgoNames[alg]);
|
||||
num_compare=0;
|
||||
num_copy=0;
|
||||
num_elements = element_count;
|
||||
order_type::num_compare=0;
|
||||
order_type::num_copy=0;
|
||||
order_type::num_elements = element_count;
|
||||
cpu_timer timer;
|
||||
timer.resume();
|
||||
switch(alg)
|
||||
{
|
||||
case MergeSort:
|
||||
merge_sort_buffered(elements, element_count, counted_less<T>());
|
||||
merge_sort_buffered(elements, element_count, order_type_less<T>());
|
||||
break;
|
||||
case StableSort:
|
||||
std::stable_sort(elements,elements+element_count,counted_less<T>());
|
||||
std::stable_sort(elements,elements+element_count,order_type_less<T>());
|
||||
break;
|
||||
case AdaptiveSort:
|
||||
boost::movelib::adaptive_sort(elements, elements+element_count, counted_less<T>());
|
||||
boost::movelib::adaptive_sort(elements, elements+element_count, order_type_less<T>());
|
||||
break;
|
||||
case SqrtHAdaptiveSort:
|
||||
adaptive_sort_buffered( elements, element_count, counted_less<T>()
|
||||
adaptive_sort_buffered( elements, element_count, order_type_less<T>()
|
||||
, boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count)/2+1);
|
||||
break;
|
||||
case SqrtAdaptiveSort:
|
||||
adaptive_sort_buffered( elements, element_count, counted_less<T>()
|
||||
adaptive_sort_buffered( elements, element_count, order_type_less<T>()
|
||||
, boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
|
||||
break;
|
||||
case Sqrt2AdaptiveSort:
|
||||
adaptive_sort_buffered( elements, element_count, counted_less<T>()
|
||||
adaptive_sort_buffered( elements, element_count, order_type_less<T>()
|
||||
, 2*boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
|
||||
break;
|
||||
case QuartAdaptiveSort:
|
||||
adaptive_sort_buffered( elements, element_count, counted_less<T>()
|
||||
adaptive_sort_buffered( elements, element_count, order_type_less<T>()
|
||||
, (element_count-1)/4+1);
|
||||
break;
|
||||
case NoBufMergeSort:
|
||||
boost::movelib::bufferless_merge_sort(elements, elements+element_count, counted_less<T>());
|
||||
boost::movelib::bufferless_merge_sort(elements, elements+element_count, order_type_less<T>());
|
||||
break;
|
||||
case InplaceStableSort:
|
||||
boost::movelib::inplace_stable_sort(elements, elements+element_count, order_type_less<T>());
|
||||
break;
|
||||
case SlowStableSort:
|
||||
boost::movelib::detail_adaptive::slow_stable_sort(elements, elements+element_count, counted_less<T>());
|
||||
boost::movelib::detail_adaptive::slow_stable_sort(elements, elements+element_count, order_type_less<T>());
|
||||
break;
|
||||
case HeapSort:
|
||||
std::make_heap(elements, elements+element_count, counted_less<T>());
|
||||
std::sort_heap(elements, elements+element_count, counted_less<T>());
|
||||
std::make_heap(elements, elements+element_count, order_type_less<T>());
|
||||
std::sort_heap(elements, elements+element_count, order_type_less<T>());
|
||||
break;
|
||||
}
|
||||
timer.stop();
|
||||
|
||||
if(num_elements == element_count){
|
||||
if(order_type::num_elements == element_count){
|
||||
std::printf(" Tmp Ok ");
|
||||
} else{
|
||||
std::printf(" Tmp KO ");
|
||||
}
|
||||
nanosecond_type new_clock = timer.elapsed().wall;
|
||||
|
||||
//std::cout << "Cmp:" << num_compare << " Cpy:" << num_copy; //for old compilers without ll size argument
|
||||
std::printf("Cmp:%7.03f Cpy:%8.03f", double(num_compare)/element_count, double(num_copy)/element_count );
|
||||
//std::cout << "Cmp:" << order_type::num_compare << " Cpy:" << order_type::num_copy; //for old compilers without ll size argument
|
||||
std::printf("Cmp:%7.03f Cpy:%8.03f", double(order_type::num_compare)/element_count, double(order_type::num_copy)/element_count );
|
||||
|
||||
double time = double(new_clock);
|
||||
|
||||
@@ -240,7 +186,7 @@ bool measure_algo(T *elements, std::size_t key_reps[], std::size_t element_count
|
||||
, units
|
||||
, prev_clock ? double(new_clock)/double(prev_clock): 1.0);
|
||||
prev_clock = new_clock;
|
||||
bool res = test_order(elements, element_count, alg != HeapSort && alg != NoBufMergeSort);
|
||||
bool res = is_order_type_ordered(elements, element_count, alg != HeapSort && alg != NoBufMergeSort);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -281,6 +227,9 @@ bool measure_all(std::size_t L, std::size_t NK)
|
||||
res = res && measure_algo(A,Keys,L,NK,AdaptiveSort, prev_clock);
|
||||
//
|
||||
prev_clock = back_clock;
|
||||
res = res && measure_algo(A,Keys,L,NK,InplaceStableSort, prev_clock);
|
||||
//
|
||||
prev_clock = back_clock;
|
||||
res = res && measure_algo(A,Keys,L,NK,NoBufMergeSort, prev_clock);
|
||||
//
|
||||
//prev_clock = back_clock;
|
||||
@@ -293,59 +242,61 @@ bool measure_all(std::size_t L, std::size_t NK)
|
||||
|
||||
//Undef it to run the long test
|
||||
#define BENCH_SORT_SHORT
|
||||
|
||||
struct less
|
||||
{
|
||||
template<class T, class U>
|
||||
bool operator()(const T &t, const U &u)
|
||||
{ return t < u; }
|
||||
};
|
||||
|
||||
#define BENCH_SORT_UNIQUE_VALUES
|
||||
|
||||
int main()
|
||||
{
|
||||
measure_all<sorted_type>(101,1);
|
||||
measure_all<sorted_type>(101,7);
|
||||
measure_all<sorted_type>(101,31);
|
||||
measure_all<sorted_type>(101,0);
|
||||
#ifndef BENCH_SORT_UNIQUE_VALUES
|
||||
//measure_all<order_type>(101,1);
|
||||
measure_all<order_type>(101,7);
|
||||
measure_all<order_type>(101,31);
|
||||
#endif
|
||||
measure_all<order_type>(101,0);
|
||||
|
||||
//
|
||||
measure_all<sorted_type>(1101,1);
|
||||
measure_all<sorted_type>(1001,7);
|
||||
measure_all<sorted_type>(1001,31);
|
||||
measure_all<sorted_type>(1001,127);
|
||||
measure_all<sorted_type>(1001,511);
|
||||
measure_all<sorted_type>(1001,0);
|
||||
#ifndef BENCH_SORT_UNIQUE_VALUES
|
||||
measure_all<order_type>(1101,1);
|
||||
measure_all<order_type>(1001,7);
|
||||
measure_all<order_type>(1001,31);
|
||||
measure_all<order_type>(1001,127);
|
||||
measure_all<order_type>(1001,511);
|
||||
#endif
|
||||
measure_all<order_type>(1001,0);
|
||||
//
|
||||
#ifndef BENCH_SORT_SHORT
|
||||
measure_all<sorted_type>(10001,65);
|
||||
measure_all<sorted_type>(10001,255);
|
||||
measure_all<sorted_type>(10001,1023);
|
||||
measure_all<sorted_type>(10001,4095);
|
||||
measure_all<sorted_type>(10001,0);
|
||||
#ifndef BENCH_SORT_UNIQUE_VALUES
|
||||
measure_all<order_type>(10001,65);
|
||||
measure_all<order_type>(10001,255);
|
||||
measure_all<order_type>(10001,1023);
|
||||
measure_all<order_type>(10001,4095);
|
||||
measure_all<order_type>(10001,0);
|
||||
#endif
|
||||
|
||||
//
|
||||
measure_all<sorted_type>(100001,511);
|
||||
measure_all<sorted_type>(100001,2047);
|
||||
measure_all<sorted_type>(100001,8191);
|
||||
measure_all<sorted_type>(100001,32767);
|
||||
measure_all<sorted_type>(100001,0);
|
||||
#ifndef BENCH_SORT_UNIQUE_VALUES
|
||||
measure_all<order_type>(100001,511);
|
||||
measure_all<order_type>(100001,2047);
|
||||
measure_all<order_type>(100001,8191);
|
||||
measure_all<order_type>(100001,32767);
|
||||
#endif
|
||||
measure_all<order_type>(100001,0);
|
||||
|
||||
//
|
||||
#ifdef NDEBUG
|
||||
measure_all<sorted_type>(1000001,1);
|
||||
measure_all<sorted_type>(1000001,1024);
|
||||
measure_all<sorted_type>(1000001,32768);
|
||||
measure_all<sorted_type>(1000001,524287);
|
||||
measure_all<sorted_type>(1000001,0);
|
||||
measure_all<sorted_type>(1500001,0);
|
||||
//measure_all<sorted_type>(10000001,0);
|
||||
#endif //NDEBUG
|
||||
//#ifdef NDEBUG
|
||||
#ifndef BENCH_SORT_UNIQUE_VALUES
|
||||
measure_all<order_type>(1000001,1);
|
||||
measure_all<order_type>(1000001,1024);
|
||||
measure_all<order_type>(1000001,32768);
|
||||
measure_all<order_type>(1000001,524287);
|
||||
#endif
|
||||
measure_all<order_type>(1000001,0);
|
||||
measure_all<order_type>(1500001,0);
|
||||
//measure_all<order_type>(10000001,0);
|
||||
//#endif //NDEBUG
|
||||
|
||||
#endif //#ifndef BENCH_SORT_SHORT
|
||||
|
||||
//measure_all<sorted_type>(100000001,0);
|
||||
//measure_all<order_type>(100000001,0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -139,7 +139,7 @@ int main()
|
||||
movable m4(function(boost::move_if_noexcept(m3)));
|
||||
BOOST_CHECK(m3.moved());
|
||||
BOOST_CHECK(!m4.moved());
|
||||
}
|
||||
}
|
||||
{
|
||||
movable m;
|
||||
movable m2(boost::move_if_noexcept(m));
|
||||
@@ -149,7 +149,7 @@ int main()
|
||||
movable m4(functionr(boost::move_if_noexcept(m3)));
|
||||
BOOST_CHECK(m3.moved());
|
||||
BOOST_CHECK(!m4.moved());
|
||||
}
|
||||
}
|
||||
{
|
||||
movable m;
|
||||
movable m2(boost::move_if_noexcept(m));
|
||||
@@ -159,7 +159,7 @@ int main()
|
||||
movable m4(function2(boost::move_if_noexcept(m3)));
|
||||
BOOST_CHECK(m3.moved());
|
||||
BOOST_CHECK(!m4.moved());
|
||||
}
|
||||
}
|
||||
{
|
||||
movable m;
|
||||
movable m2(boost::move_if_noexcept(m));
|
||||
@@ -169,7 +169,7 @@ int main()
|
||||
movable m4(function2r(boost::move_if_noexcept(m3)));
|
||||
BOOST_CHECK(m3.moved());
|
||||
BOOST_CHECK(!m4.moved());
|
||||
}
|
||||
}
|
||||
{
|
||||
movable m;
|
||||
movable m2(boost::move_if_noexcept(m));
|
||||
@@ -177,7 +177,7 @@ int main()
|
||||
BOOST_CHECK(!m2.moved());
|
||||
movable m3(move_return_function());
|
||||
BOOST_CHECK(!m3.moved());
|
||||
}
|
||||
}
|
||||
{
|
||||
movable m;
|
||||
movable m2(boost::move_if_noexcept(m));
|
||||
@@ -185,7 +185,7 @@ int main()
|
||||
BOOST_CHECK(!m2.moved());
|
||||
movable m3(move_return_function2());
|
||||
BOOST_CHECK(!m3.moved());
|
||||
}
|
||||
}
|
||||
|
||||
// copy_movable may throw during move, so it must be copied
|
||||
{
|
||||
@@ -197,7 +197,7 @@ int main()
|
||||
copy_movable m4(function(boost::move_if_noexcept(m3)));
|
||||
BOOST_CHECK(!m3.moved());
|
||||
BOOST_CHECK(!m4.moved());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// copy_movable_noexcept can not throw during move
|
||||
@@ -210,7 +210,7 @@ int main()
|
||||
copy_movable_noexcept m4(function(boost::move_if_noexcept(m3)));
|
||||
BOOST_CHECK(m3.moved());
|
||||
BOOST_CHECK(!m4.moved());
|
||||
}
|
||||
}
|
||||
|
||||
// movable_throwable can not throw during move but it has no copy constructor
|
||||
{
|
||||
@@ -222,7 +222,7 @@ int main()
|
||||
movable_throwable m4(function(boost::move_if_noexcept(m3)));
|
||||
BOOST_CHECK(m3.moved());
|
||||
BOOST_CHECK(!m4.moved());
|
||||
}
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
82
test/order_type.hpp
Normal file
82
test/order_type.hpp
Normal file
@@ -0,0 +1,82 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2016.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/move for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_MOVE_TEST_ORDER_TYPE_HPP
|
||||
#define BOOST_MOVE_TEST_ORDER_TYPE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
|
||||
struct order_type
|
||||
{
|
||||
public:
|
||||
std::size_t key;
|
||||
std::size_t val;
|
||||
|
||||
order_type()
|
||||
{
|
||||
++num_elements;
|
||||
}
|
||||
|
||||
order_type(const order_type& other)
|
||||
: key(other.key), val(other.val)
|
||||
{
|
||||
++num_elements;
|
||||
++num_copy;
|
||||
}
|
||||
|
||||
order_type & operator=(const order_type& other)
|
||||
{
|
||||
++num_copy;
|
||||
key = other.key;
|
||||
val = other.val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~order_type ()
|
||||
{
|
||||
--num_elements;
|
||||
}
|
||||
|
||||
static boost::ulong_long_type num_compare;
|
||||
static boost::ulong_long_type num_copy;
|
||||
static boost::ulong_long_type num_elements;
|
||||
};
|
||||
|
||||
boost::ulong_long_type order_type::num_compare = 0;
|
||||
boost::ulong_long_type order_type::num_copy = 0;
|
||||
boost::ulong_long_type order_type::num_elements = 0;
|
||||
|
||||
template<class T>
|
||||
struct order_type_less
|
||||
{
|
||||
bool operator()(const T &a,T const &b) const
|
||||
{ ++order_type::num_compare; return a.key < b.key; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline bool is_order_type_ordered(T *elements, std::size_t element_count, bool stable = true)
|
||||
{
|
||||
for(std::size_t i = 1; i < element_count; ++i){
|
||||
if(order_type_less<T>()(elements[i], elements[i-1])){
|
||||
std::printf("\n Ord KO !!!!");
|
||||
return false;
|
||||
}
|
||||
if( stable && !(order_type_less<T>()(elements[i-1], elements[i])) && (elements[i-1].val > elements[i].val) ){
|
||||
std::printf("\n Stb KO !!!! ");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif //BOOST_MOVE_TEST_ORDER_TYPE_HPP
|
@@ -63,11 +63,11 @@ int volatile_memcmp(const volatile void *p1, const volatile void *p2, std::size_
|
||||
unsigned char u1, u2;
|
||||
|
||||
for ( ; len-- ; s1++, s2++) {
|
||||
u1 = *s1;
|
||||
u2 = *s2;
|
||||
if (u1 != u2) {
|
||||
return (u1-u2);
|
||||
}
|
||||
u1 = *s1;
|
||||
u2 = *s2;
|
||||
if (u1 != u2) {
|
||||
return (u1-u2);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user