diff --git a/include/value.h b/include/value.h index f72304cf..626d20dc 100644 --- a/include/value.h +++ b/include/value.h @@ -380,6 +380,9 @@ class Value : private HashParent bool isObject() const { return type() == Type::Object; } bool isArray() const { return type() == Type::Array; } bool isCallable() const; + bool isList() const; + bool isMap() const { return type() == Type::Array && !isList(); } + bool isRef() const; /** * Get access to the raw buffer - you can use this for direct reading and diff --git a/zend/value.cpp b/zend/value.cpp index 9a1a5dbb..175a0061 100644 --- a/zend/value.cpp +++ b/zend/value.cpp @@ -1408,6 +1408,38 @@ bool Value::isCallable() const return zend_is_callable(_val, 0, NULL TSRMLS_CC); } +/** + * Check if the variable holds something that is list + * @return bool + */ +bool Value::isList() const +{ + // must be an array + if (!isArray()) return false; + + // get the number of elements + ulong count = zend_hash_num_elements(Z_ARRVAL_P(_val)); + + // zero length array + if (count == 0) return true; + + // count == 1 and a[0] exists + if (count == 1 && contains(0)) return true; + + // a[0] exists, a[count - 1] exists and the next index is count + return contains(0) && contains(count - 1) && + zend_hash_next_free_element(Z_ARRVAL_P(_val)) == count; +} + +/** + * Check if the variable holds something that is ref + * @return bool + */ +bool Value::isRef() const +{ + return Z_ISREF_P(_val); +} + /** * Make a clone of the type * @return Value