FILENAME 3/4 - delete the old get_fun_path etc.
[hiphop-php.git] / hphp / util / growable-vector.h
blob3490d3db8cf8970c9105697011c79b56e94cb86c
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #pragma once
19 #include <cstdlib>
20 #include <cstdint>
22 #include "hphp/util/assertions.h"
24 namespace HPHP { namespace jit {
25 ////////////////////////////////////////////////////////////////////////////////
28 * A vector of elements that will increase its capacity when it fills up. It
29 * differs from std::vector in that it only takes up 8 bytes of space, its
30 * elements must be trivially destructible, and it cannot erase individual
31 * elements.
33 template<typename T>
34 struct GrowableVector {
35 explicit GrowableVector() {}
37 GrowableVector(GrowableVector&& other) noexcept : m_vec(other.m_vec) {
38 other.m_vec = nullptr;
41 GrowableVector& operator=(GrowableVector&& other) {
42 m_vec = other.m_vec;
43 other.m_vec = nullptr;
44 return *this;
47 GrowableVector(const GrowableVector&) = delete;
48 GrowableVector& operator=(const GrowableVector&) = delete;
50 //////////////////////////////////////////////////////////////////////////////
52 bool empty() const {
53 return !m_vec;
56 size_t size() const {
57 return m_vec ? m_vec->m_size : 0;
60 void clear() {
61 free(m_vec);
62 m_vec = nullptr;
65 T& operator[](const size_t idx) {
66 assertx(idx < size());
67 return m_vec->m_data[idx];
70 const T& operator[](const size_t idx) const {
71 assertx(idx < size());
72 return m_vec->m_data[idx];
75 void push_back(const T& datum) {
76 if (!m_vec) {
77 m_vec = Impl::make();
79 m_vec = m_vec->push_back(datum);
82 void swap(GrowableVector<T>& other) {
83 std::swap(m_vec, other.m_vec);
86 T* begin() const {
87 return m_vec ? m_vec->m_data : (T*)this;
90 T* end() const {
91 return m_vec ? &m_vec->m_data[m_vec->m_size] : (T*)this;
94 void setEnd(T* newEnd) {
95 if (newEnd == begin()) {
96 free(m_vec);
97 m_vec = nullptr;
98 return;
100 m_vec->m_size = newEnd - m_vec->m_data;
103 private:
104 struct Impl {
105 static Impl* make() {
106 static_assert(
107 std::is_trivially_destructible<T>::value,
108 "GrowableVector can only hold trivially destructible types"
110 auto const mem = malloc(sizeof(Impl));
111 return new (mem) Impl();
114 Impl* push_back(const T& datum) {
115 // m_data always has room for at least one element due to the m_data[1]
116 // declaration, so the realloc() code first has to kick in when a second
117 // element is about to be pushed.
118 auto gv = [&] {
119 if (!folly::isPowTwo(m_size)) return this;
120 return (Impl*)realloc(
121 this,
122 offsetof(Impl, m_data) + 2 * m_size * sizeof(T)
124 }();
126 gv->m_data[gv->m_size++] = datum;
127 return gv;
130 ////////////////////////////////////////////////////////////////////////////
132 uint32_t m_size{0};
133 /* Actually variable length. */
134 T m_data[1];
137 //////////////////////////////////////////////////////////////////////////////
139 Impl* m_vec{nullptr};
142 ////////////////////////////////////////////////////////////////////////////////