|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r81684 - in trunk: boost/smart_ptr/detail libs/smart_ptr/test
From: glenfe_at_[hidden]
Date: 2012-12-03 00:41:35
Author: glenfe
Date: 2012-12-03 00:41:34 EST (Mon, 03 Dec 2012)
New Revision: 81684
URL: http://svn.boost.org/trac/boost/changeset/81684
Log:
For fixed size arrays upon constructor exception thrown destroy correctly.
Text files modified:
trunk/boost/smart_ptr/detail/array_deleter.hpp | 106 +++++++++++++++++++++++++++++----------
trunk/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp | 16 ++++++
trunk/libs/smart_ptr/test/make_shared_array_throws_test.cpp | 16 ++++++
3 files changed, 110 insertions(+), 28 deletions(-)
Modified: trunk/boost/smart_ptr/detail/array_deleter.hpp
==============================================================================
--- trunk/boost/smart_ptr/detail/array_deleter.hpp (original)
+++ trunk/boost/smart_ptr/detail/array_deleter.hpp 2012-12-03 00:41:34 EST (Mon, 03 Dec 2012)
@@ -24,13 +24,18 @@
object(0) {
}
~array_deleter() {
- destroy();
+ destroy(size);
}
void construct(T* memory) {
object = memory;
for (std::size_t i = 0; i < size; i++) {
- void* p1 = object + i;
- ::new(p1) T();
+ try {
+ void* p1 = memory + i;
+ ::new(p1) T();
+ } catch (...) {
+ destroy(i);
+ throw;
+ }
}
}
#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
@@ -38,39 +43,59 @@
void construct(T* memory, Args&&... args) {
object = memory;
for (std::size_t i = 0; i < size; i++) {
- void* p1 = object + i;
- ::new(p1) T(args...);
+ try {
+ void* p1 = memory + i;
+ ::new(p1) T(args...);
+ } catch (...) {
+ destroy(i);
+ throw;
+ }
}
}
#endif
void construct_list(T* memory, const T* list) {
object = memory;
for (std::size_t i = 0; i < size; i++) {
- void* p1 = object + i;
- ::new(p1) T(list[i]);
+ try {
+ void* p1 = memory + i;
+ ::new(p1) T(list[i]);
+ } catch (...) {
+ destroy(i);
+ throw;
+ }
}
}
void construct_list(T* memory, const T* list, std::size_t n) {
object = memory;
for (std::size_t i = 0; i < size; i++) {
- void* p1 = object + i;
- ::new(p1) T(list[i % n]);
+ try {
+ void* p1 = memory + i;
+ ::new(p1) T(list[i % n]);
+ } catch (...) {
+ destroy(i);
+ throw;
+ }
}
}
void construct_noinit(T* memory) {
object = memory;
for (std::size_t i = 0; i < size; i++) {
- void* p1 = object + i;
- ::new(p1) T;
+ try {
+ void* p1 = memory + i;
+ ::new(p1) T;
+ } catch (...) {
+ destroy(i);
+ throw;
+ }
}
}
void operator()(const void*) {
- destroy();
+ destroy(size);
}
private:
- void destroy() {
+ void destroy(std::size_t n) {
if (object) {
- for (std::size_t i = size; i > 0; ) {
+ for (std::size_t i = n; i > 0; ) {
object[--i].~T();
}
object = 0;
@@ -86,13 +111,18 @@
: object(0) {
}
~array_deleter() {
- destroy();
+ destroy(N);
}
void construct(T* memory) {
object = memory;
for (std::size_t i = 0; i < N; i++) {
- void* p1 = object + i;
- ::new(p1) T();
+ try {
+ void* p1 = memory + i;
+ ::new(p1) T();
+ } catch (...) {
+ destroy(i);
+ throw;
+ }
}
}
#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
@@ -100,39 +130,59 @@
void construct(T* memory, Args&&... args) {
object = memory;
for (std::size_t i = 0; i < N; i++) {
- void* p1 = object + i;
- ::new(p1) T(args...);
+ try {
+ void* p1 = memory + i;
+ ::new(p1) T(args...);
+ } catch (...) {
+ destroy(i);
+ throw;
+ }
}
}
#endif
void construct_list(T* memory, const T* list) {
object = memory;
for (std::size_t i = 0; i < N; i++) {
- void* p1 = object + i;
- ::new(p1) T(list[i]);
+ try {
+ void* p1 = memory + i;
+ ::new(p1) T(list[i]);
+ } catch (...) {
+ destroy(i);
+ throw;
+ }
}
}
void construct_list(T* memory, const T* list, std::size_t n) {
object = memory;
for (std::size_t i = 0; i < N; i++) {
- void* p1 = object + i;
- ::new(p1) T(list[i % n]);
+ try {
+ void* p1 = memory + i;
+ ::new(p1) T(list[i % n]);
+ } catch (...) {
+ destroy(i);
+ throw;
+ }
}
}
void construct_noinit(T* memory) {
object = memory;
for (std::size_t i = 0; i < N; i++) {
- void* p1 = object + i;
- ::new(p1) T;
+ try {
+ void* p1 = memory + i;
+ ::new(p1) T;
+ } catch (...) {
+ destroy(i);
+ throw;
+ }
}
}
void operator()(const void*) {
- destroy();
+ destroy(N);
}
private:
- void destroy() {
+ void destroy(std::size_t n) {
if (object) {
- for (std::size_t i = N; i > 0; ) {
+ for (std::size_t i = n; i > 0; ) {
object[--i].~T();
}
object = 0;
Modified: trunk/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp
==============================================================================
--- trunk/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp (original)
+++ trunk/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp 2012-12-03 00:41:34 EST (Mon, 03 Dec 2012)
@@ -43,5 +43,21 @@
} catch (...) {
BOOST_TEST(type::instances == 0);
}
+#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+ BOOST_TEST(type::instances == 0);
+ try {
+ boost::allocate_shared<type[6]>(std::allocator<type>());
+ BOOST_ERROR("allocate_shared did not throw");
+ } catch (...) {
+ BOOST_TEST(type::instances == 0);
+ }
+ BOOST_TEST(type::instances == 0);
+ try {
+ boost::allocate_shared<type[3][2]>(std::allocator<type>());
+ BOOST_ERROR("allocate_shared did not throw");
+ } catch (...) {
+ BOOST_TEST(type::instances == 0);
+ }
+#endif
return boost::report_errors();
}
Modified: trunk/libs/smart_ptr/test/make_shared_array_throws_test.cpp
==============================================================================
--- trunk/libs/smart_ptr/test/make_shared_array_throws_test.cpp (original)
+++ trunk/libs/smart_ptr/test/make_shared_array_throws_test.cpp 2012-12-03 00:41:34 EST (Mon, 03 Dec 2012)
@@ -43,6 +43,22 @@
} catch (...) {
BOOST_TEST(type::instances == 0);
}
+#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+ BOOST_TEST(type::instances == 0);
+ try {
+ boost::make_shared<type[6]>();
+ BOOST_ERROR("make_shared did not throw");
+ } catch (...) {
+ BOOST_TEST(type::instances == 0);
+ }
+ BOOST_TEST(type::instances == 0);
+ try {
+ boost::make_shared<type[3][2]>();
+ BOOST_ERROR("make_shared did not throw");
+ } catch (...) {
+ BOOST_TEST(type::instances == 0);
+ }
+#endif
BOOST_TEST(type::instances == 0);
try {
boost::make_shared_noinit<type[]>(6);
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk