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 BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS type; |
85 | |
86 | struct BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS type; |
99 | |
100 | struct BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS type; |
113 | |
114 | struct BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS type; |
127 | |
128 | struct BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS type; |
141 | |
142 | struct BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS type; |
155 | |
156 | struct BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS type; |
169 | |
170 | struct BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS type; |
183 | |
184 | struct BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS type; |
199 | |
200 | struct BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS type; |
213 | |
214 | struct BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS 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 BOOST_ATOMIC_DETAIL_MAY_ALIAS 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_ |
281 | |