$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r81219 - in trunk: boost/smart_ptr boost/smart_ptr/detail libs/smart_ptr libs/smart_ptr/test
From: glenfe_at_[hidden]
Date: 2012-11-06 09:17:35
Author: glenfe
Date: 2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
New Revision: 81219
URL: http://svn.boost.org/trac/boost/changeset/81219
Log:
Add allocate_shared and make_shared for shared_ptr arrays of runtime size. Fulfills need for allocate_shared_array and make_shared_array. 
Added:
   trunk/boost/smart_ptr/allocate_shared_array.hpp   (contents, props changed)
   trunk/boost/smart_ptr/detail/allocate_array_helper.hpp   (contents, props changed)
   trunk/boost/smart_ptr/detail/array_deleter.hpp   (contents, props changed)
   trunk/boost/smart_ptr/detail/make_array_helper.hpp   (contents, props changed)
   trunk/boost/smart_ptr/detail/sp_if_array.hpp   (contents, props changed)
   trunk/boost/smart_ptr/make_shared_array.hpp   (contents, props changed)
   trunk/libs/smart_ptr/make_shared_array.html   (contents, props changed)
   trunk/libs/smart_ptr/test/allocate_shared_array_esft_test.cpp   (contents, props changed)
   trunk/libs/smart_ptr/test/allocate_shared_array_test.cpp   (contents, props changed)
   trunk/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp   (contents, props changed)
   trunk/libs/smart_ptr/test/make_shared_array_esft_test.cpp   (contents, props changed)
   trunk/libs/smart_ptr/test/make_shared_array_test.cpp   (contents, props changed)
   trunk/libs/smart_ptr/test/make_shared_array_throws_test.cpp   (contents, props changed)
