Embedded Template Library 1.0
Loading...
Searching...
No Matches
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 //***************************************************************************
60
61 //***************************************************************************
63 //***************************************************************************
65 {
66 public:
67
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 address = reinterpret_cast<uintptr_t>(p);
80 return (address % required_alignment) == 0U;
81 }
82
83 //*****************************************************************************
85 //*****************************************************************************
86 template <size_t Alignment>
87 bool is_aligned(void* p)
88 {
89 uintptr_t address = reinterpret_cast<uintptr_t>(p);
90 return (address % Alignment) == 0U;
91 }
92
93 //*****************************************************************************
95 //*****************************************************************************
96 template <typename T>
97 bool is_aligned(void* p)
98 {
99 return is_aligned<etl::alignment_of<T>::value>(p);
100 }
101
102 namespace private_alignment
103 {
104#if ETL_USING_CPP11
105 //***************************************************************************
106 // Matcher.
107 //***************************************************************************
108 template <bool Is_Match, size_t Alignment, typename... TRest>
109 class type_with_alignment_matcher;
110
111 // Matching alignment.
112 template <size_t Alignment, typename T1, typename... TRest>
113 class type_with_alignment_matcher<true, Alignment, T1, TRest...>
114 {
115 public:
116
117 typedef T1 type;
118 };
119
120 // Non-matching alignment
121 template <size_t Alignment, typename T1, typename T2, typename... TRest>
122 class type_with_alignment_matcher <false, Alignment, T1, T2, TRest...>
123 {
124 public:
125
126 typedef typename type_with_alignment_matcher < Alignment <= etl::alignment_of<T2>::value , Alignment, T2, TRest... > ::type type;
127 };
128
129 // Non-matching alignment, none left.
130 template <size_t Alignment, typename T1>
131 class type_with_alignment_matcher <false, Alignment, T1>
132 {
133 public:
134
135 typedef char type;
136 };
137
138 //***************************************************************************
139 // Helper.
140 //***************************************************************************
141 template <size_t Alignment, typename T1, typename... T>
142 class type_with_alignment_helper
143 {
144 public:
145
146 typedef typename type_with_alignment_matcher<Alignment <= etl::alignment_of<T1>::value, Alignment, T1, T...>::type type;
147 };
148#else
149 //***************************************************************************
150 // Matcher.
151 //***************************************************************************
152 template <bool Is_Match, const size_t Alignment, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void,
153 typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
155
156 // Matching alignment.
157 template <size_t Alignment, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
158 class type_with_alignment_matcher <true, Alignment, T1, T2, T3, T4, T5, T6, T7, T8>
159 {
160 public:
161
162 typedef T1 type;
163 };
164
165 // Non-matching alignment.
166 template <size_t Alignment, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
167 class type_with_alignment_matcher <false, Alignment, T1, T2, T3, T4, T5, T6, T7, T8>
168 {
169 public:
170
171 typedef typename type_with_alignment_matcher<Alignment <= etl::alignment_of<T2>::value, Alignment, T2, T3, T4, T5, T6, T7, T8, void>::type type;
172 };
173
174 // Non-matching alignment, none left.
175 template <size_t Alignment>
176 class type_with_alignment_matcher <false, Alignment, void, void, void, void, void, void, void, void>
177 {
178 public:
179
180 typedef char type;
181 };
182
183 //***************************************************************************
184 // Helper.
185 //***************************************************************************
186 template <size_t Alignment, typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
187 typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
189 {
190 public:
191
192 typedef typename type_with_alignment_matcher<Alignment <= etl::alignment_of<T1>::value, Alignment, T1, T2, T3, T4, T5, T6, T7, T8>::type type;
193 };
194#endif
195 }
196
197 //***************************************************************************
200 //***************************************************************************
201 template <size_t Alignment>
203 {
204 public:
205
206#if ETL_USING_CPP11
207 typedef struct { alignas(Alignment) char dummy; } type;
208#else
209 #if ETL_NOT_USING_64BIT_TYPES
211 #else
213 #endif
214#endif
215
216 ETL_STATIC_ASSERT(etl::alignment_of<type>::value == Alignment, "Unable to create the type with the specified alignment");
217 };
218
219#if ETL_USING_CPP11
220 template <size_t Alignment>
221 using type_with_alignment_t = typename type_with_alignment<Alignment>::type;
222#endif
223
224 //***************************************************************************
228 //***************************************************************************
229 template <size_t Length, const size_t Alignment>
231 {
232 struct type
233 {
234 //type()
235 // : data()
236 //{
237 //}
238
240 template <typename T>
241 operator T& ()
242 {
243 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
244 T* t = *this;
245 return *t;
246 }
247
249 template <typename T>
250 operator const T& () const
251 {
252 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
253 const T* t = *this;
254 return *t;
255 }
256
258 template <typename T>
259 operator T* ()
260 {
261 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
262 return reinterpret_cast<T*>(data);
263 }
264
266 template <typename T>
267 operator const T* () const
268 {
269 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
270 return reinterpret_cast<const T*>(data);
271 }
272
274 template <typename T>
276 {
277 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
278 T* t = *this;
279 return *t;
280 }
281
283 template <typename T>
284 const T& get_reference() const
285 {
286 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
287 const T* t = *this;
288 return *t;
289 }
290
292 template <typename T>
294 {
295 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
296 return reinterpret_cast<T*>(data);
297 }
298
300 template <typename T>
301 const T* get_address() const
302 {
303 ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
304 return reinterpret_cast<const T*>(data);
305 }
306
307#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5)
308 alignas(Alignment) char data[Length];
309#else
310 union
311 {
312 char data[Length];
313 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment as Alignment.
314 };
315#endif
316 };
317 };
318
319#if ETL_USING_CPP11
320 template <size_t Length, const size_t Alignment>
321 using aligned_storage_t = typename aligned_storage<Length, Alignment>::type;
322#endif
323
324 //***************************************************************************
327 //***************************************************************************
328 template <size_t Length, typename T>
329 struct aligned_storage_as : public etl::aligned_storage<Length, etl::alignment_of<T>::value>
330 {
331 };
332
333#if ETL_USING_CPP11
334 template <size_t Length, typename T>
336#endif
337}
338
339#endif
Memory misalignment exception.
Definition alignment.h:65
Exception base for alignment.
Definition alignment.h:52
Definition alignment.h:203
Definition alignment.h:231
Definition alignment.h:330
Definition exception.h:47
add_rvalue_reference
Definition type_traits_generator.h:1322
is_same
Definition type_traits_generator.h:1036
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:233
const T * get_address() const
Get address as const T pointer.
Definition alignment.h:301
T * get_address()
Get address as T pointer.
Definition alignment.h:293
const T & get_reference() const
Get address as const T reference.
Definition alignment.h:284
T & get_reference()
Get address as T reference.
Definition alignment.h:275
pair holds two objects of arbitrary type
Definition utility.h:164