|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r81695 - in branches/release: . boost boost/smart_ptr boost/smart_ptr/detail libs libs/smart_ptr libs/smart_ptr/test
From: glenfe_at_[hidden]
Date: 2012-12-03 10:42:15
Author: glenfe
Date: 2012-12-03 10:42:15 EST (Mon, 03 Dec 2012)
New Revision: 81695
URL: http://svn.boost.org/trac/boost/changeset/81695
Log:
Merged revision(s) 81684-81685 from trunk:
For fixed size arrays upon constructor exception thrown destroy correctly.
........
Minor cosmetic change in detail array_deleter
........
Properties modified:
branches/release/ (props changed)
branches/release/boost/ (props changed)
branches/release/boost/smart_ptr/ (props changed)
branches/release/libs/ (props changed)
branches/release/libs/smart_ptr/ (props changed)
Text files modified:
branches/release/boost/smart_ptr/detail/array_deleter.hpp | 156 ++++++++++++++++++++++++++-------------
branches/release/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp | 16 ++++
branches/release/libs/smart_ptr/test/make_shared_array_throws_test.cpp | 16 ++++
3 files changed, 135 insertions(+), 53 deletions(-)
Modified: branches/release/boost/smart_ptr/detail/array_deleter.hpp
==============================================================================
--- branches/release/boost/smart_ptr/detail/array_deleter.hpp (original)
+++ branches/release/boost/smart_ptr/detail/array_deleter.hpp 2012-12-03 10:42:15 EST (Mon, 03 Dec 2012)
@@ -1,9 +1,9 @@
/*
- * Copyright (c) 2012 Glen Joseph Fernandes
+ * Copyright (c) 2012 Glen Joseph Fernandes
* glenfe at live dot com
*
- * Distributed under the Boost Software License,
- * Version 1.0. (See accompanying file LICENSE_1_0.txt
+ * 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)
*/
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
@@ -19,58 +19,83 @@
template<typename T>
class array_deleter<T[]> {
public:
- array_deleter(std::size_t size)
+ array_deleter(std::size_t size)
: size(size),
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();
+ std::size_t i = 0;
+ try {
+ for (object = memory; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T();
+ }
+ } catch (...) {
+ destroy(i);
+ throw;
}
}
#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
template<typename... Args>
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...);
+ std::size_t i = 0;
+ try {
+ for (object = memory; i < size; i++) {
+ 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]);
+ std::size_t i = 0;
+ try {
+ for (object = memory; i < size; i++) {
+ 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]);
+ std::size_t i = 0;
+ try {
+ for (object = memory; i < size; i++) {
+ 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;
+ std::size_t i = 0;
+ try {
+ for (object = memory; i < size; i++) {
+ 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;
@@ -82,57 +107,82 @@
template<typename T, std::size_t N>
class array_deleter<T[N]> {
public:
- array_deleter()
+ array_deleter()
: 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();
+ std::size_t i = 0;
+ try {
+ for (object = memory; i < N; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T();
+ }
+ } catch (...) {
+ destroy(i);
+ throw;
}
}
#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
template<typename... Args>
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...);
+ std::size_t i = 0;
+ try {
+ for (object = memory; i < N; i++) {
+ 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]);
+ std::size_t i = 0;
+ try {
+ for (object = memory; i < N; i++) {
+ 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]);
+ std::size_t i = 0;
+ try {
+ for (object = memory; i < N; i++) {
+ 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;
+ std::size_t i = 0;
+ try {
+ for (object = memory; i < N; i++) {
+ 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: branches/release/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp
==============================================================================
--- branches/release/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp (original)
+++ branches/release/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp 2012-12-03 10:42:15 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: branches/release/libs/smart_ptr/test/make_shared_array_throws_test.cpp
==============================================================================
--- branches/release/libs/smart_ptr/test/make_shared_array_throws_test.cpp (original)
+++ branches/release/libs/smart_ptr/test/make_shared_array_throws_test.cpp 2012-12-03 10:42:15 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