mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			128 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- sanitizer_vector.h -------------------------------------*- C++ -*-===//
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This file is shared between sanitizers run-time libraries.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| // Low-fat STL-like vector container.
 | |
| 
 | |
| #ifndef SANITIZER_VECTOR_H
 | |
| #define SANITIZER_VECTOR_H
 | |
| 
 | |
| #include "sanitizer_common/sanitizer_allocator_internal.h"
 | |
| #include "sanitizer_common/sanitizer_libc.h"
 | |
| 
 | |
| namespace __sanitizer {
 | |
| 
 | |
| template<typename T>
 | |
| class Vector {
 | |
|  public:
 | |
|   explicit Vector()
 | |
|       : begin_()
 | |
|       , end_()
 | |
|       , last_() {
 | |
|   }
 | |
| 
 | |
|   ~Vector() {
 | |
|     if (begin_)
 | |
|       InternalFree(begin_);
 | |
|   }
 | |
| 
 | |
|   void Reset() {
 | |
|     if (begin_)
 | |
|       InternalFree(begin_);
 | |
|     begin_ = 0;
 | |
|     end_ = 0;
 | |
|     last_ = 0;
 | |
|   }
 | |
| 
 | |
|   uptr Size() const {
 | |
|     return end_ - begin_;
 | |
|   }
 | |
| 
 | |
|   T &operator[](uptr i) {
 | |
|     DCHECK_LT(i, end_ - begin_);
 | |
|     return begin_[i];
 | |
|   }
 | |
| 
 | |
|   const T &operator[](uptr i) const {
 | |
|     DCHECK_LT(i, end_ - begin_);
 | |
|     return begin_[i];
 | |
|   }
 | |
| 
 | |
|   T *PushBack() {
 | |
|     EnsureSize(Size() + 1);
 | |
|     T *p = &end_[-1];
 | |
|     internal_memset(p, 0, sizeof(*p));
 | |
|     return p;
 | |
|   }
 | |
| 
 | |
|   T *PushBack(const T& v) {
 | |
|     EnsureSize(Size() + 1);
 | |
|     T *p = &end_[-1];
 | |
|     internal_memcpy(p, &v, sizeof(*p));
 | |
|     return p;
 | |
|   }
 | |
| 
 | |
|   void PopBack() {
 | |
|     DCHECK_GT(end_, begin_);
 | |
|     end_--;
 | |
|   }
 | |
| 
 | |
|   void Resize(uptr size) {
 | |
|     if (size == 0) {
 | |
|       end_ = begin_;
 | |
|       return;
 | |
|     }
 | |
|     uptr old_size = Size();
 | |
|     if (size <= old_size) {
 | |
|       end_ = begin_ + size;
 | |
|       return;
 | |
|     }
 | |
|     EnsureSize(size);
 | |
|     if (old_size < size) {
 | |
|       for (uptr i = old_size; i < size; i++)
 | |
|         internal_memset(&begin_[i], 0, sizeof(begin_[i]));
 | |
|     }
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   T *begin_;
 | |
|   T *end_;
 | |
|   T *last_;
 | |
| 
 | |
|   void EnsureSize(uptr size) {
 | |
|     if (size <= Size())
 | |
|       return;
 | |
|     if (size <= (uptr)(last_ - begin_)) {
 | |
|       end_ = begin_ + size;
 | |
|       return;
 | |
|     }
 | |
|     uptr cap0 = last_ - begin_;
 | |
|     uptr cap = cap0 * 5 / 4;  // 25% growth
 | |
|     if (cap == 0)
 | |
|       cap = 16;
 | |
|     if (cap < size)
 | |
|       cap = size;
 | |
|     T *p = (T*)InternalAlloc(cap * sizeof(T));
 | |
|     if (cap0) {
 | |
|       internal_memcpy(p, begin_, cap0 * sizeof(T));
 | |
|       InternalFree(begin_);
 | |
|     }
 | |
|     begin_ = p;
 | |
|     end_ = begin_ + size;
 | |
|     last_ = begin_ + cap;
 | |
|   }
 | |
| 
 | |
|   Vector(const Vector&);
 | |
|   void operator=(const Vector&);
 | |
| };
 | |
| }  // namespace __sanitizer
 | |
| 
 | |
| #endif  // #ifndef SANITIZER_VECTOR_H
 |