19 #include <type_traits>
41 #if !ISOSPEC_BUILDING_R
42 static_assert(std::is_trivially_copyable<T>::value,
"Cannot use a pod_vector with a non-Plain Old Data type.");
45 store =
reinterpret_cast<T*
>(malloc(
sizeof(T) * initial_size));
47 throw std::bad_alloc();
49 backend_past_end = store + initial_size;
57 backend_past_end = other.backend_past_end;
58 first_free = other.first_free;
60 other.backend_past_end = other.first_free = other.store = NULL;
66 backend_past_end = other.backend_past_end;
67 first_free = other.first_free;
69 other.backend_past_end = other.first_free = other.store = NULL;
72 ~
pod_vector() { free(store); backend_past_end = first_free = store = NULL; }
76 backend_past_end = other.backend_past_end;
77 first_free = other.first_free;
79 other.backend_past_end = other.first_free = other.store = NULL;
82 void fast_reserve(
size_t n)
84 ISOSPEC_IMPOSSIBLE(n <
static_cast<size_t>(backend_past_end - store));
85 const std::ptrdiff_t store_used_size = first_free - store;
86 T* new_store =
reinterpret_cast<T*
>(realloc(store, n *
sizeof(T)));
88 throw std::bad_alloc();
89 first_free = new_store + store_used_size;
90 backend_past_end = new_store + n;
94 void reserve(
size_t n)
96 if (n >
static_cast<size_t>(backend_past_end - store))
100 void resize(
size_t new_size)
102 ISOSPEC_IMPOSSIBLE(
static_cast<std::ptrdiff_t
>(new_size) < first_free - store);
103 size_t cap = capacity();
108 }
while(cap < new_size);
111 first_free = store + new_size;
114 void resize_and_wipe(
size_t new_size)
116 size_t old_size = size();
117 ISOSPEC_IMPOSSIBLE(new_size <= old_size);
119 memset(store+old_size, 0, (new_size-old_size) *
sizeof(T));
122 ISOSPEC_FORCE_INLINE
void nocheck_push_back(
const T& val) noexcept
124 ISOSPEC_IMPOSSIBLE(first_free >= backend_past_end);
129 ISOSPEC_FORCE_INLINE
void push_back(
const T& val)
131 if(first_free >= backend_past_end)
132 fast_reserve((std::max<std::ptrdiff_t>)(4, (backend_past_end-store)) * 2);
137 ISOSPEC_FORCE_INLINE T& operator[](
size_t n) noexcept
139 ISOSPEC_IMPOSSIBLE(store + n >= first_free);
143 ISOSPEC_FORCE_INLINE
const T& operator[](
size_t n)
const noexcept
145 ISOSPEC_IMPOSSIBLE(store + n >= first_free);
149 ISOSPEC_FORCE_INLINE
size_t size()
const noexcept
151 return first_free - store;
154 ISOSPEC_FORCE_INLINE
size_t capacity()
const noexcept
156 return backend_past_end - store;
159 ISOSPEC_FORCE_INLINE T* data() noexcept
164 ISOSPEC_FORCE_INLINE
const T* data()
const noexcept
169 ISOSPEC_FORCE_INLINE
bool empty()
const noexcept
171 return first_free == store;
174 ISOSPEC_FORCE_INLINE
const T& back()
const noexcept
176 ISOSPEC_IMPOSSIBLE(first_free > backend_past_end);
177 return *(first_free-1);
180 ISOSPEC_FORCE_INLINE
void pop_back() noexcept
183 ISOSPEC_IMPOSSIBLE(first_free == store);
189 std::swap(backend_past_end, other.backend_past_end);
190 std::swap(first_free, other.first_free);
191 std::swap(store, other.store);
195 typedef const T* const_iterator;
196 typedef T value_type;
197 typedef size_t size_type;
198 typedef T& reference;
199 typedef const T& const_reference;
201 iterator begin() noexcept {
return store; };
202 const_iterator begin()
const noexcept {
return store; }
203 const_iterator cbegin()
const noexcept {
return store; }
204 iterator end() noexcept {
return first_free; }
205 const_iterator end()
const noexcept {
return first_free; }
206 const_iterator cend()
const noexcept {
return first_free; }
208 ISOSPEC_FORCE_INLINE
const T& front()
const noexcept
210 ISOSPEC_IMPOSSIBLE(store == first_free);
217 first_free = store = backend_past_end = NULL;
235 #if !ISOSPEC_BUILDING_R
236 static_assert(std::is_trivially_copyable<T>::value,
"Cannot use a pod_vector with a non-Plain Old Data type.");
237 static_assert(std::is_trivially_copyable<
unsafe_pod_vector<T> >::value,
"Cannot use a pod_vector with a non-Plain Old Data type.");
239 memset(
this, 0,
sizeof(*
this));
242 void init(
size_t initial_size)
244 #if !ISOSPEC_BUILDING_R
245 static_assert(std::is_trivially_copyable<T>::value,
"Cannot use a pod_vector with a non-Plain Old Data type.");
246 static_assert(std::is_trivially_copyable<
unsafe_pod_vector<T> >::value,
"Cannot use a pod_vector with a non-Plain Old Data type.");
248 store =
reinterpret_cast<T*
>(malloc(
sizeof(T) * initial_size));
250 throw std::bad_alloc();
252 backend_past_end = store + initial_size;
261 void fast_reserve(
size_t n)
263 ISOSPEC_IMPOSSIBLE(n <
static_cast<size_t>(backend_past_end - store));
264 T* new_store =
reinterpret_cast<T*
>(realloc(store, n *
sizeof(T)));
265 if(new_store == NULL)
266 throw std::bad_alloc();
267 first_free = new_store + (first_free - store);
268 backend_past_end = new_store + n;
272 void reserve(
size_t n)
274 if (n > backend_past_end - store)
278 void resize(
size_t new_size)
280 ISOSPEC_IMPOSSIBLE(new_size < first_free - store);
281 size_t cap = capacity();
286 }
while(cap < new_size);
289 first_free = store + new_size;
292 void resize_and_wipe(
size_t new_size)
294 size_t old_size = size();
295 ISOSPEC_IMPOSSIBLE(new_size <= old_size);
297 memset(store+old_size, 0, (new_size-old_size) *
sizeof(T));
300 ISOSPEC_FORCE_INLINE
void nocheck_push_back(
const T& val) noexcept
302 ISOSPEC_IMPOSSIBLE(first_free >= backend_past_end);
307 ISOSPEC_FORCE_INLINE
void push_back(
const T& val)
309 if(first_free >= backend_past_end)
310 fast_reserve((std::max<std::ptrdiff_t>)(4, (backend_past_end-store)) * 2);
315 ISOSPEC_FORCE_INLINE T& operator[](
size_t n) noexcept
317 ISOSPEC_IMPOSSIBLE(store + n >= first_free);
321 ISOSPEC_FORCE_INLINE
const T& operator[](
size_t n)
const noexcept
323 ISOSPEC_IMPOSSIBLE(store + n >= first_free);
327 ISOSPEC_FORCE_INLINE
size_t size()
const noexcept
329 return first_free - store;
332 ISOSPEC_FORCE_INLINE
size_t capacity()
const noexcept
334 return backend_past_end - store;
337 ISOSPEC_FORCE_INLINE T* data() noexcept
342 ISOSPEC_FORCE_INLINE
const T* data()
const noexcept
347 ISOSPEC_FORCE_INLINE
bool empty()
const noexcept
349 return first_free == store;
352 ISOSPEC_FORCE_INLINE
const T& back()
const noexcept
354 ISOSPEC_IMPOSSIBLE(first_free > backend_past_end);
355 return *(first_free-1);
358 ISOSPEC_FORCE_INLINE
void pop_back() noexcept
361 ISOSPEC_IMPOSSIBLE(first_free == store);
367 std::swap(backend_past_end, other.backend_past_end);
368 std::swap(first_free, other.first_free);
369 std::swap(store, other.store);
373 typedef const T* const_iterator;
374 typedef T value_type;
375 typedef size_t size_type;
376 typedef T& reference;
377 typedef const T& const_reference;
379 iterator begin() noexcept {
return store; };
380 const_iterator begin()
const noexcept {
return store; }
381 const_iterator cbegin()
const noexcept {
return store; }
382 iterator end() noexcept {
return first_free; }
383 const_iterator end()
const noexcept {
return first_free; }
384 const_iterator cend()
const noexcept {
return first_free; }
386 ISOSPEC_FORCE_INLINE
const T& front()
const noexcept
388 ISOSPEC_IMPOSSIBLE(store == first_free);
395 first_free = store = backend_past_end = NULL;