]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
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> | |
20effc67 | 23 | #include <boost/atomic/detail/aligned_variable.hpp> |
f67539c2 | 24 | #include <boost/atomic/detail/type_traits/alignment_of.hpp> |
20effc67 | 25 | #include <boost/atomic/detail/header.hpp> |
f67539c2 TL |
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 > | |
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 | { | |
20effc67 TL |
44 | typedef unsigned char data_type[Size]; |
45 | BOOST_ATOMIC_DETAIL_ALIGNED_VAR_TPL(Alignment, data_type, data); | |
f67539c2 TL |
46 | |
47 | 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 | ||
52 | 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 | ||
57 | 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 > | |
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 | ||
20effc67 TL |
185 | #include <boost/atomic/detail/footer.hpp> |
186 | ||
f67539c2 | 187 | #endif // BOOST_ATOMIC_DETAIL_STORAGE_TRAITS_HPP_INCLUDED_ |