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