]> AND Private Git Repository - canny.git/blob - stc/exp/ml_stc_linux_make_v1.0/include/boost/utility/value_init.hpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
539ce709aa702bfe910af120927f6f92213cdfd4
[canny.git] / stc / exp / ml_stc_linux_make_v1.0 / include / 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 template<class T>\r
118 T const& get ( value_initialized<T> const& x )\r
119 {\r
120   return x.data() ;\r
121 }\r
122 template<class T>\r
123 T& get ( value_initialized<T>& x )\r
124 {\r
125   return x.data() ;\r
126 }\r
127 \r
128 template<class T>\r
129 void swap ( value_initialized<T> & lhs, value_initialized<T> & rhs )\r
130 {\r
131   lhs.swap(rhs) ;\r
132 }\r
133 \r
134 \r
135 class initialized_value_t\r
136 {\r
137   public :\r
138     \r
139     template <class T> operator T() const\r
140     {\r
141       return get( value_initialized<T>() );\r
142     }\r
143 };\r
144 \r
145 initialized_value_t const initialized_value = {} ;\r
146 \r
147 \r
148 } // namespace boost\r
149 \r
150 \r
151 #endif\r