Arquivos
hhvm/hphp/util/growable_vector.h
T
Tim Starling 998951619f update copyright date
We did not intend to imply our copyrights last forever

Closes #759
2013-06-03 12:43:56 -07:00

83 linhas
2.6 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef _GROWABLE_VECTOR_H_
#define _GROWABLE_VECTOR_H_
namespace HPHP {
/*
* GrowableVector --
*
* We make a large number of these, and they typically only have a small
* number of entries.
* It's a shame to use a 24-byte std::vector for this.
*/
template<typename T>
struct GrowableVector {
uint32_t m_size;
T *m_data; // Actually variable length
GrowableVector() : m_size(0) { m_data = (T*)malloc(sizeof(T)); }
typedef GrowableVector<T> Self;
Self& operator=(const Self& rhs) {
m_size = rhs.m_size;
m_data = (T*)malloc(sizeof(T) * Util::roundUpToPowerOfTwo(m_size + 1));
memcpy(m_data, rhs.m_data, m_size * sizeof(T));
return *this;
}
// Copy ctor
GrowableVector(const GrowableVector& rhs) {
*this = rhs;
}
~GrowableVector() {
free(m_data);
}
T& operator[](const size_t idx) {
ASSERT(idx < m_size);
return m_data[idx];
}
const T& operator[](const size_t idx) const {
ASSERT(idx < m_size);
return m_data[idx];
}
void push_back(const T& datum) {
// m_data always has room for at least one element due to the m_data[1]
// declaration, so the realloc() code first has to kick in when a second
// element is about to be pushed.
if (Util::isPowerOfTwo(m_size)) {
m_data = (T*)realloc(m_data, 2 * m_size * sizeof(T));
}
m_data[m_size++] = datum;
}
typedef T* iterator;
typedef T* const_iterator;
iterator begin() { return &m_data[0]; }
iterator end() { return &m_data[m_size]; }
const_iterator begin() const { return &m_data[0]; }
const_iterator end() const { return &m_data[m_size]; }
size_t size() const { return m_size; }
bool empty() const { return size() == 0; }
};
}
#endif