2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010- 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_OBJECT_H_
18 #define incl_HPHP_OBJECT_H_
20 #ifndef incl_HPHP_INSIDE_HPHP_COMPLEX_TYPES_H_
21 #error Directly including 'type_object.h' is prohibited. \
22 Include 'complex_types.h' instead.
25 #include "hphp/runtime/base/util/smart_ptr.h"
26 #include "hphp/runtime/base/object_data.h"
27 #include "hphp/runtime/base/type_string.h"
28 #include "hphp/runtime/base/hphp_value.h"
31 ///////////////////////////////////////////////////////////////////////////////
33 #define null_object Object::s_nullObject
36 class MutableArrayIter
;
39 * Object type wrapping around ObjectData to implement reference count.
41 class Object
: protected SmartPtr
<ObjectData
> {
42 typedef SmartPtr
<ObjectData
> ObjectBase
;
47 static const Object s_nullObject
;
49 ObjectData
* get() const { return m_px
; }
50 void reset() { ObjectBase::reset(); }
52 ObjectData
* operator->() const {
53 if (!m_px
) throw_null_pointer_exception();
60 /* implicit */ Object(ObjectData
*data
) : ObjectBase(data
) { }
61 /* implicit */ Object(CObjRef src
) : ObjectBase(src
.m_px
) { }
64 Object(Object
&& src
) : ObjectBase(std::move(src
)) {
65 static_assert(sizeof(Object
) == sizeof(ObjectBase
), "Fix this.");
68 Object
& operator=(const Object
& src
) {
69 static_assert(sizeof(Object
) == sizeof(ObjectBase
), "Fix this.");
70 ObjectBase::operator=(src
);
74 Object
& operator=(Object
&& src
) {
75 static_assert(sizeof(Object
) == sizeof(ObjectBase
), "Fix this.");
76 ObjectBase::operator=(std::move(src
));
86 return m_px
== nullptr;
88 bool isResource() const {
89 return m_px
&& m_px
->isResource();
91 bool instanceof(CStrRef s
) const {
92 return m_px
&& m_px
->o_instanceof(s
);
94 bool instanceof(const Class
* cls
) const {
95 return m_px
&& m_px
->instanceof(cls
);
98 template <class T
> T
& cast() { return *static_cast<T
*>(this); }
99 template <class T
> const T
& cast() const {
100 return *static_cast<const T
*>(this);
102 ArrayIter
begin(CStrRef context
= null_string
) const;
104 MutableArrayIter
begin(Variant
*key
, Variant
&val
,
105 CStrRef context
= null_string
) const;
108 * getTyped() and is() are intended for use with classes only. Using
109 * these functions with an interface will cause a compile time error.
110 * It is also worth noting that these functions have not been tested
111 * with redeclared classes or classes that have a redeclared ancestor
112 * in the inheritance hierarchy.
115 T
*getTyped(bool nullOkay
= false, bool badTypeOkay
= false) const {
116 CT_ASSERT_DESCENDENT_OF_OBJECTDATA(T
);
118 ObjectData
*cur
= m_px
;
121 throw_null_pointer_exception();
125 T
*px
= dynamic_cast<T
*>(cur
);
128 throw InvalidObjectTypeException(m_px
->o_getClassName().c_str());
133 // Assert that casting does not adjust the 'this' pointer
134 assert((void*)px
== (void*)cur
);
139 return getTyped
<T
>(true, true) != nullptr;
143 return getTyped
<T
>();
146 ObjectData
*objectForCall() const {
147 if (m_px
) return m_px
;
148 throw_call_non_object();
154 bool toBoolean() const { return m_px
? m_px
->o_toBoolean() : false;}
155 char toByte () const { return m_px
? m_px
->o_toInt64() : 0;}
156 short toInt16 () const { return m_px
? m_px
->o_toInt64() : 0;}
157 int toInt32 () const { return m_px
? m_px
->o_toInt64() : 0;}
158 int64_t toInt64 () const { return m_px
? m_px
->o_toInt64() : 0;}
159 double toDouble () const { return m_px
? m_px
->o_toDouble() : 0;}
160 String
toString () const { return m_px
? m_px
->t___tostring() : String();}
161 Array
toArray () const;
162 Variant
toKey () const;
164 int64_t toInt64ForCompare() const;
165 double toDoubleForCompare() const;
170 bool same (CObjRef v2
) const { return m_px
== v2
.get();}
171 bool equal(CObjRef v2
) const;
172 bool less (CObjRef v2
) const;
173 bool more (CObjRef v2
) const;
176 * Unresolved objects will go through these two functions than the ones
179 Variant
o_get(CStrRef propName
, bool error
= true,
180 CStrRef context
= null_string
) const;
181 Variant
o_set(CStrRef s
, CVarRef v
, CStrRef context
= null_string
);
182 Variant
o_set(CStrRef s
, RefResult v
, CStrRef context
= null_string
);
183 Variant
o_setRef(CStrRef s
, CVarRef v
, CStrRef context
= null_string
);
188 void serialize(VariableSerializer
*serializer
) const;
189 bool unserialize(std::istream
&in
);
191 void setToDefaultObject();
193 // Transfer ownership of our reference to this object.
194 ObjectData
*detach() {
195 ObjectData
*ret
= m_px
;
201 ///////////////////////////////////////////////////////////////////////////////
206 explicit ObjNR(ObjectData
*data
) {
211 return *reinterpret_cast<Object
*>(this); // XXX
214 const Object
& asObject() const {
215 return const_cast<ObjNR
*>(this)->asObject();
220 static void compileTimeAssertions() {
221 BOOST_STATIC_ASSERT((offsetof(ObjNR
, m_px
) == kExpectedMPxOffset
));
225 ///////////////////////////////////////////////////////////////////////////////
228 #endif // incl_HPHP_OBJECT_H_