Ticket #3472: initialized.patch
File initialized.patch, 4.5 KB (added by , 13 years ago) |
---|
-
boost/utility/value_init.hpp
9 9 // 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola 10 10 // 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola 11 11 // 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola 12 // 03 Apr 2010 (Added initialized<T>, suggested by Jeffrey Hellrung, fixing #3472) Niels Dekker 12 13 // 13 14 #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP 14 15 #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP … … 28 29 #include <cstring> 29 30 #include <new> 30 31 32 #ifdef BOOST_MSVC 33 #pragma warning(push) 34 #if _MSC_VER >= 1310 35 // It is safe to ignore the following warning from MSVC 7.1 or higher: 36 // "warning C4351: new behavior: elements of array will be default initialized" 37 #pragma warning(disable: 4351) 38 #endif 39 #endif 40 31 41 namespace boost { 32 42 33 43 template<class T> 34 class value_initialized44 class initialized 35 45 { 36 46 private : 37 47 struct wrapper … … 40 50 typename 41 51 #endif 42 52 remove_const<T>::type data; 53 54 wrapper() 55 : 56 data() 57 { 58 } 59 60 wrapper(T const & arg) 61 : 62 data(arg) 63 { 64 } 43 65 }; 44 66 45 67 mutable … … 55 77 56 78 public : 57 79 58 value_initialized()80 initialized() 59 81 { 82 // Note: the following memset call will become conditional when ticket #3869 is fixed: 83 // https://svn.boost.org/trac/boost/ticket/3869 reported by Aleksey Gurtovoy. 60 84 std::memset(&x, 0, sizeof(x)); 61 #ifdef BOOST_MSVC 62 #pragma warning(push) 63 #if _MSC_VER >= 1310 64 // When using MSVC 7.1 or higher, the following placement new expression may trigger warning C4345: 65 // "behavior change: an object of POD type constructed with an initializer of the form () 66 // will be default-initialized". It is safe to ignore this warning when using value_initialized. 67 #pragma warning(disable: 4345) 68 #endif 69 #endif 85 70 86 new (wrapper_address()) wrapper(); 71 #ifdef BOOST_MSVC72 #pragma warning(pop)73 #endif74 87 } 75 88 76 value_initialized(value_initialized const & arg)89 initialized(initialized const & arg) 77 90 { 78 91 new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address()))); 79 92 } 80 93 81 value_initialized & operator=(value_initializedconst & arg)94 explicit initialized(T const & arg) 82 95 { 96 new (wrapper_address()) wrapper(arg); 97 } 98 99 initialized & operator=(initialized const & arg) 100 { 83 101 // Assignment is only allowed when T is non-const. 84 102 BOOST_STATIC_ASSERT( ! is_const<T>::value ); 85 103 *wrapper_address() = static_cast<wrapper const &>(*(arg.wrapper_address())); 86 104 return *this; 87 105 } 88 106 89 ~ value_initialized()107 ~initialized() 90 108 { 91 109 wrapper_address()->wrapper::~wrapper(); 92 110 } … … 101 119 return wrapper_address()->data; 102 120 } 103 121 104 void swap( value_initialized & arg)122 void swap(initialized & arg) 105 123 { 106 124 ::boost::swap( this->data(), arg.data() ); 107 125 } 108 126 109 operator T const &() const { return this->data(); } 127 operator T const &() const 128 { 129 return wrapper_address()->data; 130 } 110 131 111 operator T&() { return this->data(); } 132 operator T&() 133 { 134 return wrapper_address()->data; 135 } 112 136 113 137 } ; 114 138 139 template<class T> 140 T const& get ( initialized<T> const& x ) 141 { 142 return x.data() ; 143 } 115 144 145 template<class T> 146 T& get ( initialized<T>& x ) 147 { 148 return x.data() ; 149 } 116 150 117 151 template<class T> 152 void swap ( initialized<T> & lhs, initialized<T> & rhs ) 153 { 154 lhs.swap(rhs) ; 155 } 156 157 template<class T> 158 class value_initialized 159 { 160 private : 161 162 // initialized<T> does value-initialization by default. 163 initialized<T> m_data; 164 165 public : 166 167 T const & data() const 168 { 169 return m_data.data(); 170 } 171 172 T& data() 173 { 174 return m_data.data(); 175 } 176 177 void swap(value_initialized & arg) 178 { 179 m_data.swap(arg.m_data); 180 } 181 182 operator T const &() const 183 { 184 return m_data; 185 } 186 187 operator T&() 188 { 189 return m_data; 190 } 191 } ; 192 193 194 template<class T> 118 195 T const& get ( value_initialized<T> const& x ) 119 196 { 120 197 return x.data() ; 121 198 } 199 122 200 template<class T> 123 201 T& get ( value_initialized<T>& x ) 124 202 { … … 138 216 139 217 template <class T> operator T() const 140 218 { 141 return get( value_initialized<T>());219 return initialized<T>().data(); 142 220 } 143 221 }; 144 222 … … 147 225 148 226 } // namespace boost 149 227 228 #ifdef BOOST_MSVC 229 #pragma warning(pop) 230 #endif 150 231 151 232 #endif