1 /* 2 * Copyright (c) 2012-2014 Glen Joseph Fernandes 3 * glenfe at live dot com 4 * 5 * Distributed under the Boost Software License, 6 * Version 1.0. (See accompanying file LICENSE_1_0.txt 7 * or copy at http://boost.org/LICENSE_1_0.txt) 8 */ 9 #ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP 10 #define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP 11 12 #include <boost/smart_ptr/detail/array_count_impl.hpp> 13 #include <boost/smart_ptr/detail/sp_if_array.hpp> 14 15 namespace boost { 16 template<class T> 17 inline typename boost::detail::sp_if_array<T>::type make_shared(std::size_t size)18 make_shared(std::size_t size) { 19 typedef typename boost::detail::array_inner<T>::type T1; 20 typedef typename boost::detail::array_base<T1>::type T2; 21 typedef boost::detail::ms_allocator<T> A1; 22 typedef boost::detail::ms_in_allocator_tag D1; 23 std::size_t n1 = size * boost::detail::array_total<T1>::size; 24 T1* p1 = 0; 25 T2* p2 = 0; 26 D1 d1; 27 A1 a1(size, &p2); 28 shared_ptr<T> s1(p1, d1, a1); 29 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 30 a2->set(0); 31 boost::detail::ms_init(p2, n1); 32 a2->set(p2); 33 p1 = reinterpret_cast<T1*>(p2); 34 return shared_ptr<T>(s1, p1); 35 } 36 37 template<class T> 38 inline typename boost::detail::sp_if_size_array<T>::type make_shared()39 make_shared() { 40 typedef typename boost::detail::array_inner<T>::type T1; 41 typedef typename boost::detail::array_base<T1>::type T2; 42 typedef boost::detail::ms_allocator<T> A1; 43 typedef boost::detail::ms_in_allocator_tag D1; 44 enum { 45 N = boost::detail::array_total<T>::size 46 }; 47 T1* p1 = 0; 48 T2* p2 = 0; 49 D1 d1; 50 A1 a1(&p2); 51 shared_ptr<T> s1(p1, d1, a1); 52 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 53 a2->set(0); 54 boost::detail::ms_init(p2, N); 55 a2->set(p2); 56 p1 = reinterpret_cast<T1*>(p2); 57 return shared_ptr<T>(s1, p1); 58 } 59 60 template<class T> 61 inline typename boost::detail::sp_if_array<T>::type make_shared(std::size_t size,const typename boost::detail::array_inner<T>::type & value)62 make_shared(std::size_t size, 63 const typename boost::detail::array_inner<T>::type& value) { 64 typedef typename boost::detail::array_inner<T>::type T1; 65 typedef typename boost::detail::array_base<T1>::type T2; 66 typedef const T2 T3; 67 typedef boost::detail::ms_allocator<T> A1; 68 typedef boost::detail::ms_in_allocator_tag D1; 69 enum { 70 M = boost::detail::array_total<T1>::size 71 }; 72 std::size_t n1 = M * size; 73 T1* p1 = 0; 74 T2* p2 = 0; 75 T3* p3 = reinterpret_cast<T3*>(&value); 76 D1 d1; 77 A1 a1(size, &p2); 78 shared_ptr<T> s1(p1, d1, a1); 79 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 80 a2->set(0); 81 boost::detail::ms_init<T2, M>(p2, n1, p3); 82 a2->set(p2); 83 p1 = reinterpret_cast<T1*>(p2); 84 return shared_ptr<T>(s1, p1); 85 } 86 87 template<class T> 88 inline typename boost::detail::sp_if_size_array<T>::type make_shared(const typename boost::detail::array_inner<T>::type & value)89 make_shared(const typename boost::detail::array_inner<T>::type& value) { 90 typedef typename boost::detail::array_inner<T>::type T1; 91 typedef typename boost::detail::array_base<T1>::type T2; 92 typedef const T2 T3; 93 typedef boost::detail::ms_allocator<T> A1; 94 typedef boost::detail::ms_in_allocator_tag D1; 95 enum { 96 M = boost::detail::array_total<T1>::size, 97 N = boost::detail::array_total<T>::size 98 }; 99 T1* p1 = 0; 100 T2* p2 = 0; 101 T3* p3 = reinterpret_cast<T3*>(&value); 102 D1 d1; 103 A1 a1(&p2); 104 shared_ptr<T> s1(p1, d1, a1); 105 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 106 a2->set(0); 107 boost::detail::ms_init<T2, M>(p2, N, p3); 108 a2->set(p2); 109 p1 = reinterpret_cast<T1*>(p2); 110 return shared_ptr<T>(s1, p1); 111 } 112 113 template<class T> 114 inline typename boost::detail::sp_if_array<T>::type make_shared_noinit(std::size_t size)115 make_shared_noinit(std::size_t size) { 116 typedef typename boost::detail::array_inner<T>::type T1; 117 typedef typename boost::detail::array_base<T1>::type T2; 118 typedef boost::detail::ms_allocator<T> A1; 119 typedef boost::detail::ms_in_allocator_tag D1; 120 std::size_t n1 = size * boost::detail::array_total<T1>::size; 121 T1* p1 = 0; 122 T2* p2 = 0; 123 D1 d1; 124 A1 a1(size, &p2); 125 shared_ptr<T> s1(p1, d1, a1); 126 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 127 a2->set(0); 128 boost::detail::ms_noinit(p2, n1); 129 a2->set(p2); 130 p1 = reinterpret_cast<T1*>(p2); 131 return shared_ptr<T>(s1, p1); 132 } 133 134 template<class T> 135 inline typename boost::detail::sp_if_size_array<T>::type make_shared_noinit()136 make_shared_noinit() { 137 typedef typename boost::detail::array_inner<T>::type T1; 138 typedef typename boost::detail::array_base<T1>::type T2; 139 typedef boost::detail::ms_allocator<T> A1; 140 typedef boost::detail::ms_in_allocator_tag D1; 141 enum { 142 N = boost::detail::array_total<T>::size 143 }; 144 T1* p1 = 0; 145 T2* p2 = 0; 146 D1 d1; 147 A1 a1(&p2); 148 shared_ptr<T> s1(p1, d1, a1); 149 A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter()); 150 a2->set(0); 151 boost::detail::ms_noinit(p2, N); 152 a2->set(p2); 153 p1 = reinterpret_cast<T1*>(p2); 154 return shared_ptr<T>(s1, p1); 155 } 156 } 157 158 #endif 159