Simplified and improved unique_ptr implementation:

- No array specialization to avoid code duplication
- Constructible and assignable from literal zero
This commit is contained in:
Ion Gaztañaga committed 2014-08-27 23:21:36 +02:00
1 parent 6b2982a385
commit 364ee17476
7 files changed
+571 -695

No files matched your search

+129 -15
View File
@@ -10,8 +10,6 @@
// See http://www.boost.org/libs/move for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/move/detail/config_begin.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/move/unique_ptr.hpp>
#include <boost/static_assert.hpp>
@@ -511,17 +509,22 @@ void test()
} //unique_ptr_asgn_move01
////////////////////////////////
// unique_ptr_asgn_null
// unique_ptr_zero
////////////////////////////////
namespace unique_ptr_asgn_null {
namespace unique_ptr_zero {
// test assignment from null
// 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;
@@ -532,6 +535,11 @@ void test()
//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;
@@ -541,8 +549,7 @@ void test()
BOOST_TEST(A::count == 0);
}
} //namespace unique_ptr_asgn_null {
} //namespace unique_ptr_zero {
////////////////////////////////
@@ -1476,7 +1483,7 @@ void test()
{
//Single unique_ptr
reset_counters();
{
{ //reset()
bml::unique_ptr<A> p(new A);
BOOST_TEST(A::count == 1);
A* i = p.get();
@@ -1486,7 +1493,7 @@ void test()
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();
@@ -1495,9 +1502,19 @@ void test()
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);
//Array unique_ptr
reset_counters();
{
{ //reset()
bml::unique_ptr<A[]> p(new A[2]);
BOOST_TEST(A::count == 2);
A* i = p.get();
@@ -1507,7 +1524,7 @@ void test()
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();
@@ -1516,6 +1533,16 @@ void test()
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);
}
} //namespace unique_ptr_modifiers_reset1{
@@ -1820,6 +1847,92 @@ void test()
} //namespace unique_ptr_observers_op_index{
////////////////////////////////
// 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);
//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);
//Array element
#endif
}
} //namespace unique_ptr_nullptr{
////////////////////////////////
// main
////////////////////////////////
@@ -1833,7 +1946,6 @@ int main()
unique_ptr_asgn_move_convert02::test();
unique_ptr_asgn_move_convert03::test();
unique_ptr_asgn_move01::test();
unique_ptr_asgn_null::test();
//Constructor
unique_ptr_ctor_default01::test();
@@ -1873,8 +1985,13 @@ int main()
unique_ptr_observers_op_arrow::test();
unique_ptr_observers_op_index::test();
//nullptr
unique_ptr_zero::test();
unique_ptr_nullptr::test();
//Test results
return boost::report_errors();
}
//Define the incomplete I type and out of line functions
@@ -1902,6 +2019,3 @@ J<T, D>::~J() {}
void reset_counters()
{ A::count = 0; B::count = 0; I::count = 0; }
#include <boost/move/detail/config_end.hpp>
-4
View File
@@ -10,8 +10,6 @@
// See http://www.boost.org/libs/move for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/move/detail/config_begin.hpp>
#include <boost/move/unique_ptr.hpp>
#include <boost/core/lightweight_test.hpp>
@@ -130,5 +128,3 @@ int main()
//Test results
return boost::report_errors();
}
#include <boost/move/detail/config_end.hpp>
+113 -8
View File
@@ -9,7 +9,6 @@
// See http://www.boost.org/libs/move for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/move/detail/config_begin.hpp>
#include <boost/move/make_unique.hpp>
#include <boost/core/lightweight_test.hpp>
@@ -135,30 +134,135 @@ void test()
//Equal
BOOST_TEST(rpl == rpl && rpl.get() == rpl.get());
BOOST_TEST(!(rpl == rpg) && !(rpl.get() != rpg.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(!(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() > 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()));
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(!(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() < 0));
BOOST_TEST((0 < pa) == (0 < pa.get()));
BOOST_TEST((pb < 0) == (pb.get() < 0));
BOOST_TEST((0 < pb) == (0 < pb.get()));
//Greater
BOOST_TEST((pa > 0) == (pa.get() > 0));
BOOST_TEST((0 > pa) == (0 > pa.get()));
BOOST_TEST((pb > 0) == (pb.get() > 0));
BOOST_TEST((0 > pb) == (0 > pb.get()));
//Less or equal
BOOST_TEST((pa <= 0) == (pa.get() <= 0));
BOOST_TEST((0 <= pa) == (0 <= pa.get()));
BOOST_TEST((pb <= 0) == (pb.get() <= 0));
BOOST_TEST((0 <= pb) == (0 <= pb.get()));
//Greater or equal
BOOST_TEST((pa >= 0) == (pa.get() >= 0));
BOOST_TEST((0 >= pa) == (0 >= pa.get()));
BOOST_TEST((pb >= 0) == (pb.get() >= 0));
BOOST_TEST((0 >= pb) == (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() < nullptr));
BOOST_TEST((nullptr < pa) == (nullptr < pa.get()));
BOOST_TEST((pb < nullptr) == (pb.get() < nullptr));
BOOST_TEST((nullptr < pb) == (nullptr < pb.get()));
//Greater
BOOST_TEST((pa > nullptr) == (pa.get() > nullptr));
BOOST_TEST((nullptr > pa) == (nullptr > pa.get()));
BOOST_TEST((pb > nullptr) == (pb.get() > nullptr));
BOOST_TEST((nullptr > pb) == (nullptr > pb.get()));
//Less or equal
BOOST_TEST((pa <= nullptr) == (pa.get() <= nullptr));
BOOST_TEST((nullptr <= pa) == (nullptr <= pa.get()));
BOOST_TEST((pb <= nullptr) == (pb.get() <= nullptr));
BOOST_TEST((nullptr <= pb) == (nullptr <= pb.get()));
//Greater or equal
BOOST_TEST((pa >= nullptr) == (pa.get() >= nullptr));
BOOST_TEST((nullptr >= pa) == (nullptr >= pa.get()));
BOOST_TEST((pb >= nullptr) == (pb.get() >= nullptr));
BOOST_TEST((nullptr >= pb) == (nullptr >= pb.get()));
}
BOOST_TEST(A::count == 0);
#endif //#if !defined(BOOST_NO_CXX11_NULLPTR)
}
} //namespace unique_compare_nullptr{
////////////////////////////////
// main
////////////////////////////////
@@ -166,9 +270,10 @@ 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();
}
#include <boost/move/detail/config_end.hpp>