mn_alignment.hpp
Go to the documentation of this file.
1 /*
2 *This file is part of the Mini Thread Library (https://github.com/RoseLeBlood/MiniThread ).
3 *Copyright (c) 2021 Amber-Sophia Schroeck
4 *
5 *The Mini Thread Library is free software; you can redistribute it and/or modify
6 *it under the terms of the GNU Lesser General Public License as published by
7 *the Free Software Foundation, version 3, or (at your option) any later version.
8 
9 *The Mini Thread Library is distributed in the hope that it will be useful, but
10 *WITHOUT ANY WARRANTY; without even the implied warranty of
11 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 *General Public License for more details.
13 *
14 *You should have received a copy of the GNU Lesser General Public
15 *License along with the Mini Thread Library; if not, see
16 *<https://www.gnu.org/licenses/>.
17 */
18 #ifndef _MINLIB_ALIGNMENT_H_
19 #define _MINLIB_ALIGNMENT_H_
20 
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #include <stdalign.h>
25 
26 
27 #include "mn_nlz.hpp"
28 #include "../mn_typetraits.hpp"
29 #include "../mn_def.hpp"
30 
31 namespace mn {
32  namespace internal {
33 
34  template<typename T>
35  struct alignof_helper {
36  char x;
37  T y;
38  };
39 
40  struct __attribute__ ((aligned (1))) aligned1 { uint8_t member; };
41  struct __attribute__ ((aligned (2))) aligned2 { uint16_t member; };
42  struct __attribute__ ((aligned (4))) aligned4 { uint32_t member; };
43  struct __attribute__ ((aligned (8))) aligned8 { uint64_t member; } ;
44  struct __attribute__ ((aligned (16))) aligned16 { uint64_t member[2]; } ;
45  struct __attribute__ ((aligned (32))) aligned32 { uint64_t member[4]; } ;
46  struct __attribute__ ((aligned (64))) aligned64 { uint64_t member[8]; } ;
47 
48 
49 
50  template<size_t N> struct type_with_alignment {
51  typedef char err_invalid_alignment[N > 0 ? -1 : 1];
52  };
53 
54  template<> struct type_with_alignment<1> { aligned1 type; };
55  template<> struct type_with_alignment<2> { aligned2 type; };
56  template<> struct type_with_alignment<4> { aligned4 type; };
57  template<> struct type_with_alignment<8> { aligned8 type; };
58  template<> struct type_with_alignment<16> { aligned16 type; };
59  template<> struct type_with_alignment<32> { aligned32 type; };
60  template<> struct type_with_alignment<64> { aligned64 type; };
61 
62  union max_align {
63  char c;
64  short s;
65  int i;
66  long l;
67  long long ll;
68  float f;
69  double d;
70  };
71  } // internal
72 
73  template<> struct is_pod<internal::aligned1> : public true_type{};
74  template<> struct is_pod<internal::aligned2> : public true_type{};
75  template<> struct is_pod<internal::aligned4> : public true_type{};
76  template<> struct is_pod<internal::aligned8> : public true_type{};
77  template<> struct is_pod<internal::aligned16> : public true_type{};
78  template<> struct is_pod<internal::aligned32> : public true_type{};
79  template<> struct is_pod<internal::aligned64> : public true_type{};
80 
81 
82  template<typename T>
83  struct alignment_of {
85  };
86  template<> struct alignment_of<void> {
87  enum { res = 0 };
88  };
89 
90  template<> struct alignment_of<void const> {
91  enum { res = 0 };
92  };
93 
94  template<> struct alignment_of<void const volatile> {
95  enum { res = 0 };
96  };
97 
98  template<> struct alignment_of<void volatile> {
99  enum { res = 0 };
100  };
101 
102 
103  template <size_t Target, bool check> struct long_double_alignment{ using type = long double; };
104  template <size_t Target> struct long_double_alignment<Target, false> {
106 
107  template <size_t Target, bool check> struct double_alignment{ using type = double; };
108  template <size_t Target> struct double_alignment<Target, false> {
110 
111  template <size_t Target, bool check> struct long_long_alignment{ using type = long long; };
112  template <size_t Target> struct long_long_alignment<Target, false> {
114 
115  template <size_t Target, bool check> struct long_alignment{ using type = long; };
116  template <size_t Target> struct long_alignment<Target, false> {
118 
119  template <size_t Target, bool check> struct int_alignment{ using type = int; };
120  template <size_t Target> struct int_alignment<Target, false>{
122 
123  template <size_t Target, bool check> struct short_alignment{ using type = short; };
124  template <size_t Target> struct short_alignment<Target, false>{
126 
127  template <size_t Target, bool check> struct char_alignment{ using type = char; };
128  template <size_t Target> struct char_alignment<Target, false>{
130 
131  template<typename T>
132  struct aligned_as {
134  };
135 
136  template <class integral>
137  constexpr bool is_aligned(integral x, size_t a) noexcept {
138  return (x & (integral(a) - 1)) == 0u;
139  }
140  inline bool is_aligned(const volatile void* p, size_t a) {
141  return is_aligned(reinterpret_cast<uintptr_t>(p), a);
142  }
143 
144  template <class integral>
145  constexpr integral align_up(integral x, size_t a) noexcept {
146  return integral((x + (integral(a) - 1)) & ~integral(a-1));
147  }
148  template <class pointer>
149  pointer align_up_ptr(pointer p, size_t a) {
150  return reinterpret_cast<pointer>(align_up(reinterpret_cast<uintptr_t>(p), a));
151  }
152 
153  template <class integral>
154  constexpr integral align_down(integral x, size_t a) noexcept {
155  return integral(x & ~integral(a-1));
156  }
157  template <class pointer>
158  pointer align_down_ptr(pointer p, size_t a) {
159  return reinterpret_cast<pointer>(align_down(reinterpret_cast<uintptr_t>(p), a));
160  }
161 
162 
166  constexpr bool is_aligvalid(size_t alignment) noexcept {
167  return alignment && (alignment & (alignment - 1)) == 0u;
168  }
169 
170  // returns the offset needed to align ptr for given alignment
171  inline size_t alig_offset(void* address, size_t alignment) noexcept {
172  if(!is_aligvalid(alignment)) return 0;
173 
174  auto _isaligned = reinterpret_cast<uintptr_t>(address) & (alignment - 1);
175  return _isaligned != 0 ? (alignment - _isaligned) : 0;
176  }
177 
178  inline size_t alignment_for(const size_t size) noexcept {
179  if(size >= max_alignment) return max_alignment;
180 
181  return (size_t(1) << nlz(size) );
182  }
183 
184 
185 }
186 
187 
188 #endif
#define offsetof(TYPE, MEMBER)
Definition: mn_def.hpp:35
char err_invalid_alignment[N > 0 ? -1 :1]
Definition: mn_alignment.hpp:51
struct __attribute__((aligned(1))) aligned1
Definition: mn_alignment.hpp:40
aligned1 type
Definition: mn_alignment.hpp:54
short s
Definition: mn_alignment.hpp:64
aligned16 type
Definition: mn_alignment.hpp:58
double d
Definition: mn_alignment.hpp:69
float f
Definition: mn_alignment.hpp:68
aligned64 type
Definition: mn_alignment.hpp:60
int i
Definition: mn_alignment.hpp:65
char x
Definition: mn_alignment.hpp:36
char c
Definition: mn_alignment.hpp:63
aligned4 type
Definition: mn_alignment.hpp:56
aligned8 type
Definition: mn_alignment.hpp:57
T y
Definition: mn_alignment.hpp:37
long long ll
Definition: mn_alignment.hpp:67
aligned32 type
Definition: mn_alignment.hpp:59
long l
Definition: mn_alignment.hpp:66
aligned2 type
Definition: mn_alignment.hpp:55
Definition: mn_alignment.hpp:35
Definition: mn_alignment.hpp:50
Definition: mn_alignment.hpp:62
struct mn::memory::detail::ptr_difference T
Definition: mn_atomic_singleton.hpp:38
Definition: mn_allocator_typetraits.hpp:25
constexpr integral align_up(integral x, size_t a) noexcept
Definition: mn_alignment.hpp:145
int type
Definition: mn_alignment.hpp:119
pointer align_up_ptr(pointer p, size_t a)
Definition: mn_alignment.hpp:149
typename int_alignment< Target, alignment_of< int >::res >=Target >::type type
Definition: mn_alignment.hpp:125
constexpr bool is_aligvalid(size_t alignment) noexcept
is a valid alignment, i.e. a power of two not zero
Definition: mn_alignment.hpp:166
typename short_alignment< Target, alignment_of< short >::res >=Target >::type type
Definition: mn_alignment.hpp:129
typename long_alignment< Target, alignment_of< long >::res >=Target >::type type
Definition: mn_alignment.hpp:121
long long type
Definition: mn_alignment.hpp:111
constexpr size_t max_alignment
Definition: mn_def.hpp:55
typename long_long_alignment< Target, alignment_of< long long >::res >=Target >::type type
Definition: mn_alignment.hpp:117
double type
Definition: mn_alignment.hpp:107
long double type
Definition: mn_alignment.hpp:103
size_t alignment_for(const size_t size) noexcept
Definition: mn_alignment.hpp:178
typename double_alignment< Target, alignment_of< double >::res >=Target >::type type
Definition: mn_alignment.hpp:113
size_t alig_offset(void *address, size_t alignment) noexcept
Definition: mn_alignment.hpp:171
constexpr integral align_down(integral x, size_t a) noexcept
Definition: mn_alignment.hpp:154
short type
Definition: mn_alignment.hpp:123
char type
Definition: mn_alignment.hpp:127
typename internal::type_with_alignment< alignment_of< T >::res > res
Definition: mn_alignment.hpp:133
constexpr bool is_aligned(integral x, size_t a) noexcept
Definition: mn_alignment.hpp:137
long type
Definition: mn_alignment.hpp:115
size_t nlz(uint64_t x)
Definition: mn_nlz.hpp:28
typename long_double_alignment< Target, alignment_of< long double >::res >=Target >::type type
Definition: mn_alignment.hpp:109
pointer align_down_ptr(pointer p, size_t a)
Definition: mn_alignment.hpp:158
Definition: mn_alignment.hpp:132
Definition: mn_alignment.hpp:127
Definition: mn_alignment.hpp:107
Definition: mn_alignment.hpp:119
Definition: mn_alignment.hpp:115
Definition: mn_alignment.hpp:103
Definition: mn_alignment.hpp:111
Definition: mn_alignment.hpp:123
Definition: mn_alignment.hpp:83
@ res
Definition: mn_alignment.hpp:84
Definition: mn_typetraits.hpp:249