Embedded Template Library 1.0
alignment.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2014 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_ALIGNMENT_INCLUDED
32#define ETL_ALIGNMENT_INCLUDED
33
34#include "platform.h"
35#include "type_traits.h"
36#include "static_assert.h"
37#include "error_handler.h"
38#include "exception.h"
39
40#include <stdint.h>
41
45
46namespace etl
47{
48 //***************************************************************************
50 //***************************************************************************
52 {
53 public:
54
55 alignment_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
56 : exception(reason_, file_name_, line_number_)
57 {
58 }
59 };
60
61 //***************************************************************************
63 //***************************************************************************
65 {
66 public:
67
68 alignment_error(string_type file_name_, numeric_type line_number_)
69 : alignment_exception(ETL_ERROR_TEXT("alignment:error", ETL_ALIGNMENT_FILE_ID"A"), file_name_, line_number_)
70 {
71 }
72 };
73
74 //*****************************************************************************
76 //*****************************************************************************
77 inline bool is_aligned(void* p, size_t required_alignment)
78 {
79 uintptr_t alignment = static_cast<uintptr_t>(required_alignment);
80 uintptr_t address = reinterpret_cast<uintptr_t>(p);
81 return (address % alignment) == 0U;
82 }
83
84 //*****************************************************************************
86 //*****************************************************************************
87 template <size_t Alignment>
88 bool is_aligned(void* p)
89 {
90 uintptr_t address = reinterpret_cast<uintptr_t>(p);
91 return (address % static_cast<uintptr_t>(Alignment)) == 0U;
92 }
93
94 //*****************************************************************************
96 //*****************************************************************************
97 template <typename T>
98 bool is_aligned(void* p)
99 {
100 return is_aligned<etl::alignment_of<T>::value>(p);
101 }
102
103 namespace private_alignment
104 {
105#if ETL_USING_CPP11
106 //***************************************************************************
107 // Matcher.
108 //***************************************************************************
109 template <bool Is_Match, size_t Alignment, typename... TRest>
110 class type_with_alignment_matcher;
111
112 // Matching alignment.
113 template <size_t Alignment, typename T1, typename... TRest>
114 class type_with_alignment_matcher<true, Alignment, T1, TRest...>
115 {
116 public:
117
118 typedef T1 type;
119 };
120
121 // Non-matching alignment
122 template <size_t Alignment, typename T1, typename T2, typename... TRest>
123 class type_with_alignment_matcher <false, Alignment, T1, T2, TRest...>
124 {
125 public:
126
127 typedef typename type_with_alignment_matcher < Alignment <= etl::alignment_of<T2>::value , Alignment, T2, TRest... > ::type type;
128 };
129
130 // Non-matching alignment, none left.
131 template <size_t Alignment, typename T1>
132 class type_with_alignment_matcher <false, Alignment, T1>
133 {
134 public:
135
136 typedef char type;
137 };
138
139 //***************************************************************************
140 // Helper.
141 //***************************************************************************
142 template <size_t Alignment, typename T1, typename... T>
143 class type_with_alignment_helper
144 {
145 public:
146
147 typedef typename type_with_alignment_matcher<Alignment <= etl::alignment_of<T1>::value, Alignment, T1, T...>::type type;
148 };
149#else
150 //***************************************************************************
151 // Matcher.
152 //***************************************************************************
153 template <bool Is_Match, const size_t Alignment, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void,
154 typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
156
157 // Matching alignment.
158 template <size_t Alignment, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
159 class type_with_alignment_matcher <true, Alignment, T1, T2, T3, T4, T5, T6, T7, T8>
160 {
161 public:
162
163 typedef T1 type;
164 };
165
166 // Non-matching alignment.
167 template <size_t Alignment, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
168 class type_with_alignment_matcher <false, Alignment, T1, T2, T3, T4, T5, T6, T7, T8>
169 {
170 public:
171
172 typedef typename type_with_alignment_matcher<Alignment <= etl::alignment_of<T2>::value, Alignment, T2, T3, T4, T5, T6, T7, T8, void>::type type;
173 };
174
175 // Non-matching alignment, none left.
176 template <size_t Alignment>
177 class type_with_alignment_matcher <false, Alignment, void, void, void, void, void, void, void, void>
178 {
179 public:
180
181 typedef char type;
182 };
183
184 //***************************************************************************
185 // Helper.
186 //***************************************************************************
187 template <size_t Alignment, typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
188 typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
190 {
191 public:
192
193 typedef typename type_with_alignment_matcher<Alignment <= etl::alignment_of<T1>::value, Alignment, T1, T2, T3, T4, T5, T6, T7, T8>::type type;
194 };
195#endif
196 }
197
198 //***************************************************************************
201 //***************************************************************************
202 template <size_t Alignment>
204 {
205 public:
206
207#if ETL_NOT_USING_64BIT_TYPES
209#else
211#endif
212 };
213
214 //***************************************************************************
218 //***************************************************************************
219 template <size_t Length, const size_t Alignment>
221 {
222 struct type
223 {
224 //type()
225 // : data()
226 //{
227 //}
228
230 template <typename T>
231 operator T& ()
232 {
233 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
234 T* t = *this;
235 return *t;
236 }
237
239 template <typename T>
240 operator const T& () const
241 {
242 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
243 const T* t = *this;
244 return *t;
245 }
246
248 template <typename T>
249 operator T* ()
250 {
251 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
252 return reinterpret_cast<T*>(data);
253 }
254
256 template <typename T>
257 operator const T* () const
258 {
259 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
260 return reinterpret_cast<const T*>(data);
261 }
262
264 template <typename T>
266 {
267 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
268 T* t = *this;
269 return *t;
270 }
271
273 template <typename T>
274 const T& get_reference() const
275 {
276 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
277 const T* t = *this;
278 return *t;
279 }
280
282 template <typename T>
284 {
285 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
286 return reinterpret_cast<T*>(data);
287 }
288
290 template <typename T>
291 const T* get_address() const
292 {
293 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
294 return reinterpret_cast<const T*>(data);
295 }
296
297#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5)
298 alignas(Alignment) char data[Length];
299#else
300 union
301 {
302 char data[Length];
303 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment as Alignment.
304 };
305#endif
306 };
307 };
308
309#if ETL_USING_CPP11
310 template <size_t Length, const size_t Alignment>
311 using aligned_storage_t = typename aligned_storage<Length, Alignment>::type;
312#endif
313
314 //***************************************************************************
317 //***************************************************************************
318 template <size_t Length, typename T>
319 struct aligned_storage_as : public etl::aligned_storage<Length, etl::alignment_of<T>::value>
320 {
321 };
322
323#if ETL_USING_CPP11
324 template <size_t Length, typename T>
325 using aligned_storage_as_t = typename aligned_storage_as<Length, T>::type;
326#endif
327}
328
329#endif
Memory misalignment exception.
Definition: alignment.h:65
Exception base for alignment.
Definition: alignment.h:52
Definition: alignment.h:204
Definition: alignment.h:221
Definition: alignment.h:320
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition: exception.h:69
Definition: exception.h:47
add_rvalue_reference
Definition: type_traits_generator.h:1327
is_same
Definition: type_traits_generator.h:1041
bitset_ext
Definition: absolute.h:38
bool is_aligned(void *p, size_t required_alignment)
Check that 'p' has 'required_alignment'.
Definition: alignment.h:77
Definition: alignment.h:223
const T * get_address() const
Get address as const T pointer.
Definition: alignment.h:291
T * get_address()
Get address as T pointer.
Definition: alignment.h:283
const T & get_reference() const
Get address as const T reference.
Definition: alignment.h:274
T & get_reference()
Get address as T reference.
Definition: alignment.h:265