12 #ifndef EASTL_FIXED_VECTOR_H
13 #define EASTL_FIXED_VECTOR_H
16 #include <EASTL/vector.h>
17 #include <EASTL/internal/fixed_pool.h>
19 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
33 #ifndef EASTL_FIXED_VECTOR_DEFAULT_NAME
34 #define EASTL_FIXED_VECTOR_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " fixed_vector"
40 #ifndef EASTL_FIXED_VECTOR_DEFAULT_ALLOCATOR
41 #define EASTL_FIXED_VECTOR_DEFAULT_ALLOCATOR overflow_allocator_type(EASTL_FIXED_VECTOR_DEFAULT_NAME)
70 template <typename T, size_t nodeCount, bool bEnableOverflow = true, typename OverflowAllocator = typename eastl::type_select<bEnableOverflow, EASTLAllocatorType, EASTLDummyAllocatorType>::type>
71 class fixed_vector :
public vector<T, fixed_vector_allocator<sizeof(T), nodeCount, EASTL_ALIGN_OF(T), 0, bEnableOverflow, OverflowAllocator> >
76 typedef OverflowAllocator overflow_allocator_type;
79 typedef typename base_type::size_type size_type;
80 typedef typename base_type::value_type value_type;
81 typedef typename base_type::reference reference;
82 typedef typename base_type::iterator iterator;
83 typedef typename base_type::const_iterator const_iterator;
86 enum { kMaxSize = nodeCount };
88 using base_type::get_allocator;
90 using base_type::mpEnd;
91 using base_type::internalCapacityPtr;
92 using base_type::resize;
93 using base_type::clear;
94 using base_type::size;
95 using base_type::assign;
96 using base_type::npos;
97 using base_type::DoAllocate;
98 using base_type::DoFree;
99 using base_type::DoAssign;
100 using base_type::DoAssignFromIterator;
107 explicit fixed_vector(
const overflow_allocator_type& overflowAllocator);
115 template <
typename InputIterator>
124 void set_capacity(size_type n);
125 void clear(
bool freeOverflow);
126 void reset_lose_memory();
127 size_type max_size()
const;
129 bool has_overflowed()
const;
130 bool can_overflow()
const;
132 void* push_back_uninitialized();
133 void push_back(
const value_type& value);
134 reference push_back();
135 void push_back(value_type&& value);
138 const overflow_allocator_type& get_overflow_allocator()
const EA_NOEXCEPT;
139 overflow_allocator_type& get_overflow_allocator() EA_NOEXCEPT;
140 void set_overflow_allocator(
const overflow_allocator_type&
allocator);
143 void* DoPushBackUninitialized(
true_type);
146 void DoPushBack(
true_type,
const value_type& value);
147 void DoPushBack(
false_type,
const value_type& value);
149 void DoPushBackMove(
true_type, value_type&& value);
150 void DoPushBackMove(
false_type, value_type&& value);
164 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
166 : base_type(fixed_allocator_type(mBuffer.buffer))
168 #if EASTL_NAME_ENABLED
169 get_allocator().set_name(EASTL_FIXED_VECTOR_DEFAULT_NAME);
172 mpBegin = mpEnd = (value_type*)&mBuffer.buffer[0];
173 internalCapacityPtr() =
mpBegin + nodeCount;
176 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
177 inline fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::fixed_vector(
const overflow_allocator_type& overflowAllocator)
178 : base_type(fixed_allocator_type(mBuffer.buffer, overflowAllocator))
180 #if EASTL_NAME_ENABLED
181 get_allocator().set_name(EASTL_FIXED_VECTOR_DEFAULT_NAME);
184 mpBegin = mpEnd = (value_type*)&mBuffer.buffer[0];
185 internalCapacityPtr() =
mpBegin + nodeCount;
188 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
189 inline fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::fixed_vector(size_type n)
190 : base_type(fixed_allocator_type(mBuffer.buffer))
192 #if EASTL_NAME_ENABLED
193 get_allocator().set_name(EASTL_FIXED_VECTOR_DEFAULT_NAME);
196 mpBegin = mpEnd = (value_type*)&mBuffer.buffer[0];
197 internalCapacityPtr() =
mpBegin + nodeCount;
202 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
203 inline fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::fixed_vector(size_type n,
const value_type& value)
204 : base_type(fixed_allocator_type(mBuffer.buffer))
206 #if EASTL_NAME_ENABLED
207 get_allocator().set_name(EASTL_FIXED_VECTOR_DEFAULT_NAME);
210 mpBegin = mpEnd = (value_type*)&mBuffer.buffer[0];
211 internalCapacityPtr() =
mpBegin + nodeCount;
216 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
217 inline fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::fixed_vector(
const this_type& x)
218 : base_type(fixed_allocator_type(mBuffer.buffer))
220 get_allocator().copy_overflow_allocator(x.get_allocator());
222 #if EASTL_NAME_ENABLED
223 get_allocator().set_name(x.get_allocator().get_name());
226 mpBegin = mpEnd = (value_type*)&mBuffer.buffer[0];
227 internalCapacityPtr() =
mpBegin + nodeCount;
228 base_type::template DoAssign<const_iterator, false>(x.begin(), x.end(), false_type());
232 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
233 inline fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::fixed_vector(this_type&& x)
234 : base_type(fixed_allocator_type(mBuffer.buffer))
251 get_allocator().copy_overflow_allocator(x.get_allocator());
253 #if EASTL_NAME_ENABLED
254 get_allocator().set_name(x.get_allocator().get_name());
257 mpBegin = mpEnd = (value_type*)&mBuffer.buffer[0];
258 internalCapacityPtr() =
mpBegin + nodeCount;
259 base_type::template DoAssign<move_iterator<iterator>,
true>(eastl::make_move_iterator(x.begin()), eastl::make_move_iterator(x.end()), false_type());
263 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
264 inline fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::fixed_vector(this_type&& x,
const overflow_allocator_type& overflowAllocator)
265 : base_type(fixed_allocator_type(mBuffer.buffer, overflowAllocator))
271 get_allocator().copy_overflow_allocator(x.get_allocator());
273 #if EASTL_NAME_ENABLED
274 get_allocator().set_name(x.get_allocator().get_name());
277 mpBegin = mpEnd = (value_type*)&mBuffer.buffer[0];
278 internalCapacityPtr() =
mpBegin + nodeCount;
279 base_type::template DoAssign<iterator, true>(x.begin(), x.end(), false_type());
283 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
284 inline fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::fixed_vector(
std::initializer_list<T> ilist,
const overflow_allocator_type& overflowAllocator)
285 : base_type(fixed_allocator_type(mBuffer.buffer, overflowAllocator))
287 typedef typename std::initializer_list<value_type>::iterator InputIterator;
288 typedef typename eastl::iterator_traits<InputIterator>::iterator_category IC;
290 mpBegin = mpEnd = (value_type*)&mBuffer.buffer[0];
291 internalCapacityPtr() =
mpBegin + nodeCount;
292 base_type::template DoAssignFromIterator<InputIterator, false>(ilist.begin(), ilist.end(), IC());
296 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
297 template <
typename InputIterator>
298 fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::fixed_vector(InputIterator first, InputIterator last)
299 : base_type(fixed_allocator_type(mBuffer.buffer))
301 #if EASTL_NAME_ENABLED
302 get_allocator().set_name(EASTL_FIXED_VECTOR_DEFAULT_NAME);
305 mpBegin = mpEnd = (value_type*)&mBuffer.buffer[0];
306 internalCapacityPtr() =
mpBegin + nodeCount;
307 base_type::template DoAssign<InputIterator, false>(first, last, is_integral<InputIterator>());
311 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
312 inline typename fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::this_type&
313 fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::operator=(
const this_type& x)
319 #if EASTL_ALLOCATOR_COPY_ENABLED
320 get_allocator() = x.get_allocator();
323 base_type::template DoAssign<const_iterator, false>(x.begin(), x.end(), false_type());
329 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
330 inline typename fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::this_type&
333 typedef typename std::initializer_list<value_type>::iterator InputIterator;
334 typedef typename eastl::iterator_traits<InputIterator>::iterator_category IC;
337 base_type::template DoAssignFromIterator<InputIterator, false>(ilist.begin(), ilist.end(), IC());
342 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
343 inline typename fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::this_type&
344 fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::operator=(this_type&& x)
355 #if EASTL_ALLOCATOR_COPY_ENABLED
356 get_allocator() = x.get_allocator();
359 base_type::template DoAssign<move_iterator<iterator>,
true>(eastl::make_move_iterator(x.begin()), eastl::make_move_iterator(x.end()), false_type());
365 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
366 inline void fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::swap(this_type& x)
368 if((has_overflowed() && x.has_overflowed()) && (get_overflow_allocator() == x.get_overflow_allocator()))
370 eastl::swap(mpBegin, x.mpBegin);
371 eastl::swap(mpEnd, x.mpEnd);
372 eastl::swap(internalCapacityPtr(), x.internalCapacityPtr());
377 eastl::fixed_swap(*
this, x);
382 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
383 inline void fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::set_capacity(size_type n)
385 const size_type nPrevSize = (size_type)(mpEnd - mpBegin);
386 const size_type nPrevCapacity = (size_type)(internalCapacityPtr() - mpBegin);
391 if(n != nPrevCapacity)
393 if(can_overflow() && (((uintptr_t)mpBegin != (uintptr_t)mBuffer.buffer) || (n > kMaxSize)))
395 T*
const pNewData = (n <= kMaxSize) ? (T*)&mBuffer.buffer[0] : DoAllocate(n);
396 T*
const pCopyEnd = (n < nPrevSize) ? (mpBegin + n) : mpEnd;
397 eastl::uninitialized_move_ptr(mpBegin, pCopyEnd, pNewData);
399 if((uintptr_t)mpBegin != (uintptr_t)mBuffer.buffer)
400 DoFree(mpBegin, (size_type)(internalCapacityPtr() - mpBegin));
402 mpEnd = pNewData + (pCopyEnd - mpBegin);
404 internalCapacityPtr() = mpBegin + n;
406 else if(n < nPrevSize)
412 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename Allocator>
413 inline void fixed_vector<T, nodeCount, bEnableOverflow, Allocator>::clear(
bool freeOverflow)
416 if (freeOverflow && mpBegin != (value_type*)&mBuffer.buffer[0])
418 EASTLFree(get_allocator(), mpBegin, (internalCapacityPtr() - mpBegin) *
sizeof(T));
419 mpBegin = mpEnd = (value_type*)&mBuffer.buffer[0];
420 internalCapacityPtr() = mpBegin + nodeCount;
425 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
426 inline void fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::reset_lose_memory()
428 mpBegin = mpEnd = (value_type*)&mBuffer.buffer[0];
429 internalCapacityPtr() = mpBegin + nodeCount;
433 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
434 inline typename fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::size_type
435 fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::max_size()
const
441 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
442 inline bool fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::full()
const
446 return ((
size_t)(mpEnd - mpBegin) >= kMaxSize) || ((
void*)mpBegin != (
void*)mBuffer.buffer);
450 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
451 inline bool fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::has_overflowed()
const
457 return ((
void*)mpBegin != (
void*)mBuffer.buffer);
461 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
462 inline bool fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::can_overflow()
const
464 return bEnableOverflow;
468 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
469 inline void* fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::push_back_uninitialized()
471 return DoPushBackUninitialized(
typename type_select<bEnableOverflow, true_type, false_type>::type());
475 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
476 inline void* fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::DoPushBackUninitialized(true_type)
478 return base_type::push_back_uninitialized();
482 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
483 inline void* fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::DoPushBackUninitialized(false_type)
485 EASTL_ASSERT(mpEnd < internalCapacityPtr());
491 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
492 inline void fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::push_back(
const value_type& value)
494 DoPushBack(
typename type_select<bEnableOverflow, true_type, false_type>::type(), value);
498 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
499 inline void fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::DoPushBack(true_type,
const value_type& value)
501 base_type::push_back(value);
507 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
508 inline void fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::DoPushBack(false_type,
const value_type& value)
510 EASTL_ASSERT(mpEnd < internalCapacityPtr());
512 ::new((
void*)mpEnd++) value_type(value);
516 template <typename T,
size_t nodeCount,
bool bEnableOverflow, typename OverflowAllocator>
517 inline typename fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::reference fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::push_back()
519 return DoPushBack(
typename type_select<bEnableOverflow, true_type, false_type>::type());
523 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
524 inline typename fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::reference fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::DoPushBack(true_type)
526 return base_type::push_back();
532 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
533 inline typename fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::reference fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::DoPushBack(false_type)
535 EASTL_ASSERT(mpEnd < internalCapacityPtr());
537 ::new((
void*)mpEnd++) value_type;
543 template <typename T,
size_t nodeCount,
bool bEnableOverflow, typename OverflowAllocator>
544 inline
void fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::push_back(value_type&& value)
546 DoPushBackMove(
typename type_select<bEnableOverflow, true_type, false_type>::type(),
eastl::move(value));
550 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
551 inline void fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::DoPushBackMove(true_type, value_type&& value)
559 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
560 inline void fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::DoPushBackMove(false_type, value_type&& value)
562 EASTL_ASSERT(mpEnd < internalCapacityPtr());
564 ::new((
void*)mpEnd++) value_type(
eastl::
move(value));
568 template <typename T,
size_t nodeCount,
bool bEnableOverflow, typename OverflowAllocator>
569 inline const typename fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::overflow_allocator_type&
570 fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::get_overflow_allocator() const EA_NOEXCEPT
572 return get_allocator().get_overflow_allocator();
576 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
577 inline typename fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::overflow_allocator_type&
578 fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::get_overflow_allocator() EA_NOEXCEPT
580 return get_allocator().get_overflow_allocator();
584 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
586 fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>::set_overflow_allocator(
const overflow_allocator_type& allocator)
588 get_allocator().set_overflow_allocator(allocator);
599 template <
typename T,
size_t nodeCount,
bool bEnableOverflow,
typename OverflowAllocator>
600 inline void swap(fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>& a,
601 fixed_vector<T, nodeCount, bEnableOverflow, OverflowAllocator>& b)
604 eastl::fixed_swap(a, b);
Definition: allocator.h:52
Definition: fixed_pool.h:1329
Definition: fixed_vector.h:72
T * mpBegin
-1 is reserved for 'npos'. It also happens to be slightly beneficial that kMaxSize is a value less th...
Definition: vector.h:142
Definition: initializer_list.h:38
EA Standard Template Library.
Definition: algorithm.h:288
OutputIterator move(InputIterator first, InputIterator last, OutputIterator result)
Definition: copy_help.h:170
void destruct(T *p)
Definition: memory.h:1324
Definition: fixed_pool.h:82
Definition: type_traits.h:263