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 >
non_atomic_load(T const volatile & from,T & to)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 
operator !boost::atomics::detail::buffer_storage45     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 
operator ==boost::atomics::detail::buffer_storage50     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 
operator !=boost::atomics::detail::buffer_storage55     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 >
non_atomic_load(buffer_storage<Size> const volatile & from,buffer_storage<Size> & to)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 
alignedboost::atomics::detail::make_storage_type::aligned76         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 
alignedboost::atomics::detail::make_storage_type::aligned90         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 
alignedboost::atomics::detail::make_storage_type::aligned104         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 
alignedboost::atomics::detail::make_storage_type::aligned118         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 
alignedboost::atomics::detail::make_storage_type::aligned132         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 
alignedboost::atomics::detail::make_storage_type::aligned146         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 
alignedboost::atomics::detail::make_storage_type::aligned160         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 
alignedboost::atomics::detail::make_storage_type::aligned174         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 
alignedboost::atomics::detail::make_storage_type::aligned188         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 
alignedboost::atomics::detail::make_storage_type::aligned204         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 
alignedboost::atomics::detail::make_storage_type::aligned218         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 
operator !boost::atomics::detail::storage128_t229     BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT
230     {
231         return data[0] == 0 && data[1] == 0;
232     }
233 };
234 
operator ==(storage128_t const & left,storage128_t const & right)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 }
operator !=(storage128_t const & left,storage128_t const & right)239 BOOST_FORCEINLINE bool operator!= (storage128_t const& left, storage128_t const& right) BOOST_NOEXCEPT
240 {
241     return !(left == right);
242 }
243 
non_atomic_load(storage128_t const volatile & from,storage128_t & to)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 
alignedboost::atomics::detail::make_storage_type::aligned259         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