fixed_vector.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // A vector without autogrowing capacity(). Can hold non-copyable/movable objects
  2. //
  3. // Platform: ISO C++ 98/11
  4. // $Id$
  5. //
  6. // (c) __vic 2007
  7. #ifndef __VIC_FIXED_VECTOR_H
  8. #define __VIC_FIXED_VECTOR_H
  9. #include<__vic/defs.h>
  10. #include<new>
  11. #include __VIC_SWAP_HEADER
  12. namespace __vic {
  13. //////////////////////////////////////////////////////////////////////////////
  14. template<class T>
  15. class fixed_vector : private non_copyable
  16. {
  17. T *mem, *next, *limit;
  18. static T *allocate(size_t n)
  19. { return static_cast<T *>(::operator new[](sizeof(T) * n)); }
  20. static void deallocate(T *p) { ::operator delete[](p); }
  21. static void destroy(T *p) { p->~T(); }
  22. public:
  23. typedef T value_type;
  24. typedef value_type *iterator;
  25. typedef const value_type *const_iterator;
  26. fixed_vector() : mem(0), next(0), limit(0) {}
  27. explicit fixed_vector(size_t );
  28. ~fixed_vector();
  29. #if __cpp_rvalue_references
  30. fixed_vector(fixed_vector &&o) noexcept
  31. : mem(o.mem), next(o.next), limit(o.limit)
  32. {
  33. o.mem = o.next = o.limit = nullptr;
  34. }
  35. fixed_vector &operator=(fixed_vector &&o) noexcept { swap(o); return *this; }
  36. #if __cpp_variadic_templates
  37. template<class... Args> T &emplace_back(Args &&... );
  38. #endif
  39. #endif
  40. // size in objects
  41. size_t size() const { return next - mem; }
  42. size_t capacity() const { return limit - mem; }
  43. bool full() const { return next == limit; }
  44. bool empty() const { return next == mem; }
  45. void recreate(size_t , bool = false);
  46. void pop_back() { destroy(--next); }
  47. void clear()
  48. {
  49. // destruct all objects
  50. while(next != mem) destroy(--next);
  51. }
  52. void swap(fixed_vector &o) noexcept
  53. {
  54. std::swap(mem, o.mem);
  55. std::swap(next, o.next);
  56. std::swap(limit, o.limit);
  57. }
  58. // BEGIN: Deprecated functions. Use emplace() in C++11 mode
  59. // returns pointer to memory for object allocation
  60. void *alloc() { return next; }
  61. // adds last allocated object to the container
  62. void push_allocated() { next++; }
  63. // END: Deprecated functions
  64. // element access
  65. T &operator[](size_t i) { return mem[i]; }
  66. iterator begin() { return mem; }
  67. iterator end() { return next; }
  68. T &front() { return *mem; }
  69. T &back() { return *(next-1); }
  70. const T &operator[](size_t i) const { return mem[i]; }
  71. const_iterator begin() const { return mem; }
  72. const_iterator end() const { return next; }
  73. const_iterator cbegin() const { return begin(); }
  74. const_iterator cend() const { return end(); }
  75. const T &front() const { return *mem; }
  76. const T &back() const { return *(next-1); }
  77. };
  78. //////////////////////////////////////////////////////////////////////////////
  79. //----------------------------------------------------------------------------
  80. template<class T>
  81. fixed_vector<T>::fixed_vector(size_t max_size)
  82. {
  83. mem = next = this->allocate(max_size);
  84. limit = mem + max_size;
  85. }
  86. //----------------------------------------------------------------------------
  87. template<class T>
  88. fixed_vector<T>::~fixed_vector()
  89. {
  90. clear();
  91. deallocate(mem);
  92. }
  93. //----------------------------------------------------------------------------
  94. template<class T>
  95. void fixed_vector<T>::recreate(size_t max_size, bool exact)
  96. {
  97. clear();
  98. if(max_size > capacity() || (exact && max_size != capacity()))
  99. {
  100. deallocate(mem);
  101. mem = next = this->allocate(max_size);
  102. limit = mem + max_size;
  103. }
  104. }
  105. //----------------------------------------------------------------------------
  106. #if __cpp_rvalue_references && __cpp_variadic_templates
  107. template<class T>
  108. template<class... Args>
  109. T &fixed_vector<T>::emplace_back(Args &&... args)
  110. {
  111. T *obj = ::new(static_cast<void*>(next)) T(std::forward<Args>(args)...);
  112. next++;
  113. return *obj;
  114. }
  115. #endif
  116. //----------------------------------------------------------------------------
  117. template<class T>
  118. inline void swap(fixed_vector<T> &o1, fixed_vector<T> &o2) noexcept { o1.swap(o2); }
  119. //----------------------------------------------------------------------------
  120. } // namespace
  121. #endif // header guard