diff options
author | Dusk <dusk@woofle.net> | 2019-11-03 18:51:49 -0800 |
---|---|---|
committer | Tyson Andre <tysonandre775@hotmail.com> | 2021-01-20 18:53:48 -0500 |
commit | 13c430b1db0ca1595122ce552ce76f84b32795f4 (patch) | |
tree | fbcbc5f25971911f3d73eb3c9f85e20d697fed59 /Zend/zend_hash.h | |
parent | 04db2c873588633daf6639a7de4a3ffd5936c47c (diff) | |
download | php-git-13c430b1db0ca1595122ce552ce76f84b32795f4.tar.gz |
Add array_is_list(array $array) function
This function tests if an array contains only sequential integer keys. While
list isn't an official type, this usage is consistent with the community usage
of "list" as an annotation type, cf.
https://psalm.dev/docs/annotating_code/type_syntax/array_types/#lists
Rebased and modified version of #4886
- Use .stub.php files
- Add opcache constant evaluation when argument is a constant
- Change from is_list(mixed $value) to array_is_list(array $array)
RFC: https://wiki.php.net/rfc/is_list
Co-Authored-By: Tyson Andre <tysonandre775@hotmail.com>
Co-Authored-By: Dusk <dusk@woofle.net>
Closes GH-6070
Diffstat (limited to 'Zend/zend_hash.h')
-rw-r--r-- | Zend/zend_hash.h | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index e339345a32..64a9220573 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -1188,6 +1188,33 @@ static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, ZEND_HASH_FILL_FINISH(); \ } while (0) +/* Check if an array is a list */ +static zend_always_inline zend_bool zend_array_is_list(zend_array *array) +{ + zend_long expected_idx = 0; + zend_long num_idx; + zend_string* str_idx; + /* Empty arrays are lists */ + if (zend_hash_num_elements(array) == 0) { + return 1; + } + + /* Packed arrays are lists */ + if (HT_IS_PACKED(array) && HT_IS_WITHOUT_HOLES(array)) { + return 1; + } + + /* Check if the list could theoretically be repacked */ + ZEND_HASH_FOREACH_KEY(array, num_idx, str_idx) { + if (str_idx != NULL || num_idx != expected_idx++) { + return 0; + } + } ZEND_HASH_FOREACH_END(); + + return 1; +} + + static zend_always_inline zval *_zend_hash_append_ex(HashTable *ht, zend_string *key, zval *zv, bool interned) { uint32_t idx = ht->nNumUsed++; |