crazy_linker_util.h revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file. 4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef CRAZY_LINKER_UTIL_H 6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define CRAZY_LINKER_UTIL_H 7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <fcntl.h> 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <stdarg.h> 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <stdio.h> 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <unistd.h> 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace crazy { 14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Helper macro to loop around EINTR errors in syscalls. 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define HANDLE_EINTR(expr) TEMP_FAILURE_RETRY(expr) 17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Helper macro to tag unused variables. Use in the declaration, between 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// the type and name, as in: 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// int CRAZY_UNUSED my_var = 0; 21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define CRAZY_UNUSED __attribute__((unused)) 22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Helper scoped pointer class. 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)template <class T> 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ScopedPtr { 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public: 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ScopedPtr() : ptr_(NULL) {} 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) explicit ScopedPtr(T* ptr) : ptr_(ptr) {} 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ~ScopedPtr() { Reset(NULL); } 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T* Release() { 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T* ret = ptr_; 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ptr_ = NULL; 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ret; 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Reset(T* ptr) { 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (ptr_) 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) delete ptr_; 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ptr_ = ptr; 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T* Get() { return ptr_; } 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T& operator*() { return *ptr_; } 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T* operator->() { return ptr_; } 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private: 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T* ptr_; 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Return the base name from a file path. Important: this is a pointer 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// into the original string. 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const char* GetBaseNamePtr(const char* path); 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Helper class used to implement a string. Similar to std::string 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// without all the crazy iterator / iostream stuff. 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Required because crazy linker should only link against the system 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// libstdc++ that only provides new/delete. 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class String { 62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public: 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) String(); 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) String(const char* str, size_t len); 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) String(const String& other); 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) explicit String(const char* str); 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) explicit String(char ch); 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ~String(); 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* c_str() const { return ptr_; } 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) char* ptr() { return ptr_; } 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t size() const { return size_; } 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t capacity() const { return capacity_; } 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool IsEmpty() const { return size_ == 0; } 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) char& operator[](size_t index) { return ptr_[index]; } 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) String& operator=(const String& other) { 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Assign(other.ptr_, other.size_); 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return *this; 83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) String& operator=(const char* str) { 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Assign(str, strlen(str)); 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return *this; 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) String& operator=(char ch) { 91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Assign(&ch, 1); 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return *this; 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) String& operator+=(const String& other) { 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Append(other); 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return *this; 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) String& operator+=(const char* str) { 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Append(str, strlen(str)); 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return *this; 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) String& operator+=(char ch) { 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Append(&ch, 1); 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return *this; 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Resize(size_t new_size); 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Reserve(size_t new_capacity); 113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Assign(const char* str, size_t len); 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Assign(const String& other) { Assign(other.ptr_, other.size_); } 117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Assign(const char* str) { Assign(str, strlen(str)); } 119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Append(const char* str, size_t len); 121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Append(const String& other) { Append(other.ptr_, other.size_); } 123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Append(const char* str) { Append(str, strlen(str)); } 125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private: 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Init(void) { 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ptr_ = const_cast<char*>(kEmpty); 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_ = 0; 130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) capacity_ = 0; 131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static const char kEmpty[]; 134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) char* ptr_; 136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t size_; 137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t capacity_; 138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Helper template used to implement a simple vector or POD-struct items. 141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// I.e. this uses memmove() to move items during insertion / removal. 142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// 143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Required because crazy linker should only link against the system 144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// libstdc++ which only provides new/delete. 145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// 146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)template <class T> 147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class Vector { 148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public: 149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Vector() : items_(0), count_(0), capacity_(0) {} 150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ~Vector() { free(items_); } 151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T& operator[](size_t index) { return items_[index]; } 153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool IsEmpty() const { return count_ == 0; } 155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void PushBack(T item) { InsertAt(static_cast<int>(count_), item); } 157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T PopFirst() { 159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T result = items_[0]; 160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) RemoveAt(0); 161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return result; 162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T PopLast() { 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T result = items_[count_ - 1]; 166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Resize(count_ - 1); 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return result; 168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Remove(T item) { 171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int index = IndexOf(item); 172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (index >= 0) 173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) RemoveAt(index); 174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void InsertAt(int index, T item); 177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void RemoveAt(int index); 179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int IndexOf(T item) const; 181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool Has(T item) const { return IndexOf(item) >= 0; } 183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t GetCount() const { return count_; } 185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Reserve(size_t new_capacity); 187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void Resize(size_t new_count); 189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private: 191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) T* items_; 192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t count_; 193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t capacity_; 194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)template <class T> 197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int Vector<T>::IndexOf(T item) const { 198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t n = 0; n < count_; ++n) { 199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (items_[n] == item) 200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return static_cast<int>(n); 201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return -1; 203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)template <class T> 206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void Vector<T>::InsertAt(int index, T item) { 207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (count_ >= capacity_) 208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Reserve(capacity_ + (capacity_ >> 1) + 4); 209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (index < 0) 211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) index = 0; 212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t n = static_cast<size_t>(index); 213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (n > count_) 214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) n = count_; 215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) else 216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) memmove(items_ + n + 1, items_ + n, (count_ - n) * sizeof(T)); 217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) items_[n] = item; 219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) count_++; 220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)template <class T> 223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void Vector<T>::RemoveAt(int index) { 224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (index < 0) 225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t n = static_cast<size_t>(index); 228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (n >= count_) 229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) memmove(items_ + n, items_ + n + 1, (count_ - n - 1) * sizeof(T)); 232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) count_--; 233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)template <class T> 236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void Vector<T>::Reserve(size_t new_capacity) { 237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) items_ = reinterpret_cast<T*>(realloc(items_, new_capacity * sizeof(T))); 238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) capacity_ = new_capacity; 239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (count_ > capacity_) 240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) count_ = capacity_; 241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)template <class T> 244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void Vector<T>::Resize(size_t new_size) { 245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (new_size > capacity_) 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Reserve(new_size); 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (new_size > count_) 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) memset(items_ + count_, 0, (new_size - count_) * sizeof(T)); 250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) count_ = new_size; 252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Helper template class to implement a set. 255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Given that the crazy linker doesn't expect to deal with hundreds 256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// of libraries at the same time, implement it with a vector. 257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)template <class T> 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class Set { 259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public: 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Set() : items_() {} 261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ~Set() {} 262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Returns the number of items in the set. 264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t GetCount() const { return items_.GetCount(); } 265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool IsEmpty() const { return items_.IsEmpty(); } 267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Returns true iff the set contains a given item. 269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool Has(T item) const { return items_.Has(item); } 270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Add an item to the set. Returns false iff the item was already in it. 272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool Add(T item); 273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Delete an item from the set. Returns false iff the item was not in it. 275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool Del(T item); 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private: 278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Vector<T> items_; 279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)template <class T> 282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool Set<T>::Add(T item) { 283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int idx = items_.IndexOf(item); 284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (idx >= 0) 285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) items_.PushBack(item); 288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)template <class T> 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool Set<T>::Del(T item) { 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int idx = items_.IndexOf(item); 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (idx < 0) 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) items_.RemoveAt(idx); 297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace crazy 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif // CRAZY_LINKER_UTIL_H 303