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 - 2020 Andrey Semashev
9 */
10 /*!
11 * \file atomic/detail/storage_traits.hpp
12 *
13 * This header defines underlying types used as storage
14 */
15
16 #ifndef BOOST_ATOMIC_DETAIL_STORAGE_TRAITS_HPP_INCLUDED_
17 #define BOOST_ATOMIC_DETAIL_STORAGE_TRAITS_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 #include <boost/atomic/detail/aligned_variable.hpp>
24 #include <boost/atomic/detail/type_traits/alignment_of.hpp>
25 #include <boost/atomic/detail/header.hpp>
26
27 #ifdef BOOST_HAS_PRAGMA_ONCE
28 #pragma once
29 #endif
30
31 namespace boost {
32 namespace atomics {
33 namespace detail {
34
35 template< typename T >
non_atomic_load(T const volatile & from,T & to)36 BOOST_FORCEINLINE void non_atomic_load(T const volatile& from, T& to) BOOST_NOEXCEPT
37 {
38 to = from;
39 }
40
41 template< std::size_t Size, std::size_t Alignment = 1u >
42 struct BOOST_ATOMIC_DETAIL_MAY_ALIAS buffer_storage
43 {
44 typedef unsigned char data_type[Size];
45 BOOST_ATOMIC_DETAIL_ALIGNED_VAR_TPL(Alignment, data_type, data);
46
operator !boost::atomics::detail::buffer_storage47 BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT
48 {
49 return (data[0] == 0u && BOOST_ATOMIC_DETAIL_MEMCMP(data, data + 1, Size - 1u) == 0);
50 }
51
operator ==boost::atomics::detail::buffer_storage52 BOOST_FORCEINLINE bool operator== (buffer_storage const& that) const BOOST_NOEXCEPT
53 {
54 return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) == 0;
55 }
56
operator !=boost::atomics::detail::buffer_storage57 BOOST_FORCEINLINE bool operator!= (buffer_storage const& that) const BOOST_NOEXCEPT
58 {
59 return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) != 0;
60 }
61 };
62
63 template< std::size_t Size, std::size_t Alignment >
non_atomic_load(buffer_storage<Size,Alignment> const volatile & from,buffer_storage<Size,Alignment> & to)64 BOOST_FORCEINLINE void non_atomic_load(buffer_storage< Size, Alignment > const volatile& from, buffer_storage< Size, Alignment >& to) BOOST_NOEXCEPT
65 {
66 BOOST_ATOMIC_DETAIL_MEMCPY(to.data, const_cast< unsigned char const* >(from.data), Size);
67 }
68
69 template< std::size_t Size >
70 struct storage_traits
71 {
72 typedef buffer_storage< Size, 1u > type;
73
74 static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = 1u;
75
76 // By default, prefer the maximum supported alignment
77 static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 16u;
78 };
79
80 template< >
81 struct storage_traits< 1u >
82 {
83 typedef boost::uint8_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
84
85 static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = 1u;
86 static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 1u;
87 };
88
89 template< >
90 struct storage_traits< 2u >
91 {
92 typedef boost::uint16_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
93
94 static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = atomics::detail::alignment_of< boost::uint16_t >::value;
95 static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 2u;
96 };
97
98 template< >
99 struct storage_traits< 4u >
100 {
101 typedef boost::uint32_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
102
103 static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = atomics::detail::alignment_of< boost::uint32_t >::value;
104 static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 4u;
105 };
106
107 template< >
108 struct storage_traits< 8u >
109 {
110 typedef boost::uint64_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
111
112 static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = atomics::detail::alignment_of< boost::uint64_t >::value;
113 static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 8u;
114 };
115
116 #if defined(BOOST_HAS_INT128)
117
118 template< >
119 struct storage_traits< 16u >
120 {
121 typedef boost::uint128_type BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
122
123 static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = atomics::detail::alignment_of< boost::uint128_type >::value;
124 static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 16u;
125 };
126
127 #else
128
129 #if (__cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)) &&\
130 (!defined(BOOST_GCC_VERSION) || BOOST_GCC_VERSION >= 40900)
131 using std::max_align_t;
132 #else
133
134 #if defined(BOOST_MSVC)
135 #pragma warning(push)
136 // alignment is sensitive to packing
137 #pragma warning(disable: 4121)
138 #endif
139
140 class max_align_helper;
141 union max_align_t
142 {
143 void* ptr;
144 void (*fun_ptr)();
145 int max_align_helper::*mem_ptr;
146 void (max_align_helper::*mem_fun_ptr)();
147 long long ll;
148 long double ld;
149 #if defined(BOOST_HAS_INT128)
150 boost::int128_type i128;
151 #endif
152 #if defined(BOOST_HAS_FLOAT128)
153 boost::float128_type f128;
154 #endif
155 };
156
157 #if defined(BOOST_MSVC)
158 #pragma warning(pop)
159 #endif
160
161 #endif // __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
162
163 template< >
164 struct storage_traits< 16u >
165 {
166 typedef buffer_storage< 16u, atomics::detail::alignment_of< atomics::detail::max_align_t >::value > type;
167
168 static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = atomics::detail::alignment_of< atomics::detail::max_align_t >::value;
169 static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 16u;
170 };
171
172 #endif
173
174 template< typename T >
175 struct storage_size_of
176 {
177 static BOOST_CONSTEXPR_OR_CONST std::size_t size = sizeof(T);
178 static BOOST_CONSTEXPR_OR_CONST std::size_t value = (size == 3u ? 4u : (size >= 5u && size <= 7u ? 8u : (size >= 9u && size <= 15u ? 16u : size)));
179 };
180
181 } // namespace detail
182 } // namespace atomics
183 } // namespace boost
184
185 #include <boost/atomic/detail/footer.hpp>
186
187 #endif // BOOST_ATOMIC_DETAIL_STORAGE_TRAITS_HPP_INCLUDED_
188