summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/move/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/move/test')
-rw-r--r--src/boost/libs/move/test/Jamfile.v229
-rw-r--r--src/boost/libs/move/test/adaptive_merge_test.cpp91
-rw-r--r--src/boost/libs/move/test/adaptive_sort_test.cpp84
-rw-r--r--src/boost/libs/move/test/adl_move_swap.cpp169
-rw-r--r--src/boost/libs/move/test/algo_test.cpp953
-rw-r--r--src/boost/libs/move/test/back_move_inserter.cpp80
-rw-r--r--src/boost/libs/move/test/bench_merge.cpp335
-rw-r--r--src/boost/libs/move/test/bench_sort.cpp377
-rw-r--r--src/boost/libs/move/test/construct_forward.cpp117
-rw-r--r--src/boost/libs/move/test/conversion_test.cpp414
-rw-r--r--src/boost/libs/move/test/copy_elision_test.cpp177
-rw-r--r--src/boost/libs/move/test/copy_move_optimization.cpp107
-rw-r--r--src/boost/libs/move/test/inplace_merge_test.cpp283
-rw-r--r--src/boost/libs/move/test/move.cpp183
-rw-r--r--src/boost/libs/move/test/move_algorithm.cpp58
-rw-r--r--src/boost/libs/move/test/move_if_noexcept.cpp230
-rw-r--r--src/boost/libs/move/test/move_iterator.cpp44
-rw-r--r--src/boost/libs/move/test/order_type.hpp275
-rw-r--r--src/boost/libs/move/test/random_shuffle.hpp37
-rw-r--r--src/boost/libs/move/test/type_traits.cpp98
-rw-r--r--src/boost/libs/move/test/unique_ptr_assign.cpp444
-rw-r--r--src/boost/libs/move/test/unique_ptr_ctordtor.cpp811
-rw-r--r--src/boost/libs/move/test/unique_ptr_default_deleter.cpp204
-rw-r--r--src/boost/libs/move/test/unique_ptr_functions.cpp395
-rw-r--r--src/boost/libs/move/test/unique_ptr_modifiers.cpp381
-rw-r--r--src/boost/libs/move/test/unique_ptr_movector.cpp517
-rw-r--r--src/boost/libs/move/test/unique_ptr_nullptr.cpp228
-rw-r--r--src/boost/libs/move/test/unique_ptr_observers.cpp287
-rw-r--r--src/boost/libs/move/test/unique_ptr_test_utils_beg.hpp209
-rw-r--r--src/boost/libs/move/test/unique_ptr_test_utils_end.hpp46
-rw-r--r--src/boost/libs/move/test/unique_ptr_types.cpp200
31 files changed, 7863 insertions, 0 deletions
diff --git a/src/boost/libs/move/test/Jamfile.v2 b/src/boost/libs/move/test/Jamfile.v2
new file mode 100644
index 000000000..472517bde
--- /dev/null
+++ b/src/boost/libs/move/test/Jamfile.v2
@@ -0,0 +1,29 @@
+##############################################################################
+##
+## (C) Copyright Ion Gaztanaga 2008-2009 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)
+##
+##
+##############################################################################
+
+import testing ;
+
+rule test_all
+{
+ local all_rules = ;
+
+ for local fileb in [ glob *.cpp ]
+ {
+ all_rules += [ run $(fileb) /boost/timer//boost_timer
+ : # additional args
+ : # test-files
+ : # requirements
+ ] ;
+ }
+
+ return $(all_rules) ;
+}
+
+test-suite move_test : [ test_all r ] ;
+
diff --git a/src/boost/libs/move/test/adaptive_merge_test.cpp b/src/boost/libs/move/test/adaptive_merge_test.cpp
new file mode 100644
index 000000000..1a647076e
--- /dev/null
+++ b/src/boost/libs/move/test/adaptive_merge_test.cpp
@@ -0,0 +1,91 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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 <iostream> //std::cout
+
+#include <boost/config.hpp>
+
+#include <boost/move/unique_ptr.hpp>
+#include <boost/move/algo/detail/merge_sort.hpp>
+
+#include "order_type.hpp"
+#include "random_shuffle.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)
+ {
+ ::random_shuffle(elements.get(), elements.get() + element_count);
+ for(std::size_t j = 0; j < (num_keys ? num_keys : element_count); ++j){
+ key_reps[j]=0;
+ }
+ for(std::size_t j = 0; j < element_count; ++j){
+ elements[j].val = key_reps[elements[j].key]++;
+ }
+
+ boost::movelib::unique_ptr<char[]> buf(new char [sizeof(T)*(element_count-element_count/2)]);
+
+ std::size_t const split = std::size_t(std::rand()) % element_count;
+ boost::movelib::merge_sort(elements.get(), elements.get()+split, order_type_less(), (T*)buf.get());
+ boost::movelib::merge_sort(elements.get()+split, elements.get()+element_count, order_type_less(), (T*)buf.get());
+
+ boost::movelib::adaptive_merge(elements.get(), elements.get()+split, elements.get()+element_count, order_type_less());
+
+ if (!is_order_type_ordered(elements.get(), element_count))
+ {
+ std::cout << "\n ERROR\n";
+ throw int(0);
+ }
+ }
+ 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);
+ test_random_shuffled<order_move_type>(10001, 101, NIter);
+ test_random_shuffled<order_move_type>(10001, 1023, NIter);
+ test_random_shuffled<order_move_type>(10001, 4095, NIter);
+ test_random_shuffled<order_move_type>(10001, 0, NIter);
+
+ return 0;
+}
diff --git a/src/boost/libs/move/test/adaptive_sort_test.cpp b/src/boost/libs/move/test/adaptive_sort_test.cpp
new file mode 100644
index 000000000..973dd4c36
--- /dev/null
+++ b/src/boost/libs/move/test/adaptive_sort_test.cpp
@@ -0,0 +1,84 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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 <iostream> //std::cout
+
+#include <boost/config.hpp>
+
+#include <boost/move/unique_ptr.hpp>
+#include <boost/container/vector.hpp>
+
+#include "order_type.hpp"
+#include "random_shuffle.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 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){
+ key_reps[i]=0;
+ }
+ for(std::size_t i = 0; i < element_count; ++i){
+ elements[i].val = key_reps[elements[i].key]++;
+ }
+
+ boost::movelib::adaptive_sort(elements.get(), elements.get()+element_count, order_type_less());
+
+ if (!is_order_type_ordered(elements.get(), element_count))
+ {
+ std::cout << "\n ERROR\n";
+ throw int(0);
+ }
+ }
+ 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);
+ test_random_shuffled<order_move_type>(10001, 101, NIter);
+ test_random_shuffled<order_move_type>(10001, 1023, NIter);
+ test_random_shuffled<order_move_type>(10001, 4095, NIter);
+ test_random_shuffled<order_move_type>(10001, 0, NIter);
+
+ return 0;
+}
diff --git a/src/boost/libs/move/test/adl_move_swap.cpp b/src/boost/libs/move/test/adl_move_swap.cpp
new file mode 100644
index 000000000..200c6cb66
--- /dev/null
+++ b/src/boost/libs/move/test/adl_move_swap.cpp
@@ -0,0 +1,169 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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/adl_move_swap.hpp>
+#include <boost/move/core.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+class swap_stats
+{
+ public:
+ static void reset_stats()
+ {
+ member_swap_calls = 0;
+ friend_swap_calls = 0;
+ move_cnstor_calls = 0;
+ move_assign_calls = 0;
+ copy_cnstor_calls = 0;
+ copy_assign_calls = 0;
+ }
+
+ static unsigned int member_swap_calls;
+ static unsigned int friend_swap_calls;
+ static unsigned int move_cnstor_calls;
+ static unsigned int move_assign_calls;
+ static unsigned int copy_cnstor_calls;
+ static unsigned int copy_assign_calls;
+};
+
+unsigned int swap_stats::member_swap_calls = 0;
+unsigned int swap_stats::friend_swap_calls = 0;
+unsigned int swap_stats::move_cnstor_calls = 0;
+unsigned int swap_stats::move_assign_calls = 0;
+unsigned int swap_stats::copy_cnstor_calls = 0;
+unsigned int swap_stats::copy_assign_calls = 0;
+
+class movable : public swap_stats
+{
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(movable)
+ public:
+ movable() {}
+ movable(BOOST_RV_REF(movable)) { ++move_cnstor_calls; }
+ movable & operator=(BOOST_RV_REF(movable)){ ++move_assign_calls; return *this; }
+ friend void swap(movable &, movable &) { ++friend_swap_calls; }
+};
+
+class movable_swap_member : public swap_stats
+{
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_swap_member)
+ public:
+ movable_swap_member() {}
+ movable_swap_member(BOOST_RV_REF(movable_swap_member)) { ++move_cnstor_calls; }
+ movable_swap_member & operator=(BOOST_RV_REF(movable_swap_member)){ ++move_assign_calls; return *this; }
+ void swap(movable_swap_member &) { ++member_swap_calls; }
+ friend void swap(movable_swap_member &, movable_swap_member &) { ++friend_swap_calls; }
+};
+
+class copyable : public swap_stats
+{
+ public:
+ copyable() {}
+ copyable(const copyable &) { ++copy_cnstor_calls; }
+ copyable & operator=(const copyable&) { ++copy_assign_calls; return *this; }
+ void swap(copyable &) { ++member_swap_calls; }
+ friend void swap(copyable &, copyable &) { ++friend_swap_calls; }
+};
+
+class no_swap : public swap_stats
+{
+ private: unsigned m_state;
+ public:
+ explicit no_swap(unsigned i): m_state(i){}
+ no_swap(const no_swap &x) { m_state = x.m_state; ++copy_cnstor_calls; }
+ no_swap & operator=(const no_swap& x) { m_state = x.m_state; ++copy_assign_calls; return *this; }
+ void swap(no_swap &) { ++member_swap_calls; }
+ friend bool operator==(const no_swap &x, const no_swap &y) { return x.m_state == y.m_state; }
+ friend bool operator!=(const no_swap &x, const no_swap &y) { return !(x==y); }
+};
+
+
+int main()
+{
+ { //movable
+ movable x, y;
+ swap_stats::reset_stats();
+ ::boost::adl_move_swap(x, y);
+ #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ //In non rvalue reference compilers,
+ //movable classes with no swap() member uses
+ //boost::move() to implement swap.
+ BOOST_TEST(swap_stats::friend_swap_calls == 0);
+ BOOST_TEST(swap_stats::member_swap_calls == 0);
+ BOOST_TEST(swap_stats::member_swap_calls == 0);
+ BOOST_TEST(swap_stats::move_cnstor_calls == 1);
+ BOOST_TEST(swap_stats::move_assign_calls == 2);
+ BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
+ BOOST_TEST(swap_stats::copy_assign_calls == 0);
+ #else
+ //In compilers with rvalue references, this should call friend swap via ADL
+ BOOST_TEST(swap_stats::friend_swap_calls == 1);
+ BOOST_TEST(swap_stats::member_swap_calls == 0);
+ BOOST_TEST(swap_stats::member_swap_calls == 0);
+ BOOST_TEST(swap_stats::move_cnstor_calls == 0);
+ BOOST_TEST(swap_stats::move_assign_calls == 0);
+ BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
+ BOOST_TEST(swap_stats::copy_assign_calls == 0);
+ #endif
+ }
+ { //movable_swap_member
+ movable_swap_member x, y;
+ swap_stats::reset_stats();
+ ::boost::adl_move_swap(x, y);
+ #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ //In non rvalue reference compilers,
+ //movable classes with no swap() member uses
+ //boost::move() to implement swap.
+ BOOST_TEST(swap_stats::friend_swap_calls == 0);
+ BOOST_TEST(swap_stats::member_swap_calls == 1);
+ BOOST_TEST(swap_stats::move_cnstor_calls == 0);
+ BOOST_TEST(swap_stats::move_assign_calls == 0);
+ BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
+ BOOST_TEST(swap_stats::copy_assign_calls == 0);
+ #else
+ //In compilers with rvalue references, this should call friend swap via ADL
+ BOOST_TEST(swap_stats::friend_swap_calls == 1);
+ BOOST_TEST(swap_stats::member_swap_calls == 0);
+ BOOST_TEST(swap_stats::move_cnstor_calls == 0);
+ BOOST_TEST(swap_stats::move_assign_calls == 0);
+ BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
+ BOOST_TEST(swap_stats::copy_assign_calls == 0);
+ #endif
+ }
+ { //copyable
+ copyable x, y;
+ swap_stats::reset_stats();
+ ::boost::adl_move_swap(x, y);
+ //This should call friend swap via ADL
+ BOOST_TEST(swap_stats::friend_swap_calls == 1);
+ BOOST_TEST(swap_stats::member_swap_calls == 0);
+ BOOST_TEST(swap_stats::move_cnstor_calls == 0);
+ BOOST_TEST(swap_stats::move_assign_calls == 0);
+ BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
+ BOOST_TEST(swap_stats::copy_assign_calls == 0);
+ }
+ { //no_swap
+ no_swap x(1), y(2), x_back(x), y_back(y);
+ swap_stats::reset_stats();
+ ::boost::adl_move_swap(x, y);
+ //This should call std::swap which uses copies
+ BOOST_TEST(swap_stats::friend_swap_calls == 0);
+ BOOST_TEST(swap_stats::member_swap_calls == 0);
+ BOOST_TEST(swap_stats::move_cnstor_calls == 0);
+ BOOST_TEST(swap_stats::move_assign_calls == 0);
+ BOOST_TEST(swap_stats::copy_cnstor_calls == 1);
+ BOOST_TEST(swap_stats::copy_assign_calls == 2);
+ BOOST_TEST(x == y_back);
+ BOOST_TEST(y == x_back);
+ BOOST_TEST(x != y);
+ }
+ return ::boost::report_errors();
+}
+#include <boost/move/detail/config_end.hpp>
diff --git a/src/boost/libs/move/test/algo_test.cpp b/src/boost/libs/move/test/algo_test.cpp
new file mode 100644
index 000000000..d4652e2e4
--- /dev/null
+++ b/src/boost/libs/move/test/algo_test.cpp
@@ -0,0 +1,953 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2017.
+// 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/algo/detail/set_difference.hpp>
+#include "order_type.hpp"
+#include <boost/core/lightweight_test.hpp>
+#include <cstddef>
+/*
+///////////////////////////////////
+//
+// set_difference
+//
+///////////////////////////////////
+void test_set_difference_normal()
+{
+ order_perf_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_perf_type range1[4];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 1u;
+ range1[1].val = 1u;
+ range1[2].key = 3u;
+ range1[2].val = 1u;
+ range1[3].key = 4u;
+ range1[3].val = 1u;
+
+ order_perf_type out[20];
+ out[2].key = 998;
+ out[2].val = 999;
+ boost::movelib::set_difference(range1, range1+4, range2, range2+10, out, order_type_less());
+ BOOST_TEST(out[0].key == 1u);
+ BOOST_TEST(out[0].val == 1u);
+ BOOST_TEST(out[1].key == 3u);
+ BOOST_TEST(out[1].val == 1u);
+ BOOST_TEST(out[2].key == 998);
+ BOOST_TEST(out[2].val == 999);
+}
+
+void test_set_difference_range1_repeated()
+{
+ order_perf_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_perf_type range1[4];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 2u;
+ range1[1].val = 1u;
+ range1[2].key = 4u;
+ range1[2].val = 1u;
+ range1[3].key = 6u;
+ range1[3].val = 1u;
+
+ order_perf_type out[20];
+ out[0].key = 998;
+ out[0].val = 999;
+ boost::movelib::set_difference(range1, range1+4, range2, range2+10, out, order_type_less());
+ BOOST_TEST(out[0].key == 998);
+ BOOST_TEST(out[0].val == 999);
+}
+
+void test_set_difference_range1_unique()
+{
+ order_perf_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_perf_type range1[4];
+ range1[0].key = 1u;
+ range1[0].val = 1u;
+ range1[1].key = 3u;
+ range1[1].val = 1u;
+ range1[2].key = 5u;
+ range1[2].val = 1u;
+ range1[3].key = 7u;
+ range1[3].val = 1u;
+
+ order_perf_type out[20];
+ out[4].key = 998;
+ out[4].val = 999;
+ boost::movelib::set_difference(range1, range1+4, range2, range2+10, out, order_type_less());
+ BOOST_TEST(out[0].key == 1u);
+ BOOST_TEST(out[0].val == 1u);
+ BOOST_TEST(out[1].key == 3u);
+ BOOST_TEST(out[1].val == 1u);
+ BOOST_TEST(out[2].key == 5u);
+ BOOST_TEST(out[3].val == 1u);
+ BOOST_TEST(out[3].key == 7u);
+ BOOST_TEST(out[3].val == 1u);
+ BOOST_TEST(out[4].key == 998);
+ BOOST_TEST(out[4].val == 999);
+}
+*/
+
+///////////////////////////////////
+//
+// set_difference
+//
+///////////////////////////////////
+void test_set_difference_normal()
+{
+ order_perf_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_perf_type range1[5];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 1u;
+ range1[1].val = 1u;
+ range1[2].key = 1u;
+ range1[2].val = 2u;
+ range1[3].key = 3u;
+ range1[3].val = 1u;
+ range1[4].key = 4u;
+ range1[4].val = 1u;
+
+ order_perf_type out[20];
+ out[3].key = 998;
+ out[3].val = 999;
+ order_perf_type *r =
+ boost::movelib::set_difference(range1, range1+5, range2, range2+10, out, order_type_less());
+ BOOST_TEST(&out[3] == r);
+ BOOST_TEST(out[0].key == 1u);
+ BOOST_TEST(out[0].val == 1u);
+ BOOST_TEST(out[1].key == 1u);
+ BOOST_TEST(out[1].val == 2u);
+ BOOST_TEST(out[2].key == 3u);
+ BOOST_TEST(out[2].val == 1u);
+ BOOST_TEST(out[3].key == 998);
+ BOOST_TEST(out[3].val == 999);
+}
+
+void test_set_difference_range1_repeated()
+{
+ order_perf_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_perf_type range1[5];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 2u;
+ range1[1].val = 1u;
+ range1[2].key = 2u;
+ range1[2].val = 2u;
+ range1[3].key = 4u;
+ range1[3].val = 1u;
+ range1[4].key = 6u;
+ range1[4].val = 1u;
+
+ order_perf_type out[20];
+ out[0].key = 998;
+ out[0].val = 999;
+ order_perf_type *r =
+ boost::movelib::set_difference(range1, range1+5, range2, range2+10, out, order_type_less());
+ BOOST_TEST(&out[1] == r);
+ BOOST_TEST(out[0].key == 2);
+ BOOST_TEST(out[0].val == 2);
+}
+
+void test_set_difference_range1_unique()
+{
+ order_perf_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_perf_type range1[5];
+ range1[0].key = 1u;
+ range1[0].val = 1u;
+ range1[1].key = 3u;
+ range1[1].val = 1u;
+ range1[2].key = 5u;
+ range1[2].val = 1u;
+ range1[3].key = 7u;
+ range1[3].val = 1u;
+ range1[4].key = 7u;
+ range1[4].val = 2u;
+
+ order_perf_type out[20];
+ out[5].key = 998;
+ out[5].val = 999;
+ order_perf_type *r =
+ boost::movelib::set_difference(range1, range1+5, range2, range2+10, out, order_type_less());
+ BOOST_TEST(&out[5] == r);
+ BOOST_TEST(out[0].key == 1u);
+ BOOST_TEST(out[0].val == 1u);
+ BOOST_TEST(out[1].key == 3u);
+ BOOST_TEST(out[1].val == 1u);
+ BOOST_TEST(out[2].key == 5u);
+ BOOST_TEST(out[2].val == 1u);
+ BOOST_TEST(out[3].key == 7u);
+ BOOST_TEST(out[3].val == 1u);
+ BOOST_TEST(out[4].key == 7u);
+ BOOST_TEST(out[4].val == 2u);
+ BOOST_TEST(out[5].key == 998);
+ BOOST_TEST(out[5].val == 999);
+}
+
+/*
+///////////////////////////////////
+//
+// inplace_set_difference
+//
+///////////////////////////////////
+void test_inplace_set_difference_normal()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[4];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 1u;
+ range1[1].val = 1u;
+ range1[2].key = 3u;
+ range1[2].val = 1u;
+ range1[3].key = 4u;
+ range1[3].val = 1u;
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+2);
+ BOOST_TEST(range1[0].key == 1u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 3u);
+ BOOST_TEST(range1[1].val == 1u);
+ BOOST_TEST(range1[2].key == order_move_type::moved_assign_mark);
+ BOOST_TEST(range1[2].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_repeated()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[5];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 2u;
+ range1[1].val = 1u;
+ range1[2].key = 4u;
+ range1[2].val = 1u;
+ range1[3].key = 6u;
+ range1[3].val = 1u;
+ range1[4].key = order_move_type::moved_assign_mark;
+ range1[4].val = order_move_type::moved_assign_mark;
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+0);
+ BOOST_TEST(range1[0].key == 0u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 2u);
+ BOOST_TEST(range1[1].val == 1u);
+ BOOST_TEST(range1[2].key == 4u);
+ BOOST_TEST(range1[3].val == 1u);
+ BOOST_TEST(range1[3].key == 6u);
+ BOOST_TEST(range1[3].val == 1u);
+ BOOST_TEST(range1[4].key == order_move_type::moved_assign_mark);
+ BOOST_TEST(range1[4].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_unique()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[5];
+ range1[0].key = 1u;
+ range1[0].val = 1u;
+ range1[1].key = 3u;
+ range1[1].val = 1u;
+ range1[2].key = 5u;
+ range1[2].val = 1u;
+ range1[3].key = 7u;
+ range1[3].val = 1u;
+ range1[4].key = order_move_type::moved_assign_mark;
+ range1[4].val = order_move_type::moved_assign_mark;
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+4);
+ BOOST_TEST(range1[0].key == 1u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 3u);
+ BOOST_TEST(range1[1].val == 1u);
+ BOOST_TEST(range1[2].key == 5u);
+ BOOST_TEST(range1[3].val == 1u);
+ BOOST_TEST(range1[3].key == 7u);
+ BOOST_TEST(range1[3].val == 1u);
+ BOOST_TEST(range1[4].key == order_move_type::moved_assign_mark);
+ BOOST_TEST(range1[4].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_unique_long()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[11];
+ for(std::size_t i = 0; i != sizeof(range1)/sizeof(*range1); ++i){
+ range1[i].key = i*2+1;
+ range1[i].val = 1u;
+ }
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+11, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+11);
+ for(std::size_t i = 0; i != sizeof(range1)/sizeof(*range1); ++i){
+ BOOST_TEST(range1[i].key == i*2+1);
+ BOOST_TEST(range1[i].val == 1u);
+ }
+}
+
+void test_inplace_set_difference_range1_same_start()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[5];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 2u;
+ range1[1].val = 1u;
+ range1[2].key = 4u;
+ range1[2].val = 1u;
+ range1[3].key = 5u;
+ range1[3].val = 1u;
+ range1[4].key = 7u;
+ range1[4].val = 1u;
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+5, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+2);
+ BOOST_TEST(range1[0].key == 5u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 7u);
+ BOOST_TEST(range1[1].val == 1u);
+}
+
+void test_inplace_set_difference_range1_same_end()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[5];
+ range1[0].key = 1u;
+ range1[0].val = 1u;
+ range1[1].key = 3u;
+ range1[1].val = 1u;
+ range1[2].key = 4u;
+ range1[2].val = 1u;
+ range1[3].key = 6u;
+ range1[3].val = 1u;
+ range1[4].key = 8u;
+ range1[4].val = 1u;
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+5, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+2);
+ BOOST_TEST(range1[0].key == 1u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 3u);
+ BOOST_TEST(range1[1].val == 1u);
+ BOOST_TEST(range1[2].key == 4u);
+ BOOST_TEST(range1[2].val == 1u);
+ BOOST_TEST(range1[3].key == 6u);
+ BOOST_TEST(range1[3].val == 1u);
+}
+*/
+
+///////////////////////////////////
+//
+// inplace_set_difference
+//
+///////////////////////////////////
+void test_inplace_set_difference_normal()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[4];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 1u;
+ range1[1].val = 1u;
+ range1[2].key = 3u;
+ range1[2].val = 1u;
+ range1[3].key = 4u;
+ range1[3].val = 1u;
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+2);
+ BOOST_TEST(range1[0].key == 1u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 3u);
+ BOOST_TEST(range1[1].val == 1u);
+ BOOST_TEST(range1[2].key == order_move_type::moved_assign_mark);
+ BOOST_TEST(range1[2].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_repeated()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[5];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 2u;
+ range1[1].val = 1u;
+ range1[2].key = 4u;
+ range1[2].val = 1u;
+ range1[3].key = 6u;
+ range1[3].val = 1u;
+ range1[4].key = order_move_type::moved_assign_mark;
+ range1[4].val = order_move_type::moved_assign_mark;
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+0);
+ BOOST_TEST(range1[0].key == 0u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 2u);
+ BOOST_TEST(range1[1].val == 1u);
+ BOOST_TEST(range1[2].key == 4u);
+ BOOST_TEST(range1[3].val == 1u);
+ BOOST_TEST(range1[3].key == 6u);
+ BOOST_TEST(range1[3].val == 1u);
+ BOOST_TEST(range1[4].key == order_move_type::moved_assign_mark);
+ BOOST_TEST(range1[4].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_unique()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[5];
+ range1[0].key = 1u;
+ range1[0].val = 1u;
+ range1[1].key = 3u;
+ range1[1].val = 1u;
+ range1[2].key = 5u;
+ range1[2].val = 1u;
+ range1[3].key = 7u;
+ range1[3].val = 1u;
+ range1[4].key = order_move_type::moved_assign_mark;
+ range1[4].val = order_move_type::moved_assign_mark;
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+4);
+ BOOST_TEST(range1[0].key == 1u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 3u);
+ BOOST_TEST(range1[1].val == 1u);
+ BOOST_TEST(range1[2].key == 5u);
+ BOOST_TEST(range1[3].val == 1u);
+ BOOST_TEST(range1[3].key == 7u);
+ BOOST_TEST(range1[3].val == 1u);
+ BOOST_TEST(range1[4].key == order_move_type::moved_assign_mark);
+ BOOST_TEST(range1[4].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_unique_long()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[11];
+ for(std::size_t i = 0; i != sizeof(range1)/sizeof(*range1); ++i){
+ range1[i].key = i*2+1;
+ range1[i].val = 1u;
+ }
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+11, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+11);
+ for(std::size_t i = 0; i != sizeof(range1)/sizeof(*range1); ++i){
+ BOOST_TEST(range1[i].key == i*2+1);
+ BOOST_TEST(range1[i].val == 1u);
+ }
+}
+
+void test_inplace_set_difference_range1_same_start()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[5];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 2u;
+ range1[1].val = 1u;
+ range1[2].key = 4u;
+ range1[2].val = 1u;
+ range1[3].key = 5u;
+ range1[3].val = 1u;
+ range1[4].key = 7u;
+ range1[4].val = 1u;
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+5, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+2);
+ BOOST_TEST(range1[0].key == 5u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 7u);
+ BOOST_TEST(range1[1].val == 1u);
+}
+
+void test_inplace_set_difference_range1_same_end()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[5];
+ range1[0].key = 1u;
+ range1[0].val = 1u;
+ range1[1].key = 3u;
+ range1[1].val = 1u;
+ range1[2].key = 4u;
+ range1[2].val = 1u;
+ range1[3].key = 6u;
+ range1[3].val = 1u;
+ range1[4].key = 8u;
+ range1[4].val = 1u;
+
+ order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+5, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+2);
+ BOOST_TEST(range1[0].key == 1u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 3u);
+ BOOST_TEST(range1[1].val == 1u);
+ BOOST_TEST(range1[2].key == 4u);
+ BOOST_TEST(range1[2].val == 1u);
+ BOOST_TEST(range1[3].key == 6u);
+ BOOST_TEST(range1[3].val == 1u);
+}
+
+
+///////////////////////////////////
+//
+// set_unique_difference
+//
+///////////////////////////////////
+void test_set_unique_difference_normal()
+{
+ order_perf_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_perf_type range1[10];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 1u;
+ range1[1].val = 1u;
+ range1[2].key = 1u;
+ range1[2].val = 2u;
+ range1[3].key = 3u;
+ range1[3].val = 1u;
+ range1[4].key = 4u;
+ range1[4].val = 1u;
+ range1[5].key = 4u;
+ range1[5].val = 2u;
+ range1[6].key = 21u;
+ range1[6].val = 1u;
+ range1[7].key = 21u;
+ range1[7].val = 2u;
+ range1[8].key = 23u;
+ range1[8].val = 1u;
+ range1[9].key = 23u;
+ range1[9].val = 2u;
+
+ order_perf_type out[20];
+ out[4].key = 998;
+ out[4].val = 999;
+ order_perf_type * r =
+ boost::movelib::set_unique_difference(range1, range1+10, range2, range2+10, out, order_type_less());
+ BOOST_TEST(&out[4] == r);
+ BOOST_TEST(out[0].key == 1u);
+ BOOST_TEST(out[0].val == 1u);
+ BOOST_TEST(out[1].key == 3u);
+ BOOST_TEST(out[1].val == 1u);
+ BOOST_TEST(out[2].key == 21u);
+ BOOST_TEST(out[2].val == 1u);
+ BOOST_TEST(out[3].key == 23u);
+ BOOST_TEST(out[3].val == 1u);
+ BOOST_TEST(out[4].key == 998);
+ BOOST_TEST(out[4].val == 999);
+}
+
+void test_set_unique_difference_range1_repeated()
+{
+ order_perf_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_perf_type range1[11];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 0u;
+ range1[1].val = 2u;
+ range1[2].key = 0u;
+ range1[2].val = 2u;
+ range1[3].key = 2u;
+ range1[3].val = 1u;
+ range1[4].key = 2u;
+ range1[4].val = 2u;
+ range1[5].key = 4u;
+ range1[5].val = 1u;
+ range1[6].key = 6u;
+ range1[6].val = 1u;
+ range1[7].key = 6u;
+ range1[7].val = 2u;
+ range1[8].key = 6u;
+ range1[8].val = 3u;
+ range1[9].key = 6u;
+ range1[9].val = 4u;
+ range1[10].key = 6u;
+ range1[10].val = 5u;
+
+ order_perf_type out[20];
+ out[0].key = 998;
+ out[0].val = 999;
+ order_perf_type * r =
+ boost::movelib::set_unique_difference(range1, range1+11, range2, range2+10, out, order_type_less());
+ BOOST_TEST(&out[0] == r);
+ BOOST_TEST(out[0].key == 998);
+ BOOST_TEST(out[0].val == 999);
+}
+
+void test_set_unique_difference_range1_unique()
+{
+ order_perf_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_perf_type range1[7];
+ range1[0].key = 1u;
+ range1[0].val = 1u;
+ range1[1].key = 3u;
+ range1[1].val = 1u;
+ range1[2].key = 3u;
+ range1[2].val = 2u;
+ range1[3].key = 5u;
+ range1[3].val = 1u;
+ range1[4].key = 7u;
+ range1[4].val = 1u;
+ range1[5].key = 7u;
+ range1[5].val = 2u;
+ range1[6].key = 7u;
+ range1[6].val = 3u;
+
+ order_perf_type out[20];
+ out[4].key = 998;
+ out[4].val = 999;
+ order_perf_type * r =
+ boost::movelib::set_unique_difference(range1, range1+7, range2, range2+10, out, order_type_less());
+ BOOST_TEST(&out[4] == r);
+ BOOST_TEST(out[0].key == 1u);
+ BOOST_TEST(out[0].val == 1u);
+ BOOST_TEST(out[1].key == 3u);
+ BOOST_TEST(out[1].val == 1u);
+ BOOST_TEST(out[2].key == 5u);
+ BOOST_TEST(out[2].val == 1u);
+ BOOST_TEST(out[3].key == 7u);
+ BOOST_TEST(out[3].val == 1u);
+ BOOST_TEST(out[4].key == 998);
+ BOOST_TEST(out[4].val == 999);
+}
+
+///////////////////////////////////
+//
+// inplace_set_unique_difference
+//
+///////////////////////////////////
+void test_inplace_set_unique_difference_normal()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[4];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 1u;
+ range1[1].val = 1u;
+ range1[2].key = 3u;
+ range1[2].val = 1u;
+ range1[3].key = 4u;
+ range1[3].val = 1u;
+
+ order_move_type *ret = boost::movelib::inplace_set_unique_difference(range1, range1+4, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+2);
+ BOOST_TEST(range1[0].key == 1u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 3u);
+ BOOST_TEST(range1[1].val == 1u);
+ BOOST_TEST(range1[2].key == order_move_type::moved_assign_mark);
+ BOOST_TEST(range1[2].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_unique_difference_range1_repeated()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[5];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 2u;
+ range1[1].val = 1u;
+ range1[2].key = 4u;
+ range1[2].val = 1u;
+ range1[3].key = 6u;
+ range1[3].val = 1u;
+ range1[4].key = order_move_type::moved_assign_mark;
+ range1[4].val = order_move_type::moved_assign_mark;
+
+ order_move_type *ret = boost::movelib::inplace_set_unique_difference(range1, range1+4, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+0);
+ BOOST_TEST(range1[0].key == 0u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 2u);
+ BOOST_TEST(range1[1].val == 1u);
+ BOOST_TEST(range1[2].key == 4u);
+ BOOST_TEST(range1[3].val == 1u);
+ BOOST_TEST(range1[3].key == 6u);
+ BOOST_TEST(range1[3].val == 1u);
+ BOOST_TEST(range1[4].key == order_move_type::moved_assign_mark);
+ BOOST_TEST(range1[4].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_unique_difference_range1_unique()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[9];
+ range1[0].key = 1u;
+ range1[0].val = 1u;
+ range1[1].key = 1u;
+ range1[1].val = 2u;
+ range1[2].key = 3u;
+ range1[2].val = 1u;
+ range1[3].key = 3u;
+ range1[3].val = 2u;
+ range1[4].key = 5u;
+ range1[4].val = 1u;
+ range1[5].key = 7u;
+ range1[5].val = 1u;
+ range1[6].key = 7u;
+ range1[6].val = 2u;
+ range1[7].key = 7u;
+ range1[7].val = 3u;
+ range1[8].val = 3u;
+ range1[8].key = order_move_type::moved_assign_mark;
+ range1[8].val = order_move_type::moved_assign_mark;
+
+ order_move_type *ret =
+ boost::movelib::inplace_set_unique_difference(range1, range1+8, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+4);
+ BOOST_TEST(range1[0].key == 1u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 3u);
+ BOOST_TEST(range1[1].val == 1u);
+ BOOST_TEST(range1[2].key == 5u);
+ BOOST_TEST(range1[3].val == 1u);
+ BOOST_TEST(range1[3].key == 7u);
+ BOOST_TEST(range1[3].val == 1u);
+}
+
+void test_inplace_set_unique_difference_range1_unique_long()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[22];
+ for(std::size_t i = 0; i != sizeof(range1)/sizeof(*range1); ++i){
+ range1[i].key = (i/2)*2+1;
+ range1[i].val = i%2;
+ }
+
+ order_move_type *ret =
+ boost::movelib::inplace_set_unique_difference(range1, range1+22, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+11);
+ for(std::size_t i = 0; i != 11; ++i){
+ BOOST_TEST(range1[i].key == i*2+1);
+ BOOST_TEST(range1[i].val == 0u);
+ }
+}
+
+void test_inplace_set_unique_difference_range1_same_start()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[6];
+ range1[0].key = 0u;
+ range1[0].val = 1u;
+ range1[1].key = 2u;
+ range1[1].val = 1u;
+ range1[2].key = 4u;
+ range1[2].val = 1u;
+ range1[3].key = 4u;
+ range1[3].val = 2u;
+ range1[4].key = 5u;
+ range1[4].val = 1u;
+ range1[5].key = 7u;
+ range1[5].val = 1u;
+
+ order_move_type *ret =
+ boost::movelib::inplace_set_unique_difference(range1, range1+6, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+2);
+ BOOST_TEST(range1[0].key == 5u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 7u);
+ BOOST_TEST(range1[1].val == 1u);
+}
+
+void test_inplace_set_unique_difference_range1_same_end()
+{
+ order_move_type range2[10];
+ for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+ range2[i].key = i*2;
+ range2[i].val = 0u;
+ }
+
+ order_move_type range1[8];
+ range1[0].key = 1u;
+ range1[0].val = 1u;
+ range1[1].key = 3u;
+ range1[1].val = 1u;
+ range1[2].key = 4u;
+ range1[2].val = 1u;
+ range1[3].key = 4u;
+ range1[3].val = 2u;
+ range1[4].key = 6u;
+ range1[4].val = 1u;
+ range1[5].key = 8u;
+ range1[5].val = 1u;
+ range1[6].key = 8u;
+ range1[6].val = 2u;
+ range1[7].key = 8u;
+ range1[7].val = 3u;
+
+ order_move_type *ret =
+ boost::movelib::inplace_set_unique_difference(range1, range1+8, range2, range2+10, order_type_less());
+ BOOST_TEST(ret == range1+2);
+ BOOST_TEST(range1[0].key == 1u);
+ BOOST_TEST(range1[0].val == 1u);
+ BOOST_TEST(range1[1].key == 3u);
+ BOOST_TEST(range1[1].val == 1u);
+}
+
+int main()
+{
+ //set_difference
+ test_set_difference_normal();
+ test_set_difference_range1_repeated();
+ test_set_difference_range1_unique();
+ //inplace_set_difference
+ test_inplace_set_difference_normal();
+ test_inplace_set_difference_range1_repeated();
+ test_inplace_set_difference_range1_unique();
+ test_inplace_set_difference_range1_unique_long();
+ test_inplace_set_difference_range1_same_start();
+ test_inplace_set_difference_range1_same_end();
+ //set_unique_difference
+ test_set_unique_difference_normal();
+ test_set_unique_difference_range1_repeated();
+ test_set_unique_difference_range1_unique();
+ //inplace_set_unique_difference
+ test_inplace_set_unique_difference_normal();
+ test_inplace_set_unique_difference_range1_repeated();
+ test_inplace_set_unique_difference_range1_unique();
+ test_inplace_set_unique_difference_range1_unique_long();
+ test_inplace_set_unique_difference_range1_same_start();
+ test_inplace_set_unique_difference_range1_same_end();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/move/test/back_move_inserter.cpp b/src/boost/libs/move/test/back_move_inserter.cpp
new file mode 100644
index 000000000..6fc4829c8
--- /dev/null
+++ b/src/boost/libs/move/test/back_move_inserter.cpp
@@ -0,0 +1,80 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
+// 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>
+// move
+#include <boost/move/algorithm.hpp>
+#include <boost/move/iterator.hpp>
+// container
+#include <boost/container/deque.hpp>
+#include <boost/container/list.hpp>
+#include <boost/container/stable_vector.hpp>
+#include "../example/movable.hpp"
+
+template<class Container>
+int move_test()
+{
+ bool use_move_iterator = false;
+ bool done = false;
+ while(!done){
+ //Default construct 10 movable objects
+ Container v(10);
+
+ //Test default constructed value
+ if(v.begin()->moved()){
+ return 1;
+ }
+
+ //Move values
+ Container v2;
+ if(use_move_iterator){
+ ::boost::copy_or_move( boost::make_move_iterator(v.begin())
+ , boost::make_move_iterator(v.end())
+ , boost::back_move_inserter(v2));
+ }
+ else{
+ std::copy(v.begin(), v.end(), boost::back_move_inserter(v2));
+ }
+
+ //Test values have been moved
+ if(!v.begin()->moved()){
+ return 1;
+ }
+
+ if(v2.size() != 10){
+ return 1;
+ }
+
+ if(v2.begin()->moved()){
+ return 1;
+ }
+ done = use_move_iterator;
+ use_move_iterator = true;
+ }
+ return 0;
+}
+
+int main()
+{
+ namespace bc = ::boost::container;
+
+ if(move_test< bc::vector<movable> >()){
+ return 1;
+ }
+ if(move_test< bc::list<movable> >()){
+ return 1;
+ }
+ if(move_test< bc::stable_vector<movable> >()){
+ return 1;
+ }
+ return 0;
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/src/boost/libs/move/test/bench_merge.cpp b/src/boost/libs/move/test/bench_merge.cpp
new file mode 100644
index 000000000..2ef34400a
--- /dev/null
+++ b/src/boost/libs/move/test/bench_merge.cpp
@@ -0,0 +1,335 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//#define BOOST_MOVE_ADAPTIVE_SORT_STATS
+//#define BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL 2
+
+#include <algorithm> //std::inplace_merge
+#include <cstdio> //std::printf
+#include <iostream> //std::cout
+#include <boost/container/vector.hpp> //boost::container::vector
+
+#include <boost/config.hpp>
+
+#include <boost/move/unique_ptr.hpp>
+#include <boost/timer/timer.hpp>
+
+#include "order_type.hpp"
+#include "random_shuffle.hpp"
+
+using boost::timer::cpu_timer;
+using boost::timer::cpu_times;
+using boost::timer::nanosecond_type;
+
+void print_stats(const char *str, boost::ulong_long_type element_count)
+{
+ std::printf("%sCmp:%8.04f Cpy:%9.04f\n", str, double(order_perf_type::num_compare)/element_count, double(order_perf_type::num_copy)/element_count );
+}
+
+#include <boost/move/algo/adaptive_merge.hpp>
+#include <boost/move/algo/detail/merge.hpp>
+#include <boost/move/core.hpp>
+
+template<class T, class Compare>
+std::size_t generate_elements(boost::container::vector<T> &elements, std::size_t L, std::size_t NK, Compare comp)
+{
+ elements.resize(L);
+ boost::movelib::unique_ptr<std::size_t[]> key_reps(new std::size_t[NK ? NK : L]);
+
+ std::srand(0);
+ for (std::size_t i = 0; i < (NK ? NK : L); ++i) {
+ key_reps[i] = 0;
+ }
+ for (std::size_t i = 0; i < L; ++i) {
+ std::size_t key = NK ? (i % NK) : i;
+ elements[i].key = key;
+ }
+ ::random_shuffle(elements.data(), elements.data() + L);
+ ::random_shuffle(elements.data(), elements.data() + L);
+
+ for (std::size_t i = 0; i < L; ++i) {
+ elements[i].val = key_reps[elements[i].key]++;
+ }
+ std::size_t split_count = L / 2;
+ std::stable_sort(elements.data(), elements.data() + split_count, comp);
+ std::stable_sort(elements.data() + split_count, elements.data() + L, comp);
+ return split_count;
+}
+
+template<class T, class Compare>
+void adaptive_merge_buffered(T *elements, T *mid, T *last, Compare comp, std::size_t BufLen)
+{
+ boost::movelib::unique_ptr<char[]> mem(new char[sizeof(T)*BufLen]);
+ boost::movelib::adaptive_merge(elements, mid, last, comp, reinterpret_cast<T*>(mem.get()), BufLen);
+}
+
+template<class T, class Compare>
+void std_like_adaptive_merge_buffered(T *elements, T *mid, T *last, Compare comp, std::size_t BufLen)
+{
+ boost::movelib::unique_ptr<char[]> mem(new char[sizeof(T)*BufLen]);
+ boost::movelib::merge_adaptive_ONlogN(elements, mid, last, comp, reinterpret_cast<T*>(mem.get()), BufLen);
+}
+
+enum AlgoType
+{
+ StdMerge,
+ AdaptMerge,
+ SqrtHAdaptMerge,
+ SqrtAdaptMerge,
+ Sqrt2AdaptMerge,
+ QuartAdaptMerge,
+ StdInplaceMerge,
+ StdSqrtHAdaptMerge,
+ StdSqrtAdaptMerge,
+ StdSqrt2AdaptMerge,
+ StdQuartAdaptMerge,
+ MaxMerge
+};
+
+const char *AlgoNames [] = { "StdMerge "
+ , "AdaptMerge "
+ , "SqrtHAdaptMerge "
+ , "SqrtAdaptMerge "
+ , "Sqrt2AdaptMerge "
+ , "QuartAdaptMerge "
+ , "StdInplaceMerge "
+ , "StdSqrtHAdaptMerge "
+ , "StdSqrtAdaptMerge "
+ , "StdSqrt2AdaptMerge "
+ , "StdQuartAdaptMerge "
+ };
+
+BOOST_STATIC_ASSERT((sizeof(AlgoNames)/sizeof(*AlgoNames)) == MaxMerge);
+
+template<class T>
+bool measure_algo(T *elements, std::size_t element_count, std::size_t split_pos, std::size_t alg, nanosecond_type &prev_clock)
+{
+ std::printf("%s ", AlgoNames[alg]);
+ order_perf_type::num_compare=0;
+ order_perf_type::num_copy=0;
+ order_perf_type::num_elements = element_count;
+ cpu_timer timer;
+ timer.resume();
+ switch(alg)
+ {
+ case StdMerge:
+ std::inplace_merge(elements, elements+split_pos, elements+element_count, order_type_less());
+ break;
+ case AdaptMerge:
+ boost::movelib::adaptive_merge(elements, elements+split_pos, elements+element_count, order_type_less());
+ break;
+ case SqrtHAdaptMerge:
+ adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+ , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count)/2+1);
+ break;
+ case SqrtAdaptMerge:
+ adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+ , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+ break;
+ case Sqrt2AdaptMerge:
+ adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+ , 2*boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+ break;
+ case QuartAdaptMerge:
+ adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+ , (element_count)/4+1);
+ break;
+ case StdInplaceMerge:
+ boost::movelib::merge_bufferless_ONlogN(elements, elements+split_pos, elements+element_count, order_type_less());
+ break;
+ case StdSqrtHAdaptMerge:
+ std_like_adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+ , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count)/2+1);
+ break;
+ case StdSqrtAdaptMerge:
+ std_like_adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+ , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+ break;
+ case StdSqrt2AdaptMerge:
+ std_like_adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+ , 2*boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+ break;
+ case StdQuartAdaptMerge:
+ std_like_adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+ , (element_count)/4+1);
+ break;
+ }
+ timer.stop();
+
+ if(order_perf_type::num_elements == element_count){
+ std::printf(" Tmp Ok ");
+ } else{
+ std::printf(" Tmp KO ");
+ }
+ nanosecond_type new_clock = timer.elapsed().wall;
+
+ //std::cout << "Cmp:" << order_perf_type::num_compare << " Cpy:" << order_perf_type::num_copy; //for old compilers without ll size argument
+ std::printf("Cmp:%8.04f Cpy:%9.04f", double(order_perf_type::num_compare)/element_count, double(order_perf_type::num_copy)/element_count );
+
+ double time = double(new_clock);
+
+ const char *units = "ns";
+ if(time >= 1000000000.0){
+ time /= 1000000000.0;
+ units = " s";
+ }
+ else if(time >= 1000000.0){
+ time /= 1000000.0;
+ units = "ms";
+ }
+ else if(time >= 1000.0){
+ time /= 1000.0;
+ units = "us";
+ }
+
+ std::printf(" %6.02f%s (%6.02f)\n"
+ , time
+ , units
+ , prev_clock ? double(new_clock)/double(prev_clock): 1.0);
+ prev_clock = new_clock;
+ bool res = is_order_type_ordered(elements, element_count, true);
+ return res;
+}
+
+template<class T>
+bool measure_all(std::size_t L, std::size_t NK)
+{
+ boost::container::vector<T> original_elements, elements;
+ std::size_t split_pos = generate_elements(original_elements, L, NK, order_type_less());
+ std::printf("\n - - N: %u, NK: %u - -\n", (unsigned)L, (unsigned)NK);
+
+ nanosecond_type prev_clock = 0;
+ nanosecond_type back_clock;
+ bool res = true;
+
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, split_pos, StdMerge, prev_clock);
+ back_clock = prev_clock;
+ //
+
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, split_pos, QuartAdaptMerge, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, split_pos, StdQuartAdaptMerge, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, split_pos, Sqrt2AdaptMerge, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, split_pos, StdSqrt2AdaptMerge, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, split_pos, SqrtAdaptMerge, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, split_pos, StdSqrtAdaptMerge, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, split_pos, SqrtHAdaptMerge, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, split_pos, StdSqrtHAdaptMerge, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, split_pos, AdaptMerge, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, split_pos,StdInplaceMerge, prev_clock);
+ //
+
+ if(!res)
+ throw int(0);
+ return res;
+}
+
+//Undef it to run the long test
+#define BENCH_MERGE_SHORT
+#define BENCH_SORT_UNIQUE_VALUES
+
+int main()
+{
+ try{
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(101,1);
+ measure_all<order_perf_type>(101,5);
+ measure_all<order_perf_type>(101,7);
+ measure_all<order_perf_type>(101,31);
+ #endif
+ measure_all<order_perf_type>(101,0);
+
+ //
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(1101,1);
+ measure_all<order_perf_type>(1001,7);
+ measure_all<order_perf_type>(1001,31);
+ measure_all<order_perf_type>(1001,127);
+ measure_all<order_perf_type>(1001,511);
+ #endif
+ measure_all<order_perf_type>(1001,0);
+
+ //
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(10001,65);
+ measure_all<order_perf_type>(10001,255);
+ measure_all<order_perf_type>(10001,1023);
+ measure_all<order_perf_type>(10001,4095);
+ #endif
+ measure_all<order_perf_type>(10001,0);
+
+ //
+ #if defined(NDEBUG)
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(100001,511);
+ measure_all<order_perf_type>(100001,2047);
+ measure_all<order_perf_type>(100001,8191);
+ measure_all<order_perf_type>(100001,32767);
+ #endif
+ measure_all<order_perf_type>(100001,0);
+
+ //
+ #if !defined(BENCH_MERGE_SHORT)
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(1000001, 8192);
+ measure_all<order_perf_type>(1000001, 32768);
+ measure_all<order_perf_type>(1000001, 131072);
+ measure_all<order_perf_type>(1000001, 524288);
+ #endif
+ measure_all<order_perf_type>(1000001,0);
+
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(10000001, 65536);
+ measure_all<order_perf_type>(10000001, 262144);
+ measure_all<order_perf_type>(10000001, 1048576);
+ measure_all<order_perf_type>(10000001, 4194304);
+ #endif
+ measure_all<order_perf_type>(10000001,0);
+ #endif //#ifndef BENCH_MERGE_SHORT
+ #endif //#ifdef NDEBUG
+ }
+ catch(...)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/src/boost/libs/move/test/bench_sort.cpp b/src/boost/libs/move/test/bench_sort.cpp
new file mode 100644
index 000000000..11aba354b
--- /dev/null
+++ b/src/boost/libs/move/test/bench_sort.cpp
@@ -0,0 +1,377 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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::stable_sort, std::make|sort_heap, std::random_shuffle
+#include <cstdio> //std::printf
+#include <iostream> //std::cout
+#include <boost/container/vector.hpp> //boost::container::vector
+
+#include <boost/config.hpp>
+#include <boost/move/unique_ptr.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 "random_shuffle.hpp"
+
+//#define BOOST_MOVE_ADAPTIVE_SORT_STATS
+//#define BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS
+void print_stats(const char *str, boost::ulong_long_type element_count)
+{
+ std::printf("%sCmp:%7.03f Cpy:%8.03f\n", str, double(order_perf_type::num_compare)/element_count, double(order_perf_type::num_copy)/element_count );
+}
+
+
+#include <boost/move/algo/adaptive_sort.hpp>
+#include <boost/move/algo/detail/merge_sort.hpp>
+#include <boost/move/algo/detail/pdqsort.hpp>
+#include <boost/move/algo/detail/heap_sort.hpp>
+#include <boost/move/core.hpp>
+
+template<class T>
+void generate_elements(boost::container::vector<T> &elements, std::size_t L, std::size_t NK)
+{
+ elements.resize(L);
+ boost::movelib::unique_ptr<std::size_t[]> key_reps(new std::size_t[NK ? NK : L]);
+
+ std::srand(0);
+ for (std::size_t i = 0; i < (NK ? NK : L); ++i) {
+ key_reps[i] = 0;
+ }
+ for (std::size_t i = 0; i < L; ++i) {
+ std::size_t key = NK ? (i % NK) : i;
+ elements[i].key = key;
+ }
+ ::random_shuffle(elements.data(), elements.data() + L);
+ ::random_shuffle(elements.data(), elements.data() + L);
+
+ for (std::size_t i = 0; i < L; ++i) {
+ elements[i].val = key_reps[elements[i].key]++;
+ }
+}
+
+template<class T, class Compare>
+void adaptive_sort_buffered(T *elements, std::size_t element_count, Compare comp, std::size_t BufLen)
+{
+ boost::movelib::unique_ptr<char[]> mem(new char[sizeof(T)*BufLen]);
+ boost::movelib::adaptive_sort(elements, elements + element_count, comp, reinterpret_cast<T*>(mem.get()), BufLen);
+}
+
+template<class T, class Compare>
+void std_like_adaptive_stable_sort_buffered(T *elements, std::size_t element_count, Compare comp, std::size_t BufLen)
+{
+ boost::movelib::unique_ptr<char[]> mem(new char[sizeof(T)*BufLen]);
+ boost::movelib::stable_sort_adaptive_ONlogN2(elements, elements + element_count, comp, reinterpret_cast<T*>(mem.get()), BufLen);
+}
+
+template<class T, class Compare>
+void merge_sort_buffered(T *elements, std::size_t element_count, Compare comp)
+{
+ boost::movelib::unique_ptr<char[]> mem(new char[sizeof(T)*((element_count+1)/2)]);
+ boost::movelib::merge_sort(elements, elements + element_count, comp, reinterpret_cast<T*>(mem.get()));
+}
+
+enum AlgoType
+{
+ MergeSort,
+ StableSort,
+ PdQsort,
+ StdSort,
+ AdaptiveSort,
+ SqrtHAdaptiveSort,
+ SqrtAdaptiveSort,
+ Sqrt2AdaptiveSort,
+ QuartAdaptiveSort,
+ InplaceStableSort,
+ StdSqrtHAdpSort,
+ StdSqrtAdpSort,
+ StdSqrt2AdpSort,
+ StdQuartAdpSort,
+ SlowStableSort,
+ HeapSort,
+ MaxSort
+};
+
+const char *AlgoNames [] = { "MergeSort "
+ , "StableSort "
+ , "PdQsort "
+ , "StdSort "
+ , "AdaptSort "
+ , "SqrtHAdaptSort "
+ , "SqrtAdaptSort "
+ , "Sqrt2AdaptSort "
+ , "QuartAdaptSort "
+ , "InplStableSort "
+ , "StdSqrtHAdpSort"
+ , "StdSqrtAdpSort "
+ , "StdSqrt2AdpSort"
+ , "StdQuartAdpSort"
+ , "SlowSort "
+ , "HeapSort "
+ };
+
+BOOST_STATIC_ASSERT((sizeof(AlgoNames)/sizeof(*AlgoNames)) == MaxSort);
+
+template<class T>
+bool measure_algo(T *elements, std::size_t element_count, std::size_t alg, nanosecond_type &prev_clock)
+{
+ std::printf("%s ", AlgoNames[alg]);
+ order_perf_type::num_compare=0;
+ order_perf_type::num_copy=0;
+ order_perf_type::num_elements = element_count;
+ cpu_timer timer;
+ timer.resume();
+ switch(alg)
+ {
+ case MergeSort:
+ merge_sort_buffered(elements, element_count, order_type_less());
+ break;
+ case StableSort:
+ std::stable_sort(elements,elements+element_count,order_type_less());
+ break;
+ case PdQsort:
+ boost::movelib::pdqsort(elements,elements+element_count,order_type_less());
+ break;
+ case StdSort:
+ std::sort(elements,elements+element_count,order_type_less());
+ break;
+ case AdaptiveSort:
+ boost::movelib::adaptive_sort(elements, elements+element_count, order_type_less());
+ break;
+ case SqrtHAdaptiveSort:
+ adaptive_sort_buffered( elements, element_count, order_type_less()
+ , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count)/2+1);
+ break;
+ case SqrtAdaptiveSort:
+ adaptive_sort_buffered( elements, element_count, order_type_less()
+ , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+ break;
+ case Sqrt2AdaptiveSort:
+ adaptive_sort_buffered( elements, element_count, order_type_less()
+ , 2*boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+ break;
+ case QuartAdaptiveSort:
+ adaptive_sort_buffered( elements, element_count, order_type_less()
+ , (element_count-1)/4+1);
+ break;
+ case InplaceStableSort:
+ boost::movelib::inplace_stable_sort(elements, elements+element_count, order_type_less());
+ break;
+ case StdSqrtHAdpSort:
+ std_like_adaptive_stable_sort_buffered( elements, element_count, order_type_less()
+ , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count)/2+1);
+ break;
+ case StdSqrtAdpSort:
+ std_like_adaptive_stable_sort_buffered( elements, element_count, order_type_less()
+ , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+ break;
+ case StdSqrt2AdpSort:
+ std_like_adaptive_stable_sort_buffered( elements, element_count, order_type_less()
+ , 2*boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+ break;
+ case StdQuartAdpSort:
+ std_like_adaptive_stable_sort_buffered( elements, element_count, order_type_less()
+ , (element_count-1)/4+1);
+ break;
+ case SlowStableSort:
+ boost::movelib::detail_adaptive::slow_stable_sort(elements, elements+element_count, order_type_less());
+ break;
+ case HeapSort:
+ boost::movelib::heap_sort(elements, elements+element_count, order_type_less());
+ boost::movelib::heap_sort((order_move_type*)0, (order_move_type*)0, order_type_less());
+
+ break;
+ }
+ timer.stop();
+
+ if(order_perf_type::num_elements == element_count){
+ std::printf(" Tmp Ok ");
+ } else{
+ std::printf(" Tmp KO ");
+ }
+ nanosecond_type new_clock = timer.elapsed().wall;
+
+ //std::cout << "Cmp:" << order_perf_type::num_compare << " Cpy:" << order_perf_type::num_copy; //for old compilers without ll size argument
+ std::printf("Cmp:%7.03f Cpy:%8.03f", double(order_perf_type::num_compare)/element_count, double(order_perf_type::num_copy)/element_count );
+
+ double time = double(new_clock);
+
+ const char *units = "ns";
+ if(time >= 1000000000.0){
+ time /= 1000000000.0;
+ units = " s";
+ }
+ else if(time >= 1000000.0){
+ time /= 1000000.0;
+ units = "ms";
+ }
+ else if(time >= 1000.0){
+ time /= 1000.0;
+ units = "us";
+ }
+
+ std::printf(" %6.02f%s (%6.02f)\n"
+ , time
+ , units
+ , prev_clock ? double(new_clock)/double(prev_clock): 1.0);
+ prev_clock = new_clock;
+ bool res = is_order_type_ordered(elements, element_count, alg != HeapSort && alg != PdQsort && alg != StdSort);
+ return res;
+}
+
+template<class T>
+bool measure_all(std::size_t L, std::size_t NK)
+{
+ boost::container::vector<T> original_elements, elements;
+ generate_elements(original_elements, L, NK);
+ std::printf("\n - - N: %u, NK: %u - -\n", (unsigned)L, (unsigned)NK);
+
+ nanosecond_type prev_clock = 0;
+ nanosecond_type back_clock;
+ bool res = true;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L,MergeSort, prev_clock);
+ back_clock = prev_clock;
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L,StableSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L,PdQsort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L,StdSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L,HeapSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L,QuartAdaptiveSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, StdQuartAdpSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L,Sqrt2AdaptiveSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, StdSqrt2AdpSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L,SqrtAdaptiveSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, StdSqrtAdpSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L,SqrtHAdaptiveSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L, StdSqrtHAdpSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L,AdaptiveSort, prev_clock);
+ //
+ prev_clock = back_clock;
+ elements = original_elements;
+ res = res && measure_algo(elements.data(), L,InplaceStableSort, prev_clock);
+ //
+ //prev_clock = back_clock;
+ //elements = original_elements;
+ //res = res && measure_algo(elements.data(), L,SlowStableSort, prev_clock);
+ //
+ if(!res)
+ throw int(0);
+ return res;
+}
+
+//Undef it to run the long test
+#define BENCH_SORT_SHORT
+#define BENCH_SORT_UNIQUE_VALUES
+
+int main()
+{
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(101,1);
+ measure_all<order_perf_type>(101,7);
+ measure_all<order_perf_type>(101,31);
+ #endif
+ measure_all<order_perf_type>(101,0);
+
+ //
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(1101,1);
+ measure_all<order_perf_type>(1001,7);
+ measure_all<order_perf_type>(1001,31);
+ measure_all<order_perf_type>(1001,127);
+ measure_all<order_perf_type>(1001,511);
+ #endif
+ measure_all<order_perf_type>(1001,0);
+ //
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(10001,65);
+ measure_all<order_perf_type>(10001,255);
+ measure_all<order_perf_type>(10001,1023);
+ measure_all<order_perf_type>(10001,4095);
+ #endif
+ measure_all<order_perf_type>(10001,0);
+
+ //
+ #ifdef NDEBUG
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(100001,511);
+ measure_all<order_perf_type>(100001,2047);
+ measure_all<order_perf_type>(100001,8191);
+ measure_all<order_perf_type>(100001,32767);
+ #endif
+ measure_all<order_perf_type>(100001,0);
+
+ //
+ #ifndef BENCH_SORT_SHORT
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(1000001, 8192);
+ measure_all<order_perf_type>(1000001, 32768);
+ measure_all<order_perf_type>(1000001, 131072);
+ measure_all<order_perf_type>(1000001, 524288);
+ #endif
+ measure_all<order_perf_type>(1000001,0);
+
+ #ifndef BENCH_SORT_UNIQUE_VALUES
+ measure_all<order_perf_type>(10000001, 65536);
+ measure_all<order_perf_type>(10000001, 262144);
+ measure_all<order_perf_type>(10000001, 1048576);
+ measure_all<order_perf_type>(10000001, 4194304);
+ #endif
+ measure_all<order_perf_type>(1000001,0);
+ #endif //#ifndef BENCH_SORT_SHORT
+ #endif //NDEBUG
+
+ //measure_all<order_perf_type>(100000001,0);
+
+ return 0;
+}
diff --git a/src/boost/libs/move/test/construct_forward.cpp b/src/boost/libs/move/test/construct_forward.cpp
new file mode 100644
index 000000000..87c9a8097
--- /dev/null
+++ b/src/boost/libs/move/test/construct_forward.cpp
@@ -0,0 +1,117 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009-2012.
+// 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/utility_core.hpp>
+#include <boost/utility/enable_if.hpp>
+#include "../example/movable.hpp"
+#include "../example/copymovable.hpp"
+#include <cstdio>
+
+class non_movable
+{
+ public:
+ non_movable()
+ {}
+};
+
+template<class MaybeRvalue>
+void catch_test(BOOST_RV_REF(MaybeRvalue) x
+ #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled<MaybeRvalue> >::type* = 0
+ #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
+ )
+{ (void)x;}
+
+template<class MaybeRvalue>
+void catch_test(BOOST_COPY_ASSIGN_REF(MaybeRvalue) x
+ #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled<MaybeRvalue> >::type* = 0
+ #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
+ )
+
+{ (void)x;}
+
+template<class MaybeRvalue>
+void catch_test(MaybeRvalue &x
+ #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled<MaybeRvalue> >::type* = 0
+ #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
+ )
+{ (void)x;}
+
+ #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+template<class MaybeRvalue>
+void catch_test(const MaybeRvalue& x
+ ,typename ::boost::disable_if< ::boost::has_move_emulation_enabled<MaybeRvalue> >::type* = 0
+ )
+{ (void)x;}
+ #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+movable create_movable()
+{ return movable(); }
+
+copy_movable create_copy_movable()
+{ return copy_movable(); }
+
+non_movable create_non_movable()
+{ return non_movable(); }
+
+
+void catch_test()
+{
+ movable m;
+ const movable constm;
+ catch_test<movable>(boost::move(m));
+ #ifdef BOOST_CATCH_CONST_RLVALUE
+ catch_test<movable>(create_movable());
+ #endif
+ catch_test<movable>(m);
+ catch_test<movable>(constm);
+ copy_movable cm;
+ const copy_movable constcm;
+ catch_test<copy_movable>(boost::move(cm));
+ catch_test<copy_movable>(create_copy_movable());
+ catch_test<copy_movable>(cm);
+ catch_test<copy_movable>(constcm);
+ non_movable nm;
+ const non_movable constnm;
+ catch_test<non_movable>(boost::move(nm));
+ catch_test<non_movable>(create_non_movable());
+ catch_test<non_movable>(nm);
+ catch_test<non_movable>(constnm);
+}
+
+template<class MaybeMovableOnly, class MaybeRvalue>
+void function_construct(BOOST_FWD_REF(MaybeRvalue) x)
+{
+ //Moves in case Convertible is boost::rv<movable> copies otherwise
+ //For C++0x perfect forwarding
+ MaybeMovableOnly m(boost::forward<MaybeRvalue>(x));
+}
+
+void forward_test()
+{
+ movable m;
+ function_construct<movable>(boost::move(m));
+// non_movable nm;
+// function_construct<non_movable>(boost::move(nm));
+// const non_movable cnm;
+// function_construct<non_movable>(cnm);
+}
+
+int main()
+{
+ catch_test();
+ forward_test();
+ return 0;
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/src/boost/libs/move/test/conversion_test.cpp b/src/boost/libs/move/test/conversion_test.cpp
new file mode 100644
index 000000000..8e901f871
--- /dev/null
+++ b/src/boost/libs/move/test/conversion_test.cpp
@@ -0,0 +1,414 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2010-2012.
+// 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/utility_core.hpp>
+#include <boost/move/detail/meta_utils.hpp>
+#include <cassert>
+#include <new>
+#include <boost/move/detail/move_helpers.hpp>
+
+
+enum ConstructionType { Copied, Moved, Other };
+
+class conversion_source
+{
+ public:
+ conversion_source(){}
+ operator int() const { return 0; }
+};
+
+class conversion_target
+{
+ ConstructionType c_type_;
+ public:
+ conversion_target(conversion_source)
+ { c_type_ = Other; }
+ conversion_target()
+ { c_type_ = Other; }
+ conversion_target(const conversion_target &)
+ { c_type_ = Copied; }
+ ConstructionType construction_type() const
+ { return c_type_; }
+};
+
+
+class conversion_target_copymovable
+{
+ ConstructionType c_type_;
+ BOOST_COPYABLE_AND_MOVABLE(conversion_target_copymovable)
+ public:
+ conversion_target_copymovable()
+ { c_type_ = Other; }
+ conversion_target_copymovable(conversion_source)
+ { c_type_ = Other; }
+ conversion_target_copymovable(const conversion_target_copymovable &)
+ { c_type_ = Copied; }
+ conversion_target_copymovable(BOOST_RV_REF(conversion_target_copymovable) )
+ { c_type_ = Moved; }
+ conversion_target_copymovable &operator=(BOOST_RV_REF(conversion_target_copymovable) )
+ { c_type_ = Moved; return *this; }
+ conversion_target_copymovable &operator=(BOOST_COPY_ASSIGN_REF(conversion_target_copymovable) )
+ { c_type_ = Copied; return *this; }
+ ConstructionType construction_type() const
+ { return c_type_; }
+};
+
+class conversion_target_movable
+{
+ ConstructionType c_type_;
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(conversion_target_movable)
+ public:
+ conversion_target_movable()
+ { c_type_ = Other; }
+ conversion_target_movable(conversion_source)
+ { c_type_ = Other; }
+ conversion_target_movable(BOOST_RV_REF(conversion_target_movable) )
+ { c_type_ = Moved; }
+ conversion_target_movable &operator=(BOOST_RV_REF(conversion_target_movable) )
+ { c_type_ = Moved; return *this; }
+ ConstructionType construction_type() const
+ { return c_type_; }
+};
+
+
+template<class T>
+class container
+{
+ T *storage_;
+ public:
+ struct const_iterator{};
+ struct iterator : const_iterator{};
+ container()
+ : storage_(0)
+ {}
+
+ ~container()
+ { delete storage_; }
+
+ container(const container &c)
+ : storage_(c.storage_ ? new T(*c.storage_) : 0)
+ {}
+
+ container &operator=(const container &c)
+ {
+ if(storage_){
+ delete storage_;
+ storage_ = 0;
+ }
+ storage_ = c.storage_ ? new T(*c.storage_) : 0;
+ return *this;
+ }
+
+ BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+
+ BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
+
+ template <class Iterator>
+ iterator insert(Iterator, Iterator){ return iterator(); }
+
+ ConstructionType construction_type() const
+ { return construction_type_impl
+ (typename ::boost::move_detail::integral_constant<bool, ::boost::move_detail::is_class_or_union<T>::value>());
+ }
+
+ ConstructionType construction_type_impl(::boost::move_detail::true_type) const
+ { return storage_->construction_type(); }
+
+ ConstructionType construction_type_impl(::boost::move_detail::false_type) const
+ { return Copied; }
+
+ iterator begin() const { return iterator(); }
+
+ private:
+ template<class U>
+ void priv_construct(BOOST_MOVE_CATCH_FWD(U) x)
+ {
+ if(storage_){
+ delete storage_;
+ storage_ = 0;
+ }
+ storage_ = new T(::boost::forward<U>(x));
+ }
+
+ template<class U>
+ void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x)
+ { priv_construct(::boost::forward<U>(x)); }
+
+ template<class U>
+ iterator priv_insert(const_iterator, BOOST_MOVE_CATCH_FWD(U) x)
+ { priv_construct(::boost::forward<U>(x)); return iterator(); }
+};
+
+class recursive_container
+{
+ BOOST_COPYABLE_AND_MOVABLE(recursive_container)
+ public:
+ recursive_container()
+ {}
+
+ recursive_container(const recursive_container &c)
+ : container_(c.container_)
+ {}
+
+ recursive_container(BOOST_RV_REF(recursive_container) c)
+ : container_(::boost::move(c.container_))
+ {}
+
+ recursive_container & operator =(BOOST_COPY_ASSIGN_REF(recursive_container) c)
+ {
+ container_= c.container_;
+ return *this;
+ }
+
+ recursive_container & operator =(BOOST_RV_REF(recursive_container) c)
+ {
+ container_= ::boost::move(c.container_);
+ return *this;
+ }
+
+ container<recursive_container> container_;
+ friend bool operator< (const recursive_container &a, const recursive_container &b)
+ { return &a < &b; }
+};
+
+
+int main()
+{
+ conversion_target_movable a;
+ conversion_target_movable b(::boost::move(a));
+ {
+ container<conversion_target> c;
+ {
+ conversion_target x;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+ {
+ const conversion_target x;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+ {
+ c.push_back(conversion_target());
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), conversion_target());
+ assert(c.construction_type() == Copied);
+ }
+ {
+ conversion_source x;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+ {
+ const conversion_source x;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+ {
+ c.push_back(conversion_source());
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), conversion_source());
+ assert(c.construction_type() == Copied);
+ }
+ }
+
+ {
+ container<conversion_target_copymovable> c;
+ {
+ conversion_target_copymovable x;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+ {
+ const conversion_target_copymovable x;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+ {
+ c.push_back(conversion_target_copymovable());
+ assert(c.construction_type() == Moved);
+ c.insert(c.begin(), conversion_target_copymovable());
+ assert(c.construction_type() == Moved);
+ }
+ {
+ conversion_source x;
+ c.push_back(x);
+ assert(c.construction_type() == Moved);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Moved);
+ }
+ {
+ const conversion_source x;
+ c.push_back(x);
+ assert(c.construction_type() == Moved);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Moved);
+ }
+ {
+ c.push_back(conversion_source());
+ assert(c.construction_type() == Moved);
+ c.insert(c.begin(), conversion_source());
+ assert(c.construction_type() == Moved);
+ }
+ }
+ {
+ container<conversion_target_movable> c;
+ //This should not compile
+ //{
+ // conversion_target_movable x;
+ // c.push_back(x);
+ // assert(c.construction_type() == Copied);
+ //}
+ //{
+ // const conversion_target_movable x;
+ // c.push_back(x);
+ // assert(c.construction_type() == Copied);
+ //}
+ {
+ c.push_back(conversion_target_movable());
+ assert(c.construction_type() == Moved);
+ c.insert(c.begin(), conversion_target_movable());
+ assert(c.construction_type() == Moved);
+ }
+ {
+ conversion_source x;
+ c.push_back(x);
+ assert(c.construction_type() == Moved);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Moved);
+ }
+ {
+ const conversion_source x;
+ c.push_back(x);
+ assert(c.construction_type() == Moved);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Moved);
+ }
+ {
+ c.push_back(conversion_source());
+ assert(c.construction_type() == Moved);
+ c.insert(c.begin(), conversion_source());
+ assert(c.construction_type() == Moved);
+ }
+ }
+ {
+ container<int> c;
+ {
+ int x = 0;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), c.construction_type());
+ assert(c.construction_type() == Copied);
+ }
+ {
+ const int x = 0;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+ {
+ c.push_back(int(0));
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), int(0));
+ assert(c.construction_type() == Copied);
+ }
+ {
+ conversion_source x;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+
+ {
+ const conversion_source x;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+ {
+ c.push_back(conversion_source());
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), conversion_source());
+ assert(c.construction_type() == Copied);
+ }
+ //c.insert(c.begin(), c.begin());
+ }
+
+ {
+ container<int> c;
+ {
+ int x = 0;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), c.construction_type());
+ assert(c.construction_type() == Copied);
+ }
+ {
+ const int x = 0;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+ {
+ c.push_back(int(0));
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), int(0));
+ assert(c.construction_type() == Copied);
+ }
+ {
+ conversion_source x;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+
+ {
+ const conversion_source x;
+ c.push_back(x);
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), x);
+ assert(c.construction_type() == Copied);
+ }
+ {
+ c.push_back(conversion_source());
+ assert(c.construction_type() == Copied);
+ c.insert(c.begin(), conversion_source());
+ assert(c.construction_type() == Copied);
+ }
+ c.insert(c.begin(), c.begin());
+ }
+
+ {
+ recursive_container c;
+ recursive_container internal;
+ c.container_.insert(c.container_.begin(), recursive_container());
+ c.container_.insert(c.container_.begin(), internal);
+ c.container_.insert(c.container_.begin(), c.container_.begin());
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/move/test/copy_elision_test.cpp b/src/boost/libs/move/test/copy_elision_test.cpp
new file mode 100644
index 000000000..39123e1d5
--- /dev/null
+++ b/src/boost/libs/move/test/copy_elision_test.cpp
@@ -0,0 +1,177 @@
+// Copyright David Abrahams 2009. 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)
+
+#include <boost/move/detail/config_begin.hpp>
+#include <iostream>
+#include <boost/core/lightweight_test.hpp>
+
+#ifdef NO_MOVE
+# undef BOOST_COPY_ASSIGN_REF
+# define BOOST_COPY_ASSIGN_REF(X) X const&
+# undef BOOST_COPYABLE_AND_MOVABLE
+# define BOOST_COPYABLE_AND_MOVABLE(X)
+# define MOVE(x) (x)
+#else
+#include <boost/move/utility_core.hpp>
+# define MOVE(x) boost::move(x)
+#endif
+
+struct X
+{
+ X() : id(instances++)
+ {
+ std::cout << "X" << id << ": construct\n";
+ }
+
+ X(X const& rhs) : id(instances++)
+ {
+ std::cout << "X" << id << ": <- " << "X" << rhs.id << ": **copy**\n";
+ ++copies;
+ }
+
+ // This particular test doesn't exercise assignment, but for
+ // completeness:
+ X& operator=(BOOST_COPY_ASSIGN_REF(X) rhs)
+ {
+ std::cout << "X" << id << ": <- " << "X" << rhs.id << ": assign\n";
+ return *this;
+ }
+
+#ifndef NO_MOVE
+ X& operator=(BOOST_RV_REF(X) rhs)
+ {
+ std::cout << "X" << id << ": <- " << "X" << rhs.id << ": move assign\n";
+ return *this;
+ }
+
+ X(BOOST_RV_REF(X) rhs) : id(instances++)
+ {
+ std::cout << "X" << id << ": <- " << "X" << rhs.id << ": ..move construct..\n";
+ ++copies;
+ }
+#endif
+
+ ~X() { std::cout << "X" << id << ": destroy\n"; }
+
+ unsigned id;
+
+ static unsigned copies;
+ static unsigned instances;
+
+ BOOST_COPYABLE_AND_MOVABLE(X)
+};
+
+unsigned X::copies = 0;
+unsigned X::instances = 0;
+
+#define CHECK_COPIES( stmt, min, max, comment ) \
+{ \
+ unsigned const old_copies = X::copies; \
+ \
+ std::cout << "\n" comment "\n" #stmt "\n===========\n"; \
+ { \
+ stmt; \
+ } \
+ unsigned const n = X::copies - old_copies; \
+ volatile unsigned const minv(min), maxv(max); \
+ BOOST_TEST(n <= maxv); \
+ if (n > maxv) \
+ std::cout << "*** max is too low or compiler is buggy ***\n"; \
+ BOOST_TEST(n >= minv); \
+ if (n < minv) \
+ std::cout << "*** min is too high or compiler is buggy ***\n"; \
+ \
+ std::cout << "-----------\n" \
+ << n << "/" << max \
+ << " possible copies/moves made\n" \
+ << max - n << "/" << max - min \
+ << " possible elisions performed\n\n"; \
+ \
+ if (n > minv) \
+ std::cout << "*** " << n - min \
+ << " possible elisions missed! ***\n"; \
+}
+
+struct trace
+{
+ trace(char const* name)
+ : m_name(name)
+ {
+ std::cout << "->: " << m_name << "\n";
+ }
+
+ ~trace()
+ {
+ std::cout << "<-: " << m_name << "\n";
+ }
+
+ char const* m_name;
+};
+
+void sink(X)
+{
+ trace t("sink");
+}
+
+X nrvo_source()
+{
+ trace t("nrvo_source");
+ X a;
+ return a;
+}
+
+X urvo_source()
+{
+ trace t("urvo_source");
+ return X();
+}
+
+X identity(X a)
+{
+ trace t("identity");
+ return a;
+}
+
+X lvalue_;
+X& lvalue()
+{
+ return lvalue_;
+}
+typedef X rvalue;
+
+X ternary( bool y )
+{
+ X a, b;
+ return MOVE(y?a:b);
+}
+
+int main(int argc, char* argv[])
+{
+ (void)argv;
+ // Double parens prevent "most vexing parse"
+ CHECK_COPIES( X a(( lvalue() )), 1U, 1U, "Direct initialization from lvalue");
+ CHECK_COPIES( X a(( rvalue() )), 0U, 1U, "Direct initialization from rvalue");
+
+ CHECK_COPIES( X a = lvalue(), 1U, 1U, "Copy initialization from lvalue" );
+ CHECK_COPIES( X a = rvalue(), 0U, 1U, "Copy initialization from rvalue" );
+
+ CHECK_COPIES( sink( lvalue() ), 1U, 1U, "Pass lvalue by value" );
+ CHECK_COPIES( sink( rvalue() ), 0U, 1U, "Pass rvalue by value" );
+
+ CHECK_COPIES( nrvo_source(), 0U, 1U, "Named return value optimization (NRVO)" );
+ CHECK_COPIES( urvo_source(), 0U, 1U, "Unnamed return value optimization (URVO)" );
+
+ // Just to prove these things compose properly
+ CHECK_COPIES( X a(urvo_source()), 0U, 2U, "Return value used as ctor arg" );
+
+ // Expect to miss one possible elision here
+ CHECK_COPIES( identity( rvalue() ), 0U, 2U, "Return rvalue passed by value" );
+
+ // Expect to miss an elision in at least one of the following lines
+ CHECK_COPIES( X a = ternary( argc == 1000 ), 0U, 2U, "Return result of ternary operation" );
+ CHECK_COPIES( X a = ternary( argc != 1000 ), 0U, 2U, "Return result of ternary operation again" );
+ return boost::report_errors();
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/src/boost/libs/move/test/copy_move_optimization.cpp b/src/boost/libs/move/test/copy_move_optimization.cpp
new file mode 100644
index 000000000..06d184756
--- /dev/null
+++ b/src/boost/libs/move/test/copy_move_optimization.cpp
@@ -0,0 +1,107 @@
+//We need to declare:
+//
+//2 conversions: rv<T> & and const rv<T> &
+//1 rv<T> & constructor: move constructor
+//1 const rv<T> & constructor: copy constructor
+//1 T & constructor: copy constructor
+//
+//Optimization:
+//Since RVO is better than move-construction,
+//avoid copy constructor overloading.
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/utility_core.hpp>
+#include <iostream>
+
+bool moved = false;
+
+class obj
+{
+ BOOST_COPYABLE_AND_MOVABLE(obj)
+ public:
+
+ obj()
+ {
+ std::cout << "constructing obj" << "\n";
+ }
+
+ ~obj()
+ {}
+
+ obj(const obj &)
+ {
+ std::cout << "copy construct from const obj" << "\n";
+ }
+
+ // copy construct from movable object (non-const rvalue, explicitly moved lvalue)
+ obj(BOOST_RV_REF(obj))
+ {
+ std::cout << "move construct from movable rvalue" << "\n";
+ }
+
+ obj& operator =(BOOST_COPY_ASSIGN_REF(obj))
+ {
+ std::cout << "copy assign from const obj" << "\n";
+ return *this;
+ }
+
+ obj& operator =(BOOST_RV_REF(obj))
+ {
+ std::cout << "move assign from movable rvalue" << "\n";
+ return *this;
+ }
+};
+
+
+obj rvalue_func() { return obj(); }
+const obj const_rvalue_func() { return obj(); }
+obj& lvalue_func() { static obj o; return o; }
+const obj& const_lvalue_func() { static obj o; return o; }
+
+obj produce() { return obj(); }
+
+void consume(obj){}
+
+int main()
+{
+ { consume(produce()); }
+ { obj o = produce(); }
+ { obj o(produce()); }
+ {
+ obj o1(rvalue_func());
+ obj o2 = const_rvalue_func();
+ obj o3 = lvalue_func();
+ obj o4 = const_lvalue_func();
+ // can't explicitly move temporaries
+ //obj o5 = boost::move(rvalue_func());
+ obj o5;
+ //Maybe missed optimization: copied
+ o5 = rvalue_func();
+ //Explicit forward works OK and optimized
+ o5 = boost::forward<obj>(rvalue_func());
+
+ obj o7 = boost::move(lvalue_func());
+ obj o8 = boost::move(const_lvalue_func());
+
+ obj o;
+ o = rvalue_func();
+ o = const_rvalue_func();
+ o = lvalue_func();
+ o = const_lvalue_func();
+ // can't explicitly move temporaries
+ //o = boost::move(rvalue_func());
+ o = boost::forward<obj>(rvalue_func());
+ o = boost::move(const_rvalue_func());
+ o = boost::move(lvalue_func());
+ o = boost::move(const_lvalue_func());
+ }
+ return 0;
+}
+
+//We need to declare:
+//
+//2 conversions: rv<T> & and const rv<T> &
+//1 rv<T> & constructor: move constructor
+//1 const rv<T> & constructor: copy constructor
+//1 T & constructor: copy constructor
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/src/boost/libs/move/test/inplace_merge_test.cpp b/src/boost/libs/move/test/inplace_merge_test.cpp
new file mode 100644
index 000000000..b69bce0cb
--- /dev/null
+++ b/src/boost/libs/move/test/inplace_merge_test.cpp
@@ -0,0 +1,283 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2016-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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//#define BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS
+#define BOOST_MOVE_ADAPTIVE_SORT_STATS
+
+#include "order_type.hpp"
+
+#include <iostream> //std::cout
+#include <boost/config.hpp>
+
+#include <boost/move/algo/detail/adaptive_sort_merge.hpp>
+#include <boost/move/core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/move/make_unique.hpp>
+
+#include <boost/move/detail/type_traits.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+#include <cstddef>
+
+const std::size_t BlockSize = 7u;
+
+#if defined(BOOST_MSVC)
+#pragma warning (disable : 4267)
+#endif
+
+
+const std::size_t left_merge = 0;
+const std::size_t buf_merge = 1;
+const std::size_t unbuf_merge= 2;
+const std::size_t max_merge = 3;
+
+template<class Op>
+void alternating_test(
+ const std::size_t NumBlocksA,
+ const std::size_t NumBlocksB,
+ const std::size_t ExtraA,
+ const std::size_t ExtraB,
+ Op op)
+{
+ using namespace boost::movelib::detail_adaptive;
+
+
+ const std::size_t DataSize = ExtraA + NumBlocksA*BlockSize + NumBlocksB*BlockSize + ExtraB;
+ const std::size_t KeySize = NumBlocksA + NumBlocksB + 1;
+ const std::size_t HdrSize = BlockSize + KeySize;
+ const std::size_t ArraySize = HdrSize + DataSize;
+
+ boost::movelib::unique_ptr<order_move_type[]> testarray(boost::movelib::make_unique<order_move_type[]>(ArraySize));
+
+
+ for(std::size_t szt_merge = 0; szt_merge != max_merge; ++szt_merge){
+ //Order keys
+ for (std::size_t szt_i = 0u; szt_i != KeySize; ++szt_i) {
+ testarray[szt_i].key = szt_i;
+ testarray[szt_i].val = std::size_t(-1);
+ }
+
+ //Order buffer
+ for (std::size_t szt_i = 0u; szt_i != BlockSize; ++szt_i) {
+ testarray[KeySize+szt_i].key = std::size_t(-1);
+ testarray[KeySize+szt_i].val = szt_i;
+ }
+
+ //Block A
+ std::size_t szt_k = 0;
+ for (std::size_t szt_i = 0u; szt_i != ExtraA; ++szt_i) {
+ testarray[HdrSize+szt_k].key = (szt_k/2)*2;
+ testarray[HdrSize+szt_k].val = szt_k & 1;
+ ++szt_k;
+ }
+
+ for (std::size_t szt_b = 0u; szt_b != NumBlocksA; ++szt_b)
+ for (std::size_t szt_i = 0u; szt_i != BlockSize; ++szt_i) {
+ testarray[HdrSize+szt_k].key = (szt_k/2)*2;
+ testarray[HdrSize+szt_k].val = szt_k & 1;
+ ++szt_k;
+ }
+
+ //Block B
+ std::size_t szt_l = 0;
+ for (std::size_t szt_b = 0u, szt_t = 0; szt_b != NumBlocksB; ++szt_b)
+ for (std::size_t szt_i = 0u; szt_i != BlockSize; ++szt_i, ++szt_t) {
+ testarray[HdrSize+szt_k].key = (szt_l/2)*2+1;
+ testarray[HdrSize+szt_k].val = szt_l & 1;
+ ++szt_k;
+ ++szt_l;
+ }
+
+ for (std::size_t szt_i = 0u; szt_i != ExtraB; ++szt_i) {
+ testarray[HdrSize+szt_k].key = (szt_l/2)*2+1;
+ testarray[HdrSize+szt_k].val = szt_l & 1;
+ ++szt_k;
+ ++szt_l;
+ }
+
+ if(szt_merge == left_merge){
+ //Merge Left
+ op_merge_blocks_left
+ ( testarray.get(), order_type_less()
+ , testarray.get()+HdrSize, BlockSize, ExtraA, NumBlocksA, NumBlocksB, ExtraB
+ , order_type_less(), op );
+ BOOST_TEST( is_order_type_ordered(testarray.get()+KeySize, DataSize) );
+ BOOST_TEST( is_key(testarray.get(), KeySize) );
+ BOOST_TEST(( !boost::move_detail::is_same<Op, boost::movelib::swap_op>::value
+ || is_buffer(testarray.get()+ KeySize+DataSize, BlockSize) ));
+ }
+ else if(szt_merge == buf_merge){
+ //Merge with buf
+ op_merge_blocks_with_buf
+ ( testarray.get(), order_type_less()
+ , testarray.get()+HdrSize, BlockSize, ExtraA, NumBlocksA, NumBlocksB, ExtraB
+ , order_type_less(), op, testarray.get()+KeySize );
+ BOOST_TEST( is_order_type_ordered(testarray.get()+HdrSize, DataSize) );
+ BOOST_TEST( is_key(testarray.get(), KeySize) );
+ BOOST_TEST(( !boost::move_detail::is_same<Op, boost::movelib::swap_op>::value
+ || is_buffer(testarray.get()+ KeySize, BlockSize) ));
+ }
+ else if(szt_merge == unbuf_merge){
+ //Merge Left
+ merge_blocks_bufferless
+ ( testarray.get(), order_type_less()
+ , testarray.get()+HdrSize, BlockSize, ExtraA, NumBlocksA, NumBlocksB, ExtraB
+ , order_type_less());
+ BOOST_TEST( is_order_type_ordered(testarray.get()+HdrSize, DataSize) );
+ BOOST_TEST( is_key(testarray.get(), KeySize) );
+ BOOST_TEST(( !boost::move_detail::is_same<Op, boost::movelib::swap_op>::value
+ || is_buffer(testarray.get()+ KeySize, BlockSize) ));
+ }
+ }
+}
+
+int main()
+{
+ {
+ const std::size_t NumBlocksA = 3u;
+ const std::size_t NumBlocksB = 3u;
+ const std::size_t ExtraA = BlockSize/2;
+ const std::size_t ExtraB = ExtraA;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 3u;
+ const std::size_t NumBlocksB = 3u;
+ const std::size_t ExtraA = 0u;
+ const std::size_t ExtraB = BlockSize/2;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 3u;
+ const std::size_t NumBlocksB = 3u;
+ const std::size_t ExtraA = BlockSize/2;
+ const std::size_t ExtraB = 0;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 3u;
+ const std::size_t NumBlocksB = 3u;
+ const std::size_t ExtraA = 0;
+ const std::size_t ExtraB = 0;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 6u;
+ const std::size_t NumBlocksB = 3u;
+ const std::size_t ExtraA = BlockSize/2;
+ const std::size_t ExtraB = ExtraA;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 6u;
+ const std::size_t NumBlocksB = 3u;
+ const std::size_t ExtraA = BlockSize/2;
+ const std::size_t ExtraB = 0;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 3u;
+ const std::size_t NumBlocksB = 5u;
+ const std::size_t ExtraA = BlockSize/2;
+ const std::size_t ExtraB = ExtraA;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 3u;
+ const std::size_t NumBlocksB = 5u;
+ const std::size_t ExtraA = BlockSize/2;
+ const std::size_t ExtraB = 0;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 0u;
+ const std::size_t NumBlocksB = 0u;
+ const std::size_t ExtraA = 0;
+ const std::size_t ExtraB = 0;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 0u;
+ const std::size_t NumBlocksB = 0u;
+ const std::size_t ExtraA = BlockSize/2;
+ const std::size_t ExtraB = 0;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 0u;
+ const std::size_t NumBlocksB = 0u;
+ const std::size_t ExtraA = 0;
+ const std::size_t ExtraB = BlockSize/2;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ //
+ {
+ const std::size_t NumBlocksA = 0u;
+ const std::size_t NumBlocksB = 1u;
+ const std::size_t ExtraA = 0;
+ const std::size_t ExtraB = 0;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 1u;
+ const std::size_t NumBlocksB = 0u;
+ const std::size_t ExtraA = 0;
+ const std::size_t ExtraB = 0;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 1u;
+ const std::size_t NumBlocksB = 0u;
+ const std::size_t ExtraA = BlockSize/2;
+ const std::size_t ExtraB = 0;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 0u;
+ const std::size_t NumBlocksB = 1u;
+ const std::size_t ExtraA = BlockSize/2;
+ const std::size_t ExtraB = 0;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 1u;
+ const std::size_t NumBlocksB = 0u;
+ const std::size_t ExtraA = 0;
+ const std::size_t ExtraB = BlockSize/2;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+ {
+ const std::size_t NumBlocksA = 0u;
+ const std::size_t NumBlocksB = 1u;
+ const std::size_t ExtraA = 0;
+ const std::size_t ExtraB = BlockSize/2;
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+ alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+ }
+
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/move/test/move.cpp b/src/boost/libs/move/test/move.cpp
new file mode 100644
index 000000000..2d40ec813
--- /dev/null
+++ b/src/boost/libs/move/test/move.cpp
@@ -0,0 +1,183 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
+// (C) Copyright Ion Gaztanaga 2009-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/utility_core.hpp>
+#include "../example/movable.hpp"
+#include "../example/copymovable.hpp"
+#include <boost/static_assert.hpp>
+
+movable function(movable m)
+{
+ return movable(boost::move(m));
+}
+
+movable functionr(BOOST_RV_REF(movable) m)
+{
+ return movable(boost::move(m));
+}
+
+movable function2(movable m)
+{
+ return boost::move(m);
+}
+
+BOOST_RV_REF(movable) function2r(BOOST_RV_REF(movable) m)
+{
+ return boost::move(m);
+}
+
+movable move_return_function2 ()
+{
+ return movable();
+}
+
+movable move_return_function ()
+{
+ movable m;
+ return (boost::move(m));
+}
+
+
+//Catch by value
+void function_value(movable)
+{}
+
+//Catch by reference
+void function_ref(const movable &)
+{}
+
+//Catch by reference
+void function_ref(BOOST_RV_REF(movable))
+{}
+
+movable create_movable()
+{ return movable(); }
+
+template<class Type>
+struct factory
+{
+ Type operator()() const
+ {
+ Type t;
+ return BOOST_MOVE_RET(Type, t);
+ }
+};
+
+template<class Type>
+struct factory<Type &>
+{
+ static Type t;
+ Type &operator()() const
+ {
+ return BOOST_MOVE_RET(Type&, t);
+ }
+};
+
+template<class Type>
+Type factory<Type&>::t;
+
+template <class R, class F>
+R factory_wrapper(F f)
+{
+ // lock();
+ R r = f();
+ // unlock();
+ return BOOST_MOVE_RET(R, r);
+}
+
+int main()
+{
+ #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ BOOST_STATIC_ASSERT((boost::has_nothrow_move<movable>::value == true));
+ BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<copyable>::value == false));
+ BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<copyable*>::value == false));
+ BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<int>::value == false));
+ BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<int&>::value == false));
+ BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<int*>::value == false));
+ #endif
+
+ {
+ movable m;
+ movable m2(boost::move(m));
+ movable m3(function(movable(boost::move(m2))));
+ movable m4(function(boost::move(m3)));
+ (void)m;(void)m2;(void)m3;(void)m4;
+ }
+ {
+ movable m;
+ movable m2(boost::move(m));
+ movable m3(functionr(movable(boost::move(m2))));
+ movable m4(functionr(boost::move(m3)));
+ (void)m;(void)m2;(void)m3;(void)m4;
+ }
+ {
+ movable m;
+ movable m2(boost::move(m));
+ movable m3(function2(movable(boost::move(m2))));
+ movable m4(function2(boost::move(m3)));
+ (void)m;(void)m2;(void)m3;(void)m4;
+ }
+ {
+ movable m;
+ movable m2(boost::move(m));
+ movable m3(function2r(movable(boost::move(m2))));
+ movable m4(function2r(boost::move(m3)));
+ (void)m;(void)m2;(void)m3;(void)m4;
+ }
+ {
+ movable m;
+ movable m2(boost::move(m));
+ movable m3(move_return_function());
+ (void)m;(void)m2;(void)m3;
+ }
+ {
+ movable m;
+ movable m2(boost::move(m));
+ movable m3(move_return_function2());
+ (void)m;(void)m2;(void)m3;
+ }
+ {
+ //movable
+ movable m (factory_wrapper<movable>(factory<movable>()));
+ m = factory_wrapper<movable>(factory<movable>());
+ movable&mr(factory_wrapper<movable&>(factory<movable&>()));
+ movable&mr2 = factory_wrapper<movable&>(factory<movable&>());
+ (void)mr;
+ (void)mr2;
+ (void)m;
+ }
+ {
+ //copyable
+ copyable c (factory_wrapper<copyable>(factory<copyable>()));
+ c = factory_wrapper<copyable>(factory<copyable>());
+ copyable&cr(factory_wrapper<copyable&>(factory<copyable&>()));
+ copyable&cr2 = factory_wrapper<copyable&>(factory<copyable&>());
+ (void)cr;
+ (void)cr2;
+ (void)c;
+ }
+
+ {
+ //copy_movable
+ copy_movable c (factory_wrapper<copy_movable>(factory<copy_movable>()));
+ c = factory_wrapper<copy_movable>(factory<copy_movable>());
+ copy_movable&cr(factory_wrapper<copy_movable&>(factory<copy_movable&>()));
+ copy_movable&cr2 = factory_wrapper<copy_movable&>(factory<copy_movable&>());
+ (void)cr;
+ (void)cr2;
+ (void)c;
+ }
+
+ return 0;
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/src/boost/libs/move/test/move_algorithm.cpp b/src/boost/libs/move/test/move_algorithm.cpp
new file mode 100644
index 000000000..217832897
--- /dev/null
+++ b/src/boost/libs/move/test/move_algorithm.cpp
@@ -0,0 +1,58 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
+// 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/algorithm.hpp>
+#include <boost/container/vector.hpp>
+#include "../example/movable.hpp"
+
+int main()
+{
+ namespace bc = ::boost::container;
+ //Default construct 10 movable objects
+ bc::vector<movable> v(10);
+ bc::vector<movable> v2(10);
+
+ //Move to v2
+ boost::move(v.begin(), v.end(), v2.begin());
+
+ //Test values have been moved
+ if(!v[0].moved()){
+ return 1;
+ }
+
+ if(v2.size() != 10){
+ return 1;
+ }
+
+ if(v2[0].moved()){
+ return 1;
+ }
+
+ //Move to v again
+ boost::move_backward(v2.begin(), v2.end(), v.end());
+
+ //Test values have been moved
+ if(!v2[1].moved()){
+ return 1;
+ }
+
+ if(v.size() != 10){
+ return 1;
+ }
+
+ if(v[1].moved()){
+ return 1;
+ }
+
+ return 0;
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/src/boost/libs/move/test/move_if_noexcept.cpp b/src/boost/libs/move/test/move_if_noexcept.cpp
new file mode 100644
index 000000000..a03a82192
--- /dev/null
+++ b/src/boost/libs/move/test/move_if_noexcept.cpp
@@ -0,0 +1,230 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Antony Polukhin 2014.
+// (C) Copyright Ion Gaztanaga 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/utility.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include "../example/movable.hpp"
+#include "../example/copymovable.hpp"
+#include <boost/static_assert.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+//A copy_movable_noexcept class
+class copy_movable_noexcept
+{
+ BOOST_COPYABLE_AND_MOVABLE(copy_movable_noexcept)
+ int value_;
+
+ public:
+ copy_movable_noexcept() : value_(1){}
+
+ //Move constructor and assignment
+ copy_movable_noexcept(BOOST_RV_REF(copy_movable_noexcept) m)
+ { value_ = m.value_; m.value_ = 0; }
+
+ copy_movable_noexcept(const copy_movable_noexcept &m)
+ { value_ = m.value_; }
+
+ copy_movable_noexcept & operator=(BOOST_RV_REF(copy_movable_noexcept) m)
+ { value_ = m.value_; m.value_ = 0; return *this; }
+
+ copy_movable_noexcept & operator=(BOOST_COPY_ASSIGN_REF(copy_movable_noexcept) m)
+ { value_ = m.value_; return *this; }
+
+ bool moved() const //Observer
+ { return value_ == 0; }
+};
+
+namespace boost{
+
+template<>
+struct has_nothrow_move<copy_movable_noexcept>
+{
+ static const bool value = true;
+};
+
+} //namespace boost{
+
+//////////////////////////////////////////////////////////////////////////////
+//A movable_throwable class
+class movable_throwable
+{
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_throwable)
+ int value_;
+
+ public:
+ movable_throwable() : value_(1){}
+
+ //Move constructor and assignment
+ movable_throwable(BOOST_RV_REF(movable_throwable) m)
+ { value_ = m.value_; m.value_ = 0; }
+
+ movable_throwable & operator=(BOOST_RV_REF(movable_throwable) m)
+ { value_ = m.value_; m.value_ = 0; return *this; }
+
+ bool moved() const //Observer
+ { return !value_; }
+
+ int value() const //Observer
+ { return value_; }
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Helper functions
+movable function(movable m)
+{
+ return movable(boost::move_if_noexcept(m));
+}
+
+copy_movable function(copy_movable m)
+{
+ return copy_movable(boost::move_if_noexcept(m));
+}
+
+copy_movable_noexcept function(copy_movable_noexcept m)
+{
+ return copy_movable_noexcept(boost::move_if_noexcept(m));
+}
+
+movable_throwable function(movable_throwable m)
+{
+ return movable_throwable(boost::move_if_noexcept(m));
+}
+
+movable functionr(BOOST_RV_REF(movable) m)
+{
+ return movable(boost::move_if_noexcept(m));
+}
+
+movable function2(movable m)
+{
+ return boost::move_if_noexcept(m);
+}
+
+BOOST_RV_REF(movable) function2r(BOOST_RV_REF(movable) m)
+{
+ return boost::move_if_noexcept(m);
+}
+
+movable move_return_function2 ()
+{
+ return movable();
+}
+
+movable move_return_function ()
+{
+ movable m;
+ return (boost::move_if_noexcept(m));
+}
+
+#define BOOST_CHECK(x) if (!(x)) { return __LINE__; }
+
+int main()
+{
+ {
+ movable m;
+ movable m2(boost::move_if_noexcept(m));
+ BOOST_CHECK(m.moved());
+ movable m3(function(movable(boost::move_if_noexcept(m2))));
+ BOOST_CHECK(m2.moved());
+ 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));
+ BOOST_CHECK(m.moved());
+ movable m3(functionr(movable(boost::move_if_noexcept(m2))));
+ BOOST_CHECK(m2.moved());
+ 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));
+ BOOST_CHECK(m.moved());
+ movable m3(function2(movable(boost::move_if_noexcept(m2))));
+ BOOST_CHECK(m2.moved());
+ 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));
+ BOOST_CHECK(m.moved());
+ movable m3(function2r(movable(boost::move_if_noexcept(m2))));
+ BOOST_CHECK(m2.moved());
+ 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));
+ BOOST_CHECK(m.moved());
+ BOOST_CHECK(!m2.moved());
+ movable m3(move_return_function());
+ BOOST_CHECK(!m3.moved());
+ }
+ {
+ movable m;
+ movable m2(boost::move_if_noexcept(m));
+ BOOST_CHECK(m.moved());
+ BOOST_CHECK(!m2.moved());
+ movable m3(move_return_function2());
+ BOOST_CHECK(!m3.moved());
+ }
+
+ // copy_movable may throw during move, so it must be copied
+ {
+ copy_movable m;
+ copy_movable m2(boost::move_if_noexcept(m));
+ BOOST_CHECK(!m.moved());
+ copy_movable m3(function(copy_movable(boost::move_if_noexcept(m2))));
+ BOOST_CHECK(!m2.moved());
+ 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
+ {
+ copy_movable_noexcept m;
+ copy_movable_noexcept m2(boost::move_if_noexcept(m));
+ BOOST_CHECK(m.moved());
+ copy_movable_noexcept m3(function(copy_movable_noexcept(boost::move_if_noexcept(m2))));
+ BOOST_CHECK(m2.moved());
+ 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
+ {
+ movable_throwable m;
+ movable_throwable m2(boost::move_if_noexcept(m));
+ BOOST_CHECK(m.moved());
+ movable_throwable m3(function(movable_throwable(boost::move_if_noexcept(m2))));
+ BOOST_CHECK(m2.moved());
+ movable_throwable m4(function(boost::move_if_noexcept(m3)));
+ BOOST_CHECK(m3.moved());
+ BOOST_CHECK(!m4.moved());
+ }
+
+ return boost::report_errors();
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/src/boost/libs/move/test/move_iterator.cpp b/src/boost/libs/move/test/move_iterator.cpp
new file mode 100644
index 000000000..fded99a8b
--- /dev/null
+++ b/src/boost/libs/move/test/move_iterator.cpp
@@ -0,0 +1,44 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
+// 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/iterator.hpp>
+#include <boost/container/vector.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include "../example/movable.hpp"
+
+int main()
+{
+ namespace bc = ::boost::container;
+ //Default construct 10 movable objects
+ bc::vector<movable> v(10);
+
+ //Test default constructed value
+ BOOST_TEST(!v[0].moved());
+
+ //Move values
+ bc::vector<movable> v2
+ (boost::make_move_iterator(v.begin()), boost::make_move_iterator(v.end()));
+
+ //Test values have been moved
+ BOOST_TEST(v[0].moved());
+ BOOST_TEST(v2.size() == 10);
+
+ //Move again
+ v.assign(boost::make_move_iterator(v2.begin()), boost::make_move_iterator(v2.end()));
+
+ //Test values have been moved
+ BOOST_TEST(v2[0].moved());
+ BOOST_TEST(!v[0].moved());
+
+ return ::boost::report_errors();
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/src/boost/libs/move/test/order_type.hpp b/src/boost/libs/move/test/order_type.hpp
new file mode 100644
index 000000000..de398abcb
--- /dev/null
+++ b/src/boost/libs/move/test/order_type.hpp
@@ -0,0 +1,275 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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 <boost/move/core.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+#include <cstddef>
+#include <cstdio>
+
+struct order_perf_type
+{
+ public:
+ std::size_t key;
+ std::size_t val;
+
+ order_perf_type()
+ {
+ ++num_elements;
+ }
+
+ order_perf_type(const order_perf_type& other)
+ : key(other.key), val(other.val)
+ {
+ ++num_elements;
+ ++num_copy;
+ }
+
+ order_perf_type & operator=(const order_perf_type& other)
+ {
+ ++num_copy;
+ key = other.key;
+ val = other.val;
+ return *this;
+ }
+
+ ~order_perf_type ()
+ {
+ --num_elements;
+ }
+
+ static void reset_stats()
+ {
+ num_compare=0;
+ num_copy=0;
+ }
+
+ friend bool operator< (const order_perf_type& left, const order_perf_type& right)
+ { ++num_compare; return left.key < right.key; }
+
+ 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_perf_type::num_compare = 0;
+boost::ulong_long_type order_perf_type::num_copy = 0;
+boost::ulong_long_type order_perf_type::num_elements = 0;
+
+
+struct order_move_type
+{
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(order_move_type)
+
+ public:
+ std::size_t key;
+ std::size_t val;
+
+ static const std::size_t moved_constr_mark = std::size_t(-1);
+ static const std::size_t moved_assign_mark = std::size_t(-2);
+
+ order_move_type()
+ : key(0u), val(0u)
+ {}
+
+ order_move_type(BOOST_RV_REF(order_move_type) other)
+ : key(other.key), val(other.val)
+ {
+ other.key = other.val = std::size_t(-1);
+ }
+
+ order_move_type & operator=(BOOST_RV_REF(order_move_type) other)
+ {
+ key = other.key;
+ val = other.val;
+ other.key = other.val = std::size_t(-2);
+ return *this;
+ }
+
+ friend bool operator< (const order_move_type& left, const order_move_type& right)
+ { return left.key < right.key; }
+
+ ~order_move_type ()
+ {
+ key = val = std::size_t(-3);
+ }
+};
+
+struct order_type_less
+{
+ template<class T, class U>
+ bool operator()(const T &a, U const &b) const
+ { return a < b; }
+};
+
+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()(elements[i], elements[i-1])){
+ std::printf("\n Ord KO !!!!");
+ return false;
+ }
+ if( stable && !(order_type_less()(elements[i-1], elements[i])) && (elements[i-1].val > elements[i].val) ){
+ std::printf("\n Stb KO !!!! ");
+ return false;
+ }
+ }
+ return true;
+}
+
+namespace boost {
+namespace movelib {
+namespace detail_adaptive {
+
+
+
+}}}
+
+template<class T>
+inline bool is_key(T *elements, std::size_t element_count)
+{
+ for(std::size_t i = 1; i < element_count; ++i){
+ if(elements[i].key >= element_count){
+ std::printf("\n Key.key KO !!!!");
+ return false;
+ }
+ if(elements[i].val != std::size_t(-1)){
+ std::printf("\n Key.val KO !!!!");
+ return false;
+ }
+ }
+ return true;
+}
+
+template<class T>
+inline bool is_buffer(T *elements, std::size_t element_count)
+{
+ for(std::size_t i = 1; i < element_count; ++i){
+ if(elements[i].key != std::size_t(-1)){
+ std::printf("\n Buf.key KO !!!!");
+ return false;
+ }
+ if(elements[i].val >= element_count){
+ std::printf("\n Buf.val KO !!!!");
+ return false;
+ }
+ }
+ return true;
+}
+
+
+//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
diff --git a/src/boost/libs/move/test/random_shuffle.hpp b/src/boost/libs/move/test/random_shuffle.hpp
new file mode 100644
index 000000000..907d195f5
--- /dev/null
+++ b/src/boost/libs/move/test/random_shuffle.hpp
@@ -0,0 +1,37 @@
+#ifndef BOOST_MOVE_TEST_RANDOM_SHUFFLE_HPP
+#define BOOST_MOVE_TEST_RANDOM_SHUFFLE_HPP
+
+
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+#include <stdlib.h>
+
+inline unsigned long long rand_15_bit()
+{
+ //Many rand implementation only use 15 bits
+ //so make sure we have only 15 bits
+ return (unsigned long long)((std::rand()) & 0x7fffu);
+}
+
+inline unsigned long long ullrand()
+{
+ return (rand_15_bit() << 54u) ^ (rand_15_bit() << 39u)
+ ^ (rand_15_bit() << 26u) ^ (rand_15_bit() << 13u)
+ ^ rand_15_bit();
+}
+
+template< class RandomIt >
+void random_shuffle( RandomIt first, RandomIt last )
+{
+ typedef typename boost::movelib::iterator_traits<RandomIt>::difference_type difference_type;
+ difference_type n = last - first;
+ for (difference_type i = n-1; i > 0; --i) {
+ difference_type j = ullrand() % (i+1);
+ if(j != i) {
+ boost::adl_move_swap(first[i], first[j]);
+ }
+ }
+}
+
+
+#endif// BOOST_MOVE_TEST_RANDOM_SHUFFLE_HPP
diff --git a/src/boost/libs/move/test/type_traits.cpp b/src/boost/libs/move/test/type_traits.cpp
new file mode 100644
index 000000000..3625777a1
--- /dev/null
+++ b/src/boost/libs/move/test/type_traits.cpp
@@ -0,0 +1,98 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015.
+//
+// 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/type_traits.hpp>
+#include <boost/move/core.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//
+// pod_struct
+//
+#if defined(BOOST_MOVE_IS_POD)
+struct pod_struct
+{
+ int i;
+ float f;
+};
+#endif
+
+//
+// deleted_copy_and_assign_type
+//
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+
+struct deleted_copy_and_assign_type
+{
+ deleted_copy_and_assign_type(const deleted_copy_and_assign_type&) = delete;
+ deleted_copy_and_assign_type & operator=(const deleted_copy_and_assign_type&) = delete;
+};
+
+#endif //defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+
+//
+// boost_move_type
+//
+class boost_move_type
+{
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(boost_move_type)
+ public:
+ boost_move_type(BOOST_RV_REF(boost_move_type)){}
+ boost_move_type & operator=(BOOST_RV_REF(boost_move_type)){ return *this; }
+};
+
+namespace is_pod_test
+{
+
+void test()
+{
+ BOOST_STATIC_ASSERT((boost::move_detail::is_pod<int>::value));
+ #if defined(BOOST_MOVE_IS_POD)
+ BOOST_STATIC_ASSERT((boost::move_detail::is_pod<pod_struct>::value));
+ #endif
+}
+
+} //namespace is_pod_test
+
+namespace trivially_memcopyable_test {
+
+void test()
+{
+ #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+ BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible<deleted_copy_and_assign_type>::value));
+ BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable<deleted_copy_and_assign_type>::value));
+ #endif //#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+ //boost_move_type
+ BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible<boost_move_type>::value));
+ BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable<boost_move_type>::value));
+ BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_constructible<boost_move_type>::value));
+ BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_assignable<boost_move_type>::value));
+ //POD
+ BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_constructible<int>::value));
+ BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_assignable<int>::value));
+ BOOST_STATIC_ASSERT((boost::move_detail::is_copy_constructible<int>::value));
+ BOOST_STATIC_ASSERT((boost::move_detail::is_copy_assignable<int>::value));
+ #if defined(BOOST_MOVE_IS_POD)
+ BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_constructible<pod_struct>::value));
+ BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_assignable<pod_struct>::value));
+ BOOST_STATIC_ASSERT((boost::move_detail::is_copy_constructible<pod_struct>::value));
+ BOOST_STATIC_ASSERT((boost::move_detail::is_copy_assignable<pod_struct>::value));
+ #endif
+}
+
+} //namespace trivially_memcopyable_test {
+
+int main()
+{
+ trivially_memcopyable_test::test();
+ is_pod_test::test();
+ boost::report_errors();
+}
diff --git a/src/boost/libs/move/test/unique_ptr_assign.cpp b/src/boost/libs/move/test/unique_ptr_assign.cpp
new file mode 100644
index 000000000..088b7f4dc
--- /dev/null
+++ b/src/boost/libs/move/test/unique_ptr_assign.cpp
@@ -0,0 +1,444 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (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/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant.
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+// unique_ptr_asgn_move_convert_defdel
+////////////////////////////////
+namespace unique_ptr_asgn_move_convert_defdel {
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<B> s(new B);
+ A* p = s.get();
+ bml::unique_ptr<A> s2(new A);
+ BOOST_TEST(A::count == 2);
+ s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[]> s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<const A[]> s2(new const A[2]);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[2]> s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<const A[2]> s2(new const A[2]);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ }
+ {
+ BOOST_TEST(A::count == 0);
+ bml::unique_ptr<A[2]> s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<const A[]> s2(new const A[2]);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_asgn_move_convert_defdel{
+
+////////////////////////////////
+// unique_ptr_asgn_move_convert_movdel
+////////////////////////////////
+
+namespace unique_ptr_asgn_move_convert_movedel{
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<B, move_constr_deleter<B> > s(new B);
+ A* p = s.get();
+ bml::unique_ptr<A, move_constr_deleter<A> > s2(new A);
+ BOOST_TEST(A::count == 2);
+ s2 = (boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[], move_constr_deleter<A[]> > s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<const A[], move_constr_deleter<const A[]> > s2(new const A[2]);
+ BOOST_TEST(A::count == 4);
+ s2 = (boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s(new A[3]);
+ A* p = s.get();
+ bml::unique_ptr<const A[2], move_constr_deleter<const A[2]> > s2(new const A[2]);
+ BOOST_TEST(A::count == 5);
+ s2 = (boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 3);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ reset_counters();
+ {
+ bml::unique_ptr<A[2], move_constr_deleter<A[3]> > s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<const A[], move_constr_deleter<const A[]> > s2(new const A[2]);
+ BOOST_TEST(A::count == 4);
+ s2 = (boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_asgn_move_convert_movedel{
+
+////////////////////////////////
+// unique_ptr_asgn_move_convert_copydelref
+////////////////////////////////
+
+namespace unique_ptr_asgn_move_convert_copydelref{
+
+// test converting move assignment with reference deleters
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ copy_constr_deleter<B> db(5);
+ bml::unique_ptr<B, copy_constr_deleter<B>&> s(new B, db);
+ A* p = s.get();
+ copy_constr_deleter<A> da(6);
+ bml::unique_ptr<A, copy_constr_deleter<A>&> s2(new A, da);
+ s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ copy_constr_deleter<A[]> db(5);
+ bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s(new A[2], db);
+ A* p = s.get();
+ copy_constr_deleter<const A[]> da(6);
+ bml::unique_ptr<const A[], copy_constr_deleter<const A[]>&> s2(new const A[2], da);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ copy_constr_deleter<A[2]> db(5);
+ bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s(new A[2], db);
+ A* p = s.get();
+ copy_constr_deleter<const A[2]> da(6);
+ bml::unique_ptr<const A[2], copy_constr_deleter<const A[2]>&> s2(new const A[2], da);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ reset_counters();
+ {
+ copy_constr_deleter<A[2]> db(5);
+ bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s(new A[2], db);
+ A* p = s.get();
+ copy_constr_deleter<const A[]> da(6);
+ bml::unique_ptr<const A[], copy_constr_deleter<const A[]>&> s2(new const A[2], da);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_asgn_move_convert_copydelref{
+
+////////////////////////////////
+// unique_ptr_asgn_move_defdel
+////////////////////////////////
+namespace unique_ptr_asgn_move_defdel {
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A> s1(new A);
+ A* p = s1.get();
+ bml::unique_ptr<A> s2(new A);
+ BOOST_TEST(A::count == 2);
+ s2 = boost::move(s1);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s1.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[]> s1(new A[2]);
+ A* p = s1.get();
+ bml::unique_ptr<A[]> s2(new A[2]);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s1);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s1.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[2]> s1(new A[2]);
+ A* p = s1.get();
+ bml::unique_ptr<A[2]> s2(new A[2]);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s1);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s1.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //unique_ptr_asgn_move_defdel
+
+////////////////////////////////
+// unique_ptr_asgn_move_movedel
+////////////////////////////////
+namespace unique_ptr_asgn_move_movedel {
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A, move_constr_deleter<A> > s1(new A);
+ A* p = s1.get();
+ bml::unique_ptr<A, move_constr_deleter<A> > s2(new A);
+ BOOST_TEST(A::count == 2);
+ s2 = boost::move(s1);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s1.get() == 0);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s1.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[], move_constr_deleter<A[]> > s1(new A[2]);
+ A* p = s1.get();
+ bml::unique_ptr<A[], move_constr_deleter<A[]> > s2(new A[2]);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s1);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s1.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s1.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s1(new A[2]);
+ A* p = s1.get();
+ bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s2(new A[2]);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s1);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s1.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s1.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //unique_ptr_asgn_move_movedel
+
+////////////////////////////////
+// unique_ptr_asgn_move_copydelref
+////////////////////////////////
+namespace unique_ptr_asgn_move_copydelref {
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ copy_constr_deleter<A> d1(5);
+ bml::unique_ptr<A, copy_constr_deleter<A>&> s1(new A, d1);
+ A* p = s1.get();
+ copy_constr_deleter<A> d2(6);
+ bml::unique_ptr<A, copy_constr_deleter<A>&> s2(new A, d2);
+ s2 = boost::move(s1);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s1.get() == 0);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(d1.state() == 5);
+ BOOST_TEST(d2.state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ copy_constr_deleter<A[]> d1(5);
+ bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s1(new A[2], d1);
+ A* p = s1.get();
+ copy_constr_deleter<A[]> d2(6);
+ bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s2(new A[2], d2);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s1);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s1.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(d1.state() == 5);
+ BOOST_TEST(d2.state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ copy_constr_deleter<A[2]> d1(5);
+ bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s1(new A[2], d1);
+ A* p = s1.get();
+ copy_constr_deleter<A[2]> d2(6);
+ bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s2(new A[2], d2);
+ BOOST_TEST(A::count == 4);
+ s2 = boost::move(s1);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s1.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(d1.state() == 5);
+ BOOST_TEST(d2.state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //unique_ptr_asgn_move_copydelref
+
+////////////////////////////////
+// main
+////////////////////////////////
+int main()
+{
+ //Assignment
+ unique_ptr_asgn_move_convert_defdel::test();
+ unique_ptr_asgn_move_convert_movedel::test();
+ unique_ptr_asgn_move_convert_copydelref::test();
+ unique_ptr_asgn_move_defdel::test();
+ unique_ptr_asgn_move_movedel::test();
+ unique_ptr_asgn_move_copydelref::test();
+
+ //Test results
+ return boost::report_errors();
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/src/boost/libs/move/test/unique_ptr_ctordtor.cpp b/src/boost/libs/move/test/unique_ptr_ctordtor.cpp
new file mode 100644
index 000000000..a583b9262
--- /dev/null
+++ b/src/boost/libs/move/test/unique_ptr_ctordtor.cpp
@@ -0,0 +1,811 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (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/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant.
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+// unique_ptr_dtor_null
+////////////////////////////////
+
+namespace unique_ptr_dtor_null{
+
+// The deleter is not called if get() == 0
+
+void test()
+{
+ //Single unique_ptr
+ {
+ def_constr_deleter<int> d;
+ BOOST_TEST(d.state() == 5);
+ {
+ bml::unique_ptr<int, def_constr_deleter<int>&> p(0, d);
+ BOOST_TEST(p.get() == 0);
+ BOOST_TEST(&p.get_deleter() == &d);
+ }
+ BOOST_TEST(d.state() == 5);
+ }
+ {
+ //Unbounded array unique_ptr
+ def_constr_deleter<int[]> d;
+ BOOST_TEST(d.state() == 5);
+ {
+ bml::unique_ptr<int[], def_constr_deleter<int[]>&> p(0, d);
+ BOOST_TEST(p.get() == 0);
+ BOOST_TEST(&p.get_deleter() == &d);
+ }
+ BOOST_TEST(d.state() == 5);
+ }
+ {
+ //Bounded array unique_ptr
+ def_constr_deleter<int[2]> d;
+ BOOST_TEST(d.state() == 5);
+ {
+ bml::unique_ptr<int[2], def_constr_deleter<int[2]>&> p(0, d);
+ BOOST_TEST(p.get() == 0);
+ BOOST_TEST(&p.get_deleter() == &d);
+ }
+ BOOST_TEST(d.state() == 5);
+ }
+}
+
+} //namespace unique_ptr_dtor_null{
+
+////////////////////////////////
+// unique_ptr_ctor_default_delreq
+////////////////////////////////
+
+namespace unique_ptr_ctor_default_delreq{
+
+// default unique_ptr ctor should only require default deleter ctor
+
+void test()
+{
+ //Single unique_ptr
+ {
+ bml::unique_ptr<int> p;
+ BOOST_TEST(p.get() == 0);
+ }
+ {
+ bml::unique_ptr<int, def_constr_deleter<int> > p;
+ BOOST_TEST(p.get() == 0);
+ BOOST_TEST(p.get_deleter().state() == 5);
+ }
+ //Unbounded array unique_ptr
+ {
+ bml::unique_ptr<int[]> p;
+ BOOST_TEST(p.get() == 0);
+ }
+ {
+ bml::unique_ptr<int[], def_constr_deleter<int[]> > p;
+ BOOST_TEST(p.get() == 0);
+ BOOST_TEST(p.get_deleter().state() == 5);
+ }
+
+ //Unbounded array unique_ptr
+ {
+ bml::unique_ptr<int[]> p;
+ BOOST_TEST(p.get() == 0);
+ }
+ {
+ bml::unique_ptr<int[], def_constr_deleter<int[]> > p;
+ BOOST_TEST(p.get() == 0);
+ BOOST_TEST(p.get_deleter().state() == 5);
+ }
+
+ //Unbounded array unique_ptr
+ {
+ bml::unique_ptr<int[2]> p;
+ BOOST_TEST(p.get() == 0);
+ }
+ {
+ bml::unique_ptr<int[2], def_constr_deleter<int[2]> > p;
+ BOOST_TEST(p.get() == 0);
+ BOOST_TEST(p.get_deleter().state() == 5);
+ }
+}
+
+} //namespace unique_ptr_ctor_default_delreq{
+
+////////////////////////////////
+// unique_ptr_ctor_default_nocomplete
+////////////////////////////////
+
+namespace unique_ptr_ctor_default_nocomplete{
+
+// default unique_ptr ctor shouldn't require complete type
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ J<I> s;
+ BOOST_TEST(s.get() == 0);
+ }
+ check(0);
+ {
+ J<I, def_constr_deleter<I> > s;
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ check(0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ J<I[]> s;
+ BOOST_TEST(s.get() == 0);
+ }
+ check(0);
+ {
+ J<I[], def_constr_deleter<I[]> > s;
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ check(0);
+
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ J<I[2]> s;
+ BOOST_TEST(s.get() == 0);
+ }
+ check(0);
+ {
+ J<I[2], def_constr_deleter<I[2]> > s;
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ check(0);
+}
+
+} //namespace unique_ptr_ctor_default_nocomplete{
+
+////////////////////////////////
+// unique_ptr_ctor_pointer_delreq
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_delreq{
+
+// unique_ptr(pointer) ctor should only require default deleter ctor
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ A* p = new A;
+ BOOST_TEST(A::count == 1);
+ bml::unique_ptr<A> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ A* p = new A;
+ BOOST_TEST(A::count == 1);
+ bml::unique_ptr<A, def_constr_deleter<A> > s(p);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ bml::unique_ptr<A[]> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ bml::unique_ptr<A[], def_constr_deleter<A[]> > s(p);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ bml::unique_ptr<A[2]> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ bml::unique_ptr<A[2], def_constr_deleter<A[2]> > s(p);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_pointer_delreq{
+
+////////////////////////////////
+// unique_ptr_ctor_pointer_nocomplete
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_nocomplete{
+
+// unique_ptr(pointer) ctor shouldn't require complete type
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ I* p = get();
+ check(1);
+ J<I> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ check(0);
+ {
+ I* p = get();
+ check(1);
+ J<I, def_constr_deleter<I> > s(p);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ check(0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ I* p = get_array(2);
+ check(2);
+ J<I[]> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ check(0);
+ {
+ I* p = get_array(2);
+ check(2);
+ J<I[], def_constr_deleter<I[]> > s(p);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ check(0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ I* p = get_array(2);
+ check(2);
+ J<I[]> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ check(0);
+ {
+ I* p = get_array(2);
+ check(2);
+ J<I[2], def_constr_deleter<I[2]> > s(p);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ check(0);
+}
+
+} //namespace unique_ptr_ctor_pointer_nocomplete{
+
+////////////////////////////////
+// unique_ptr_ctor_pointer_convert
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_convert{
+
+// unique_ptr(pointer) ctor should work with derived pointers
+// or same types (cv aside) for unique_ptr<arrays>
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ B* p = new B;
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ bml::unique_ptr<A> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ {
+ B* p = new B;
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ bml::unique_ptr<A, def_constr_deleter<A> > s(p);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ bml::unique_ptr<const A[]> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ const A* p = new const A[2];
+ BOOST_TEST(A::count == 2);
+ bml::unique_ptr<const volatile A[], def_constr_deleter<const volatile A[]> > s(p);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ bml::unique_ptr<const A[2]> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ const A* p = new const A[2];
+ BOOST_TEST(A::count == 2);
+ bml::unique_ptr<const volatile A[2], def_constr_deleter<const volatile A[2]> > s(p);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_pointer_convert{
+
+////////////////////////////////
+// unique_ptr_ctor_pointer_deleter_movedel
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_movedel{
+
+// test move ctor. Should only require a MoveConstructible deleter, or if
+// deleter is a reference, not even that.
+
+// unique_ptr(pointer, deleter()) only requires MoveConstructible deleter
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ A* p = new A;
+ BOOST_TEST(A::count == 1);
+ move_constr_deleter<A> d;
+ bml::unique_ptr<A, move_constr_deleter<A> > s(p, ::boost::move(d));
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ bml::unique_ptr<A, move_constr_deleter<A> > s2(s.release(), move_constr_deleter<A>(6));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s2.get_deleter().state() == 6);
+ }
+ BOOST_TEST(A::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ move_constr_deleter<A[]> d;
+ bml::unique_ptr<A[], move_constr_deleter<A[]> > s(p, ::boost::move(d));
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ bml::unique_ptr<A[], move_constr_deleter<A[]> > s2(s.release(), move_constr_deleter<A[]>(6));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s2.get_deleter().state() == 6);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ move_constr_deleter<A[2]> d;
+ bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s(p, ::boost::move(d));
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s2(s.release(), move_constr_deleter<A[2]>(6));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s2.get_deleter().state() == 6);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_pointer_deleter_movedel{
+
+////////////////////////////////
+// unique_ptr_ctor_pointer_deleter_copydel
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_copydel{
+
+// unique_ptr(pointer, d) requires CopyConstructible deleter
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ A* p = new A;
+ BOOST_TEST(A::count == 1);
+ copy_constr_deleter<A> d;
+ bml::unique_ptr<A, copy_constr_deleter<A> > s(p, d);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ d.set_state(6);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ copy_constr_deleter<A[]> d;
+ bml::unique_ptr<A[], copy_constr_deleter<A[]> > s(p, d);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ d.set_state(6);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ copy_constr_deleter<A[2]> d;
+ bml::unique_ptr<A[2], copy_constr_deleter<A[2]> > s(p, d);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ d.set_state(6);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_pointer_deleter_copydel{
+
+////////////////////////////////
+// unique_ptr_ctor_pointer_deleter_dfctrdelref
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_dfctrdelref{
+
+// unique_ptr<T, D&>(pointer, d) does not requires CopyConstructible deleter
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ A* p = new A;
+ BOOST_TEST(A::count == 1);
+ def_constr_deleter<A> d;
+ bml::unique_ptr<A, def_constr_deleter<A>&> s(p, d);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ d.set_state(6);
+ BOOST_TEST(s.get_deleter().state() == 6);
+ }
+ BOOST_TEST(A::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ def_constr_deleter<A[]> d;
+ bml::unique_ptr<A[], def_constr_deleter<A[]>&> s(p, d);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ d.set_state(6);
+ BOOST_TEST(s.get_deleter().state() == 6);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ def_constr_deleter<A[2]> d;
+ bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> s(p, d);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ d.set_state(6);
+ BOOST_TEST(s.get_deleter().state() == 6);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_pointer_deleter_dfctrdelref{
+
+////////////////////////////////
+// unique_ptr_ctor_pointer_deleter_dfctrdelconstref
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_dfctrdelconstref{
+
+// unique_ptr<T, const D&>(pointer, d) does not requires CopyConstructible deleter
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ A* p = new A;
+ BOOST_TEST(A::count == 1);
+ def_constr_deleter<A> d;
+ bml::unique_ptr<A, const def_constr_deleter<A>&> s(p, d);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ def_constr_deleter<A[]> d;
+ bml::unique_ptr<A[], const def_constr_deleter<A[]>&> s(p, d);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ def_constr_deleter<A[2]> d;
+ bml::unique_ptr<A[2], const def_constr_deleter<A[2]>&> s(p, d);
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_pointer_deleter_dfctrdelconstref{
+
+////////////////////////////////
+// unique_ptr_ctor_pointer_deleter_convert
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_convert{
+
+// unique_ptr(pointer, deleter) should work with derived pointers
+// or same (cv aside) types for array unique_ptrs
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ B* p = new B;
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ bml::unique_ptr<A, copy_constr_deleter<A> > s(p, copy_constr_deleter<A>());
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ bml::unique_ptr<const A[], copy_constr_deleter<const A[]> > s(p, copy_constr_deleter<const A[]>());
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ bml::unique_ptr<const A[2], copy_constr_deleter<const A[2]> > s(p, copy_constr_deleter<const A[2]>());
+ BOOST_TEST(s.get() == p);
+ BOOST_TEST(s.get_deleter().state() == 5);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+}
+
+} //namespace unique_ptr_ctor_pointer_deleter_convert{
+
+////////////////////////////////
+// unique_ptr_ctor_pointer_deleter_void
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_void{
+
+// unique_ptr(pointer, deleter) should work with function pointers
+// unique_ptr<void> should work
+
+bool my_free_called = false;
+
+void my_free(void*)
+{
+ my_free_called = true;
+}
+
+void test()
+{
+ {
+ int i = 0;
+ bml::unique_ptr<void, void (*)(void*)> s(&i, my_free);
+ BOOST_TEST(s.get() == &i);
+ BOOST_TEST(s.get_deleter() == my_free);
+ BOOST_TEST(!my_free_called);
+ }
+ BOOST_TEST(my_free_called);
+}
+
+} //namespace unique_ptr_ctor_pointer_deleter_void{
+
+////////////////////////////////
+// return_unique_single_conversion
+////////////////////////////////
+
+namespace return_unique_single_conversion{
+
+template<class T>
+bml::unique_ptr<T> make_unique_ptr_of_t()
+{
+ return bml::unique_ptr<T>(new T);
+}
+
+template<class T>
+bml::unique_ptr<T const> return_const_unique_of_t()
+{
+ return bml::unique_ptr<T const> (make_unique_ptr_of_t<T>());
+}
+
+void test()
+{
+ reset_counters();
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<const A> p(return_const_unique_of_t<A>());
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<const A> p(return_const_unique_of_t<B>());
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace return_unique_single_conversion{
+
+
+////////////////////////////////
+// return_unique_array_conversion
+////////////////////////////////
+
+namespace return_unique_array_conversion{
+
+template<class T>
+bml::unique_ptr<T[]> return_unique_array_of_t(std::size_t n)
+{
+ return bml::unique_ptr<T[]>(new T[n]);
+}
+
+template<class T>
+bml::unique_ptr<const T[]> return_const_array_of_t(std::size_t n)
+{
+ return bml::unique_ptr<const T[]>(return_unique_array_of_t<T>(n));
+}
+
+template<class T>
+bml::unique_ptr<T[2]> return_unique_array_of_t_2()
+{
+ return bml::unique_ptr<T[2]>(new T[2]);
+}
+
+template<class T>
+bml::unique_ptr<const T[2]> return_const_array_of_t_2()
+{
+ return bml::unique_ptr<const T[2]>(return_unique_array_of_t_2<T>());
+}
+
+void test()
+{
+ reset_counters();
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<const A[]> p(return_unique_array_of_t<A>(2));
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(B::count == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<const volatile A[]> p(return_unique_array_of_t<volatile A>(2));
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(B::count == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<const volatile A[2]> p(return_const_array_of_t_2<A>());
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(B::count == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<const volatile A[]> p(return_const_array_of_t_2<A>());
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(B::count == 0);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace return_unique_array_conversion{
+
+////////////////////////////////
+// main
+////////////////////////////////
+int main()
+{
+ //Constructors/Destructor
+ unique_ptr_dtor_null::test();
+ unique_ptr_ctor_default_delreq::test();
+ unique_ptr_ctor_default_nocomplete::test();
+ unique_ptr_ctor_pointer_delreq::test();
+ unique_ptr_ctor_pointer_nocomplete::test();
+ unique_ptr_ctor_pointer_convert::test();
+ unique_ptr_ctor_pointer_deleter_movedel::test();
+ unique_ptr_ctor_pointer_deleter_copydel::test();
+ unique_ptr_ctor_pointer_deleter_dfctrdelref::test();
+ unique_ptr_ctor_pointer_deleter_dfctrdelconstref::test();
+ unique_ptr_ctor_pointer_deleter_convert::test();
+ unique_ptr_ctor_pointer_deleter_void::test();
+ return_unique_single_conversion::test();
+ return_unique_array_conversion::test();
+
+ //Test results
+ return boost::report_errors();
+
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/src/boost/libs/move/test/unique_ptr_default_deleter.cpp b/src/boost/libs/move/test/unique_ptr_default_deleter.cpp
new file mode 100644
index 000000000..1bf16eaad
--- /dev/null
+++ b/src/boost/libs/move/test/unique_ptr_default_deleter.cpp
@@ -0,0 +1,204 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (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/default_delete.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant.
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+////////////////////////////////
+// unique_ptr_dltr_dflt_convert_ctor
+////////////////////////////////
+
+namespace bml = ::boost::movelib;
+
+struct A
+{
+ static int count;
+ A() {++count;}
+ A(const A&) {++count;}
+ virtual ~A() {--count;}
+};
+
+int A::count = 0;
+
+struct B
+ : public A
+{
+ static int count;
+ B() : A() {++count;}
+ B(const B&) : A() {++count;}
+ virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+void reset_counters()
+{ A::count = B::count = 0; }
+
+namespace unique_ptr_dltr_dflt_convert_ctor{
+
+void test()
+{
+ //Single element deleter
+ {
+ reset_counters();
+ bml::default_delete<B> d2;
+ bml::default_delete<A> d1 = d2;
+ A* p = new B;
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ d1(p);
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ }
+ //Array element deleter
+ {
+ reset_counters();
+ bml::default_delete<A[]> d2;
+ bml::default_delete<const A[]> d1 = d2;
+ const A* p = new const A[2];
+ BOOST_TEST(A::count == 2);
+ d1(p);
+ BOOST_TEST(A::count == 0);
+ }
+ //Bounded array element deleter
+ {
+ reset_counters();
+ bml::default_delete<A[2]> d2;
+ bml::default_delete<const A[2]> d1 = d2;
+ const A* p = new const A[2];
+ BOOST_TEST(A::count == 2);
+ d1(p);
+ bml::default_delete<const A[]> d0 = d1;
+ d0(0);
+ BOOST_TEST(A::count == 0);
+ }
+}
+
+} //namespace unique_ptr_dltr_dflt_convert_ctor{
+
+////////////////////////////////
+// unique_ptr_dltr_dflt_convert_assign
+////////////////////////////////
+
+namespace unique_ptr_dltr_dflt_convert_assign{
+
+void test()
+{
+ //Single element deleter
+ {
+ reset_counters();
+ bml::default_delete<B> d2;
+ bml::default_delete<A> d1;
+ d1 = d2;
+ A* p = new B;
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ d1(p);
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ }
+ //Array element deleter
+ {
+ reset_counters();
+ bml::default_delete<A[]> d2;
+ bml::default_delete<const A[]> d1;
+ d1 = d2;
+ const A* p = new const A[2];
+ BOOST_TEST(A::count == 2);
+ d1(p);
+ BOOST_TEST(A::count == 0);
+ }
+ //Bounded array element deleter
+ {
+ reset_counters();
+ bml::default_delete<A[2]> d2;
+ bml::default_delete<const A[2]> d1;
+ d1 = d2;
+ const A* p = new const A[2];
+ BOOST_TEST(A::count == 2);
+ d1(p);
+ bml::default_delete<const A[]> d0;
+ d0 = d1;
+ d0(0);
+ BOOST_TEST(A::count == 0);
+ }
+}
+
+} //namespace unique_ptr_dltr_dflt_convert_assign{
+
+
+////////////////////////////////
+// unique_ptr_dltr_dflt_default
+////////////////////////////////
+
+namespace unique_ptr_dltr_dflt_default{
+
+void test()
+{
+ {
+ //Single element deleter
+ reset_counters();
+ bml::default_delete<A> d;
+ A* p = new A;
+ BOOST_TEST(A::count == 1);
+ d(p);
+ BOOST_TEST(A::count == 0);
+ }
+ {
+ //Array element deleter
+ reset_counters();
+ bml::default_delete<A[]> d;
+ A* p = new A[2];
+ BOOST_TEST(A::count == 2);
+ d(p);
+ BOOST_TEST(A::count == 0);
+ }
+
+ {
+ //Bounded Array element deleter
+ reset_counters();
+ bml::default_delete<A[10]> d;
+ A* p = new A[10];
+ BOOST_TEST(A::count == 10);
+ d(p);
+ BOOST_TEST(A::count == 0);
+ }
+}
+
+} //namespace unique_ptr_dltr_dflt_default{
+
+////////////////////////////////
+// main
+////////////////////////////////
+int main()
+{
+ unique_ptr_dltr_dflt_convert_ctor::test();
+ unique_ptr_dltr_dflt_convert_assign::test();
+ unique_ptr_dltr_dflt_default::test();
+
+ //Test results
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/move/test/unique_ptr_functions.cpp b/src/boost/libs/move/test/unique_ptr_functions.cpp
new file mode 100644
index 000000000..d3b4d6d57
--- /dev/null
+++ b/src/boost/libs/move/test/unique_ptr_functions.cpp
@@ -0,0 +1,395 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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/make_unique.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <cstring>
+
+struct A
+{
+ int a, b, c;
+ static int count;
+ A() : a (999), b(1000), c(1001) {++count;}
+ A(int a) : a (a), b(1000), c(1001) {++count;}
+ A(int a, int b) : a (a), b(b), c(1001) {++count;}
+ A(int a, int b, int c) : a (a), b(b), c(c) {++count;}
+ A(const A&) {++count;}
+ virtual ~A() {--count;}
+};
+
+int A::count = 0;
+
+struct B
+ : public A
+{
+ static int count;
+ B() : A() {++count;}
+ B(const B&) : A() {++count;}
+ virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+void reset_counters()
+{ A::count = B::count = 0; }
+
+static const unsigned PatternSize = 8;
+static const unsigned char ff_patternbuf[PatternSize] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+static const unsigned char ee_patternbuf[PatternSize] = { 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE };
+static const unsigned char dd_patternbuf[PatternSize] = { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD };
+static const unsigned char cc_patternbuf[PatternSize] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC };
+
+void volatile_memset(volatile void *p, int ch, std::size_t len)
+{
+ volatile unsigned char *puch = static_cast<volatile unsigned char *>(p);
+ for(std::size_t i = 0; i != len; ++i){
+ *puch = (unsigned char)ch;
+ ++puch;
+ }
+}
+
+int volatile_memcmp(const volatile void *p1, const volatile void *p2, std::size_t len)
+{
+ const volatile unsigned char *s1 = static_cast<const volatile unsigned char *>(p1);
+ const volatile unsigned char *s2 = static_cast<const volatile unsigned char *>(p2);
+ unsigned char u1, u2;
+
+ for ( ; len-- ; s1++, s2++) {
+ u1 = *s1;
+ u2 = *s2;
+ if (u1 != u2) {
+ return (u1-u2);
+ }
+ }
+ return 0;
+}
+
+void volatile_memcmp(volatile void *p, int ch, std::size_t len)
+{
+ volatile unsigned char *puch = static_cast<volatile unsigned char *>(p);
+ for(std::size_t i = 0; i != len; ++i){
+ *puch = (unsigned char)ch;
+ ++puch;
+ }
+}
+
+#include <iostream>
+
+struct default_init
+{
+ static void* operator new(std::size_t sz)
+ {
+ void *const p = ::operator new(sz);
+ //Make sure they are not optimized out
+ volatile_memset(p, 0xFF, sz);
+ std::cout << "0xFF" << '\n';
+ return p;
+ }
+ static void* operator new[](std::size_t sz)
+ {
+ void *const p = ::operator new[](sz);
+ //Make sure they are not optimized out
+ volatile_memset(p, 0xEE, sz);
+ std::cout << "0xEE" << '\n';
+ return p;
+ }
+ static void* operator new(std::size_t sz, const std::nothrow_t &)
+ {
+ void *const p = ::operator new(sz);
+ //Make sure they are not optimized out
+ volatile_memset(p, 0xDD, sz);
+ std::cout << "0xDD" << '\n';
+ return p;
+ }
+ static void* operator new[](std::size_t sz, const std::nothrow_t &)
+ {
+ void *const p = ::operator new[](sz);
+ //Make sure they are not optimized out
+ volatile_memset(p, 0xCC, sz);
+ std::cout << "0xCC" << '\n';
+ return p;
+ }
+ unsigned char buf[PatternSize];
+};
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+// make_unique_single
+////////////////////////////////
+
+namespace make_unique_single{
+
+void test()
+{
+ //Single element deleter
+ reset_counters();
+ {
+ bml::unique_ptr<default_init> p(bml::make_unique_definit<default_init>());
+ BOOST_TEST(0 == volatile_memcmp(p.get(), ff_patternbuf, sizeof(ff_patternbuf)));
+ }
+ {
+ bml::unique_ptr<default_init> p(bml::make_unique_nothrow_definit<default_init>());
+
+ BOOST_TEST(0 == volatile_memcmp(p.get(), dd_patternbuf, sizeof(dd_patternbuf)));
+ }
+
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A> p(bml::make_unique<A>());
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(p->a == 999);
+ BOOST_TEST(p->b == 1000);
+ BOOST_TEST(p->c == 1001);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A> p(bml::make_unique_nothrow<A>(0));
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(p->a == 0);
+ BOOST_TEST(p->b == 1000);
+ BOOST_TEST(p->c == 1001);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A> p(bml::make_unique<A>(0, 1));
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(p->a == 0);
+ BOOST_TEST(p->b == 1);
+ BOOST_TEST(p->c == 1001);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A> p(bml::make_unique_nothrow<A>(0, 1, 2));
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(p->a == 0);
+ BOOST_TEST(p->b == 1);
+ BOOST_TEST(p->c == 2);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace make_unique_single{
+
+
+////////////////////////////////
+// make_unique_array
+////////////////////////////////
+
+namespace make_unique_array{
+
+void test()
+{
+ //Array element
+ reset_counters();
+ {
+ bml::unique_ptr<A[]> p(bml::make_unique<A[]>(10));
+ BOOST_TEST(A::count == 10);
+ for(int i = 0; i != 10; ++i){
+ BOOST_TEST(p[i].a == 999);
+ BOOST_TEST(p[i].b == 1000);
+ BOOST_TEST(p[i].c == 1001);
+ }
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A[]> p(bml::make_unique_nothrow<A[]>(10));
+ BOOST_TEST(A::count == 10);
+ for(int i = 0; i != 10; ++i){
+ BOOST_TEST(p[i].a == 999);
+ BOOST_TEST(p[i].b == 1000);
+ BOOST_TEST(p[i].c == 1001);
+ }
+ }
+ BOOST_TEST(A::count == 0);
+ reset_counters();
+ {
+ bml::unique_ptr<default_init[]> p(bml::make_unique_definit<default_init[]>(10));
+ for(unsigned i = 0; i != 10; ++i){
+ BOOST_TEST(0 == volatile_memcmp(&p[i], ee_patternbuf, sizeof(ee_patternbuf)));
+ }
+ }
+ reset_counters();
+ {
+ bml::unique_ptr<default_init[]> p(bml::make_unique_nothrow_definit<default_init[]>(10));
+ for(unsigned i = 0; i != 10; ++i){
+ BOOST_TEST(0 == volatile_memcmp(&p[i], cc_patternbuf, sizeof(cc_patternbuf)));
+ }
+ }
+}
+
+} //namespace make_unique_array{
+
+////////////////////////////////
+// unique_compare
+////////////////////////////////
+
+namespace unique_compare{
+
+void test()
+{
+ //Single element deleter
+ reset_counters();
+ {
+ bml::unique_ptr<A> pa(bml::make_unique<A>());
+ bml::unique_ptr<A> pb(bml::make_unique<A>());
+ BOOST_TEST(A::count == 2);
+
+ //Take references to less and greater
+ bml::unique_ptr<A> &rpl = pa < pb ? pa : pb;
+ bml::unique_ptr<A> &rpg = pa < pb ? pb : pa;
+
+ //Now test operations with .get()
+
+ //Equal
+ BOOST_TEST(rpl == rpl && rpl.get() == rpl.get());
+ BOOST_TEST(!(rpl == rpg) && !(rpl.get() == rpg.get()));
+ //Unequal
+ BOOST_TEST(rpl != rpg && rpl.get() != rpg.get());
+ BOOST_TEST(!(rpl != rpl) && !(rpl.get() != rpl.get()));
+ //Less
+ BOOST_TEST(rpl < rpg && rpl.get() < rpg.get());
+ BOOST_TEST(!(rpg < rpl) && !(rpg.get() < rpl.get()));
+ //Greater
+ BOOST_TEST(rpg > rpl && rpg.get() > rpl.get());
+ BOOST_TEST(!(rpg > rpg) && !(rpg.get() > rpg.get()));
+ //Less or equal
+ BOOST_TEST(rpl <= rpg && rpl.get() <= rpg.get());
+ BOOST_TEST(rpl <= rpl && rpl.get() <= rpl.get());
+ BOOST_TEST(!(rpg <= rpl) && !(rpg.get() <= rpl.get()));
+ //Greater or equal
+ BOOST_TEST(rpg >= rpl && rpg.get() >= rpl.get());
+ BOOST_TEST(rpg >= rpg && rpg.get() >= rpg.get());
+ BOOST_TEST(!(rpl >= rpg) && !(rpl.get() >= rpg.get()));
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_compare{
+
+////////////////////////////////
+// unique_compare_zero
+////////////////////////////////
+namespace unique_compare_zero{
+
+void test()
+{
+ //Single element deleter
+ reset_counters();
+ {
+ bml::unique_ptr<A> pa(bml::make_unique<A>());
+ bml::unique_ptr<A> pb;
+ BOOST_TEST(A::count == 1);
+
+ //Equal
+ BOOST_TEST(!(pa == 0));
+ BOOST_TEST(!(0 == pa));
+ BOOST_TEST((pb == 0));
+ BOOST_TEST((0 == pb));
+ //Unequal
+ BOOST_TEST((pa != 0));
+ BOOST_TEST((0 != pa));
+ BOOST_TEST(!(pb != 0));
+ BOOST_TEST(!(0 != pb));
+ //Less
+ BOOST_TEST((pa < 0) == (pa.get() < (A*)0));
+ BOOST_TEST((0 < pa) == ((A*)0 < pa.get()));
+ BOOST_TEST((pb < 0) == (pb.get() < (A*)0));
+ BOOST_TEST((0 < pb) == ((A*)0 < pb.get()));
+ //Greater
+ BOOST_TEST((pa > 0) == (pa.get() > (A*)0));
+ BOOST_TEST((0 > pa) == ((A*)0 > pa.get()));
+ BOOST_TEST((pb > 0) == (pb.get() > (A*)0));
+ BOOST_TEST((0 > pb) == ((A*)0 > pb.get()));
+ //Less or equal
+ BOOST_TEST((pa <= 0) == (pa.get() <= (A*)0));
+ BOOST_TEST((0 <= pa) == ((A*)0 <= pa.get()));
+ BOOST_TEST((pb <= 0) == (pb.get() <= (A*)0));
+ BOOST_TEST((0 <= pb) == ((A*)0 <= pb.get()));
+ //Greater or equal
+ BOOST_TEST((pa >= 0) == (pa.get() >= (A*)0));
+ BOOST_TEST((0 >= pa) == ((A*)0 >= pa.get()));
+ BOOST_TEST((pb >= 0) == (pb.get() >= (A*)0));
+ BOOST_TEST((0 >= pb) == ((A*)0 >= pb.get()));
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_compare_zero{
+
+////////////////////////////////
+// unique_compare_nullptr
+////////////////////////////////
+
+namespace unique_compare_nullptr{
+
+void test()
+{
+ #if !defined(BOOST_NO_CXX11_NULLPTR)
+ //Single element deleter
+ reset_counters();
+ {
+ bml::unique_ptr<A> pa(bml::make_unique<A>());
+ bml::unique_ptr<A> pb;
+ BOOST_TEST(A::count == 1);
+
+ //Equal
+ BOOST_TEST(!(pa == nullptr));
+ BOOST_TEST(!(nullptr == pa));
+ BOOST_TEST((pb == nullptr));
+ BOOST_TEST((nullptr == pb));
+ //Unequal
+ BOOST_TEST((pa != nullptr));
+ BOOST_TEST((nullptr != pa));
+ BOOST_TEST(!(pb != nullptr));
+ BOOST_TEST(!(nullptr != pb));
+ //Less
+ BOOST_TEST((pa < nullptr) == (pa.get() < (A*)nullptr));
+ BOOST_TEST((nullptr < pa) == ((A*)nullptr < pa.get()));
+ BOOST_TEST((pb < nullptr) == (pb.get() < (A*)nullptr));
+ BOOST_TEST((nullptr < pb) == ((A*)nullptr < pb.get()));
+ //Greater
+ BOOST_TEST((pa > nullptr) == (pa.get() > (A*)nullptr));
+ BOOST_TEST((nullptr > pa) == ((A*)nullptr > pa.get()));
+ BOOST_TEST((pb > nullptr) == (pb.get() > (A*)nullptr));
+ BOOST_TEST((nullptr > pb) == ((A*)nullptr > pb.get()));
+ //Less or equal
+ BOOST_TEST((pa <= nullptr) == (pa.get() <= (A*)nullptr));
+ BOOST_TEST((nullptr <= pa) == ((A*)nullptr <= pa.get()));
+ BOOST_TEST((pb <= nullptr) == (pb.get() <= (A*)nullptr));
+ BOOST_TEST((nullptr <= pb) == ((A*)nullptr <= pb.get()));
+ //Greater or equal
+ BOOST_TEST((pa >= nullptr) == (pa.get() >= (A*)nullptr));
+ BOOST_TEST((nullptr >= pa) == ((A*)nullptr >= pa.get()));
+ BOOST_TEST((pb >= nullptr) == (pb.get() >= (A*)nullptr));
+ BOOST_TEST((nullptr >= pb) == ((A*)nullptr >= pb.get()));
+ }
+ BOOST_TEST(A::count == 0);
+ #endif //#if !defined(BOOST_NO_CXX11_NULLPTR)
+}
+
+} //namespace unique_compare_nullptr{
+
+
+////////////////////////////////
+// main
+////////////////////////////////
+int main()
+{
+ make_unique_single::test();
+ make_unique_array::test();
+ unique_compare::test();
+ unique_compare_zero::test();
+ unique_compare_nullptr::test();
+
+ //Test results
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/move/test/unique_ptr_modifiers.cpp b/src/boost/libs/move/test/unique_ptr_modifiers.cpp
new file mode 100644
index 000000000..376c1044b
--- /dev/null
+++ b/src/boost/libs/move/test/unique_ptr_modifiers.cpp
@@ -0,0 +1,381 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (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/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant.
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+// unique_ptr_modifiers_release
+////////////////////////////////
+
+namespace unique_ptr_modifiers_release{
+
+void test()
+{
+ //Single unique_ptr
+ {
+ bml::unique_ptr<int> p(new int(3));
+ int* i = p.get();
+ int* j = p.release();
+ BOOST_TEST(p.get() == 0);
+ BOOST_TEST(i == j);
+ p.reset(j);
+ }
+ //Unbounded array unique_ptr
+ {
+ bml::unique_ptr<int[]> p(new int[2]);
+ int* i = p.get();
+ int* j = p.release();
+ BOOST_TEST(p.get() == 0);
+ BOOST_TEST(i == j);
+ p.reset(j);
+ }
+ //Bounded array unique_ptr
+ {
+ bml::unique_ptr<int[2]> p(new int[2]);
+ int* i = p.get();
+ int* j = p.release();
+ BOOST_TEST(p.get() == 0);
+ BOOST_TEST(i == j);
+ p.reset(j);
+ }
+}
+
+} //namespace unique_ptr_modifiers_release{
+
+////////////////////////////////
+// unique_ptr_modifiers_reset
+////////////////////////////////
+
+namespace unique_ptr_modifiers_reset{
+
+void test()
+{
+ //Single unique_ptr
+ {
+ reset_counters();
+ { //reset()
+ bml::unique_ptr<A> p(new A);
+ BOOST_TEST(A::count == 1);
+ A* i = p.get();
+ (void)i;
+ p.reset();
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ { //reset(p)
+ bml::unique_ptr<A> p(new A);
+ BOOST_TEST(A::count == 1);
+ A* i = p.get();
+ (void)i;
+ p.reset(new A);
+ BOOST_TEST(A::count == 1);
+ }
+ BOOST_TEST(A::count == 0);
+ { //reset(0)
+ bml::unique_ptr<A> p(new A);
+ BOOST_TEST(A::count == 1);
+ A* i = p.get();
+ (void)i;
+ p.reset(0);
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ }
+ //Unbounded array unique_ptr
+ {
+ reset_counters();
+ { //reset()
+ bml::unique_ptr<A[]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ A* i = p.get();
+ (void)i;
+ p.reset();
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ { //reset(p)
+ bml::unique_ptr<A[]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ A* i = p.get();
+ (void)i;
+ p.reset(new A[3]);
+ BOOST_TEST(A::count == 3);
+ }
+ BOOST_TEST(A::count == 0);
+ { //reset(0)
+ bml::unique_ptr<A[]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ A* i = p.get();
+ (void)i;
+ p.reset(0);
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ }
+ {
+ //Bounded array unique_ptr
+ reset_counters();
+ { //reset()
+ bml::unique_ptr<A[2]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ A* i = p.get();
+ (void)i;
+ p.reset();
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ { //reset(p)
+ bml::unique_ptr<A[2]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ A* i = p.get();
+ (void)i;
+ p.reset(new A[3]);
+ BOOST_TEST(A::count == 3);
+ }
+ BOOST_TEST(A::count == 0);
+ { //reset(0)
+ bml::unique_ptr<A[2]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ A* i = p.get();
+ (void)i;
+ p.reset(0);
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ }
+}
+
+} //namespace unique_ptr_modifiers_reset{
+
+////////////////////////////////
+// unique_ptr_modifiers_reset_convert
+////////////////////////////////
+
+namespace unique_ptr_modifiers_reset_convert{
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A> p(new A);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 0);
+ A* i = p.get();
+ (void)i;
+ p.reset(new B);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ {
+ bml::unique_ptr<A> p(new B);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ A* i = p.get();
+ (void)i;
+ p.reset(new B);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<const volatile A[2]> p(new const A[2]);
+ BOOST_TEST(A::count == 2);
+ const volatile A* i = p.get();
+ (void)i;
+ p.reset(new volatile A[3]);
+ BOOST_TEST(A::count == 3);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<const A[2]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ const A* i = p.get();
+ (void)i;
+ p.reset(new const A[3]);
+ BOOST_TEST(A::count == 3);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<const volatile A[2]> p(new const A[2]);
+ BOOST_TEST(A::count == 2);
+ const volatile A* i = p.get();
+ (void)i;
+ p.reset(new volatile A[3]);
+ BOOST_TEST(A::count == 3);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<const A[2]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ const A* i = p.get();
+ (void)i;
+ p.reset(new const A[3]);
+ BOOST_TEST(A::count == 3);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //unique_ptr_modifiers_reset_convert
+
+
+////////////////////////////////
+// unique_ptr_modifiers
+////////////////////////////////
+
+namespace unique_ptr_modifiers_swap{
+
+// test swap
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ A* p1 = new A(1);
+ move_constr_deleter<A> d1(1);
+ bml::unique_ptr<A, move_constr_deleter<A> > s1(p1, ::boost::move(d1));
+ A* p2 = new A(2);
+ move_constr_deleter<A> d2(2);
+ bml::unique_ptr<A, move_constr_deleter<A> > s2(p2, ::boost::move(d2));
+ BOOST_TEST(s1.get() == p1);
+ BOOST_TEST(*s1 == A(1));
+ BOOST_TEST(s1.get_deleter().state() == 1);
+ BOOST_TEST(s2.get() == p2);
+ BOOST_TEST(*s2 == A(2));
+ BOOST_TEST(s2.get_deleter().state() == 2);
+ boost::adl_move_swap(s1, s2);
+ BOOST_TEST(s1.get() == p2);
+ BOOST_TEST(*s1 == A(2));
+ BOOST_TEST(s1.get_deleter().state() == 2);
+ BOOST_TEST(s2.get() == p1);
+ BOOST_TEST(*s2 == A(1));
+ BOOST_TEST(s2.get_deleter().state() == 1);
+ }
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ A* p1 = new A[2];
+ p1[0].set(1);
+ p1[1].set(2);
+ move_constr_deleter<A[]> d1(1);
+ bml::unique_ptr<A[], move_constr_deleter<A[]> > s1(p1, ::boost::move(d1));
+ A* p2 = new A[2];
+ p2[0].set(3);
+ p2[1].set(4);
+ move_constr_deleter<A[]> d2(2);
+ bml::unique_ptr<A[], move_constr_deleter<A[]> > s2(p2, ::boost::move(d2));
+ BOOST_TEST(s1.get() == p1);
+ BOOST_TEST(s1[0] == A(1));
+ BOOST_TEST(s1[1] == A(2));
+ BOOST_TEST(s1.get_deleter().state() == 1);
+ BOOST_TEST(s2.get() == p2);
+ BOOST_TEST(s2[0] == A(3));
+ BOOST_TEST(s2[1] == A(4));
+ BOOST_TEST(s2.get_deleter().state() == 2);
+ swap(s1, s2);
+ BOOST_TEST(s1.get() == p2);
+ BOOST_TEST(s1[0] == A(3));
+ BOOST_TEST(s1[1] == A(4));
+ BOOST_TEST(s1.get_deleter().state() == 2);
+ BOOST_TEST(s2.get() == p1);
+ BOOST_TEST(s2[0] == A(1));
+ BOOST_TEST(s2[1] == A(2));
+ BOOST_TEST(s2.get_deleter().state() == 1);
+ }
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ A* p1 = new A[2];
+ p1[0].set(1);
+ p1[1].set(2);
+ move_constr_deleter<A[2]> d1(1);
+ bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s1(p1, ::boost::move(d1));
+ A* p2 = new A[2];
+ p2[0].set(3);
+ p2[1].set(4);
+ move_constr_deleter<A[2]> d2(2);
+ bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s2(p2, ::boost::move(d2));
+ BOOST_TEST(s1.get() == p1);
+ BOOST_TEST(s1[0] == A(1));
+ BOOST_TEST(s1[1] == A(2));
+ BOOST_TEST(s1.get_deleter().state() == 1);
+ BOOST_TEST(s2.get() == p2);
+ BOOST_TEST(s2[0] == A(3));
+ BOOST_TEST(s2[1] == A(4));
+ BOOST_TEST(s2.get_deleter().state() == 2);
+ swap(s1, s2);
+ BOOST_TEST(s1.get() == p2);
+ BOOST_TEST(s1[0] == A(3));
+ BOOST_TEST(s1[1] == A(4));
+ BOOST_TEST(s1.get_deleter().state() == 2);
+ BOOST_TEST(s2.get() == p1);
+ BOOST_TEST(s2[0] == A(1));
+ BOOST_TEST(s2[1] == A(2));
+ BOOST_TEST(s2.get_deleter().state() == 1);
+ }
+}
+
+} //namespace unique_ptr_modifiers_swap{
+
+////////////////////////////////
+// main
+////////////////////////////////
+int main()
+{
+ //Modifiers
+ unique_ptr_modifiers_release::test();
+ unique_ptr_modifiers_reset::test();
+ unique_ptr_modifiers_reset_convert::test();
+ unique_ptr_modifiers_swap::test();
+
+ //Test results
+ return boost::report_errors();
+
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/src/boost/libs/move/test/unique_ptr_movector.cpp b/src/boost/libs/move/test/unique_ptr_movector.cpp
new file mode 100644
index 000000000..ece216b2e
--- /dev/null
+++ b/src/boost/libs/move/test/unique_ptr_movector.cpp
@@ -0,0 +1,517 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (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/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant.
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+namespace bmupmu = ::boost::move_upmu;
+
+////////////////////////////////
+// unique_ptr_ctor_move_defdel
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_defdel{
+
+// test converting move ctor. Should only require a MoveConstructible deleter, or if
+// deleter is a reference, not even that.
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A> s(new A);
+ A* p = s.get();
+ bml::unique_ptr<A> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 1);
+ }
+ BOOST_TEST(A::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[]> s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<A[]> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[2]> s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<A[2]> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_move_defdel{
+
+////////////////////////////////
+// unique_ptr_ctor_move_movedel
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_movedel{
+
+// test converting move ctor. Should only require a MoveConstructible deleter, or if
+// deleter is a reference, not even that.
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A, move_constr_deleter<A> > s(new A);
+ A* p = s.get();
+ bml::unique_ptr<A, move_constr_deleter<A> > s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[], move_constr_deleter<A[]> > s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<A[], move_constr_deleter<A[]> > s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[2]> s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<A[2]> s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_move_movedel{
+
+////////////////////////////////
+// unique_ptr_ctor_move_dfctrdelref
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_dfctrdelref{
+
+// test converting move ctor. Should only require a MoveConstructible deleter, or if
+// deleter is a reference, not even that.
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ def_constr_deleter<A> d;
+ bml::unique_ptr<A, def_constr_deleter<A>&> s(new A, d);
+ A* p = s.get();
+ bml::unique_ptr<A, def_constr_deleter<A>&> s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 1);
+ d.set_state(6);
+ BOOST_TEST(s2.get_deleter().state() == d.state());
+ BOOST_TEST(s.get_deleter().state() == d.state());
+ }
+ BOOST_TEST(A::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ def_constr_deleter<A[]> d;
+ bml::unique_ptr<A[], def_constr_deleter<A[]>&> s(new A[2], d);
+ A* p = s.get();
+ bml::unique_ptr<A[], def_constr_deleter<A[]>&> s2 = boost::move(s);
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ d.set_state(6);
+ BOOST_TEST(s2.get_deleter().state() == d.state());
+ BOOST_TEST(s.get_deleter().state() == d.state());
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ def_constr_deleter<A[2]> d;
+ bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> s(new A[2], d);
+ A* p = s.get();
+ bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ d.set_state(6);
+ BOOST_TEST(s2.get_deleter().state() == d.state());
+ BOOST_TEST(s.get_deleter().state() == d.state());
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_move_dfctrdelref{
+
+////////////////////////////////
+// unique_ptr_ctor_move_convert_defdel
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_convert_defdel{
+
+// test converting move ctor. Should only require a MoveConstructible deleter, or if
+// deleter is a reference, not even that.
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<B> s(new B);
+ A* p = s.get();
+ bml::unique_ptr<A> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[]> s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<const volatile A[]> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ }
+ BOOST_TEST(A::count == 0);
+
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[2]> s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<const volatile A[2]> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A[2]> s(new A[2]);
+ A* p = s.get();
+ bml::unique_ptr<const volatile A[]> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_move_convert_defdel{
+
+////////////////////////////////
+// unique_ptr_ctor_move_convert_movedel
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_convert_movedel{
+
+// test converting move ctor. Should only require a MoveConstructible deleter, or if
+// deleter is a reference, not even that.
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ BOOST_STATIC_ASSERT((bmupmu::is_convertible<B, A>::value));
+ {
+ bml::unique_ptr<B, move_constr_deleter<B> > s(new B);
+ A* p = s.get();
+ bml::unique_ptr<A, move_constr_deleter<A> > s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<const A[], move_constr_deleter<const A[]> > s(new const A[2]);
+ const A* p = s.get();
+ bml::unique_ptr<const volatile A[], move_constr_deleter<const volatile A[]> > s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<const A[2], move_constr_deleter<const A[2]> > s(new const A[2]);
+ const A* p = s.get();
+ bml::unique_ptr<const volatile A[2], move_constr_deleter<const volatile A[2]> > s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ {
+ bml::unique_ptr<const A[2], move_constr_deleter<const A[2]> > s(new const A[2]);
+ const A* p = s.get();
+ bml::unique_ptr<const volatile A[], move_constr_deleter<const volatile A[]> > s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ BOOST_TEST(s2.get_deleter().state() == 5);
+ BOOST_TEST(s.get_deleter().state() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+}
+
+} //namespace unique_ptr_ctor_move_convert_movedel{
+
+////////////////////////////////
+// unique_ptr_ctor_move_convert_dfctrdelref
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_convert_dfctrdelref{
+
+// test converting move ctor. Should only require a MoveConstructible deleter, or if
+// deleter is a reference, not even that.
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ def_constr_deleter<A> d;
+ bml::unique_ptr<B, def_constr_deleter<A>&> s(new B, d);
+ A* p = s.get();
+ bml::unique_ptr<A, def_constr_deleter<A>&> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 1);
+ BOOST_TEST(B::count == 1);
+ d.set_state(6);
+ BOOST_TEST(s2.get_deleter().state() == d.state());
+ BOOST_TEST(s.get_deleter().state() == d.state());
+ }
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(B::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ def_constr_deleter<volatile A[]> d;
+ bml::unique_ptr<A[], def_constr_deleter<volatile A[]>&> s(new A[2], d);
+ A* p = s.get();
+ bml::unique_ptr<volatile A[], def_constr_deleter<volatile A[]>&> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ d.set_state(6);
+ BOOST_TEST(s2.get_deleter().state() == d.state());
+ BOOST_TEST(s.get_deleter().state() == d.state());
+ }
+ BOOST_TEST(A::count == 0);
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ def_constr_deleter<volatile A[2]> d;
+ bml::unique_ptr<A[2], def_constr_deleter<volatile A[2]>&> s(new A[2], d);
+ A* p = s.get();
+ bml::unique_ptr<volatile A[2], def_constr_deleter<volatile A[2]>&> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ d.set_state(6);
+ BOOST_TEST(s2.get_deleter().state() == d.state());
+ BOOST_TEST(s.get_deleter().state() == d.state());
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ def_constr_deleter<volatile A[]> d;
+ bml::unique_ptr<A[2], def_constr_deleter<volatile A[]>&> s(new A[2], d);
+ A* p = s.get();
+ bml::unique_ptr<volatile A[], def_constr_deleter<volatile A[]>&> s2(boost::move(s));
+ BOOST_TEST(s2.get() == p);
+ BOOST_TEST(s.get() == 0);
+ BOOST_TEST(A::count == 2);
+ d.set_state(6);
+ BOOST_TEST(s2.get_deleter().state() == d.state());
+ BOOST_TEST(s.get_deleter().state() == d.state());
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_move_convert_dfctrdelref{
+
+////////////////////////////////
+// unique_ptr_ctor_move_sourcesink
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_sourcesink{
+
+// test move ctor. Should only require a MoveConstructible deleter, or if
+// deleter is a reference, not even that.
+
+bml::unique_ptr<A> source1()
+{ return bml::unique_ptr<A>(new A); }
+
+bml::unique_ptr<A[]> source1_unbounded_array()
+{ return bml::unique_ptr<A[]> (new A[2]); }
+
+bml::unique_ptr<A[2]> source1_bounded_array()
+{ return bml::unique_ptr<A[2]> (new A[2]); }
+
+void sink1(bml::unique_ptr<A>)
+{}
+
+void sink1_unbounded_array(bml::unique_ptr<A[]>)
+{}
+
+void sink1_bounded_array(bml::unique_ptr<A[2]>)
+{}
+
+bml::unique_ptr<A, move_constr_deleter<A> > source2()
+{ return bml::unique_ptr<A, move_constr_deleter<A> > (new A); }
+
+bml::unique_ptr<A[], move_constr_deleter<A[]> > source2_unbounded_array()
+{ return bml::unique_ptr<A[], move_constr_deleter<A[]> >(new A[2]); }
+
+bml::unique_ptr<A[2], move_constr_deleter<A[2]> > source2_bounded_array()
+{ return bml::unique_ptr<A[2], move_constr_deleter<A[2]> >(new A[2]); }
+
+void sink2(bml::unique_ptr<A, move_constr_deleter<A> >)
+{}
+
+void sink2_unbounded_array(bml::unique_ptr<A[], move_constr_deleter<A[]> >)
+{}
+
+void sink2_bounded_array(bml::unique_ptr<A[2], move_constr_deleter<A[2]> >)
+{}
+
+bml::unique_ptr<A, def_constr_deleter<A>&> source3()
+{
+ static def_constr_deleter<A> d;
+ return bml::unique_ptr<A, def_constr_deleter<A>&>(new A, d);
+}
+
+bml::unique_ptr<A[], def_constr_deleter<A[]>&> source3_unbounded_array()
+{
+ static def_constr_deleter<A[]> d;
+ return bml::unique_ptr<A[], def_constr_deleter<A[]>&>(new A[2], d);
+}
+
+bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> source3_bounded_array()
+{
+ static def_constr_deleter<A[2]> d;
+ return bml::unique_ptr<A[2], def_constr_deleter<A[2]>&>(new A[2], d);
+}
+
+void sink3(bml::unique_ptr<A, def_constr_deleter<A>&> )
+{}
+
+void sink3_unbounded_array(bml::unique_ptr<A[], def_constr_deleter<A[]>&> )
+{}
+
+void sink3_bounded_array(bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> )
+{}
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ sink1(source1());
+ sink2(source2());
+ sink3(source3());
+ BOOST_TEST(A::count == 0);
+ //Unbounded array unique_ptr
+ reset_counters();
+ sink1_unbounded_array(source1_unbounded_array());
+ sink2_unbounded_array(source2_unbounded_array());
+ sink3_unbounded_array(source3_unbounded_array());
+ BOOST_TEST(A::count == 0);
+ //Bbounded array unique_ptr
+ reset_counters();
+ sink1_bounded_array(source1_bounded_array());
+ sink2_bounded_array(source2_bounded_array());
+ sink3_bounded_array(source3_bounded_array());
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_ctor_move_sourcesink{
+
+////////////////////////////////
+// main
+////////////////////////////////
+int main()
+{
+ //Move Constructor
+ unique_ptr_ctor_move_defdel::test();
+ unique_ptr_ctor_move_movedel::test();
+ unique_ptr_ctor_move_dfctrdelref::test();
+ unique_ptr_ctor_move_convert_defdel::test();
+ unique_ptr_ctor_move_convert_movedel::test();
+ unique_ptr_ctor_move_convert_dfctrdelref::test();
+ unique_ptr_ctor_move_sourcesink::test();
+
+ //Test results
+ return boost::report_errors();
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/src/boost/libs/move/test/unique_ptr_nullptr.cpp b/src/boost/libs/move/test/unique_ptr_nullptr.cpp
new file mode 100644
index 000000000..555fcc20c
--- /dev/null
+++ b/src/boost/libs/move/test/unique_ptr_nullptr.cpp
@@ -0,0 +1,228 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (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/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant.
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+// unique_ptr_zero
+////////////////////////////////
+namespace unique_ptr_zero {
+
+// test initialization/assignment from zero
+
+void test()
+{
+ //Single unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A> s2(0);
+ BOOST_TEST(A::count == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A> s2(new A);
+ BOOST_TEST(A::count == 1);
+ s2 = 0;
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(s2.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+
+ //Unbounded array unique_ptr
+ {
+ bml::unique_ptr<A[]> s2(0);
+ BOOST_TEST(A::count == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A[]> s2(new A[2]);
+ BOOST_TEST(A::count == 2);
+ s2 = 0;
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(s2.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+
+ //Bounded array unique_ptr
+ {
+ bml::unique_ptr<A[2]> s2(0);
+ BOOST_TEST(A::count == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A[2]> s2(new A[2]);
+ BOOST_TEST(A::count == 2);
+ s2 = 0;
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(s2.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+}
+
+} //namespace unique_ptr_zero {
+
+
+////////////////////////////////
+// unique_ptr_nullptr
+////////////////////////////////
+
+namespace unique_ptr_nullptr{
+
+void test()
+{
+ #if !defined(BOOST_NO_CXX11_NULLPTR)
+ //Single unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A> p(new A);
+ BOOST_TEST(A::count == 1);
+ A* i = p.get();
+ (void)i;
+ p.reset(nullptr);
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A> p(new A);
+ BOOST_TEST(A::count == 1);
+ A* i = p.get();
+ (void)i;
+ p = nullptr;
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+
+ {
+ bml::unique_ptr<A> pi(nullptr);
+ BOOST_TEST(pi.get() == nullptr);
+ BOOST_TEST(pi.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A> pi(nullptr, bml::unique_ptr<A>::deleter_type());
+ BOOST_TEST(pi.get() == nullptr);
+ BOOST_TEST(pi.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+
+ //Unbounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ A* i = p.get();
+ (void)i;
+ p.reset(nullptr);
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A[]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ A* i = p.get();
+ (void)i;
+ p = nullptr;
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A[]> pi(nullptr);
+ BOOST_TEST(pi.get() == nullptr);
+ BOOST_TEST(pi.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A[]> pi(nullptr, bml::unique_ptr<A[]>::deleter_type());
+ BOOST_TEST(pi.get() == nullptr);
+ BOOST_TEST(pi.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+
+ //Bounded array unique_ptr
+ reset_counters();
+ {
+ bml::unique_ptr<A[2]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ A* i = p.get();
+ (void)i;
+ p.reset(nullptr);
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A[2]> p(new A[2]);
+ BOOST_TEST(A::count == 2);
+ A* i = p.get();
+ (void)i;
+ p = nullptr;
+ BOOST_TEST(A::count == 0);
+ BOOST_TEST(p.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A[2]> pi(nullptr);
+ BOOST_TEST(pi.get() == nullptr);
+ BOOST_TEST(pi.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr<A[2]> pi(nullptr, bml::unique_ptr<A[2]>::deleter_type());
+ BOOST_TEST(pi.get() == nullptr);
+ BOOST_TEST(pi.get() == 0);
+ }
+ BOOST_TEST(A::count == 0);
+ #endif
+}
+
+} //namespace unique_ptr_nullptr{
+
+////////////////////////////////
+// main
+////////////////////////////////
+int main()
+{
+ //nullptr
+ unique_ptr_zero::test();
+ unique_ptr_nullptr::test();
+
+ //Test results
+ return boost::report_errors();
+
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/src/boost/libs/move/test/unique_ptr_observers.cpp b/src/boost/libs/move/test/unique_ptr_observers.cpp
new file mode 100644
index 000000000..14376a0bb
--- /dev/null
+++ b/src/boost/libs/move/test/unique_ptr_observers.cpp
@@ -0,0 +1,287 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (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/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant.
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+// unique_ptr_observers_dereference
+////////////////////////////////
+
+namespace unique_ptr_observers_dereference{
+
+void test()
+{
+ //Single unique_ptr
+ {
+ bml::unique_ptr<int> p(new int(3));
+ BOOST_TEST(*p == 3);
+ }
+ //Unbounded array unique_ptr
+ {
+ int *pi = new int[2];
+ pi[0] = 3;
+ pi[1] = 4;
+ bml::unique_ptr<int[]> p(pi);
+ BOOST_TEST(p[0] == 3);
+ BOOST_TEST(p[1] == 4);
+ }
+ //Bounded array unique_ptr
+ {
+ int *pi = new int[2];
+ pi[0] = 3;
+ pi[1] = 4;
+ bml::unique_ptr<int[2]> p(pi);
+ BOOST_TEST(p[0] == 3);
+ BOOST_TEST(p[1] == 4);
+ }
+}
+
+} //namespace unique_ptr_observers_dereference{
+
+////////////////////////////////
+// unique_ptr_observers_dereference
+////////////////////////////////
+
+namespace unique_ptr_observers_explicit_bool{
+
+void test()
+{
+ //Single unique_ptr
+ {
+ bml::unique_ptr<int> p(new int(3));
+ if (p)
+ ;
+ else
+ BOOST_TEST(false);
+ if (!p)
+ BOOST_TEST(false);
+ }
+ {
+ bml::unique_ptr<int> p;
+ if (!p)
+ ;
+ else
+ BOOST_TEST(false);
+ if (p)
+ BOOST_TEST(false);
+ }
+ //Unbounded array unique_ptr
+ {
+ bml::unique_ptr<int[]> p(new int[2]);
+ if (p)
+ ;
+ else
+ BOOST_TEST(false);
+ if (!p)
+ BOOST_TEST(false);
+ }
+ {
+ bml::unique_ptr<int[]> p;
+ if (!p)
+ ;
+ else
+ BOOST_TEST(false);
+ if (p)
+ BOOST_TEST(false);
+ }
+ //Bounded array unique_ptr
+ {
+ bml::unique_ptr<int[2]> p(new int[2]);
+ if (p)
+ ;
+ else
+ BOOST_TEST(false);
+ if (!p)
+ BOOST_TEST(false);
+ }
+ {
+ bml::unique_ptr<int[2]> p;
+ if (!p)
+ ;
+ else
+ BOOST_TEST(false);
+ if (p)
+ BOOST_TEST(false);
+ }
+}
+
+} //namespace unique_ptr_observers_explicit_bool{
+
+////////////////////////////////
+// unique_ptr_observers_get
+////////////////////////////////
+
+namespace unique_ptr_observers_get{
+
+void test()
+{
+ //Single unique_ptr
+ {
+ int* p = new int;
+ bml::unique_ptr<int> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ //Unbounded array unique_ptr
+ {
+ int* p = new int[2];
+ bml::unique_ptr<int[]> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ {
+ int* p = new int[2];
+ bml::unique_ptr<int[2]> s(p);
+ BOOST_TEST(s.get() == p);
+ }
+ //Bounded array unique_ptr
+ {
+ int *pi = new int[2];
+ pi[0] = 3;
+ pi[1] = 4;
+ bml::unique_ptr<int[2]> p(pi);
+ BOOST_TEST(p[0] == 3);
+ BOOST_TEST(p[1] == 4);
+ }
+}
+
+} //namespace unique_ptr_observers_get{
+
+////////////////////////////////
+// unique_ptr_observers_get_deleter
+////////////////////////////////
+
+namespace unique_ptr_observers_get_deleter{
+
+struct Deleter
+{
+ void operator()(void*) {}
+
+ int test() {return 5;}
+ int test() const {return 6;}
+};
+
+void test()
+{
+ //Single unique_ptr
+ {
+ bml::unique_ptr<int, Deleter> p;
+ BOOST_TEST(p.get_deleter().test() == 5);
+ }
+ {
+ const bml::unique_ptr<int, Deleter> p;
+ BOOST_TEST(p.get_deleter().test() == 6);
+ }
+ //Unbounded array unique_ptr
+ {
+ bml::unique_ptr<int[], Deleter> p;
+ BOOST_TEST(p.get_deleter().test() == 5);
+ }
+ {
+ const bml::unique_ptr<int[], Deleter> p;
+ BOOST_TEST(p.get_deleter().test() == 6);
+ }
+ //Bounded array unique_ptr
+ {
+ bml::unique_ptr<int[2], Deleter> p;
+ BOOST_TEST(p.get_deleter().test() == 5);
+ }
+ {
+ const bml::unique_ptr<int[2], Deleter> p;
+ BOOST_TEST(p.get_deleter().test() == 6);
+ }
+}
+
+} //namespace unique_ptr_observers_get_deleter{
+
+////////////////////////////////
+// unique_ptr_observers_op_arrow
+////////////////////////////////
+
+namespace unique_ptr_observers_op_arrow{
+
+void test()
+{
+ //Single unique_ptr
+ {
+ bml::unique_ptr<A> p(new A);
+ BOOST_TEST(p->state_ == 999);
+ }
+}
+
+} //namespace unique_ptr_observers_op_arrow{
+
+
+namespace unique_ptr_observers_op_index{
+
+void test()
+{
+ //Unbounded array unique_ptr
+ {
+ A *pa = new A[2];
+ //pa[0] is left default constructed
+ pa[1].set(888);
+ bml::unique_ptr<A[]> p(pa);
+ BOOST_TEST(p[0].state_ == 999);
+ BOOST_TEST(p[1].state_ == 888);
+ }
+ //Bounded array unique_ptr
+ {
+ A *pa = new A[2];
+ //pa[0] is left default constructed
+ pa[1].set(888);
+ bml::unique_ptr<A[2]> p(pa);
+ BOOST_TEST(p[0].state_ == 999);
+ BOOST_TEST(p[1].state_ == 888);
+ }
+}
+
+} //namespace unique_ptr_observers_op_index{
+
+////////////////////////////////
+// main
+////////////////////////////////
+int main()
+{
+ //Observers
+ unique_ptr_observers_dereference::test();
+ unique_ptr_observers_explicit_bool::test();
+ unique_ptr_observers_get::test();
+ unique_ptr_observers_get_deleter::test();
+ unique_ptr_observers_op_arrow::test();
+ unique_ptr_observers_op_index::test();
+
+ //Test results
+ return boost::report_errors();
+
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/src/boost/libs/move/test/unique_ptr_test_utils_beg.hpp b/src/boost/libs/move/test/unique_ptr_test_utils_beg.hpp
new file mode 100644
index 000000000..965732c05
--- /dev/null
+++ b/src/boost/libs/move/test/unique_ptr_test_utils_beg.hpp
@@ -0,0 +1,209 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (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_UNIQUE_PTR_TEST_UTILS_BEG_HPP
+#define BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
+#include <boost/move/core.hpp>
+#include <boost/move/detail/unique_ptr_meta_utils.hpp>
+#include <boost/static_assert.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant.
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+//A deleter that can only default constructed
+template <class T>
+class def_constr_deleter
+{
+ int state_;
+ def_constr_deleter(const def_constr_deleter&);
+ def_constr_deleter& operator=(const def_constr_deleter&);
+
+ public:
+ typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
+ static const bool is_array = ::boost::move_upmu::is_array<T>::value;
+
+ def_constr_deleter() : state_(5) {}
+
+ explicit def_constr_deleter(int s) : state_(s) {}
+
+ int state() const {return state_;}
+
+ void set_state(int s) {state_ = s;}
+
+ void operator()(element_type* p) const
+ { is_array ? delete []p : delete p; }
+
+ void operator()(element_type* p)
+ { ++state_; is_array ? delete []p : delete p; }
+};
+
+//A deleter that can be copy constructed
+template <class T>
+class copy_constr_deleter
+{
+ int state_;
+
+ public:
+ typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
+ static const bool is_array = ::boost::move_upmu::is_array<T>::value;
+
+ copy_constr_deleter() : state_(5) {}
+
+ template<class U>
+ copy_constr_deleter(const copy_constr_deleter<U>&
+ , typename boost::move_upd::enable_def_del<U, T>::type* =0)
+ { state_ = 5; }
+
+ explicit copy_constr_deleter(int s) : state_(s) {}
+
+ template <class U>
+ typename boost::move_upd::enable_def_del<U, T, copy_constr_deleter&>::type
+ operator=(const copy_constr_deleter<U> &d)
+ {
+ state_ = d.state();
+ return *this;
+ }
+
+ int state() const {return state_;}
+
+ void set_state(int s) {state_ = s;}
+
+ void operator()(element_type* p) const
+ { is_array ? delete []p : delete p; }
+
+ void operator()(element_type* p)
+ { ++state_; is_array ? delete []p : delete p; }
+};
+
+//A deleter that can be only move constructed
+template <class T>
+class move_constr_deleter
+{
+ int state_;
+
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(move_constr_deleter)
+
+ public:
+ typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
+ static const bool is_array = ::boost::move_upmu::is_array<T>::value;
+
+ move_constr_deleter() : state_(5) {}
+
+ move_constr_deleter(BOOST_RV_REF(move_constr_deleter) r)
+ : state_(r.state_)
+ { r.state_ = 0; }
+
+ explicit move_constr_deleter(int s) : state_(s) {}
+
+ template <class U>
+ move_constr_deleter(BOOST_RV_REF(move_constr_deleter<U>) d
+ , typename boost::move_upd::enable_def_del<U, T>::type* =0)
+ : state_(d.state())
+ { d.set_state(0); }
+
+ move_constr_deleter& operator=(BOOST_RV_REF(move_constr_deleter) r)
+ {
+ state_ = r.state_;
+ r.state_ = 0;
+ return *this;
+ }
+
+ template <class U>
+ typename boost::move_upd::enable_def_del<U, T, move_constr_deleter&>::type
+ operator=(BOOST_RV_REF(move_constr_deleter<U>) d)
+ {
+ state_ = d.state();
+ d.set_state(0);
+ return *this;
+ }
+
+ int state() const {return state_;}
+
+ void set_state(int s) {state_ = s;}
+
+ void operator()(element_type* p) const
+ { is_array ? delete []p : delete p; }
+
+ void operator()(element_type* p)
+ { ++state_; is_array ? delete []p : delete p; }
+
+ friend bool operator==(const move_constr_deleter& x, const move_constr_deleter& y)
+ {return x.state_ == y.state_;}
+};
+
+//A base class containing state with a static instance counter
+struct A
+{
+ int state_;
+ static int count;
+
+ A() : state_(999) {++count;}
+ explicit A(int i) : state_(i) {++count;}
+ A(const A& a) : state_(a.state_) {++count;}
+ A& operator=(const A& a) { state_ = a.state_; return *this; }
+ void set(int i) {state_ = i;}
+ virtual ~A() {--count;}
+ friend bool operator==(const A& x, const A& y) { return x.state_ == y.state_; }
+};
+
+int A::count = 0;
+
+//A class derived from A with a static instance counter
+struct B
+ : public A
+{
+ static int count;
+ B() : A() {++count;}
+ B(const B &b) : A(b) {++count;}
+ virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+void reset_counters();
+
+BOOST_STATIC_ASSERT((::boost::move_upmu::is_convertible<B, A>::value));
+
+//Incomplete Type function declarations
+struct I;
+void check(int i);
+I* get();
+I* get_array(int i);
+
+#include <boost/move/unique_ptr.hpp>
+
+template <class T, class D = ::boost::movelib::default_delete<T> >
+struct J
+{
+ typedef boost::movelib::unique_ptr<T, D> unique_ptr_type;
+ typedef typename unique_ptr_type::element_type element_type;
+ boost::movelib::unique_ptr<T, D> a_;
+ J() {}
+ explicit J(element_type*a) : a_(a) {}
+ ~J();
+
+ element_type* get() const {return a_.get();}
+ D& get_deleter() {return a_.get_deleter();}
+};
+
+#endif //BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
diff --git a/src/boost/libs/move/test/unique_ptr_test_utils_end.hpp b/src/boost/libs/move/test/unique_ptr_test_utils_end.hpp
new file mode 100644
index 000000000..ca0fb9201
--- /dev/null
+++ b/src/boost/libs/move/test/unique_ptr_test_utils_end.hpp
@@ -0,0 +1,46 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (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_UNIQUE_PTR_TEST_UTILS_END_HPP
+#define BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_END_HPP
+
+#ifndef BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
+#error "unique_ptr_test_utils_beg.hpp MUST be included before this header"
+#endif
+
+//Define the incomplete I type and out of line functions
+
+struct I
+{
+ static int count;
+ I() {++count;}
+ I(const A&) {++count;}
+ ~I() {--count;}
+};
+
+int I::count = 0;
+
+I* get() {return new I;}
+I* get_array(int i) {return new I[i];}
+
+void check(int i)
+{
+ BOOST_TEST(I::count == i);
+}
+
+template <class T, class D>
+J<T, D>::~J() {}
+
+void reset_counters()
+{ A::count = 0; B::count = 0; I::count = 0; }
+
+#endif //BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_END_HPP
diff --git a/src/boost/libs/move/test/unique_ptr_types.cpp b/src/boost/libs/move/test/unique_ptr_types.cpp
new file mode 100644
index 000000000..7dbc0c376
--- /dev/null
+++ b/src/boost/libs/move/test/unique_ptr_types.cpp
@@ -0,0 +1,200 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (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/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/move/detail/type_traits.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant.
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+namespace bmupmu = ::boost::move_upmu;
+
+////////////////////////////////
+// unique_ptr_pointer_type
+////////////////////////////////
+namespace unique_ptr_pointer_type {
+
+struct Deleter
+{
+ struct pointer {};
+};
+
+// Test unique_ptr::pointer type
+void test()
+{
+ //Single unique_ptr
+ {
+ typedef bml::unique_ptr<int> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, int*>::value));
+ }
+ {
+ typedef bml::unique_ptr<int, Deleter> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, Deleter::pointer>::value));
+ }
+ //Unbounded array unique_ptr
+ {
+ typedef bml::unique_ptr<int[]> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, int*>::value));
+ }
+ {
+ typedef bml::unique_ptr<int[], Deleter> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, Deleter::pointer>::value));
+ }
+ //Bounded array unique_ptr
+ {
+ typedef bml::unique_ptr<int[5]> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, int*>::value));
+ }
+ {
+ typedef bml::unique_ptr<int[5], Deleter> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, Deleter::pointer>::value));
+ }
+ //Unbounded array of bounded array unique_ptr
+ {
+ typedef int int_5_t [5];
+ typedef bml::unique_ptr<int_5_t[]> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, int_5_t*>::value));
+ }
+ {
+ typedef int int_5_t [5];
+ typedef bml::unique_ptr<int_5_t[], Deleter> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, Deleter::pointer>::value));
+ }
+}
+
+} //namespace unique_ptr_pointer_type {
+
+////////////////////////////////
+// unique_ptr_deleter_type
+////////////////////////////////
+namespace unique_ptr_deleter_type {
+
+struct Deleter
+{};
+
+// Test unique_ptr::deleter type
+void test()
+{
+ //Single unique_ptr
+ {
+ typedef bml::unique_ptr<int> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, bml::default_delete<int> >::value));
+ }
+ {
+ typedef bml::unique_ptr<int, Deleter> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, Deleter >::value));
+ }
+ //Unbounded array unique_ptr
+ {
+ typedef bml::unique_ptr<int[]> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, bml::default_delete<int[]> >::value));
+ }
+ {
+ typedef bml::unique_ptr<int[], Deleter> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, Deleter >::value));
+ }
+ //Bounded array unique_ptr
+ {
+ typedef bml::unique_ptr<int[2]> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, bml::default_delete<int[2]> >::value));
+ }
+ {
+ typedef bml::unique_ptr<int[2], Deleter> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, Deleter >::value));
+ }
+}
+
+} //namespace unique_ptr_deleter_type {
+
+////////////////////////////////
+// unique_ptr_element_type
+////////////////////////////////
+namespace unique_ptr_element_type {
+
+// Test unique_ptr::deleter type
+void test()
+{
+ //Single unique_ptr
+ {
+ typedef bml::unique_ptr<const int> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::element_type, const int>::value));
+ }
+ //Unbounded array unique_ptr
+ {
+ typedef bml::unique_ptr<const int[]> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::element_type, const int>::value));
+ }
+ //Bounded array unique_ptr
+ {
+ typedef bml::unique_ptr<const int[2]> P;
+ BOOST_STATIC_ASSERT((bmupmu::is_same<P::element_type, const int>::value));
+ }
+}
+
+} //namespace unique_ptr_element_type {
+
+////////////////////////////////
+// unique_ptr_construct_assign_traits
+////////////////////////////////
+
+namespace unique_ptr_construct_assign_traits {
+
+ void test()
+ {
+ typedef bml::unique_ptr<int> unique_ptr_t;
+ //Even if BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE is not defined
+ //boost::unique_ptr shall work with boost::movelib traits
+ BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_constructible<unique_ptr_t>::value));
+ //Even if BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE is not defined
+ //boost::unique_ptr shall work with boost::movelib traits
+ BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_assignable<unique_ptr_t>::value));
+ //Important traits for containers like boost::vector
+ BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible<unique_ptr_t>::value));
+ BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable<unique_ptr_t>::value));
+ }
+
+} //namespace unique_ptr_construct_assign_traits {
+
+////////////////////////////////
+// main
+////////////////////////////////
+
+int main()
+{
+ //General
+ unique_ptr_pointer_type::test();
+ unique_ptr_deleter_type::test();
+ unique_ptr_element_type::test();
+ unique_ptr_construct_assign_traits::test();
+
+ //Test results
+ return boost::report_errors();
+}
+
+#include "unique_ptr_test_utils_end.hpp"