////////////////////////////////////////////////////////////////////////////// // // (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; 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 s(new A); A* p = s.get(); bml::unique_ptr 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 s(new A[2]); A* p = s.get(); bml::unique_ptr 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 s(new A[2]); A* p = s.get(); bml::unique_ptr 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 > s(new A); A* p = s.get(); bml::unique_ptr > 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 > s(new A[2]); A* p = s.get(); bml::unique_ptr > 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 s(new A[2]); A* p = s.get(); bml::unique_ptr 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 d; bml::unique_ptr&> s(new A, d); A* p = s.get(); bml::unique_ptr&> 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 d; bml::unique_ptr&> s(new A[2], d); A* p = s.get(); bml::unique_ptr&> 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 d; bml::unique_ptr&> s(new A[2], d); A* p = s.get(); bml::unique_ptr&> 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 s(new B); A* p = s.get(); bml::unique_ptr 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 s(new A[2]); A* p = s.get(); bml::unique_ptr 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 s(new A[2]); A* p = s.get(); bml::unique_ptr 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 s(new A[2]); A* p = s.get(); bml::unique_ptr 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::value)); { bml::unique_ptr > s(new B); A* p = s.get(); bml::unique_ptr > 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 > s(new const A[2]); const A* p = s.get(); bml::unique_ptr > 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 > s(new const A[2]); const A* p = s.get(); bml::unique_ptr > 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 > s(new const A[2]); const A* p = s.get(); bml::unique_ptr > 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 d; bml::unique_ptr&> s(new B, d); A* p = s.get(); bml::unique_ptr&> 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 d; bml::unique_ptr&> s(new A[2], d); A* p = s.get(); bml::unique_ptr&> 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 d; bml::unique_ptr&> s(new A[2], d); A* p = s.get(); bml::unique_ptr&> 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 d; bml::unique_ptr&> s(new A[2], d); A* p = s.get(); bml::unique_ptr&> 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 source1() { return bml::unique_ptr(new A); } bml::unique_ptr source1_unbounded_array() { return bml::unique_ptr (new A[2]); } bml::unique_ptr source1_bounded_array() { return bml::unique_ptr (new A[2]); } void sink1(bml::unique_ptr) {} void sink1_unbounded_array(bml::unique_ptr) {} void sink1_bounded_array(bml::unique_ptr) {} bml::unique_ptr > source2() { return bml::unique_ptr > (new A); } bml::unique_ptr > source2_unbounded_array() { return bml::unique_ptr >(new A[2]); } bml::unique_ptr > source2_bounded_array() { return bml::unique_ptr >(new A[2]); } void sink2(bml::unique_ptr >) {} void sink2_unbounded_array(bml::unique_ptr >) {} void sink2_bounded_array(bml::unique_ptr >) {} bml::unique_ptr&> source3() { static def_constr_deleter d; return bml::unique_ptr&>(new A, d); } bml::unique_ptr&> source3_unbounded_array() { static def_constr_deleter d; return bml::unique_ptr&>(new A[2], d); } bml::unique_ptr&> source3_bounded_array() { static def_constr_deleter d; return bml::unique_ptr&>(new A[2], d); } void sink3(bml::unique_ptr&> ) {} void sink3_unbounded_array(bml::unique_ptr&> ) {} void sink3_bounded_array(bml::unique_ptr&> ) {} 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"