From 72e5fb6fd704ba5ad77c76ae4b5b6a3eba559839 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 29 Jan 2014 16:33:32 -0800 Subject: [PATCH] Add fourth form of make_unique for objects To support initialization syntax that Args&&... cannot forward perfectly. --- .../boost/smart_ptr/make_unique_object.hpp | 7 +++ make_unique.html | 36 +++++++++---- test/Jamfile.v2 | 1 + test/make_unique_args_test.cpp | 18 +++---- test/make_unique_array_noinit_test.cpp | 13 +---- test/make_unique_noinit_test.cpp | 6 --- test/make_unique_value_test.cpp | 51 +++++++++++++++++++ 7 files changed, 95 insertions(+), 37 deletions(-) create mode 100644 test/make_unique_value_test.cpp diff --git a/include/boost/smart_ptr/make_unique_object.hpp b/include/boost/smart_ptr/make_unique_object.hpp index 3ebdabd..12149c5 100644 --- a/include/boost/smart_ptr/make_unique_object.hpp +++ b/include/boost/smart_ptr/make_unique_object.hpp @@ -11,6 +11,7 @@ #include #include +#include namespace boost { template @@ -27,6 +28,12 @@ namespace boost { } #endif + template + inline typename boost::detail::up_if_not_array::type + make_unique(T&& value) { + return std::unique_ptr(new T(std::move(value))); + } + template inline typename boost::detail::up_if_not_array::type make_unique_noinit() { diff --git a/make_unique.html b/make_unique.html index ab4db62..2d5544d 100644 --- a/make_unique.html +++ b/make_unique.html @@ -26,6 +26,9 @@ unique_ptr<U> make_unique(Args&&... args); #endif + template<typename U> // U is not array + unique_ptr<U> make_unique(U&& value); + template<typename U> // U is not array unique_ptr<U> make_unique_noinit(); @@ -59,6 +62,14 @@ unique_ptr<U> make_unique(Args&&... args); expression new U(forward<Args>(args)...).

template<typename U> // U is not array
+unique_ptr<U> make_unique(U&& value);
+
+

Requires: The expression new U(move(value)) shall + be well-formed.

+

Effects: Constructs an object of type U via the + expression new U(move(value)).

+
+
template<typename U> // U is not array
 unique_ptr<U> make_unique_noinit();

Requires: The expression new U shall be @@ -87,28 +98,33 @@ unique_ptr<U> make_unique_noinit(size_t size);

Examples

For objects with value-initialization.

-
std::unique_ptr<float> p1 = boost::make_unique<float>();
-std::unique_ptr<point> p2 = boost::make_unique<point>();
+
unique_ptr<float> p1 = boost::make_unique<float>();
+unique_ptr<point> p2 = boost::make_unique<point>();

For objects with construction arguments.

-
std::unique_ptr<float> p3 = boost::make_unique<float>(1.5);
-std::unique_ptr<point> p4 = boost::make_unique<point>(x, y);
+
unique_ptr<float> p3 = boost::make_unique<float>(1.0f);
+unique_ptr<point> p4 = boost::make_unique<point>(x, y);
+
+

For objects with given value.

+
+
unique_ptr<string> p4 = boost::make_unique<string>({'a', 'b'});
+unique_ptr<type>   p5 = boost::make_unique<type>({3, 5, 4});

For objects with default-initialization.

-
std::unique_ptr<float> p4 = boost::make_unique_noinit<float>();
-std::unique_ptr<point> p5 = boost::make_unique_noinit<point>();
+
unique_ptr<float> p6 = boost::make_unique_noinit<float>();
+unique_ptr<point> p7 = boost::make_unique_noinit<point>();

For arrays with value-initialization.

-
std::unique_ptr<double[]> a1 = boost::make_unique<double[]>();
-std::unique_ptr<int[][4]> a2 = boost::make_unique<int[][4]>();
+
unique_ptr<double[]> a1 = boost::make_unique<double[]>();
+unique_ptr<int[][4]> a2 = boost::make_unique<int[][4]>();

For arrays with default-initialization.

-
std::unique_ptr<double[]> a3 = boost::make_unique_noinit<double[]>();
-std::unique_ptr<int[][4]> a4 = boost::make_unique_noinit<int[][4]>();
+
unique_ptr<double[]> a3 = boost::make_unique_noinit<double[]>();
+unique_ptr<int[][4]> a4 = boost::make_unique_noinit<int[][4]>();

History

