Boost logo

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