-/* avhv_delete leaks. Caller can re-index and compress if so desired. */
-SV *
-avhv_delete(AV *av, char *key, U32 klen, I32 flags)
-{
- HV *keys = avhv_keys(av);
- SV *sv;
- SV **svp;
- I32 ind;
-
- sv = hv_delete(keys, key, klen, 0);
- if (!sv)
- return Nullsv;
- ind = SvIV(sv);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- svp = av_fetch(av, ind, FALSE);
- if (!svp)
- return Nullsv;
- if (flags & G_DISCARD) {
- sv = Nullsv;
- SvREFCNT_dec(*svp);
- } else {
- sv = sv_2mortal(*svp);
+
+ if (SvRMAGICAL(av)) {
+ const MAGIC * const tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
+ if (tied_magic || mg_find((SV*)av, PERL_MAGIC_regdata)) {
+ SV *sv = sv_newmortal();
+ MAGIC *mg;
+ /* Handle negative array indices 20020222 MJD */
+ if (key < 0) {
+ unsigned adjust_index = 1;
+ if (tied_magic) {
+ SV * const * const negative_indices_glob =
+ hv_fetch(SvSTASH(SvRV(SvTIED_obj((SV *)av,
+ tied_magic))),
+ NEGATIVE_INDICES_VAR, 16, 0);
+ if (negative_indices_glob
+ && SvTRUE(GvSV(*negative_indices_glob)))
+ adjust_index = 0;
+ }
+ if (adjust_index) {
+ key += AvFILL(av) + 1;
+ if (key < 0)
+ return FALSE;
+ }
+ }
+
+ mg_copy((SV*)av, sv, 0, key);
+ mg = mg_find(sv, PERL_MAGIC_tiedelem);
+ if (mg) {
+ magic_existspack(sv, mg);
+ return (bool)SvTRUE(sv);
+ }
+
+ }