123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- #ifndef __DAHUA_INFRA_VECTOR_H__
- #define __DAHUA_INFRA_VECTOR_H__
- #include "Allocator.h"
- #include "Detail/construct.h"
- namespace Dahua {
- namespace Infra {
- template<typename T>
- class TVector
- {
- public:
-
- typedef T value_type;
- typedef value_type* iterator;
- typedef value_type& reference;
- typedef size_t size_type;
-
- iterator begin() const
- {
- return m_start;
- }
-
- iterator end() const
- {
- return m_end;
- }
-
- size_type size() const
- {
- return size_type(m_end - m_start);
- }
-
- size_type capacity() const
- {
- return size_type(m_capEnd - m_start);
- }
-
- bool empty() const
- {
- return begin() == end();
- }
-
- reference operator[](size_type n) const
- {
- return *(begin() + n);
- }
-
- TVector()
- : m_start(0)
- , m_end(0)
- , m_capEnd(0)
- {}
-
- TVector(size_type n, const T& value)
- {
- fill_initialize(n, value);
- }
-
- explicit TVector(size_type n)
- {
- fill_initialize(n, T());
- }
-
- TVector(TVector const& r)
- {
- m_start = (iterator)CAllocator::allocate(r.capacity() * sizeof(T));
- for (size_t i = 0; i < r.size(); ++i)
- {
- Datail::construct(&m_start[i], r.m_start[i]);
- }
- m_end = m_start + r.size();
- m_capEnd = m_start + r.capacity();
- }
-
- TVector& operator=(TVector const& r)
- {
- if (this == &r)
- {
- return *this;
- }
-
- m_start = (iterator)CAllocator::allocate(r.capacity() * sizeof(T));
- for (size_t i = 0; i < r.size(); ++i)
- {
- Datail::construct(&m_start[i], r.m_start[i]);
- }
- m_end = m_start + r.size();
- m_capEnd = m_start + r.capacity();
- return *this;
- }
-
- ~TVector()
- {
- for (size_t i = 0; i < size(); ++i)
- {
- Datail::destruct(m_start[i]);
- }
-
- if (m_start != 0)
- {
- CAllocator::dealocate((void *)m_start, size() * sizeof(T));
- }
- m_start = m_end = m_capEnd = 0;
- }
-
- reference front() const
- {
- return *m_start;
- }
-
- reference back() const
- {
- return *(m_end - 1);
- }
-
- void push_back(const T& value)
- {
- if (m_end == m_capEnd)
- {
- realloc();
- }
- Datail::construct(m_end, value);
- ++m_end;
- }
-
- void pop_back()
- {
- --m_end;
- Datail::destruct(m_end);
- }
-
- iterator erase(iterator pos)
- {
- if (pos + 1 != end())
- {
- size_t copy_size = size_t(m_end - pos) - 1;
- for (size_t i = 0; i < copy_size; ++i)
- pos[i] = pos[i + 1];
- }
- --m_end;
- Datail::destruct(m_end);
- return pos;
- }
-
- void resize(size_type new_size, const T& x)
- {
- if (new_size < size())
- {
- m_end = m_start + new_size;
- for (iterator s = m_start; s != m_end; ++s)
- {
- Datail::destruct(s);
- Datail::construct(s, x);
- }
- return;
- }
-
- for ( iterator s = m_start; s != m_end; ++s )
- {
- Datail::destruct(s);
- }
-
- if (new_size > capacity())
- {
- realloc(new_size);
- }
-
- m_end = m_start + new_size;
- for ( iterator s = m_start; s != m_end; ++s )
- {
- Datail::construct(s, x);
- }
- }
-
- void resize(size_type new_size)
- {
- resize(new_size, T());
- }
-
- void clear()
- {
- for ( iterator s = m_start; s != m_end; ++s )
- {
- Datail::destruct(s);
- }
- m_end = m_start;
- }
-
- private:
-
- void realloc()
- {
- size_t cap = capacity();
- if (0 == cap)
- {
- m_start = (iterator)CAllocator::allocate(sizeof(T));
- m_capEnd = m_start + 1;
- m_end = m_start;
- }
- else
- {
- size_t s = size();
- m_start = (T*)CAllocator::reallocate(m_start, cap * sizeof(T), 2 * cap * sizeof(T));
- m_capEnd = m_start + 2 * cap;
- m_end = m_start + s;
- }
- }
-
- void realloc(size_t new_size)
- {
- size_t s = size();
- size_t cap = capacity();
- if (cap == 0)
- {
- m_start = (iterator)CAllocator::allocate(sizeof(T) * new_size);
- m_capEnd = m_start + new_size;
- m_end = m_start;
- return;
- }
- size_t nbr = new_size / cap + (new_size % cap ? 1 : 0);
- m_start = (T*)CAllocator::reallocate(m_start, cap * sizeof(T), cap * nbr * sizeof(T));
- m_capEnd = m_start + cap * nbr;
- m_end = m_start + s;
- }
-
- void fill_initialize(size_type n, const T& value)
- {
- m_start = (iterator)CAllocator::allocate(n * sizeof(T));
- for (size_t i = 0; i < n; ++i)
- Datail::construct(m_start + i, value);
-
- m_end = m_start + n;
- m_capEnd = m_end;
- }
-
- iterator m_start;
- iterator m_end;
- iterator m_capEnd;
- };
- } // end of Infra
- } // end of Dahua
- #endif // end of __DAHUA_INFRA_VECTOR_H__
|