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