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 #include <boost/atomic/detail/string_ops.hpp>
23
24 #ifdef BOOST_HAS_PRAGMA_ONCE
25 #pragma once
26 #endif
27
28 namespace boost {
29 namespace atomics {
30 namespace detail {
31
32 template< typename T >
non_atomic_load(T const volatile & from,T & to)33 BOOST_FORCEINLINE void non_atomic_load(T const volatile& from, T& to) BOOST_NOEXCEPT
34 {
35 to = from;
36 }
37
38 template< std::size_t Size >
39 struct BOOST_ATOMIC_DETAIL_MAY_ALIAS buffer_storage
40 {
41 BOOST_ALIGNMENT(16) unsigned char data[Size];
42
operator !boost::atomics::detail::buffer_storage43 BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT
44 {
45 return (data[0] == 0u && BOOST_ATOMIC_DETAIL_MEMCMP(data, data + 1, Size - 1) == 0);
46 }
47
operator ==boost::atomics::detail::buffer_storage48 BOOST_FORCEINLINE bool operator== (buffer_storage const& that) const BOOST_NOEXCEPT
49 {
50 return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) == 0;
51 }
52
operator !=boost::atomics::detail::buffer_storage53 BOOST_FORCEINLINE bool operator!= (buffer_storage const& that) const BOOST_NOEXCEPT
54 {
55 return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) != 0;
56 }
57 };
58
59 template< std::size_t Size >
non_atomic_load(buffer_storage<Size> const volatile & from,buffer_storage<Size> & to)60 BOOST_FORCEINLINE void non_atomic_load(buffer_storage< Size > const volatile& from, buffer_storage< Size >& to) BOOST_NOEXCEPT
61 {
62 BOOST_ATOMIC_DETAIL_MEMCPY(to.data, const_cast< unsigned char const* >(from.data), Size);
63 }
64
65 template< std::size_t Size >
66 struct make_storage_type
67 {
68 typedef buffer_storage< Size > type;
69
70 struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned
71 {
72 type value;
73
alignedboost::atomics::detail::make_storage_type::aligned74 BOOST_DEFAULTED_FUNCTION(aligned(), {})
75 BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type const& v) BOOST_NOEXCEPT : value(v) {}
76 };
77 };
78
79 template< >
80 struct make_storage_type< 1u >
81 {
82 typedef boost::uint8_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
83
84 struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned
85 {
86 type value;
87
alignedboost::atomics::detail::make_storage_type::aligned88 BOOST_DEFAULTED_FUNCTION(aligned(), {})
89 BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {}
90 };
91 };
92
93 template< >
94 struct make_storage_type< 2u >
95 {
96 typedef boost::uint16_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
97
98 struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned
99 {
100 BOOST_ALIGNMENT(2) type value;
101
alignedboost::atomics::detail::make_storage_type::aligned102 BOOST_DEFAULTED_FUNCTION(aligned(), {})
103 BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {}
104 };
105 };
106
107 template< >
108 struct make_storage_type< 4u >
109 {
110 typedef boost::uint32_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
111
112 struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned
113 {
114 BOOST_ALIGNMENT(4) type value;
115
alignedboost::atomics::detail::make_storage_type::aligned116 BOOST_DEFAULTED_FUNCTION(aligned(), {})
117 BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {}
118 };
119 };
120
121 template< >
122 struct make_storage_type< 8u >
123 {
124 typedef boost::uint64_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
125
126 struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned
127 {
128 BOOST_ALIGNMENT(8) type value;
129
alignedboost::atomics::detail::make_storage_type::aligned130 BOOST_DEFAULTED_FUNCTION(aligned(), {})
131 BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {}
132 };
133 };
134
135 #if defined(BOOST_HAS_INT128)
136
137 template< >
138 struct make_storage_type< 16u >
139 {
140 typedef boost::uint128_type BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
141
142 struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned
143 {
144 BOOST_ALIGNMENT(16) 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 #elif !defined(BOOST_NO_ALIGNMENT)
152
153 struct BOOST_ATOMIC_DETAIL_MAY_ALIAS storage128_t
154 {
155 typedef boost::uint64_t BOOST_ATOMIC_DETAIL_MAY_ALIAS element_type;
156
157 element_type data[2];
158
operator !boost::atomics::detail::storage128_t159 BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT
160 {
161 return (data[0] | data[1]) == 0u;
162 }
163 };
164
operator ==(storage128_t const & left,storage128_t const & right)165 BOOST_FORCEINLINE bool operator== (storage128_t const& left, storage128_t const& right) BOOST_NOEXCEPT
166 {
167 return ((left.data[0] ^ right.data[0]) | (left.data[1] ^ right.data[1])) == 0u;
168 }
operator !=(storage128_t const & left,storage128_t const & right)169 BOOST_FORCEINLINE bool operator!= (storage128_t const& left, storage128_t const& right) BOOST_NOEXCEPT
170 {
171 return !(left == right);
172 }
173
non_atomic_load(storage128_t const volatile & from,storage128_t & to)174 BOOST_FORCEINLINE void non_atomic_load(storage128_t const volatile& from, storage128_t& to) BOOST_NOEXCEPT
175 {
176 to.data[0] = from.data[0];
177 to.data[1] = from.data[1];
178 }
179
180 template< >
181 struct make_storage_type< 16u >
182 {
183 typedef storage128_t type;
184
185 struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned
186 {
187 BOOST_ALIGNMENT(16) type value;
188
alignedboost::atomics::detail::make_storage_type::aligned189 BOOST_DEFAULTED_FUNCTION(aligned(), {})
190 BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type const& v) BOOST_NOEXCEPT : value(v) {}
191 };
192 };
193
194 #endif
195
196 template< typename T >
197 struct storage_size_of
198 {
199 static BOOST_CONSTEXPR_OR_CONST std::size_t size = sizeof(T);
200 static BOOST_CONSTEXPR_OR_CONST std::size_t value = (size == 3u ? 4u : (size >= 5u && size <= 7u ? 8u : (size >= 9u && size <= 15u ? 16u : size)));
201 };
202
203 } // namespace detail
204 } // namespace atomics
205 } // namespace boost
206
207 #endif // BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_
208