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