]> git.lyx.org Git - features.git/blob - boost/boost/utility/value_init.hpp
boost: add eol property
[features.git] / boost / boost / utility / value_init.hpp
1 // (C) Copyright 2002-2008, Fernando Luis Cacciola Carballal.
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // 21 Ago 2002 (Created) Fernando Cacciola
8 // 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker
9 // 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
10 // 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola
11 // 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola
12 //
13 #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
14 #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
15
16 // Note: The implementation of boost::value_initialized had to deal with the
17 // fact that various compilers haven't fully implemented value-initialization.
18 // The constructor of boost::value_initialized<T> works around these compiler
19 // issues, by clearing the bytes of T, before constructing the T object it
20 // contains. More details on these issues are at libs/utility/value_init.htm
21
22 #include <boost/aligned_storage.hpp>
23 #include <boost/detail/workaround.hpp>
24 #include <boost/static_assert.hpp>
25 #include <boost/type_traits/cv_traits.hpp>
26 #include <boost/type_traits/alignment_of.hpp>
27 #include <boost/swap.hpp>
28 #include <cstring>
29 #include <new>
30
31 namespace boost {
32
33 template<class T>
34 class value_initialized
35 {
36   private :
37     struct wrapper
38     {
39 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
40       typename
41 #endif 
42       remove_const<T>::type data;
43     };
44
45     mutable
46 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
47       typename
48 #endif 
49       aligned_storage<sizeof(wrapper), alignment_of<wrapper>::value>::type x;
50
51     wrapper * wrapper_address() const
52     {
53       return static_cast<wrapper *>( static_cast<void*>(&x));
54     }
55
56   public :
57
58     value_initialized()
59     {
60       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
70       new (wrapper_address()) wrapper();
71 #ifdef BOOST_MSVC
72 #pragma warning(pop)
73 #endif
74     }
75
76     value_initialized(value_initialized const & arg)
77     {
78       new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
79     }
80
81     value_initialized & operator=(value_initialized const & arg)
82     {
83       // Assignment is only allowed when T is non-const.
84       BOOST_STATIC_ASSERT( ! is_const<T>::value );
85       *wrapper_address() = static_cast<wrapper const &>(*(arg.wrapper_address()));
86       return *this;
87     }
88
89     ~value_initialized()
90     {
91       wrapper_address()->wrapper::~wrapper();
92     }
93
94     T const & data() const
95     {
96       return wrapper_address()->data;
97     }
98
99     T& data()
100     {
101       return wrapper_address()->data;
102     }
103
104     void swap(value_initialized & arg)
105     {
106       ::boost::swap( this->data(), arg.data() );
107     }
108
109     operator T const &() const { return this->data(); }
110
111     operator T&() { return this->data(); }
112
113 } ;
114
115
116
117
118
119 template<class T>
120 T const& get ( value_initialized<T> const& x )
121 {
122   return x.data() ;
123 }
124 template<class T>
125 T& get ( value_initialized<T>& x )
126 {
127   return x.data() ;
128 }
129
130 template<class T>
131 void swap ( value_initialized<T> & lhs, value_initialized<T> & rhs )
132 {
133   lhs.swap(rhs) ;
134 }
135
136
137 class initialized_value_t
138 {
139   public :
140     
141     template <class T> operator T() const
142     {
143       return get( value_initialized<T>() );
144     }
145 };
146
147 initialized_value_t const initialized_value = {} ;
148
149
150 } // namespace boost
151
152
153 #endif