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