////////////////////////////////////////////////////////////////////////////// // // (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 #include #include #include ////////////////////////////////////////////// // // 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 d; BOOST_TEST(d.state() == 5); { bml::unique_ptr&> 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 d; BOOST_TEST(d.state() == 5); { bml::unique_ptr&> 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 d; BOOST_TEST(d.state() == 5); { bml::unique_ptr&> 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 p; BOOST_TEST(p.get() == 0); } { bml::unique_ptr > p; BOOST_TEST(p.get() == 0); BOOST_TEST(p.get_deleter().state() == 5); } //Unbounded array unique_ptr { bml::unique_ptr p; BOOST_TEST(p.get() == 0); } { bml::unique_ptr > p; BOOST_TEST(p.get() == 0); BOOST_TEST(p.get_deleter().state() == 5); } //Unbounded array unique_ptr { bml::unique_ptr p; BOOST_TEST(p.get() == 0); } { bml::unique_ptr > p; BOOST_TEST(p.get() == 0); BOOST_TEST(p.get_deleter().state() == 5); } //Unbounded array unique_ptr { bml::unique_ptr p; BOOST_TEST(p.get() == 0); } { bml::unique_ptr > 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 s; BOOST_TEST(s.get() == 0); } check(0); { J > s; BOOST_TEST(s.get() == 0); BOOST_TEST(s.get_deleter().state() == 5); } check(0); //Unbounded array unique_ptr reset_counters(); { J s; BOOST_TEST(s.get() == 0); } check(0); { J > s; BOOST_TEST(s.get() == 0); BOOST_TEST(s.get_deleter().state() == 5); } check(0); //Bounded array unique_ptr reset_counters(); { J s; BOOST_TEST(s.get() == 0); } check(0); { J > 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 s(p); BOOST_TEST(s.get() == p); } BOOST_TEST(A::count == 0); { A* p = new A; BOOST_TEST(A::count == 1); bml::unique_ptr > 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 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 > 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 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 > 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 s(p); BOOST_TEST(s.get() == p); } check(0); { I* p = get(); check(1); J > 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 s(p); BOOST_TEST(s.get() == p); } check(0); { I* p = get_array(2); check(2); J > 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 s(p); BOOST_TEST(s.get() == p); } check(0); { I* p = get_array(2); check(2); J > 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 void test() { //Single unique_ptr reset_counters(); { B* p = new B; BOOST_TEST(A::count == 1); BOOST_TEST(B::count == 1); bml::unique_ptr 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 > 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 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 > 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 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 > 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 d; bml::unique_ptr > s(p, ::boost::move(d)); BOOST_TEST(s.get() == p); BOOST_TEST(s.get_deleter().state() == 5); bml::unique_ptr > s2(s.release(), move_constr_deleter(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 d; bml::unique_ptr > s(p, ::boost::move(d)); BOOST_TEST(s.get() == p); BOOST_TEST(s.get_deleter().state() == 5); bml::unique_ptr > s2(s.release(), move_constr_deleter(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 d; bml::unique_ptr > s(p, ::boost::move(d)); BOOST_TEST(s.get() == p); BOOST_TEST(s.get_deleter().state() == 5); bml::unique_ptr > s2(s.release(), move_constr_deleter(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 d; bml::unique_ptr > 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 d; bml::unique_ptr > 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 d; bml::unique_ptr > 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(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 d; bml::unique_ptr&> 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 d; bml::unique_ptr&> 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 d; bml::unique_ptr&> 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(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 d; bml::unique_ptr&> 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 d; bml::unique_ptr&> 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 d; bml::unique_ptr&> 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 > s(p, copy_constr_deleter()); 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 > s(p, copy_constr_deleter()); 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 > s(p, copy_constr_deleter()); 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 should work bool my_free_called = false; void my_free(void*) { my_free_called = true; } void test() { { int i = 0; bml::unique_ptr 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 bml::unique_ptr make_unique_ptr_of_t() { return bml::unique_ptr(new T); } template bml::unique_ptr return_const_unique_of_t() { return bml::unique_ptr (make_unique_ptr_of_t()); } void test() { reset_counters(); BOOST_TEST(A::count == 0); { bml::unique_ptr p(return_const_unique_of_t()); BOOST_TEST(A::count == 1); BOOST_TEST(B::count == 0); } BOOST_TEST(A::count == 0); { bml::unique_ptr p(return_const_unique_of_t()); 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 bml::unique_ptr return_unique_array_of_t(std::size_t n) { return bml::unique_ptr(new T[n]); } template bml::unique_ptr return_const_array_of_t(std::size_t n) { return bml::unique_ptr(return_unique_array_of_t(n)); } template bml::unique_ptr return_unique_array_of_t_2() { return bml::unique_ptr(new T[2]); } template bml::unique_ptr return_const_array_of_t_2() { return bml::unique_ptr(return_unique_array_of_t_2()); } void test() { reset_counters(); BOOST_TEST(A::count == 0); { bml::unique_ptr p(return_unique_array_of_t(2)); BOOST_TEST(A::count == 2); BOOST_TEST(B::count == 0); } BOOST_TEST(A::count == 0); { bml::unique_ptr p(return_unique_array_of_t(2)); BOOST_TEST(A::count == 2); BOOST_TEST(B::count == 0); } BOOST_TEST(A::count == 0); { bml::unique_ptr p(return_const_array_of_t_2()); BOOST_TEST(A::count == 2); BOOST_TEST(B::count == 0); } BOOST_TEST(A::count == 0); { bml::unique_ptr p(return_const_array_of_t_2()); 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"