Automatic forward-decl fixup
[hiphop-php.git] / hphp / runtime / base / collections.h
blob232cb93f354db89a718f7555b1799fc7560e1a0a
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2016 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_COLLECTIONS_H_
18 #define incl_HPHP_COLLECTIONS_H_
20 #include <folly/Optional.h>
22 #include "hphp/runtime/base/header-kind.h"
23 #include "hphp/runtime/base/type-string.h"
25 namespace HPHP {
26 struct ArrayData;
27 struct c_Pair;
28 struct c_Vector;
29 struct c_ImmVector;
30 struct c_Map;
31 struct c_ImmMap;
32 struct c_Set;
33 struct c_ImmSet;
36 namespace HPHP { namespace collections {
37 /////////////////////////////////////////////////////////////////////////////
39 #define COLLECTIONS_PAIRED_TYPES(MACRO) \
40 MACRO(Vector) MACRO(ImmVector) \
41 MACRO(Map) MACRO(ImmMap) \
42 MACRO(Set) MACRO(ImmSet)
44 #define COLLECTIONS_ALL_TYPES(MACRO) \
45 MACRO(Pair) \
46 COLLECTIONS_PAIRED_TYPES(MACRO)
48 #define X(type) extern const StaticString s_##type;
49 COLLECTIONS_ALL_TYPES(X)
50 #undef X
52 /////////////////////////////////////////////////////////////////////////////
53 // Constructor/Initializer
55 using newEmptyInstanceFunc = ObjectData* (*)();
56 using newFromArrayFunc = ObjectData* (*)(ArrayData* arr);
58 /* Get a function capable of creating a collection class.
59 * This is primarily used by the JIT to burn the initializer into the TC.
61 newEmptyInstanceFunc allocEmptyFunc(CollectionType ctype);
62 newFromArrayFunc allocFromArrayFunc(CollectionType ctype);
65 * Create a new empty collection, with refcount set to 1.
67 inline ObjectData* alloc(CollectionType ctype) {
68 return allocEmptyFunc(ctype)();
72 * Create a collection from an array, with refcount set to 1.
74 * Pre: The array must have a kind that's compatible with the collection type
75 * we're creating.
77 inline ObjectData* alloc(CollectionType ctype, ArrayData* arr) {
78 return allocFromArrayFunc(ctype)(arr);
81 /* Preallocate room for {sz} elements in the Collection */
82 void reserve(ObjectData* obj, int64_t sz);
84 /* Used by Collections Literals syntax for Maps */
85 void initMapElem(ObjectData* obj, TypedValue* key, TypedValue* val);
86 /* Used by Collections Literals syntax for non-Maps */
87 void initElem(ObjectData* obj, TypedValue* val);
89 /////////////////////////////////////////////////////////////////////////////
90 // Casting and Cloing
92 bool isType(const Class* cls, CollectionType type);
93 template<typename ...Args>
94 bool isType(const Class* cls, CollectionType type, Args... args) {
95 return isType(cls, type) || isType(cls, args...);
98 Array toArray(const ObjectData* obj);
99 bool toBool(const ObjectData* obj);
100 ObjectData* clone(ObjectData* obj);
102 void deepCopy(TypedValue* tv);
105 * Return the inner-array for array-backed collections, and nullptr if it's a
106 * Pair. The returned array pointer is not incref'd.
108 ArrayData* asArray(ObjectData* obj);
109 inline const ArrayData* asArray(const ObjectData* obj) {
110 return asArray(const_cast<ObjectData*>(obj));
113 /////////////////////////////////////////////////////////////////////////////
114 // Read/Write
116 /* at() and get() retrieve a collection element for reading.
117 * If the key does not exist in the collection, at() will throw an exception
118 * while get() will return nullptr
120 TypedValue* at(ObjectData* obj, const TypedValue* key);
121 TypedValue* get(ObjectData* obj, const TypedValue* key);
123 /* atLval() is used to get the address of an element when the
124 * caller is NOT going to do direct write per se, but it intends to use
125 * the element as the base of a member operation in an "lvalue" context
126 * (which could mutate the element in various ways).
128 TypedValue* atLval(ObjectData* obj, const TypedValue* key);
130 /* atRw() is used to get the address of an element for reading
131 * and writing. It is typically used for read-modify-write operations (the
132 * SetOp* and IncDec* instructions).
134 TypedValue* atRw(ObjectData* obj, const TypedValue* key);
136 /* Check for {key} within {obj} Collection
137 * `contains` merely need to exist
138 * `isset` needs to exist and not be null
139 * `empty` needs to exist and not be falsy
141 bool contains(ObjectData* obj, const Variant& offset);
142 bool isset(ObjectData* obj, const TypedValue* key);
143 bool empty(ObjectData* obj, const TypedValue* key);
145 /* Remove element {key} from Collection {obj} */
146 void unset(ObjectData* obj, const TypedValue* key);
148 /* Add element {val} to Collection {obj} at {key} or the next slot */
149 void append(ObjectData* obj, TypedValue* val);
150 void set(ObjectData* obj, const TypedValue* key, const TypedValue* val);
152 /* Compare two collections.
153 * Only collections of the same type with the same elements are equal.
154 * Whether elements must be in the same order is CollectionType dependent.
156 bool equals(const ObjectData* obj1, const ObjectData* obj2);
158 /* Take element from end(pop) or beginning(shift) of a mutable collection */
159 Variant pop(ObjectData* obj);
160 Variant shift(ObjectData* obj);
162 /////////////////////////////////////////////////////////////////////////////
163 // CollectionType <-> Human-readable name conversions
166 * Returns a collection type name given a CollectionType.
168 inline StringData* typeToString(CollectionType ctype) {
169 switch (ctype) {
170 #define X(type) case CollectionType::type: return s_##type.get();
171 COLLECTIONS_ALL_TYPES(X)
172 #undef X
174 not_reached();
178 * Returns a CollectionType given a name, folly::none if name is not a
179 * collection type.
181 inline folly::Optional<CollectionType> stringToType(const StringData* name) {
182 #define X(type) if (name->isame(s_##type.get())) return CollectionType::type;
183 COLLECTIONS_ALL_TYPES(X)
184 #undef X
185 return folly::none;
188 inline folly::Optional<CollectionType> stringToType(const std::string& s) {
189 return stringToType(
190 req::ptr<StringData>::attach(StringData::Make(s)).get()
194 inline bool isTypeName(const StringData* str) {
195 return stringToType(str).hasValue();
198 /////////////////////////////////////////////////////////////////////////////
200 #endif