January 2014. Glen Fernandes contributed implementations of diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 6cb4243..09263d3 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -151,6 +151,7 @@ import testing ; [ run make_unique_test.cpp ] [ run make_unique_args_test.cpp ] + [ run make_unique_value_test.cpp ] [ run make_unique_noinit_test.cpp ] [ run make_unique_throws_test.cpp ] [ run make_unique_array_test.cpp ] diff --git a/test/make_unique_args_test.cpp b/test/make_unique_args_test.cpp index d502b30..769c887 100644 --- a/test/make_unique_args_test.cpp +++ b/test/make_unique_args_test.cpp @@ -53,7 +53,7 @@ int main() { #if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) { - std::unique_ptr a1 = boost::make_unique(1); + std::unique_ptr a1 = boost::make_unique(1); BOOST_TEST(a1.get() != 0); BOOST_TEST(type::instances == 1); BOOST_TEST(a1->sum == 1); @@ -62,7 +62,7 @@ int main() { } { - std::unique_ptr a1 = boost::make_unique(1, 2); + std::unique_ptr a1 = boost::make_unique(1, 2); BOOST_TEST(a1.get() != 0); BOOST_TEST(type::instances == 1); BOOST_TEST(a1->sum == 1 + 2); @@ -71,7 +71,7 @@ int main() { } { - std::unique_ptr a1 = boost::make_unique(1, 2, 3); + std::unique_ptr a1 = boost::make_unique(1, 2, 3); BOOST_TEST(a1.get() != 0); BOOST_TEST(type::instances == 1); BOOST_TEST(a1->sum == 1 + 2 + 3); @@ -80,7 +80,7 @@ int main() { } { - std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4); + std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4); BOOST_TEST(a1.get() != 0); BOOST_TEST(type::instances == 1); BOOST_TEST(a1->sum == 1 + 2 + 3 + 4); @@ -89,7 +89,7 @@ int main() { } { - std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4, 5); + std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4, 5); BOOST_TEST(a1.get() != 0); BOOST_TEST(type::instances == 1); BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5); @@ -98,7 +98,7 @@ int main() { } { - std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4, 5, 6); + std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4, 5, 6); BOOST_TEST(a1.get() != 0); BOOST_TEST(type::instances == 1); BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6); @@ -107,7 +107,7 @@ int main() { } { - std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4, 5, 6, 7); + std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4, 5, 6, 7); BOOST_TEST(a1.get() != 0); BOOST_TEST(type::instances == 1); BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6 + 7); @@ -116,7 +116,7 @@ int main() { } { - std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4, 5, 6, 7, 8); + std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4, 5, 6, 7, 8); BOOST_TEST(a1.get() != 0); BOOST_TEST(type::instances == 1); BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8); @@ -125,7 +125,7 @@ int main() { } { - std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4, 5, 6, 7, 8, 9); + std::unique_ptr a1 = boost::make_unique(1, 2, 3, 4, 5, 6, 7, 8, 9); BOOST_TEST(a1.get() != 0); BOOST_TEST(type::instances == 1); BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9); diff --git a/test/make_unique_array_noinit_test.cpp b/test/make_unique_array_noinit_test.cpp index 68b6056..7f85f24 100644 --- a/test/make_unique_array_noinit_test.cpp +++ b/test/make_unique_array_noinit_test.cpp @@ -40,17 +40,7 @@ int main() { std::unique_ptr a1 = boost::make_unique_noinit(2); BOOST_TEST(a1.get() != 0); } - - { - std::unique_ptr a1 = boost::make_unique_noinit(3); - BOOST_TEST(a1.get() != 0); - } - - { - std::unique_ptr a1 = boost::make_unique_noinit(2); - BOOST_TEST(a1.get() != 0); - } - + BOOST_TEST(type::instances == 0); { std::unique_ptr a1 = boost::make_unique_noinit(3); @@ -72,7 +62,6 @@ int main() { BOOST_TEST(type::instances == 0); { std::unique_ptr a1 = boost::make_unique_noinit(3); - const type* a2 = a1.get(); BOOST_TEST(a1.get() != 0); BOOST_TEST(type::instances == 3); a1.reset(); diff --git a/test/make_unique_noinit_test.cpp b/test/make_unique_noinit_test.cpp index 406c958..66026ac 100644 --- a/test/make_unique_noinit_test.cpp +++ b/test/make_unique_noinit_test.cpp @@ -35,11 +35,6 @@ int main() { BOOST_TEST(a1.get() != 0); } - { - std::unique_ptr a1 = boost::make_unique_noinit(); - BOOST_TEST(a1.get() != 0); - } - BOOST_TEST(type::instances == 0); { std::unique_ptr a1 = boost::make_unique_noinit(); @@ -52,7 +47,6 @@ int main() { BOOST_TEST(type::instances == 0); { std::unique_ptr a1 = boost::make_unique_noinit(); - const type* a2 = a1.get(); BOOST_TEST(a1.get() != 0); BOOST_TEST(type::instances == 1); a1.reset(); diff --git a/test/make_unique_value_test.cpp b/test/make_unique_value_test.cpp new file mode 100644 index 0000000..308d488 --- /dev/null +++ b/test/make_unique_value_test.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#include +#include + +struct type { + int x; + int y; +}; + +int main() { +#if !defined(BOOST_NO_CXX11_SMART_PTR) + { + std::unique_ptr a1 = boost::make_unique(); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1->x == 0); + BOOST_TEST(a1->y == 0); + } + + { + std::unique_ptr a1 = boost::make_unique(); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1->x == 0); + BOOST_TEST(a1->y == 0); + } + +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) + { + std::unique_ptr a1 = boost::make_unique({ 1, 2 }); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1->x == 1); + BOOST_TEST(a1->y == 2); + } + + { + std::unique_ptr a1 = boost::make_unique({ 1, 2 }); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1->x == 1); + BOOST_TEST(a1->y == 2); + } +#endif +#endif + + return boost::report_errors(); +}