aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-05-17 19:47:10 +0000
committerted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-05-17 19:47:10 +0000
commitbcf029f3330db5ad7e3994cf519df7c43476b418 (patch)
tree2d71e37dcf81c63de92edda3025e14b973442893 /src
parentAvoid gmock warning "Uninteresting mock function call" (diff)
downloadbreakpad-bcf029f3330db5ad7e3994cf519df7c43476b418.tar.xz
Use std::vector with a custom allocator wrapping PageAllocator for wasteful_vector
Patch by Mike Hommey <mh@glandium.org>, R=me at https://breakpad.appspot.com/581002/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1184 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src')
-rw-r--r--src/common/memory.h99
1 files changed, 29 insertions, 70 deletions
diff --git a/src/common/memory.h b/src/common/memory.h
index 1fda60f9..cb37b5fa 100644
--- a/src/common/memory.h
+++ b/src/common/memory.h
@@ -30,13 +30,13 @@
#ifndef GOOGLE_BREAKPAD_COMMON_MEMORY_H_
#define GOOGLE_BREAKPAD_COMMON_MEMORY_H_
+#include <memory>
+#include <vector>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
-#include <algorithm>
-
#ifdef __APPLE__
#define sys_mmap mmap
#define sys_mmap2 mmap
@@ -133,83 +133,42 @@ class PageAllocator {
unsigned page_offset_;
};
-// A wasteful vector is like a normal std::vector, except that it's very much
-// simplier and it allocates memory from a PageAllocator. It's wasteful
-// because, when resizing, it always allocates a whole new array since the
-// PageAllocator doesn't support realloc.
-template<class T>
-class wasteful_vector {
- public:
- wasteful_vector(PageAllocator *allocator, unsigned size_hint = 16)
- : allocator_(allocator),
- a_((T*) allocator->Alloc(sizeof(T) * size_hint)),
- allocated_(size_hint),
- used_(0) {
- }
-
- T& back() {
- return a_[used_ - 1];
- }
-
- const T& back() const {
- return a_[used_ - 1];
- }
+// Wrapper to use with STL containers
+template <typename T>
+struct PageStdAllocator: public std::allocator<T> {
+ typedef typename std::allocator<T>::pointer pointer;
+ typedef typename std::allocator<T>::size_type size_type;
- bool empty() const {
- return used_ == 0;
- }
+ PageStdAllocator(PageAllocator& allocator): allocator_(allocator) {}
+ template <class Other> PageStdAllocator(const PageStdAllocator<Other>& other):
+ allocator_(other.allocator_) {}
- void push_back(const T& new_element) {
- if (used_ == allocated_)
- Realloc(std::max(allocated_ * 2, 1u));
- a_[used_++] = new_element;
+ inline pointer allocator(size_type n, const void* = 0) {
+ return allocator_.Alloc(sizeof(T) * n);
}
- size_t size() const {
- return used_;
+ inline void deallocate(pointer, size_type) {
+ // The PageAllocator doesn't free.
}
- void resize(unsigned sz, T c = T()) {
- // No need to test "sz >= 0", as "sz" is unsigned.
- if (sz <= used_) {
- used_ = sz;
- } else {
- unsigned a = allocated_;
- if (sz > a) {
- while (sz > a) {
- a *= 2;
- }
- Realloc(a);
- }
- while (sz > used_) {
- a_[used_++] = c;
- }
- }
- }
-
- T& operator[](size_t index) {
- return a_[index];
- }
+ template <typename U> struct rebind {
+ typedef PageStdAllocator<U> other;
+ };
- const T& operator[](size_t index) const {
- return a_[index];
- }
+private:
+ PageAllocator& allocator_;
+};
- private:
- void Realloc(unsigned new_size) {
- T *new_array =
- reinterpret_cast<T*>(allocator_->Alloc(sizeof(T) * new_size));
- if (new_size > 0) {
- memcpy(new_array, a_, used_ * sizeof(T));
- }
- a_ = new_array;
- allocated_ = new_size;
+// A wasteful vector is a std::vector, except that it allocates memory from a
+// PageAllocator. It's wasteful because, when resizing, it always allocates a
+// whole new array since the PageAllocator doesn't support realloc.
+template<class T>
+class wasteful_vector: public std::vector<T, PageStdAllocator<T> > {
+ public:
+ wasteful_vector(PageAllocator* allocator, unsigned size_hint = 16)
+ : std::vector<T, PageStdAllocator<T> >(PageStdAllocator<T>(*allocator)) {
+ std::vector<T, PageStdAllocator<T> >::reserve(size_hint);
}
-
- PageAllocator *const allocator_;
- T *a_; // pointer to an array of |allocated_| elements.
- unsigned allocated_; // size of |a_|, in elements.
- unsigned used_; // number of used slots in |a_|.
};
} // namespace google_breakpad