arraysperlxs

How to use perlapi/ XS in an XSUB for array element insertion and removal


I would like to insert and remove elements into an existing Perl array passed into a XSUB.

perlapi has av_push, av_pop, av_fetch, av_store and friends for array manipulation. I was hoping for av_insert or av_splice or similar functions, but these don't seem to exist.

There is av_delete, but the documentation describes this as replacing the element with undef, not actually removing the item from the array.

Of course I could manually resize the array (av_extend) and loop moving elements (av_fetch/av_store).

Is there an existing API function I can use? If so a pointer to its documentation would be great.


Solution

  • void av_insert( pTHX_ AV * av, Size_t key, SV * sv ) {
    #define av_insert( a, b, c ) av_insert( aTHX_ a, b, c )
       sv = newSVsv( sv );
    
       Size_t count = av_count( av );
       if ( key < count ) {
          av_extend( av, count );
          SV ** a = AvARRAY( av );
          memmove( a+key, a+key+1, sizeof( SV * ) * ( count - key ) );
          a[ key ] = sv;
       } else {
          *av_fetch( av, key, 1 ) = sv;
       }
    }