@@ -983,6 +983,191 @@ PHP_METHOD(Vector, indexOf)
983
983
RETURN_FALSE ;
984
984
}
985
985
986
+ PHP_METHOD (Vector , filter )
987
+ {
988
+ zend_fcall_info fci = empty_fcall_info ;
989
+ zend_fcall_info_cache fci_cache = empty_fcall_info_cache ;
990
+ ZEND_PARSE_PARAMETERS_START (0 , 1 )
991
+ Z_PARAM_OPTIONAL
992
+ Z_PARAM_FUNC_OR_NULL (fci , fci_cache )
993
+ ZEND_PARSE_PARAMETERS_END ();
994
+
995
+ const spl_vector * intern = Z_VECTOR_P (ZEND_THIS );
996
+ size_t size = 0 ;
997
+ size_t capacity = 0 ;
998
+ zval * entries = NULL ;
999
+ zval operand ;
1000
+ if (intern -> array .size == 0 ) {
1001
+ /* do nothing */
1002
+ } else if (ZEND_FCI_INITIALIZED (fci )) {
1003
+ zval retval ;
1004
+
1005
+ fci .params = & operand ;
1006
+ fci .param_count = 1 ;
1007
+ fci .retval = & retval ;
1008
+
1009
+ for (size_t i = 0 ; i < intern -> array .size ; i ++ ) {
1010
+ ZVAL_COPY (& operand , & intern -> array .entries [i ]);
1011
+ const int result = zend_call_function (& fci , & fci_cache );
1012
+ if (UNEXPECTED (result != SUCCESS || EG (exception ))) {
1013
+ zval_ptr_dtor (& operand );
1014
+ cleanup :
1015
+ if (entries ) {
1016
+ for (; size > 0 ; size -- ) {
1017
+ zval_ptr_dtor (& entries [size ]);
1018
+ }
1019
+ efree (entries );
1020
+ }
1021
+ return ;
1022
+ }
1023
+ const bool is_true = zend_is_true (& retval );
1024
+ zval_ptr_dtor (& retval );
1025
+ if (UNEXPECTED (EG (exception ))) {
1026
+ goto cleanup ;
1027
+ }
1028
+ if (!is_true ) {
1029
+ zval_ptr_dtor (& operand );
1030
+ if (UNEXPECTED (EG (exception ))) {
1031
+ goto cleanup ;
1032
+ }
1033
+ continue ;
1034
+ }
1035
+
1036
+ if (size >= capacity ) {
1037
+ if (entries ) {
1038
+ capacity = size + intern -> array .size - i ;
1039
+ entries = safe_erealloc (entries , capacity , sizeof (zval ), 0 );
1040
+ } else {
1041
+ ZEND_ASSERT (size == 0 );
1042
+ ZEND_ASSERT (capacity == 0 );
1043
+ capacity = intern -> array .size > i ? intern -> array .size - i : 1 ;
1044
+ entries = safe_emalloc (capacity , sizeof (zval ), 0 );
1045
+ }
1046
+ }
1047
+ ZEND_ASSERT (size < capacity );
1048
+ ZVAL_COPY_VALUE (& entries [size ], & operand );
1049
+ size ++ ;
1050
+ }
1051
+ } else {
1052
+ for (size_t i = 0 ; i < intern -> array .size ; i ++ ) {
1053
+ ZVAL_COPY (& operand , & intern -> array .entries [i ]);
1054
+ const bool is_true = zend_is_true (& operand );
1055
+ if (!is_true ) {
1056
+ zval_ptr_dtor (& operand );
1057
+ if (UNEXPECTED (EG (exception ))) {
1058
+ goto cleanup ;
1059
+ }
1060
+ continue ;
1061
+ }
1062
+
1063
+ if (size >= capacity ) {
1064
+ if (entries ) {
1065
+ capacity = size + intern -> array .size - i ;
1066
+ entries = safe_erealloc (entries , capacity , sizeof (zval ), 0 );
1067
+ } else {
1068
+ ZEND_ASSERT (size == 0 );
1069
+ ZEND_ASSERT (capacity == 0 );
1070
+ capacity = intern -> array .size > i ? intern -> array .size - i : 1 ;
1071
+ entries = safe_emalloc (capacity , sizeof (zval ), 0 );
1072
+ }
1073
+ }
1074
+ ZEND_ASSERT (size < capacity );
1075
+ ZVAL_COPY_VALUE (& entries [size ], & operand );
1076
+ size ++ ;
1077
+ }
1078
+ }
1079
+
1080
+ zend_object * new_object = spl_vector_new_ex (spl_ce_Vector , NULL , 0 );
1081
+ spl_vector * new_intern = spl_vector_from_object (new_object );
1082
+ if (size == 0 ) {
1083
+ ZEND_ASSERT (!entries );
1084
+ spl_vector_entries_set_empty_list (& new_intern -> array );
1085
+ RETURN_OBJ (new_object );
1086
+ }
1087
+ if (capacity > size ) {
1088
+ /* Shrink allocated value to actual required size */
1089
+ entries = erealloc (entries , size * sizeof (zval ));
1090
+ }
1091
+
1092
+ new_intern -> array .entries = entries ;
1093
+ new_intern -> array .size = size ;
1094
+ new_intern -> array .capacity = size ;
1095
+ RETURN_OBJ (new_object );
1096
+ }
1097
+
1098
+ PHP_METHOD (Vector , map )
1099
+ {
1100
+ zend_fcall_info fci ;
1101
+ zend_fcall_info_cache fci_cache ;
1102
+ ZEND_PARSE_PARAMETERS_START (1 , 1 )
1103
+ Z_PARAM_FUNC (fci , fci_cache )
1104
+ ZEND_PARSE_PARAMETERS_END ();
1105
+
1106
+ const spl_vector * intern = Z_VECTOR_P (ZEND_THIS );
1107
+ size_t new_capacity = intern -> array .size ;
1108
+
1109
+ if (new_capacity == 0 ) {
1110
+ zend_object * new_object = spl_vector_new_ex (spl_ce_Vector , NULL , 0 );
1111
+ spl_vector * new_intern = spl_vector_from_object (new_object );
1112
+ spl_vector_entries_set_empty_list (& new_intern -> array );
1113
+ RETURN_OBJ (new_object );
1114
+ }
1115
+
1116
+ zval * entries = emalloc (new_capacity * sizeof (zval ));
1117
+ size_t size = 0 ;
1118
+
1119
+ zval operand ;
1120
+ fci .params = & operand ;
1121
+ fci .param_count = 1 ;
1122
+
1123
+ do {
1124
+ if (UNEXPECTED (size >= new_capacity )) {
1125
+ if (entries ) {
1126
+ new_capacity = size + 1 ;
1127
+ entries = safe_erealloc (entries , new_capacity , sizeof (zval ), 0 );
1128
+ } else {
1129
+ ZEND_ASSERT (size == 0 );
1130
+ ZEND_ASSERT (new_capacity == 0 );
1131
+ new_capacity = intern -> array .size ;
1132
+ entries = safe_emalloc (new_capacity , sizeof (zval ), 0 );
1133
+ }
1134
+ }
1135
+ fci .retval = & entries [size ];
1136
+ ZVAL_COPY (& operand , & intern -> array .entries [size ]);
1137
+ const int result = zend_call_function (& fci , & fci_cache );
1138
+ fci .retval = & entries [size ];
1139
+ zval_ptr_dtor (& operand );
1140
+ if (UNEXPECTED (result != SUCCESS || EG (exception ))) {
1141
+ cleanup :
1142
+ if (entries ) {
1143
+ for (; size > 0 ; size -- ) {
1144
+ zval_ptr_dtor (& entries [size ]);
1145
+ }
1146
+ efree (entries );
1147
+ }
1148
+ return ;
1149
+ }
1150
+ size ++ ;
1151
+ } while (size < intern -> array .size );
1152
+
1153
+ zend_object * new_object = spl_vector_new_ex (spl_ce_Vector , NULL , 0 );
1154
+ spl_vector * new_intern = spl_vector_from_object (new_object );
1155
+ if (size == 0 ) {
1156
+ ZEND_ASSERT (!entries );
1157
+ spl_vector_entries_set_empty_list (& new_intern -> array );
1158
+ RETURN_OBJ (new_object );
1159
+ }
1160
+ if (UNEXPECTED (new_capacity > size )) {
1161
+ /* Shrink allocated value to actual required size */
1162
+ entries = erealloc (entries , size * sizeof (zval ));
1163
+ }
1164
+
1165
+ new_intern -> array .entries = entries ;
1166
+ new_intern -> array .size = size ;
1167
+ new_intern -> array .capacity = size ;
1168
+ RETURN_OBJ (new_object );
1169
+ }
1170
+
986
1171
PHP_METHOD (Vector , contains )
987
1172
{
988
1173
zval * value ;
@@ -1213,7 +1398,6 @@ PHP_MINIT_FUNCTION(spl_vector)
1213
1398
spl_handler_Vector .count_elements = spl_vector_count_elements ;
1214
1399
spl_handler_Vector .get_properties = spl_vector_get_properties ;
1215
1400
spl_handler_Vector .get_gc = spl_vector_get_gc ;
1216
- spl_handler_Vector .dtor_obj = zend_objects_destroy_object ;
1217
1401
spl_handler_Vector .free_obj = spl_vector_free_storage ;
1218
1402
1219
1403
spl_handler_Vector .read_dimension = spl_vector_read_dimension ;
0 commit comments