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