diff --git a/include/boost/move/make_unique.hpp b/include/boost/move/make_unique.hpp
index 4a4f99a..59cfafa 100644
--- a/include/boost/move/make_unique.hpp
+++ b/include/boost/move/make_unique.hpp
@@ -25,10 +25,15 @@
//! This header can be a bit heavyweight in C++03 compilers due to the use of the
//! preprocessor library, that's why it's a a separate header from unique_ptr.hpp
-namespace boost{
-
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+namespace std { //no namespace versioning in clang+libc++
+
+struct nothrow_t;
+
+} //namespace std {
+
+namespace boost{
namespace move_upmu {
//Compile time switch between
@@ -52,10 +57,14 @@ struct unique_ptr_if
typedef void t_is_array_of_known_bound;
};
+static std::nothrow_t *pnothrow;
+
} //namespace move_upmu {
+} //namespace boost{
#endif //!defined(BOOST_MOVE_DOXYGEN_INVOKED)
+namespace boost{
namespace movelib {
#if defined(BOOST_MOVE_DOXYGEN_INVOKED) || !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -69,6 +78,15 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
make_unique(BOOST_FWD_REF(Args)... args)
{ return unique_ptr(new T(::boost::forward(args)...)); }
+//! Remarks: This function shall not participate in overload resolution unless T is not an array.
+//!
+//! Returns: unique_ptr(new T(std::nothrow)(std::forward(args)...)).
+template
+inline BOOST_MOVE_DOC1ST(unique_ptr,
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array)
+ make_unique_nothrow(BOOST_FWD_REF(Args)... args)
+{ return unique_ptr(new (*boost::move_upmu::pnothrow)T(::boost::forward(args)...)); }
+
#else
//0 arg
@@ -76,6 +94,12 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
make_unique()
{ return unique_ptr(new T()); }
+
+ template
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
+ make_unique_nothrow()
+ { return unique_ptr(new (*boost::move_upmu::pnothrow)T()); }
+
//1 arg
template
typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
@@ -87,6 +111,17 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
)
);
}
+
+ template
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
+ make_unique_nothrow( BOOST_FWD_REF(P0) p0
+ )
+ {
+ return unique_ptr
+ ( new (*boost::move_upmu::pnothrow)T ( ::boost::forward(p0)
+ )
+ );
+ }
//2 arg
template
typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
@@ -100,6 +135,19 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
)
);
}
+
+ template
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
+ make_unique_nothrow( BOOST_FWD_REF(P0) p0
+ , BOOST_FWD_REF(P1) p1
+ )
+ {
+ return unique_ptr
+ ( new (*boost::move_upmu::pnothrow)T ( ::boost::forward(p0)
+ , ::boost::forward(p1)
+ )
+ );
+ }
//3 arg
template
typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
@@ -115,6 +163,21 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
)
);
}
+
+ template
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
+ make_unique_nothrow ( BOOST_FWD_REF(P0) p0
+ , BOOST_FWD_REF(P1) p1
+ , BOOST_FWD_REF(P2) p2
+ )
+ {
+ return unique_ptr
+ ( new (*boost::move_upmu::pnothrow)T ( ::boost::forward(p0)
+ , ::boost::forward(p1)
+ , ::boost::forward(p2)
+ )
+ );
+ }
//4 arg
template
typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
@@ -132,6 +195,23 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
)
);
}
+
+ template
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
+ make_unique_nothrow ( BOOST_FWD_REF(P0) p0
+ , BOOST_FWD_REF(P1) p1
+ , BOOST_FWD_REF(P2) p2
+ , BOOST_FWD_REF(P3) p3
+ )
+ {
+ return unique_ptr
+ ( new (*boost::move_upmu::pnothrow)T ( ::boost::forward(p0)
+ , ::boost::forward(p1)
+ , ::boost::forward(p2)
+ , ::boost::forward(p3)
+ )
+ );
+ }
//5 arg
template
typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
@@ -151,6 +231,25 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
)
);
}
+
+ template
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
+ make_unique_nothrow ( BOOST_FWD_REF(P0) p0
+ , BOOST_FWD_REF(P1) p1
+ , BOOST_FWD_REF(P2) p2
+ , BOOST_FWD_REF(P3) p3
+ , BOOST_FWD_REF(P4) p4
+ )
+ {
+ return unique_ptr
+ ( new (*boost::move_upmu::pnothrow)T ( ::boost::forward(p0)
+ , ::boost::forward(p1)
+ , ::boost::forward(p2)
+ , ::boost::forward(p3)
+ , ::boost::forward(p4)
+ )
+ );
+ }
//6 arg
template
typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
@@ -172,6 +271,27 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
)
);
}
+
+ template
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
+ make_unique_nothrow ( BOOST_FWD_REF(P0) p0
+ , BOOST_FWD_REF(P1) p1
+ , BOOST_FWD_REF(P2) p2
+ , BOOST_FWD_REF(P3) p3
+ , BOOST_FWD_REF(P4) p4
+ , BOOST_FWD_REF(P5) p5
+ )
+ {
+ return unique_ptr
+ ( new (*boost::move_upmu::pnothrow)T ( ::boost::forward(p0)
+ , ::boost::forward(p1)
+ , ::boost::forward(p2)
+ , ::boost::forward(p3)
+ , ::boost::forward(p4)
+ , ::boost::forward(p5)
+ )
+ );
+ }
//7 arg
template
typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
@@ -195,6 +315,30 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
)
);
}
+
+ template
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
+ make_unique_nothrow ( BOOST_FWD_REF(P0) p0
+ , BOOST_FWD_REF(P1) p1
+ , BOOST_FWD_REF(P2) p2
+ , BOOST_FWD_REF(P3) p3
+ , BOOST_FWD_REF(P4) p4
+ , BOOST_FWD_REF(P5) p5
+ , BOOST_FWD_REF(P6) p6
+ )
+ {
+ return unique_ptr
+ ( new (*boost::move_upmu::pnothrow)T ( ::boost::forward(p0)
+ , ::boost::forward(p1)
+ , ::boost::forward(p2)
+ , ::boost::forward(p3)
+ , ::boost::forward(p4)
+ , ::boost::forward(p5)
+ , ::boost::forward(p6)
+ )
+ );
+ }
+
//8 arg
template
typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
@@ -220,6 +364,31 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
)
);
}
+
+ template
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
+ make_unique_nothrow ( BOOST_FWD_REF(P0) p0
+ , BOOST_FWD_REF(P1) p1
+ , BOOST_FWD_REF(P2) p2
+ , BOOST_FWD_REF(P3) p3
+ , BOOST_FWD_REF(P4) p4
+ , BOOST_FWD_REF(P5) p5
+ , BOOST_FWD_REF(P6) p6
+ , BOOST_FWD_REF(P7) p7
+ )
+ {
+ return unique_ptr
+ ( new (*boost::move_upmu::pnothrow)T ( ::boost::forward(p0)
+ , ::boost::forward(p1)
+ , ::boost::forward(p2)
+ , ::boost::forward(p3)
+ , ::boost::forward(p4)
+ , ::boost::forward(p5)
+ , ::boost::forward(p6)
+ , ::boost::forward(p7)
+ )
+ );
+ }
//9 arg
template
typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
@@ -247,6 +416,33 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
)
);
}
+
+ template
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
+ make_unique_nothrow ( BOOST_FWD_REF(P0) p0
+ , BOOST_FWD_REF(P1) p1
+ , BOOST_FWD_REF(P2) p2
+ , BOOST_FWD_REF(P3) p3
+ , BOOST_FWD_REF(P4) p4
+ , BOOST_FWD_REF(P5) p5
+ , BOOST_FWD_REF(P6) p6
+ , BOOST_FWD_REF(P7) p7
+ , BOOST_FWD_REF(P8) p8
+ )
+ {
+ return unique_ptr
+ ( new (*boost::move_upmu::pnothrow)T ( ::boost::forward(p0)
+ , ::boost::forward(p1)
+ , ::boost::forward(p2)
+ , ::boost::forward(p3)
+ , ::boost::forward(p4)
+ , ::boost::forward(p5)
+ , ::boost::forward(p6)
+ , ::boost::forward(p7)
+ , ::boost::forward(p8)
+ )
+ );
+ }
//10 arg
template
typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
@@ -277,6 +473,35 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
);
}
+ template
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array
+ make_unique_nothrow ( BOOST_FWD_REF(P0) p0
+ , BOOST_FWD_REF(P1) p1
+ , BOOST_FWD_REF(P2) p2
+ , BOOST_FWD_REF(P3) p3
+ , BOOST_FWD_REF(P4) p4
+ , BOOST_FWD_REF(P5) p5
+ , BOOST_FWD_REF(P6) p6
+ , BOOST_FWD_REF(P7) p7
+ , BOOST_FWD_REF(P8) p8
+ , BOOST_FWD_REF(P9) p9
+ )
+ {
+ return unique_ptr
+ ( new (*boost::move_upmu::pnothrow)T ( ::boost::forward(p0)
+ , ::boost::forward(p1)
+ , ::boost::forward(p2)
+ , ::boost::forward(p3)
+ , ::boost::forward(p4)
+ , ::boost::forward(p5)
+ , ::boost::forward(p6)
+ , ::boost::forward(p7)
+ , ::boost::forward(p8)
+ , ::boost::forward(p9)
+ )
+ );
+ }
+
#endif
//! Remarks: This function shall not participate in overload resolution unless T is not an array.
@@ -290,6 +515,17 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
return unique_ptr(new T);
}
+//! Remarks: This function shall not participate in overload resolution unless T is not an array.
+//!
+//! Returns: unique_ptr(new T(std::nothrow) (default initialization)
+template
+inline BOOST_MOVE_DOC1ST(unique_ptr,
+ typename ::boost::move_upmu::unique_ptr_if::t_is_not_array)
+ make_unique_nothrow_definit()
+{
+ return unique_ptr(new (*boost::move_upmu::pnothrow)T);
+}
+
//! Remarks: This function shall not participate in overload resolution unless T is an array of
//! unknown bound.
//!
@@ -303,6 +539,19 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
return unique_ptr(new U[n]());
}
+//! Remarks: This function shall not participate in overload resolution unless T is an array of
+//! unknown bound.
+//!
+//! Returns: unique_ptr(new (std::nothrow)remove_extent_t[n]()) (value initialization)
+template
+inline BOOST_MOVE_DOC1ST(unique_ptr,
+ typename ::boost::move_upmu::unique_ptr_if::t_is_array_of_unknown_bound)
+ make_unique_nothrow(std::size_t n)
+{
+ typedef typename ::boost::move_upmu::remove_extent::type U;
+ return unique_ptr(new (*boost::move_upmu::pnothrow)U[n]());
+}
+
//! Remarks: This function shall not participate in overload resolution unless T is an array of
//! unknown bound.
//!
@@ -316,6 +565,19 @@ inline BOOST_MOVE_DOC1ST(unique_ptr,
return unique_ptr(new U[n]);
}
+//! Remarks: This function shall not participate in overload resolution unless T is an array of
+//! unknown bound.
+//!
+//! Returns: unique_ptr(new (std::nothrow)remove_extent_t[n]) (default initialization)
+template
+inline BOOST_MOVE_DOC1ST(unique_ptr,
+ typename ::boost::move_upmu::unique_ptr_if::t_is_array_of_unknown_bound)
+ make_unique_nothrow_definit(std::size_t n)
+{
+ typedef typename ::boost::move_upmu::remove_extent::type U;
+ return unique_ptr(new (*boost::move_upmu::pnothrow) U[n]);
+}
+
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
//! Remarks: This function shall not participate in overload resolution unless T is
@@ -324,6 +586,28 @@ template
inline BOOST_MOVE_DOC1ST(unspecified,
typename ::boost::move_upmu::unique_ptr_if::t_is_array_of_known_bound)
make_unique(BOOST_FWD_REF(Args) ...) = delete;
+
+//! Remarks: This function shall not participate in overload resolution unless T is
+//! an array of known bound.
+template
+inline BOOST_MOVE_DOC1ST(unspecified,
+ typename ::boost::move_upmu::unique_ptr_if::t_is_array_of_known_bound)
+ make_unique_definit(BOOST_FWD_REF(Args) ...) = delete;
+
+//! Remarks: This function shall not participate in overload resolution unless T is
+//! an array of known bound.
+template
+inline BOOST_MOVE_DOC1ST(unspecified,
+ typename ::boost::move_upmu::unique_ptr_if::t_is_array_of_known_bound)
+ make_unique_nothrow(BOOST_FWD_REF(Args) ...) = delete;
+
+//! Remarks: This function shall not participate in overload resolution unless T is
+//! an array of known bound.
+template
+inline BOOST_MOVE_DOC1ST(unspecified,
+ typename ::boost::move_upmu::unique_ptr_if::t_is_array_of_known_bound)
+ make_unique_nothrow_definit(BOOST_FWD_REF(Args) ...) = delete;
+
#endif
} //namespace movelib {
diff --git a/test/unique_ptr_functions.cpp b/test/unique_ptr_functions.cpp
index 21dc99c..33274d2 100644
--- a/test/unique_ptr_functions.cpp
+++ b/test/unique_ptr_functions.cpp
@@ -44,6 +44,8 @@ void reset_counters()
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 };
struct default_init
{
@@ -57,6 +59,16 @@ struct default_init
void *const p = ::operator new[](sz);
return std::memset(p, 0xEE, sz);
}
+ static void* operator new(std::size_t sz, const std::nothrow_t &)
+ {
+ void *const p = ::operator new(sz);
+ return std::memset(p, 0xDD, sz);
+ }
+ static void* operator new[](std::size_t sz, const std::nothrow_t &)
+ {
+ void *const p = ::operator new[](sz);
+ return std::memset(p, 0xCC, sz);
+ }
unsigned char buf[PatternSize];
};
@@ -78,6 +90,11 @@ void test()
bml::unique_ptr p(bml::make_unique_definit());
BOOST_TEST(0 == std::memcmp(p.get(), ff_patternbuf, sizeof(ff_patternbuf)));
}
+ {
+ bml::unique_ptr p(bml::make_unique_nothrow_definit());
+ BOOST_TEST(0 == std::memcmp(p.get(), dd_patternbuf, sizeof(dd_patternbuf)));
+ }
+
BOOST_TEST(A::count == 0);
{
bml::unique_ptr p(bml::make_unique());
@@ -88,7 +105,7 @@ void test()
}
BOOST_TEST(A::count == 0);
{
- bml::unique_ptr p(bml::make_unique(0));
+ bml::unique_ptr p(bml::make_unique_nothrow(0));
BOOST_TEST(A::count == 1);
BOOST_TEST(p->a == 0);
BOOST_TEST(p->b == 1000);
@@ -104,7 +121,7 @@ void test()
}
BOOST_TEST(A::count == 0);
{
- bml::unique_ptr p(bml::make_unique(0, 1, 2));
+ bml::unique_ptr p(bml::make_unique_nothrow(0, 1, 2));
BOOST_TEST(A::count == 1);
BOOST_TEST(p->a == 0);
BOOST_TEST(p->b == 1);
@@ -115,6 +132,7 @@ void test()
} //namespace make_unique_single{
+
////////////////////////////////
// make_unique_single
////////////////////////////////
@@ -135,6 +153,16 @@ void test()
}
}
BOOST_TEST(A::count == 0);
+ {
+ bml::unique_ptr p(bml::make_unique_nothrow(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 p(bml::make_unique_definit(10));
@@ -142,6 +170,13 @@ void test()
BOOST_TEST(0 == std::memcmp(&p[i], ee_patternbuf, sizeof(ee_patternbuf)));
}
}
+ reset_counters();
+ {
+ bml::unique_ptr p(bml::make_unique_nothrow_definit(10));
+ for(unsigned i = 0; i != 10; ++i){
+ BOOST_TEST(0 == std::memcmp(&p[i], cc_patternbuf, sizeof(cc_patternbuf)));
+ }
+ }
}
} //namespace make_unique_array{