2 +----------------------------------------------------------------------+
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 #ifndef incl_HPHP_GROWABLE_VECTOR_H_
18 #define incl_HPHP_GROWABLE_VECTOR_H_
23 #include "hphp/util/assertions.h"
25 namespace HPHP
{ namespace jit
{
26 ////////////////////////////////////////////////////////////////////////////////
29 * A vector of elements that will increase its capacity when it fills up. It
30 * differs from std::vector in that it only takes up 8 bytes of space, its
31 * elements must be trivially destructible, and it cannot erase individual
35 struct GrowableVector
{
36 explicit GrowableVector() {}
38 GrowableVector(GrowableVector
&& other
) noexcept
: m_vec(other
.m_vec
) {
39 other
.m_vec
= nullptr;
42 GrowableVector
& operator=(GrowableVector
&& other
) {
44 other
.m_vec
= nullptr;
48 GrowableVector(const GrowableVector
&) = delete;
49 GrowableVector
& operator=(const GrowableVector
&) = delete;
51 //////////////////////////////////////////////////////////////////////////////
58 return m_vec
? m_vec
->m_size
: 0;
66 T
& operator[](const size_t idx
) {
67 assertx(idx
< size());
68 return m_vec
->m_data
[idx
];
71 const T
& operator[](const size_t idx
) const {
72 assertx(idx
< size());
73 return m_vec
->m_data
[idx
];
76 void push_back(const T
& datum
) {
80 m_vec
= m_vec
->push_back(datum
);
83 void swap(GrowableVector
<T
>& other
) {
84 std::swap(m_vec
, other
.m_vec
);
88 return m_vec
? m_vec
->m_data
: (T
*)this;
92 return m_vec
? &m_vec
->m_data
[m_vec
->m_size
] : (T
*)this;
95 void setEnd(T
* newEnd
) {
96 if (newEnd
== begin()) {
101 m_vec
->m_size
= newEnd
- m_vec
->m_data
;
106 static Impl
* make() {
108 std::is_trivially_destructible
<T
>::value
,
109 "GrowableVector can only hold trivially destructible types"
111 auto const mem
= malloc(sizeof(Impl
));
112 return new (mem
) Impl();
115 Impl
* push_back(const T
& datum
) {
116 // m_data always has room for at least one element due to the m_data[1]
117 // declaration, so the realloc() code first has to kick in when a second
118 // element is about to be pushed.
120 if (!folly::isPowTwo(m_size
)) return this;
121 return (Impl
*)realloc(
123 offsetof(Impl
, m_data
) + 2 * m_size
* sizeof(T
)
127 gv
->m_data
[gv
->m_size
++] = datum
;
131 ////////////////////////////////////////////////////////////////////////////
134 /* Actually variable length. */
138 //////////////////////////////////////////////////////////////////////////////
140 Impl
* m_vec
{nullptr};
143 ////////////////////////////////////////////////////////////////////////////////