1
- #ifndef ALIGNED_HPP_INCLUDED
2
- #define ALIGNED_HPP_INCLUDED
3
-
4
- #include < cstddef>
5
- #include < cstdint>
6
- #include < initializer_list>
7
- #include < memory>
8
- #include < type_traits>
9
-
10
- #include " AlignedBase.hpp"
11
- #include " AlignedArrayConstructorCaller.hpp"
12
- #include " AlignedArrayDestructorCaller.hpp"
13
-
14
- #define ALIGNED_BYTES_SIZE (alignment, sizeOfTPaddedToAlignment ) (alignment + sizeOfTPaddedToAlignment - 1 )
15
- #define ALIGNED_POINTER (T, bytes, sizeOfTPaddedToAlignment ) (reinterpret_cast <T *>(uintptr_t (bytes) + (sizeOfTPaddedToAlignment - 1 ) & ~uintptr_t (sizeOfTPaddedToAlignment - 1 )))
16
- #define ALIGNED_ARRAY_BYTES_SIZE (T, sizeOfTPaddedToAlignment, size ) (sizeof (T) + (sizeOfTPaddedToAlignment * size) - 1 )
17
- #define ALIGNED_ARRAY_INDEX_POINTER (T, pFirstElement, sizeOfTPaddedToAlignment, index ) (reinterpret_cast <T *>(uintptr_t (pFirstElement) + (sizeOfTPaddedToAlignment * index)))
18
-
19
- template <typename T, std::size_t Alignment = -1 >
20
- class Aligned : AlignedBase<T, Alignment> {
21
- uint8_t bytes[ALIGNED_BYTES_SIZE(Alignment, sizeOfTPaddedToAlignment)];
22
- T * const pValue;
23
- Aligned (Aligned const &);
24
- Aligned const & operator =(Aligned const &);
25
- public:
26
- template <typename ... Args>
27
- Aligned (Args &&... args) : pValue(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment)) { new (pValue)T (std::forward<Args>(args)...); }
28
- ~Aligned () { pValue->T ::~T (); }
29
- T & Ref () { return *pValue; }
30
- T const & Ref () const { return *pValue; }
31
- };
32
-
33
- template <typename T>
34
- class Aligned <T, -1 > : AlignedBase<T, -1 > {
35
- std::unique_ptr<uint8_t []> const pBytes;
36
- T * const pValue;
37
- public:
38
- template <typename ... Args>
39
- Aligned (std::size_t alignment, Args &&... args) : AlignedBase(alignment)
40
- , pBytes(new uint8_t [ALIGNED_BYTES_SIZE(alignment, sizeOfTPaddedToAlignment)])
41
- , pValue(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
42
- {
43
- new (pValue)T (std::forward<Args>(args)...);
44
- }
45
- ~Aligned () { pValue->T ::~T (); }
46
- T & Ref () { return *pValue; }
47
- T const & Ref () const { return *pValue; }
48
- };
49
-
50
- template <typename T, std::size_t Size , std::size_t Alignment>
51
- class Aligned <T[Size ], Alignment> : AlignedBase<T, Alignment> {
52
- Aligned (Aligned const &);
53
- Aligned & operator =(Aligned const &);
54
- static std::size_t const size = Size ;
55
- uint8_t bytes[ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, Size )];
56
- T * const pFirstElement;
57
- T & element (std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER (T, pFirstElement, sizeOfTPaddedToAlignment, index ); }
58
- public:
59
- Aligned ()
60
- : pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
61
- {
62
- AlignedArrayConstructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
63
- }
64
- Aligned (std::initializer_list<T> const & list)
65
- : pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
66
- {
67
- int i = 0 ;
68
- for (auto it = list.begin (); it != list.end (); ++it)
69
- this ->element (i++) = *it;
70
- }
71
- ~Aligned () {
72
- AlignedArrayDestructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
73
- }
74
- T & operator [](std::size_t index) { return element (index ); }
75
- T const & operator [](std::size_t index) const { return element (index ); }
76
- std::size_t Size () const { return size; }
77
- };
78
-
79
- template <typename T, std::size_t Alignment>
80
- class Aligned <T[], Alignment> : AlignedBase<T, Alignment> {
81
- Aligned (Aligned const &);
82
- Aligned & operator =(Aligned const &);
83
- std::size_t const size;
84
- std::unique_ptr<uint8_t []> const pBytes;
85
- T * const pFirstElement;
86
- T & element (std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER (T, pFirstElement, sizeOfTPaddedToAlignment, index ); }
87
- public:
88
- Aligned (std::size_t size)
89
- : size(size)
90
- , pBytes(new uint8_t [ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
91
- , pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
92
- {
93
- AlignedArrayConstructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
94
- }
95
- Aligned (std::initializer_list<T> const & list)
96
- : pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
97
- {
98
- int i = 0 ;
99
- for (auto it = list.begin (); it != list.end (); ++it)
100
- this ->element (i++) = *it;
101
- }
102
- ~Aligned () {
103
- AlignedArrayDestructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
104
- }
105
- T & operator [](std::size_t index) { return element (index ); }
106
- T const & operator [](std::size_t index) const { return element (index ); }
107
- std::size_t Size () const { return size; }
108
- };
109
-
110
- template <typename T>
111
- class Aligned <T[], -1 > : AlignedBase<T, -1 > {
112
- Aligned (Aligned const &);
113
- Aligned & operator =(Aligned const &);
114
- std::size_t const size;
115
- std::unique_ptr<uint8_t []> const pBytes;
116
- T * const pFirstElement;
117
- Aligned ();
118
- protected:
119
- T & element (std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER (T, pFirstElement, sizeOfTPaddedToAlignment, index ); }
120
- public:
121
- Aligned (std::size_t alignment, std::size_t size)
122
- : AlignedBase<T, -1 >(alignment)
123
- , size(size)
124
- , pBytes(new uint8_t [ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
125
- , pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
126
- {
127
- AlignedArrayConstructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
128
- }
129
- Aligned (std::size_t alignment, std::initializer_list<T> const & list)
130
- : AlignedBase<T, -1 >(alignment)
131
- , size(list.size())
132
- , pBytes(new uint8_t [ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
133
- , pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
134
- {
135
- int i = 0 ;
136
- for (auto it = list.begin (); it != list.end (); ++it)
137
- this ->element (i++) = *it;
138
- }
139
- ~Aligned () {
140
- AlignedArrayDestructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
141
- }
142
- T & operator [](std::size_t index) { return element (index ); }
143
- T const & operator [](std::size_t index) const { return element (index ); }
144
- std::size_t Size () const { return size; }
145
- };
146
-
147
- #undef ALIGNED_BYTES_SIZE
148
- #undef ALIGNED_POINTER
149
- #undef ALIGNED_ARRAY_BYTES_SIZE
150
- #undef ALIGNED_ARRAY_INDEX_POINTER
151
-
1
+ #ifndef ALIGNED_HPP_INCLUDED
2
+ #define ALIGNED_HPP_INCLUDED
3
+
4
+ #include < cstddef>
5
+ #include < cstdint>
6
+ #include < initializer_list>
7
+ #include < memory>
8
+ #include < type_traits>
9
+
10
+ #include " AlignedBase.hpp"
11
+ #include " AlignedArrayConstructorCaller.hpp"
12
+ #include " AlignedArrayDestructorCaller.hpp"
13
+ #include " InitializerListLongerThanSizeException.hpp"
14
+
15
+ #define ALIGNED_BYTES_SIZE (alignment, sizeOfTPaddedToAlignment ) (alignment + sizeOfTPaddedToAlignment - 1 )
16
+ #define ALIGNED_POINTER (T, bytes, sizeOfTPaddedToAlignment ) (reinterpret_cast <T *>(uintptr_t (bytes) + (sizeOfTPaddedToAlignment - 1 ) & ~uintptr_t (sizeOfTPaddedToAlignment - 1 )))
17
+ #define ALIGNED_ARRAY_BYTES_SIZE (T, sizeOfTPaddedToAlignment, size ) (sizeof (T) + (sizeOfTPaddedToAlignment * size) - 1 )
18
+ #define ALIGNED_ARRAY_INDEX_POINTER (T, pFirstElement, sizeOfTPaddedToAlignment, index ) (reinterpret_cast <T *>(uintptr_t (pFirstElement) + (sizeOfTPaddedToAlignment * index)))
19
+
20
+ template <typename T, std::size_t Alignment = -1 >
21
+ class Aligned : AlignedBase<T, Alignment> {
22
+ uint8_t bytes[ALIGNED_BYTES_SIZE(Alignment, sizeOfTPaddedToAlignment)];
23
+ T * const pValue;
24
+ Aligned (Aligned const &);
25
+ Aligned const & operator =(Aligned const &);
26
+ public:
27
+ template <typename ... Args>
28
+ Aligned (Args &&... args) : pValue(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment)) { new (pValue)T (std::forward<Args>(args)...); }
29
+ ~Aligned () { pValue->T ::~T (); }
30
+ T & Ref () { return *pValue; }
31
+ T const & Ref () const { return *pValue; }
32
+ };
33
+
34
+ template <typename T>
35
+ class Aligned <T, -1 > : AlignedBase<T, -1 > {
36
+ std::unique_ptr<uint8_t []> const pBytes;
37
+ T * const pValue;
38
+ public:
39
+ template <typename ... Args>
40
+ Aligned (std::size_t alignment, Args &&... args) : AlignedBase(alignment)
41
+ , pBytes(new uint8_t [ALIGNED_BYTES_SIZE(alignment, sizeOfTPaddedToAlignment)])
42
+ , pValue(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
43
+ {
44
+ new (pValue)T (std::forward<Args>(args)...);
45
+ }
46
+ ~Aligned () { pValue->T ::~T (); }
47
+ T & Ref () { return *pValue; }
48
+ T const & Ref () const { return *pValue; }
49
+ };
50
+
51
+ template <typename T, std::size_t Size , std::size_t Alignment>
52
+ class Aligned <T[Size ], Alignment> : AlignedBase<T, Alignment> {
53
+ Aligned (Aligned const &);
54
+ Aligned & operator =(Aligned const &);
55
+ static std::size_t const size = Size ;
56
+ uint8_t bytes[ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, Size )];
57
+ T * const pFirstElement;
58
+ T & element (std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER (T, pFirstElement, sizeOfTPaddedToAlignment, index ); }
59
+ public:
60
+ Aligned ()
61
+ : pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
62
+ {
63
+ AlignedArrayConstructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
64
+ }
65
+ Aligned (std::size_t size, std::initializer_list<T> const & list)
66
+ : pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
67
+ {
68
+ if (size < list.size ())
69
+ throw InitializerListLongerThanSizeException ();
70
+ int i = 0 ;
71
+ for (auto it = list.begin (); it != list.end (); ++it)
72
+ this ->element (i++) = *it;
73
+ }
74
+ Aligned (std::initializer_list<T> const & list)
75
+ : Aligned(list.size(), list)
76
+ {}
77
+ ~Aligned () {
78
+ AlignedArrayDestructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
79
+ }
80
+ T & operator [](std::size_t index) { return element (index ); }
81
+ T const & operator [](std::size_t index) const { return element (index ); }
82
+ std::size_t Size () const { return size; }
83
+ };
84
+
85
+ template <typename T, std::size_t Alignment>
86
+ class Aligned <T[], Alignment> : AlignedBase<T, Alignment> {
87
+ Aligned (Aligned const &);
88
+ Aligned & operator =(Aligned const &);
89
+ std::size_t const size;
90
+ std::unique_ptr<uint8_t []> const pBytes;
91
+ T * const pFirstElement;
92
+ T & element (std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER (T, pFirstElement, sizeOfTPaddedToAlignment, index ); }
93
+ public:
94
+ Aligned (std::size_t size)
95
+ : size(size)
96
+ , pBytes(new uint8_t [ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
97
+ , pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
98
+ {
99
+ AlignedArrayConstructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
100
+ }
101
+ Aligned (std::size_t size, std::initializer_list<T> const & list)
102
+ : pFirstElement(ALIGNED_POINTER(T, bytes, sizeOfTPaddedToAlignment))
103
+ {
104
+ if (size < list.size ())
105
+ throw InitializerListLongerThanSizeException ();
106
+ int i = 0 ;
107
+ for (auto it = list.begin (); it != list.end (); ++it)
108
+ this ->element (i++) = *it;
109
+ }
110
+ Aligned (std::initializer_list<T> const & list)
111
+ : Aligned(list.size(), list)
112
+ {}
113
+ ~Aligned () {
114
+ AlignedArrayDestructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
115
+ }
116
+ T & operator [](std::size_t index) { return element (index ); }
117
+ T const & operator [](std::size_t index) const { return element (index ); }
118
+ std::size_t Size () const { return size; }
119
+ };
120
+
121
+ template <typename T>
122
+ class Aligned <T[], -1 > : AlignedBase<T, -1 > {
123
+ Aligned (Aligned const &);
124
+ Aligned & operator =(Aligned const &);
125
+ std::size_t const size;
126
+ std::unique_ptr<uint8_t []> const pBytes;
127
+ T * const pFirstElement;
128
+ Aligned ();
129
+ protected:
130
+ T & element (std::size_t index) { return *ALIGNED_ARRAY_INDEX_POINTER (T, pFirstElement, sizeOfTPaddedToAlignment, index ); }
131
+ public:
132
+ Aligned (std::size_t alignment, std::size_t size)
133
+ : AlignedBase<T, -1 >(alignment)
134
+ , size(size)
135
+ , pBytes(new uint8_t [ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
136
+ , pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
137
+ {
138
+ AlignedArrayConstructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
139
+ }
140
+ Aligned (std::size_t alignment, std::size_t size, std::initializer_list<T> const & list)
141
+ : AlignedBase<T, -1 >(alignment)
142
+ , size(size)
143
+ , pBytes(new uint8_t [ALIGNED_ARRAY_BYTES_SIZE(T, sizeOfTPaddedToAlignment, size)])
144
+ , pFirstElement(ALIGNED_POINTER(T, pBytes.get(), sizeOfTPaddedToAlignment))
145
+ {
146
+ if (size < list.size ())
147
+ throw InitializerListLongerThanSizeException ();
148
+ int i = 0 ;
149
+ for (auto it = list.begin (); it != list.end (); ++it)
150
+ this ->element (i++) = *it;
151
+ }
152
+ Aligned (std::size_t alignment, std::initializer_list<T> const & list)
153
+ : Aligned(alignment, list.size(), list)
154
+ {}
155
+ ~Aligned () {
156
+ AlignedArrayDestructorCaller<T>::Call (size, pFirstElement, sizeOfTPaddedToAlignment);
157
+ }
158
+ T & operator [](std::size_t index) { return element (index ); }
159
+ T const & operator [](std::size_t index) const { return element (index ); }
160
+ std::size_t Size () const { return size; }
161
+ };
162
+
163
+ #undef ALIGNED_BYTES_SIZE
164
+ #undef ALIGNED_POINTER
165
+ #undef ALIGNED_ARRAY_BYTES_SIZE
166
+ #undef ALIGNED_ARRAY_INDEX_POINTER
167
+
152
168
#endif
0 commit comments