Ticket #1217: value_init_MSVC_workaround.hpp

File value_init_MSVC_workaround.hpp, 3.4 KB (added by Niels Dekker, 15 years ago)

Proposes new version of value_init.hpp

Line 
1////////////////////////////////////////////////////////////////////////
2// Adapted version of http://svn.boost.org/trac/boost/log/trunk/boost/boost/utility/value_init.hpp?rev=35084
3////////////////////////////////////////////////////////////////////////
4// (C) Copyright 2002, Fernando Luis Cacciola Carballal.
5//
6// Distributed under the Boost Software License, Version 1.0. (See
7// accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9//
10// 21 Ago 2002 (Created) Fernando Cacciola
11// 27 Ago 2007 (Worked around MSVC++ bug) Fernando Cacciola, Niels Dekker
12//
13#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
14#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
15
16#include <boost/detail/select_type.hpp>
17#include <boost/type_traits/cv_traits.hpp>
18#include <boost/detail/workaround.hpp>
19
20#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) )
21// Microsoft Visual C++ does not correctly support value initialization, as reported by
22// Pavel, 7/28/2005, Feedback ID 100744, Value-initialization in new-expression
23// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
24// The report was closed at 11/14/2006, and its status was set to "Closed (Won't Fix)".
25// Luckily, even in the presence of this compiler bug, boost::value_initialized will still
26// do its job correctly, when using the following workaround:
27#define BOOST_UTILITY_VALUE_INIT_WORKAROUND
28#endif
29
30#ifdef BOOST_UTILITY_VALUE_INIT_WORKAROUND
31#include <boost/aligned_storage.hpp>
32#include <boost/type_traits/alignment_of.hpp>
33#include <cstring>
34
35namespace boost {
36
37namespace vinit_detail {
38
39template<class T>
40class const_T_base
41{
42 protected :
43
44 const_T_base() { std::memset(&x, 0, sizeof(x)); new (&x) T(); }
45 ~const_T_base() { get().T::~T(); }
46
47 T & get() const { void const * ptr = &x; return *static_cast<T*>(ptr); }
48 private :
49 typename ::boost::aligned_storage<sizeof(T), ::boost::alignment_of<T>::value>::type x;
50} ;
51
52template<class T>
53class non_const_T_base
54{
55 protected :
56
57 non_const_T_base() { std::memset(&x, 0, sizeof(x)); new (&x) T(); }
58 ~non_const_T_base() { get().T::~T(); }
59
60 T & get() const { void * ptr = &x; return *static_cast<T*>(ptr); }
61 private :
62 mutable typename ::boost::aligned_storage<sizeof(T), ::boost::alignment_of<T>::value>::type x;
63} ;
64
65#else
66
67namespace boost {
68
69namespace vinit_detail {
70
71template<class T>
72class const_T_base
73{
74 protected :
75
76 const_T_base() : x() {}
77 T & get() const { return x; }
78
79 private :
80 T x ;
81} ;
82
83template<class T>
84class non_const_T_base
85{
86 protected :
87
88 non_const_T_base() : x() {}
89 T & get() const { return x; }
90
91 private :
92 mutable T x ;
93} ;
94
95#endif
96
97template<class T>
98struct select_base
99{
100 typedef
101#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
102 typename
103#endif
104 ::boost::detail::if_true< ::boost::is_const<T>::value >
105 ::template then< const_T_base<T>, non_const_T_base<T> >::type type ;
106} ;
107
108} // namespace vinit_detail
109
110template<class T>
111class value_initialized : private vinit_detail::select_base<T>::type
112{
113 public :
114
115 value_initialized() {}
116
117 operator T&() const { return this->get(); }
118
119 T& data() const { return this->get(); }
120
121} ;
122
123template<class T>
124T const& get ( value_initialized<T> const& x )
125{
126 return x.data() ;
127}
128template<class T>
129T& get ( value_initialized<T>& x )
130{
131 return x.data() ;
132}
133
134} // namespace boost
135
136
137#endif