]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | * Distributed under the Boost Software License, Version 1.0. | |
3 | * (See accompanying file LICENSE_1_0.txt or copy at | |
4 | * http://www.boost.org/LICENSE_1_0.txt) | |
5 | * | |
6 | * Copyright (c) 2009 Helge Bahmann | |
7 | * Copyright (c) 2012 Tim Blechmann | |
8 | * Copyright (c) 2013 - 2014 Andrey Semashev | |
9 | */ | |
10 | /*! | |
11 | * \file atomic/detail/storage_type.hpp | |
12 | * | |
13 | * This header defines underlying types used as storage | |
14 | */ | |
15 | ||
16 | #ifndef BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_ | |
17 | #define BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_ | |
18 | ||
19 | #include <cstddef> | |
20 | #include <boost/cstdint.hpp> | |
21 | #include <boost/atomic/detail/config.hpp> | |
22 | #if !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP) || !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY) | |
23 | #include <cstring> | |
24 | #endif | |
25 | ||
26 | #ifdef BOOST_HAS_PRAGMA_ONCE | |
27 | #pragma once | |
28 | #endif | |
29 | ||
30 | namespace boost { | |
31 | namespace atomics { | |
32 | namespace detail { | |
33 | ||
34 | template< typename T > | |
35 | BOOST_FORCEINLINE void non_atomic_load(T const volatile& from, T& to) BOOST_NOEXCEPT | |
36 | { | |
37 | to = from; | |
38 | } | |
39 | ||
40 | template< std::size_t Size > | |
41 | struct buffer_storage | |
42 | { | |
43 | BOOST_ALIGNMENT(16) unsigned char data[Size]; | |
44 | ||
45 | BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT | |
46 | { | |
47 | return (data[0] == 0u && BOOST_ATOMIC_DETAIL_MEMCMP(data, data + 1, Size - 1) == 0); | |
48 | } | |
49 | ||
50 | BOOST_FORCEINLINE bool operator== (buffer_storage const& that) const BOOST_NOEXCEPT | |
51 | { | |
52 | return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) == 0; | |
53 | } | |
54 | ||
55 | BOOST_FORCEINLINE bool operator!= (buffer_storage const& that) const BOOST_NOEXCEPT | |
56 | { | |
57 | return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) != 0; | |
58 | } | |
59 | }; | |
60 | ||
61 | template< std::size_t Size > | |
62 | BOOST_FORCEINLINE void non_atomic_load(buffer_storage< Size > const volatile& from, buffer_storage< Size >& to) BOOST_NOEXCEPT | |
63 | { | |
64 | BOOST_ATOMIC_DETAIL_MEMCPY(to.data, const_cast< unsigned char const* >(from.data), Size); | |
65 | } | |
66 | ||
67 | template< std::size_t Size, bool Signed > | |
68 | struct make_storage_type | |
69 | { | |
70 | typedef buffer_storage< Size > type; | |
71 | ||
72 | struct aligned | |
73 | { | |
74 | type value; | |
75 | ||
76 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
77 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type const& v) BOOST_NOEXCEPT : value(v) {} | |
78 | }; | |
79 | }; | |
80 | ||
81 | template< > | |
82 | struct make_storage_type< 1u, false > | |
83 | { | |
84 | typedef boost::uint8_t type; | |
85 | ||
86 | struct aligned | |
87 | { | |
88 | type value; | |
89 | ||
90 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
91 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} | |
92 | }; | |
93 | }; | |
94 | ||
95 | template< > | |
96 | struct make_storage_type< 1u, true > | |
97 | { | |
98 | typedef boost::int8_t type; | |
99 | ||
100 | struct aligned | |
101 | { | |
102 | type value; | |
103 | ||
104 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
105 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} | |
106 | }; | |
107 | }; | |
108 | ||
109 | template< > | |
110 | struct make_storage_type< 2u, false > | |
111 | { | |
112 | typedef boost::uint16_t type; | |
113 | ||
114 | struct aligned | |
115 | { | |
116 | BOOST_ALIGNMENT(2) type value; | |
117 | ||
118 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
119 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} | |
120 | }; | |
121 | }; | |
122 | ||
123 | template< > | |
124 | struct make_storage_type< 2u, true > | |
125 | { | |
126 | typedef boost::int16_t type; | |
127 | ||
128 | struct aligned | |
129 | { | |
130 | BOOST_ALIGNMENT(2) type value; | |
131 | ||
132 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
133 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} | |
134 | }; | |
135 | }; | |
136 | ||
137 | template< > | |
138 | struct make_storage_type< 4u, false > | |
139 | { | |
140 | typedef boost::uint32_t type; | |
141 | ||
142 | struct aligned | |
143 | { | |
144 | BOOST_ALIGNMENT(4) type value; | |
145 | ||
146 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
147 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} | |
148 | }; | |
149 | }; | |
150 | ||
151 | template< > | |
152 | struct make_storage_type< 4u, true > | |
153 | { | |
154 | typedef boost::int32_t type; | |
155 | ||
156 | struct aligned | |
157 | { | |
158 | BOOST_ALIGNMENT(4) type value; | |
159 | ||
160 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
161 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} | |
162 | }; | |
163 | }; | |
164 | ||
165 | template< > | |
166 | struct make_storage_type< 8u, false > | |
167 | { | |
168 | typedef boost::uint64_t type; | |
169 | ||
170 | struct aligned | |
171 | { | |
172 | BOOST_ALIGNMENT(8) type value; | |
173 | ||
174 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
175 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} | |
176 | }; | |
177 | }; | |
178 | ||
179 | template< > | |
180 | struct make_storage_type< 8u, true > | |
181 | { | |
182 | typedef boost::int64_t type; | |
183 | ||
184 | struct aligned | |
185 | { | |
186 | BOOST_ALIGNMENT(8) type value; | |
187 | ||
188 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
189 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} | |
190 | }; | |
191 | }; | |
192 | ||
193 | #if defined(BOOST_HAS_INT128) | |
194 | ||
195 | template< > | |
196 | struct make_storage_type< 16u, false > | |
197 | { | |
198 | typedef boost::uint128_type type; | |
199 | ||
200 | struct aligned | |
201 | { | |
202 | BOOST_ALIGNMENT(16) type value; | |
203 | ||
204 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
205 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} | |
206 | }; | |
207 | }; | |
208 | ||
209 | template< > | |
210 | struct make_storage_type< 16u, true > | |
211 | { | |
212 | typedef boost::int128_type type; | |
213 | ||
214 | struct aligned | |
215 | { | |
216 | BOOST_ALIGNMENT(16) type value; | |
217 | ||
218 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
219 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} | |
220 | }; | |
221 | }; | |
222 | ||
223 | #elif !defined(BOOST_NO_ALIGNMENT) | |
224 | ||
225 | struct storage128_t | |
226 | { | |
227 | boost::uint64_t data[2]; | |
228 | ||
229 | BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT | |
230 | { | |
231 | return data[0] == 0 && data[1] == 0; | |
232 | } | |
233 | }; | |
234 | ||
235 | BOOST_FORCEINLINE bool operator== (storage128_t const& left, storage128_t const& right) BOOST_NOEXCEPT | |
236 | { | |
237 | return left.data[0] == right.data[0] && left.data[1] == right.data[1]; | |
238 | } | |
239 | BOOST_FORCEINLINE bool operator!= (storage128_t const& left, storage128_t const& right) BOOST_NOEXCEPT | |
240 | { | |
241 | return !(left == right); | |
242 | } | |
243 | ||
244 | BOOST_FORCEINLINE void non_atomic_load(storage128_t const volatile& from, storage128_t& to) BOOST_NOEXCEPT | |
245 | { | |
246 | to.data[0] = from.data[0]; | |
247 | to.data[1] = from.data[1]; | |
248 | } | |
249 | ||
250 | template< bool Signed > | |
251 | struct make_storage_type< 16u, Signed > | |
252 | { | |
253 | typedef storage128_t type; | |
254 | ||
255 | struct aligned | |
256 | { | |
257 | BOOST_ALIGNMENT(16) type value; | |
258 | ||
259 | BOOST_DEFAULTED_FUNCTION(aligned(), {}) | |
260 | BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type const& v) BOOST_NOEXCEPT : value(v) {} | |
261 | }; | |
262 | }; | |
263 | ||
264 | #endif | |
265 | ||
266 | template< typename T > | |
267 | struct storage_size_of | |
268 | { | |
269 | enum _ | |
270 | { | |
271 | size = sizeof(T), | |
272 | value = (size == 3 ? 4 : (size >= 5 && size <= 7 ? 8 : (size >= 9 && size <= 15 ? 16 : size))) | |
273 | }; | |
274 | }; | |
275 | ||
276 | } // namespace detail | |
277 | } // namespace atomics | |
278 | } // namespace boost | |
279 | ||
280 | #endif // BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_ |