2929#include < cassert>
3030#include < type_traits>
3131#include < iterator>
32+ #include < new>
3233
3334enum class Fixedvector_Init {
3435 UNINIT
@@ -54,14 +55,14 @@ class Fixed_vector {
5455 T& push_back (const T& e) noexcept {
5556 assert (count < N);
5657 (*this )[count] = e;
57- return (* this )[count++];
58+ return reinterpret_raw ( )[count++];
5859 }
5960 // construct into
6061 template <typename ... Args>
6162 T& emplace_back (Args&&... args) noexcept {
6263 assert (count < N);
63- new (&element[ count]) T (args...);
64- return (* this )[count++];
64+ new (static_cast < void *>( reinterpret_raw () + count)) T (std::forward<Args>( args) ...);
65+ return reinterpret_raw ( )[count++];
6566 }
6667
6768 /* *
@@ -108,36 +109,36 @@ class Fixed_vector {
108109 { return capacity () - size (); }
109110
110111 T& operator [] (uint32_t i) noexcept {
111- return *(T*) (element + i) ;
112+ return reinterpret_raw ()[i] ;
112113 }
113114 T* at (uint32_t i) noexcept {
114115 if (i >= size ()) return nullptr ;
115- return (T*) (element + i) ;
116+ return reinterpret_raw () + i;
116117 }
117118
118119 T* data () noexcept {
119- return (T*) &element[ 0 ] ;
120+ return reinterpret_raw () ;
120121 }
121122 T* begin () noexcept {
122- return (T*) &element[ 0 ] ;
123+ return reinterpret_raw () ;
123124 }
124125 T* end () noexcept {
125- return (T*) &element[ count] ;
126+ return reinterpret_raw () + count;
126127 }
127128
128129 const T* data () const noexcept {
129- return (T*) &element[ 0 ] ;
130+ return reinterpret_raw () ;
130131 }
131132 const T* begin () const noexcept {
132- return (T*) &element[ 0 ] ;
133+ return reinterpret_raw () ;
133134 }
134135 const T* end () const noexcept {
135- return (T*) &element[ count] ;
136+ return reinterpret_raw () + count;
136137 }
137138
138139 T& back () noexcept {
139140 assert (not empty ());
140- return (T&)element [count-1 ];
141+ return reinterpret_raw () [count-1 ];
141142 }
142143
143144 constexpr int capacity () const noexcept {
@@ -151,7 +152,7 @@ class Fixed_vector {
151152 // source of the same type T, with @size elements
152153 // Note: size and capacity are not related, and they don't have to match
153154 void copy (T* src, uint32_t size) {
154- memcpy (element , src, size * sizeof (T));
155+ memcpy (reinterpret_raw () , src, size * sizeof (T));
155156 count = size;
156157 }
157158
@@ -163,7 +164,10 @@ class Fixed_vector {
163164
164165private:
165166 uint32_t count;
166- typename std::aligned_storage<sizeof (T), alignof (T)>::type element[N];
167+ alignas (T) std::byte storage[sizeof (T) * N];
168+
169+ T* reinterpret_raw () noexcept { return std::launder (reinterpret_cast < T*>(storage)); }
170+ const T* reinterpret_raw () const noexcept { return std::launder (reinterpret_cast <const T*>(storage)); }
167171};
168172
169173
0 commit comments