Added: trunk/boost/smart_ptr/allocate_shared_array.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/smart_ptr/allocate_shared_array.hpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,49 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
+#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
+
+#include <boost/shared_ptr.hpp>
+#include <boost/smart_ptr/detail/allocate_array_helper.hpp>
+#include <boost/smart_ptr/detail/array_deleter.hpp>
+#include <boost/smart_ptr/detail/sp_if_array.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+
+namespace boost {
+    template<typename T, typename A>
+    inline typename detail::sp_if_array<T>::type 
+    allocate_shared(const A& allocator, size_t size) {
+        typedef typename remove_cv<shared_ptr<T>::element_type>::type T1;
+        T1* p1 = 0;
+        detail::allocate_array_helper<A, T1> a1(allocator, size, &p1);
+        detail::array_deleter<T1> d1;
+        shared_ptr<T> s1(p1, d1, a1);
+        detail::array_deleter<T1>* d2;
+        d2 = get_deleter<detail::array_deleter<T1> >(s1);
+        d2->construct(p1, size);
+        return shared_ptr<T>(s1, p1);
+    }
+#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+    template<typename T, typename A, typename... Args>
+    inline typename detail::sp_if_array<T>::type
+    allocate_shared(const A& allocator, size_t size, Args&&... args) {
+        typedef typename remove_cv<shared_ptr<T>::element_type>::type T1;
+        T1* p1 = 0;
+        detail::allocate_array_helper<A, T1> a1(allocator, size, &p1);
+        detail::array_deleter<T1> d1;
+        shared_ptr<T> s1(p1, d1, a1);
+        detail::array_deleter<T1>* d2;
+        d2 = get_deleter<detail::array_deleter<T1> >(s1);
+        d2->construct(p1, size, std::forward<Args>(args)...);
+        return shared_ptr<T>(s1, p1);
+    }
+#endif
+}
+
+#endif
Added: trunk/boost/smart_ptr/detail/allocate_array_helper.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/smart_ptr/detail/allocate_array_helper.hpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,99 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
+#define BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
+
+#include <boost/type_traits/alignment_of.hpp>
+#include <cstddef>
+
+namespace boost {
+    namespace detail {
+        template<typename A, typename T, typename Y = T>
+        class allocate_array_helper {
+            template<typename A, typename T, typename Y>
+            friend class allocate_array_helper;
+            typedef typename A::rebind<Y>   ::other A2;
+            typedef typename A::rebind<char>::other A3;
+        public:
+            typedef typename A2::value_type      value_type;
+            typedef typename A2::pointer         pointer;
+            typedef typename A2::const_pointer   const_pointer;
+            typedef typename A2::reference       reference;
+            typedef typename A2::const_reference const_reference;
+            typedef typename A2::size_type       size_type;
+            typedef typename A2::difference_type difference_type;
+            template<typename U>
+            struct rebind {
+                typedef allocate_array_helper<A, T, U> other;
+            };
+            allocate_array_helper(const A& allocator, std::size_t size, T** data)
+                : allocator(allocator),
+                  size(sizeof(T) * size),
+                  data(data) {
+            }
+            allocate_array_helper(const allocate_array_helper& other)
+                : allocator(other.allocator),
+                  size(other.size),
+                  data(other.data) {
+            }
+            template<class U>
+            allocate_array_helper(const allocate_array_helper<A, T, U>& other) 
+                : allocator(other.allocator),
+                  size(other.size),
+                  data(other.data) {
+            }
+            pointer address(reference value) const {
+                return allocator.address(value);
+            }
+            const_pointer address(const_reference value) const {
+                return allocator.address(value);
+            }
+            size_type max_size() const {
+                return allocator.max_size();
+            }
+            pointer allocate(size_type count, const void* value = 0) {
+                std::size_t a1 = alignment_of<T>::value;
+                std::size_t n1 = count * sizeof(Y) + a1 - 1;
+                char*  p1 = A3(allocator).allocate(n1 + size, value);
+                char*  p2 = p1 + n1;
+                while (std::size_t(p2) % a1 != 0) {
+                    p2--;
+                }
+                *data = reinterpret_cast<T*>(p2);
+                return  reinterpret_cast<Y*>(p1);
+            }
+            void deallocate(pointer memory, size_type count) {
+                std::size_t a1 = alignment_of<T>::value;
+                std::size_t n1 = count * sizeof(Y) + a1 - 1;
+                char*  p1 = reinterpret_cast<char*>(memory);
+                A3(allocator).deallocate(p1, n1 + size);
+            }
+            void construct(pointer memory, const Y& value) {
+                allocator.construct(memory, value);
+            }
+            void destroy(pointer memory) {
+                allocator.destroy(memory);
+            }
+            template<typename U>
+            bool operator==(const allocate_array_helper<A, T, U>& other) const {
+                return allocator == other.allocator;
+            }
+            template<typename U>
+            bool operator!=(const allocate_array_helper<A, T, U>& other) const {
+                return !(*this == other); 
+            }
+        private:
+            A2 allocator;
+            std::size_t size;
+            T** data;
+        };
+    }
+}
+
+#endif
Added: trunk/boost/smart_ptr/detail/array_deleter.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/smart_ptr/detail/array_deleter.hpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,62 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
+#define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
+
+#include <boost/config.hpp>
+#include <cstddef>
+
+namespace boost {
+    namespace detail {
+        template<typename T>
+        class array_deleter {
+        public:
+            array_deleter() 
+                : size(0) {
+            }
+            ~array_deleter() {
+                destroy();
+            }
+            void construct(T* memory, std::size_t count) {
+                for (object = memory; size < count; size++) {
+                    void* p1 = object + size;
+                    ::new(p1) T();
+                }
+            }
+#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+            template<typename... Args>
+            void construct(T* memory, std::size_t count, Args&&... args) {
+                for (object = memory; size < count; size++) {
+                    void* p1 = object + size;
+                    ::new(p1) T(args...);
+                }
+            }
+#endif
+            void construct_noinit(T* memory, std::size_t count) {
+                for (object = memory; size < count; size++) {
+                    void* p1 = object + size;
+                    ::new(p1) T;
+                }
+            }
+            void operator()(T*) {
+                destroy();
+            }
+        private:
+            void destroy() {
+                while (size > 0) {
+                    object[--size].~T();
+                }
+            }
+            std::size_t size;
+            T* object;
+        };
+    }
+}
+
+#endif
Added: trunk/boost/smart_ptr/detail/make_array_helper.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/smart_ptr/detail/make_array_helper.hpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,92 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
+#define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
+
+#include <boost/type_traits/alignment_of.hpp>
+#include <cstddef>
+
+namespace boost {
+    namespace detail {
+        template<typename T, typename Y = T>
+        class make_array_helper {
+            template<typename T, typename Y>
+            friend class make_array_helper;
+        public:
+            typedef typename Y           value_type;
+            typedef typename Y*          pointer;
+            typedef typename const Y*    const_pointer;
+            typedef typename Y&          reference;
+            typedef typename const Y&    const_reference;
+            typedef typename std::size_t size_type;
+            typedef typename ptrdiff_t   difference_type;
+            template<typename U>
+            struct rebind {
+                typedef make_array_helper<T, U> other;
+            };
+            make_array_helper(std::size_t size, T** data)
+                : size(sizeof(T) * size),
+                  data(data) {
+            }
+            make_array_helper(const make_array_helper& other)
+                : size(other.size),
+                  data(other.data) {
+            }
+            template<class U>
+            make_array_helper(const make_array_helper<T, U>& other) 
+                : size(other.size),
+                  data(other.data) {
+            }
+            pointer address(reference value) const {
+                return &value;
+            }
+            const_pointer address(const_reference value) const {
+                return &value;
+            }
+            size_type max_size() const {
+                return static_cast<std::size_t>(-1) / sizeof(Y);
+            }
+            pointer allocate(size_type count, const void* = 0) {
+                std::size_t a1 = alignment_of<T>::value;
+                std::size_t n1 = count * sizeof(Y) + a1 - 1;
+                void*  p1 = ::operator new(n1 + size);
+                char*  p2 = static_cast<char*>(p1) + n1;
+                while (std::size_t(p2) % a1 != 0) {
+                    p2--;
+                }
+                *data = reinterpret_cast<T*>(p2);
+                return  reinterpret_cast<Y*>(p1);
+            }
+            void deallocate(pointer memory, size_type) {
+                void* p1 = memory;
+                ::operator delete(p1);
+            }
+            void construct(pointer memory, const Y& value) {
+                void* p1 = memory;
+                ::new(p1) Y(value);
+            }
+            void destroy(pointer memory) {
+                memory->~Y();
+            }
+            template<typename U>
+            bool operator==(const make_array_helper<T, U>& other) const {
+                return true;
+            }
+            template<typename U>
+            bool operator!=(const make_array_helper<T, U>& other) const {
+                return !(*this == other); 
+            }
+        private:
+            std::size_t size;
+            T** data;
+        };
+    }
+}
+
+#endif
Added: trunk/boost/smart_ptr/detail/sp_if_array.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/smart_ptr/detail/sp_if_array.hpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,28 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
+#define BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
+
+#include <boost/smart_ptr/shared_ptr.hpp>
+
+namespace boost {
+    namespace detail {
+        template<typename T> 
+        struct sp_if_array {
+        };
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+        template<typename T>
+        struct sp_if_array<T[]> {
+            typedef boost::shared_ptr<T[]> type;
+        };
+#endif
+    }
+}
+
+#endif
Added: trunk/boost/smart_ptr/make_shared_array.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/smart_ptr/make_shared_array.hpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,62 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
+#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
+
+#include <boost/shared_ptr.hpp>
+#include <boost/smart_ptr/detail/array_deleter.hpp>
+#include <boost/smart_ptr/detail/make_array_helper.hpp>
+#include <boost/smart_ptr/detail/sp_if_array.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+
+namespace boost {
+    template<typename T>
+    inline typename detail::sp_if_array<T>::type
+    make_shared(std::size_t size) {
+        typedef typename remove_cv<shared_ptr<T>::element_type>::type T1;
+        T1* p1 = 0;
+        detail::make_array_helper<T1> a1(size, &p1);
+        detail::array_deleter<T1> d1;
+        shared_ptr<T> s1(p1, d1, a1);
+        detail::array_deleter<T1>* d2;
+        d2 = get_deleter<detail::array_deleter<T1> >(s1);
+        d2->construct(p1, size);
+        return shared_ptr<T>(s1, p1);
+    }
+#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+    template<typename T, typename... Args>
+    inline typename detail::sp_if_array<T>::type
+    make_shared(std::size_t size, Args&&... args) {
+        typedef typename remove_cv<shared_ptr<T>::element_type>::type T1;
+        T1* p1 = 0;
+        detail::make_array_helper<T1> a1(size, &p1);
+        detail::array_deleter<T1> d1;
+        shared_ptr<T> s1(p1, d1, a1);
+        detail::array_deleter<T1>* d2;
+        d2 = get_deleter<detail::array_deleter<T1> >(s1);
+        d2->construct(p1, size, std::forward<Args>(args)...);
+        return shared_ptr<T>(s1, p1);
+    }
+#endif
+    template<typename T>
+    inline typename detail::sp_if_array<T>::type
+    make_shared_noinit(std::size_t size) {
+        typedef typename remove_cv<shared_ptr<T>::element_type>::type T1;
+        T1* p1 = 0;
+        detail::make_array_helper<T1> a1(size, &p1);
+        detail::array_deleter<T1> d1;
+        shared_ptr<T> s1(p1, d1, a1);
+        detail::array_deleter<T1>* d2;
+        d2 = get_deleter<detail::array_deleter<T1> >(s1);
+        d2->construct_noinit(p1, size);
+        return shared_ptr<T>(s1, p1);
+    }
+}
+
+#endif
Added: trunk/libs/smart_ptr/make_shared_array.html
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/make_shared_array.html	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <title>make_shared and allocate_shared</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+  </head>
+  <body text="#000000" bgColor="#ffffff" link="#0000ff" vlink="#0000ff">
+    <h1><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" 
+      width="277" align="middle" border="0">make_shared and allocate_shared 
+      for arrays</h1>
+    <p>Introduction<br>
+      Synopsis<br>
+      Free Functions<br>
+      Example<br>
+    <h2><a name="Introduction">Introduction</a></h2>
+    <p>One criticism of Boost shared_array is 
+      the lack of utility similar to make_shared 
+      which ensures only a single allocation for an array. A second criticism 
+      is Boost <code>shared_array</code> does not support custom allocators 
+      and so also lacks an <code>allocate_shared</code> utility.</p>
+    <p>The header files <boost/smart_ptr/make_shared_array.hpp> and 
+      <boost/smart_ptr/allocate_shared_array.hpp> provide new function 
+      templates, <code>make_shared</code> and <code>allocate_shared</code>, 
+      to address this need. <code>make_shared</code> uses the global 
+      operator <code>new</code> to allocate memory, whereas 
+      <code>allocate_shared</code> uses an user-supplied allocator, 
+      allowing finer control.</p>
+    <h2><a name="Synopsis">Synopsis</a></h2>
+    <pre>namespace boost {
+    template<typename T>
+    shared_ptr<T> make_shared(size_t size);
+
+    template<typename T, typename A>
+    shared_ptr<T> allocate_shared(const A& allocator, size_t size);
+    
+#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+    template<typename T, typename... Args>
+    shared_ptr<T> make_shared(size_t size, Args&&... args);
+    
+    template<typename T, typename A, typename... Args>
+    shared_ptr<T> allocate_shared(const A& allocator, size_t size, Args&&... args);
+#endif
+
+    template<typename T>
+    shared_ptr<T> make_shared_noinit(size_t size);
+}</pre>
+    <h2><a name="functions">Free Functions</a></h2>
+    <pre>template<typename T, typename... Args>
+    shared_ptr<T> make_shared(size_t size, Args&&... args);
+template<typename T, typename A, typename... Args>
+    shared_ptr<T> allocate_shared(const A& allocator, size_t size, Args&&... args);</pre>
+    <blockquote>
+      <p><b>Requires:</b> The expression 
+        <code>new(pointer) T(std::forward<Args>(args)...)</code>, where 
+        <code>pointer</code> is a <code>void*</code> pointing to storage 
+        suitable to hold an object of type <code>T</code>, shall be 
+        well-formed. <code>A</code> shall be an <em>Allocator</em>, as 
+        described in section 20.1.5 (<strong>Allocator requirements</strong>) 
+        of the C++ Standard.  The copy constructor and destructor of 
+        <code>A</code> shall not throw.</p>
+      <p><b>Effects:</b> Allocates memory suitable for an array of type 
+        <code>T</code> and size <code>size</code> and constructs an array 
+        of objects in it via the placement new expression 
+        <code>new(pointer) T()</code> or 
+        <code>new(pointer) T(std::forward<Args>(args)...)</code>.
+        <code>allocate_shared</code> uses a copy of 
+        <code>allocator</code> to allocate memory.  If an exception is thrown, 
+        has no effect.</p>
+      <p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and 
+        owns the address of the newly constructed array of type <code>T</code> 
+        and size <code>size</code>.</p>
+      <p><b>Postconditions:</b> 
+        <code>get() != 0 && use_count() == 1</code>.</p>
+      <p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from 
+        <code>A::allocate</code> or the constructor of <code>T</code>.</p>
+      <p><b>Notes:</b> This implementation allocates the memory required for 
+        the returned <code>shared_ptr</code> and an array of type 
+        <code>T</code> of size <code>size</code> in a single allocation. This 
+        provides efficiency to equivalent to an intrusive smart array 
+        pointer.</p>
+      <p>The prototypes shown above are used if your compiler supports r-value
+        references and variadic templates. They perfectly forward the 
+        <code>args</code> parameters to the constructors of 
+        <code>T</code> for each array element.</p>
+      <p>Otherwise, you can use the overloads which take only the array size 
+        (and the allocator in case of <code>allocate_shared</code>) and do not 
+        take any constructor arguments. These overloads invoke the default 
+        constructor of <code>T</code> for each array element.</p>
+    </blockquote>
+    <h2><a name="example">Example</a></h2>
+    <pre>boost::shared_ptr<int[]> array = boost::make_shared<int[]>(size);</pre>
+    <hr>
+    <p>$Date: 2012-10-30 10:12:25 -0800 (Tue, 30 Oct 2012) $</p>
+    <p><small>Copyright 2012 Glen Fernandes. Distributed under the Boost 
+      Software License, Version 1.0. See accompanying file 
+      LICENSE_1_0.txt or copy at 
+      <A href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt>.</small></p>
+  </body>
+</html>
Added: trunk/libs/smart_ptr/test/allocate_shared_array_esft_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/allocate_shared_array_esft_test.cpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,42 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/smart_ptr/allocate_shared_array.hpp>
+#include <boost/smart_ptr/enable_shared_from_this.hpp>
+
+class type 
+    : public boost::enable_shared_from_this<type> {
+public:
+    static unsigned int instances;
+    explicit type() {
+        instances++;
+    }
+    ~type() {
+        instances--;
+    }
+private:
+    type(const type&);
+    type& operator=(const type&);
+};
+
+unsigned int type::instances = 0;
+
+int main() {
+    BOOST_TEST(type::instances == 0);
+    {
+        boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3);
+        try {
+            a1[0].shared_from_this();
+            BOOST_ERROR("shared_from_this did not throw");
+        } catch (const boost::bad_weak_ptr&) {
+            BOOST_TEST(type::instances == 3);
+        }
+    }
+    return boost::report_errors();
+}
Added: trunk/libs/smart_ptr/test/allocate_shared_array_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/allocate_shared_array_test.cpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,87 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/smart_ptr/allocate_shared_array.hpp>
+#include <boost/smart_ptr/weak_ptr.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+
+class type {
+public:
+    static unsigned int instances;
+    explicit type(int = 0, int = 0)
+        : member() {
+        instances++;
+    }
+    ~type() {
+        instances--;
+    }
+private:
+    type(const type&);
+    type& operator=(const type&);
+    double member;
+};
+
+unsigned int type::instances = 0;
+
+int main() {
+    {
+        boost::shared_ptr<int[]> a1 = boost::allocate_shared<int[]>(std::allocator<int>(), 3);
+        int* a2 = a1.get();
+        BOOST_TEST(a1.use_count() == 1);
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
+        BOOST_TEST(a1[0] == 0);
+        BOOST_TEST(a1[1] == 0);
+        BOOST_TEST(a1[2] == 0);
+    }
+    {
+        boost::shared_ptr<const int[]> a1 = boost::allocate_shared<const int[]>(std::allocator<int>(), 3);
+        const int* a2 = a1.get();
+        BOOST_TEST(a1.use_count() == 1);
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
+        BOOST_TEST(a1[0] == 0);
+        BOOST_TEST(a1[1] == 0);
+        BOOST_TEST(a1[2] == 0);
+    }
+    BOOST_TEST(type::instances == 0);
+    {
+        boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3);
+        type* a2 = a1.get();
+        BOOST_TEST(a1.use_count() == 1);
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
+        BOOST_TEST(type::instances == 3);
+        boost::weak_ptr<type[]> w1 = a1;
+        a1.reset();
+        BOOST_TEST(type::instances == 0);
+    }
+    BOOST_TEST(type::instances == 0);
+    {
+        boost::shared_ptr<const type[]> a1 = boost::allocate_shared<const type[]>(std::allocator<type>(), 3);
+        const type* a2 = a1.get();
+        BOOST_TEST(a1.use_count() == 1);
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
+        BOOST_TEST(type::instances == 3);
+    }
+#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+    BOOST_TEST(type::instances == 0);
+    {
+        boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3, 1, 5);
+        type* a2 = a1.get();
+        BOOST_TEST(type::instances == 3);
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
+        a1.reset();
+        BOOST_TEST(type::instances == 0);
+    }
+#endif
+    return boost::report_errors();
+}
Added: trunk/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,40 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/smart_ptr/allocate_shared_array.hpp>
+
+class type {
+public:
+    static unsigned int instances;
+    explicit type() {
+        if (instances == 5) {
+            throw true;
+        }
+        instances++;
+    }
+    ~type() {
+        instances--;
+    }
+private:
+    type(const type&);
+    type& operator=(const type&);
+};
+
+unsigned int type::instances = 0;
+
+int main() {
+    BOOST_TEST(type::instances == 0);
+    try {
+        boost::allocate_shared<type[]>(std::allocator<type>(), 6);
+        BOOST_ERROR("allocate_shared did not throw");
+    } catch (...) {
+        BOOST_TEST(type::instances == 0);
+    }
+    return boost::report_errors();
+}
Added: trunk/libs/smart_ptr/test/make_shared_array_esft_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/make_shared_array_esft_test.cpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,52 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/smart_ptr/enable_shared_from_this.hpp>
+#include <boost/smart_ptr/make_shared_array.hpp>
+
+class type
+    : public boost::enable_shared_from_this<type> {
+public:
+    static unsigned int instances;
+    explicit type() {
+        instances++;
+    }
+    ~type() {
+        instances--;
+    }
+private:
+    type(const type&);
+    type& operator=(const type&);
+};
+
+unsigned int type::instances = 0;
+
+int main() {
+    BOOST_TEST(type::instances == 0);
+    {
+        boost::shared_ptr<type[]> a1 = boost::make_shared<type[]>(3);
+        try {
+            a1[0].shared_from_this();
+            BOOST_ERROR("shared_from_this did not throw");
+        } catch (const boost::bad_weak_ptr&) {
+            BOOST_TEST(type::instances == 3);
+        }
+    }
+    BOOST_TEST(type::instances == 0);
+    {
+        boost::shared_ptr<type[]> a1 = boost::make_shared_noinit<type[]>(3);
+        try {
+            a1[0].shared_from_this();
+            BOOST_ERROR("shared_from_this did not throw");
+        } catch (const boost::bad_weak_ptr&) {
+            BOOST_TEST(type::instances == 3);
+        }
+    }
+    return boost::report_errors();
+}
Added: trunk/libs/smart_ptr/test/make_shared_array_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/make_shared_array_test.cpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,118 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/smart_ptr/make_shared_array.hpp>
+#include <boost/smart_ptr/weak_ptr.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+
+class type {
+public:
+    static unsigned int instances;
+    explicit type(int = 0, int = 0)
+        : member() {
+        instances++;
+    }
+    ~type() {
+        instances--;
+    }
+private:
+    type(const type&);
+    type& operator=(const type&);
+    double member;
+};
+
+unsigned int type::instances = 0;
+
+int main() {
+    {
+        boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(3);
+        int* a2 = a1.get();
+        BOOST_TEST(a1.use_count() == 1);
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
+        BOOST_TEST(a1[0] == 0);
+        BOOST_TEST(a1[1] == 0);
+        BOOST_TEST(a1[2] == 0);
+    }
+    {
+        boost::shared_ptr<const int[]> a1 = boost::make_shared<const int[]>(3);
+        const int* a2 = a1.get();
+        BOOST_TEST(a1.use_count() == 1);
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
+        BOOST_TEST(a1[0] == 0);
+        BOOST_TEST(a1[1] == 0);
+        BOOST_TEST(a1[2] == 0);
+    }
+    BOOST_TEST(type::instances == 0);
+    {
+        boost::shared_ptr<type[]> a1 = boost::make_shared<type[]>(3);
+        type* a2 = a1.get();
+        BOOST_TEST(a1.use_count() == 1);
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
+        BOOST_TEST(type::instances == 3);
+        boost::weak_ptr<type[]> w1 = a1;
+        a1.reset();
+        BOOST_TEST(type::instances == 0);
+    }
+    BOOST_TEST(type::instances == 0);
+    {
+        boost::shared_ptr<const type[]> a1 = boost::make_shared<const type[]>(3);
+        const type* a2 = a1.get();
+        BOOST_TEST(a1.use_count() == 1);
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
+        BOOST_TEST(type::instances == 3);
+    }
+#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
+    BOOST_TEST(type::instances == 0);
+    {
+        boost::shared_ptr<type[]> a1 = boost::make_shared<type[]>(3, 1, 5);
+        type* a2 = a1.get();
+        BOOST_TEST(type::instances == 3);
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
+        a1.reset();
+        BOOST_TEST(type::instances == 0);
+    }
+#endif
+    {
+        boost::shared_ptr<int[]> a1 = boost::make_shared_noinit<int[]>(3);
+        int* a2 = a1.get();
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
+    }
+    {
+        boost::shared_ptr<const int[]> a1 = boost::make_shared_noinit<const int[]>(3);
+        const int* a2 = a1.get();
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
+    }
+    BOOST_TEST(type::instances == 0);
+    {
+        boost::shared_ptr<type[]> a1 = boost::make_shared_noinit<type[]>(3);
+        type* a2 = a1.get();
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
+        BOOST_TEST(type::instances == 3);
+        boost::weak_ptr<type[]> w1 = a1;
+        a1.reset();
+        BOOST_TEST(type::instances == 0);
+    }
+    BOOST_TEST(type::instances == 0);
+    {
+        boost::shared_ptr<const type[]> a1 = boost::make_shared_noinit<const type[]>(3);
+        const type* a2 = a1.get();
+        BOOST_TEST(a2 != 0);
+        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
+        BOOST_TEST(type::instances == 3);
+    }
+    return boost::report_errors();
+}
Added: trunk/libs/smart_ptr/test/make_shared_array_throws_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/make_shared_array_throws_test.cpp	2012-11-06 09:17:32 EST (Tue, 06 Nov 2012)
@@ -0,0 +1,47 @@
+/*
+ * 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 
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/smart_ptr/make_shared_array.hpp>
+
+class type {
+public:
+    static unsigned int instances;
+    explicit type() {
+        if (instances == 5) {
+            throw true;
+        }
+        instances++;
+    }
+    ~type() {
+        instances--;
+    }
+private:
+    type(const type&);
+    type& operator=(const type&);
+};
+
+unsigned int type::instances = 0;
+
+int main() {
+    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::shared_ptr<type[]> a1 = boost::make_shared_noinit<type[]>(6);
+        BOOST_ERROR("make_shared_noinit did not throw");
+    } catch (...) {
+        BOOST_TEST(type::instances == 0);
+    }
+    return boost::report_errors();
+}