/*
 * This file was generated automatically by ExtUtils::ParseXS version 3.40 from the
 * contents of ListUtil.xs. Do not edit this file, edit ListUtil.xs instead.
 *
 *    ANY CHANGES MADE HERE WILL BE LOST!
 *
 */

#line 1 "ListUtil.xs"
/* Copyright (c) 1997-2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
 * This program is free software; you can redistribute it and/or
 * modify it under the same terms as Perl itself.
 */
#define PERL_NO_GET_CONTEXT /* we want efficiency */
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>

#ifdef USE_PPPORT_H
#  define NEED_sv_2pv_flags 1
#  define NEED_newSVpvn_flags 1
#  define NEED_sv_catpvn_flags
#  include "ppport.h"
#endif

#ifndef PERL_VERSION_DECIMAL
#  define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
#endif
#ifndef PERL_DECIMAL_VERSION
#  define PERL_DECIMAL_VERSION \
	  PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
#endif
#ifndef PERL_VERSION_GE
#  define PERL_VERSION_GE(r,v,s) \
	  (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
#endif
#ifndef PERL_VERSION_LE
#  define PERL_VERSION_LE(r,v,s) \
	  (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s))
#endif

#if PERL_VERSION_GE(5,6,0)
#  include "multicall.h"
#endif

#if !PERL_VERSION_GE(5,23,8)
#  define UNUSED_VAR_newsp PERL_UNUSED_VAR(newsp)
#else
#  define UNUSED_VAR_newsp NOOP
#endif

#ifndef CvISXSUB
#  define CvISXSUB(cv) CvXSUB(cv)
#endif

#ifndef HvNAMELEN_get
#define HvNAMELEN_get(stash) strlen(HvNAME(stash))
#endif

#ifndef HvNAMEUTF8
#define HvNAMEUTF8(stash) 0
#endif

#ifndef GvNAMEUTF8
#ifdef GvNAME_HEK
#define GvNAMEUTF8(gv) HEK_UTF8(GvNAME_HEK(gv))
#else
#define GvNAMEUTF8(gv) 0
#endif
#endif

#ifndef SV_CATUTF8
#define SV_CATUTF8 0
#endif

#ifndef SV_CATBYTES
#define SV_CATBYTES 0
#endif

#ifndef sv_catpvn_flags
#define sv_catpvn_flags(b,n,l,f) sv_catpvn(b,n,l)
#endif

/* Some platforms have strict exports. And before 5.7.3 cxinc (or Perl_cxinc)
   was not exported. Therefore platforms like win32, VMS etc have problems
   so we redefine it here -- GMB
*/
#if !PERL_VERSION_GE(5,7,0)
/* Not in 5.6.1. */
#  ifdef cxinc
#    undef cxinc
#  endif
#  define cxinc() my_cxinc(aTHX)
static I32
my_cxinc(pTHX)
{
    cxstack_max = cxstack_max * 3 / 2;
    Renew(cxstack, cxstack_max + 1, struct context); /* fencepost bug in older CXINC macros requires +1 here */
    return cxstack_ix + 1;
}
#endif

#ifndef sv_copypv
#define sv_copypv(a, b) my_sv_copypv(aTHX_ a, b)
static void
my_sv_copypv(pTHX_ SV *const dsv, SV *const ssv)
{
    STRLEN len;
    const char * const s = SvPV_const(ssv,len);
    sv_setpvn(dsv,s,len);
    if(SvUTF8(ssv))
        SvUTF8_on(dsv);
    else
        SvUTF8_off(dsv);
}
#endif

#ifdef SVf_IVisUV
#  define slu_sv_value(sv) (SvIOK(sv)) ? (SvIOK_UV(sv)) ? (NV)(SvUVX(sv)) : (NV)(SvIVX(sv)) : (SvNV(sv))
#else
#  define slu_sv_value(sv) (SvIOK(sv)) ? (NV)(SvIVX(sv)) : (SvNV(sv))
#endif

#if PERL_VERSION < 13 || (PERL_VERSION == 13 && PERL_SUBVERSION < 9)
#  define PERL_HAS_BAD_MULTICALL_REFCOUNT
#endif

#if PERL_VERSION < 14
#  define croak_no_modify() croak("%s", PL_no_modify)
#endif

#ifndef SvNV_nomg
#  define SvNV_nomg SvNV
#endif

enum slu_accum {
    ACC_IV,
    ACC_NV,
    ACC_SV,
};

static enum slu_accum accum_type(SV *sv) {
    if(SvAMAGIC(sv))
        return ACC_SV;

    if(SvIOK(sv) && !SvNOK(sv) && !SvUOK(sv))
        return ACC_IV;

    return ACC_NV;
}

/* Magic for set_subname */
static MGVTBL subname_vtbl;

#line 156 "ListUtil.c"
#ifndef PERL_UNUSED_VAR
#  define PERL_UNUSED_VAR(var) if (0) var = var
#endif

#ifndef dVAR
#  define dVAR		dNOOP
#endif


/* This stuff is not part of the API! You have been warned. */
#ifndef PERL_VERSION_DECIMAL
#  define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
#endif
#ifndef PERL_DECIMAL_VERSION
#  define PERL_DECIMAL_VERSION \
	  PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
#endif
#ifndef PERL_VERSION_GE
#  define PERL_VERSION_GE(r,v,s) \
	  (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
#endif
#ifndef PERL_VERSION_LE
#  define PERL_VERSION_LE(r,v,s) \
	  (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s))
#endif

/* XS_INTERNAL is the explicit static-linkage variant of the default
 * XS macro.
 *
 * XS_EXTERNAL is the same as XS_INTERNAL except it does not include
 * "STATIC", ie. it exports XSUB symbols. You probably don't want that
 * for anything but the BOOT XSUB.
 *
 * See XSUB.h in core!
 */


/* TODO: This might be compatible further back than 5.10.0. */
#if PERL_VERSION_GE(5, 10, 0) && PERL_VERSION_LE(5, 15, 1)
#  undef XS_EXTERNAL
#  undef XS_INTERNAL
#  if defined(__CYGWIN__) && defined(USE_DYNAMIC_LOADING)
#    define XS_EXTERNAL(name) __declspec(dllexport) XSPROTO(name)
#    define XS_INTERNAL(name) STATIC XSPROTO(name)
#  endif
#  if defined(__SYMBIAN32__)
#    define XS_EXTERNAL(name) EXPORT_C XSPROTO(name)
#    define XS_INTERNAL(name) EXPORT_C STATIC XSPROTO(name)
#  endif
#  ifndef XS_EXTERNAL
#    if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
#      define XS_EXTERNAL(name) void name(pTHX_ CV* cv __attribute__unused__)
#      define XS_INTERNAL(name) STATIC void name(pTHX_ CV* cv __attribute__unused__)
#    else
#      ifdef __cplusplus
#        define XS_EXTERNAL(name) extern "C" XSPROTO(name)
#        define XS_INTERNAL(name) static XSPROTO(name)
#      else
#        define XS_EXTERNAL(name) XSPROTO(name)
#        define XS_INTERNAL(name) STATIC XSPROTO(name)
#      endif
#    endif
#  endif
#endif

/* perl >= 5.10.0 && perl <= 5.15.1 */


/* The XS_EXTERNAL macro is used for functions that must not be static
 * like the boot XSUB of a module. If perl didn't have an XS_EXTERNAL
 * macro defined, the best we can do is assume XS is the same.
 * Dito for XS_INTERNAL.
 */
#ifndef XS_EXTERNAL
#  define XS_EXTERNAL(name) XS(name)
#endif
#ifndef XS_INTERNAL
#  define XS_INTERNAL(name) XS(name)
#endif

/* Now, finally, after all this mess, we want an ExtUtils::ParseXS
 * internal macro that we're free to redefine for varying linkage due
 * to the EXPORT_XSUB_SYMBOLS XS keyword. This is internal, use
 * XS_EXTERNAL(name) or XS_INTERNAL(name) in your code if you need to!
 */

#undef XS_EUPXS
#if defined(PERL_EUPXS_ALWAYS_EXPORT)
#  define XS_EUPXS(name) XS_EXTERNAL(name)
#else
   /* default to internal */
#  define XS_EUPXS(name) XS_INTERNAL(name)
#endif

#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
#define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)

/* prototype to pass -Wmissing-prototypes */
STATIC void
S_croak_xs_usage(const CV *const cv, const char *const params);

STATIC void
S_croak_xs_usage(const CV *const cv, const char *const params)
{
    const GV *const gv = CvGV(cv);

    PERL_ARGS_ASSERT_CROAK_XS_USAGE;

    if (gv) {
        const char *const gvname = GvNAME(gv);
        const HV *const stash = GvSTASH(gv);
        const char *const hvname = stash ? HvNAME(stash) : NULL;

        if (hvname)
	    Perl_croak_nocontext("Usage: %s::%s(%s)", hvname, gvname, params);
        else
	    Perl_croak_nocontext("Usage: %s(%s)", gvname, params);
    } else {
        /* Pants. I don't think that it should be possible to get here. */
	Perl_croak_nocontext("Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
    }
}
#undef  PERL_ARGS_ASSERT_CROAK_XS_USAGE

#define croak_xs_usage        S_croak_xs_usage

#endif

/* NOTE: the prototype of newXSproto() is different in versions of perls,
 * so we define a portable version of newXSproto()
 */
#ifdef newXS_flags
#define newXSproto_portable(name, c_impl, file, proto) newXS_flags(name, c_impl, file, proto, 0)
#else
#define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv)
#endif /* !defined(newXS_flags) */

#if PERL_VERSION_LE(5, 21, 5)
#  define newXS_deffile(a,b) Perl_newXS(aTHX_ a,b,file)
#else
#  define newXS_deffile(a,b) Perl_newXS_deffile(aTHX_ a,b)
#endif

#line 300 "ListUtil.c"

XS_EUPXS(XS_List__Util_min); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_min)
{
    dVAR; dXSARGS;
    dXSI32;
    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    {
#line 155 "ListUtil.xs"
{
    int index;
    NV retval = 0.0; /* avoid 'uninit var' warning */
    SV *retsv;
    int magic;

    if(!items)
        XSRETURN_UNDEF;

    retsv = ST(0);
    SvGETMAGIC(retsv);
    magic = SvAMAGIC(retsv);
    if(!magic)
      retval = slu_sv_value(retsv);

    for(index = 1 ; index < items ; index++) {
        SV *stacksv = ST(index);
        SV *tmpsv;
        SvGETMAGIC(stacksv);
        if((magic || SvAMAGIC(stacksv)) && (tmpsv = amagic_call(retsv, stacksv, gt_amg, 0))) {
             if(SvTRUE(tmpsv) ? !ix : ix) {
                  retsv = stacksv;
                  magic = SvAMAGIC(retsv);
                  if(!magic) {
                      retval = slu_sv_value(retsv);
                  }
             }
        }
        else {
            NV val = slu_sv_value(stacksv);
            if(magic) {
                retval = slu_sv_value(retsv);
                magic = 0;
            }
            if(val < retval ? !ix : ix) {
                retsv = stacksv;
                retval = val;
            }
        }
    }
    ST(0) = retsv;
    XSRETURN(1);
}
#line 354 "ListUtil.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__Util_sum); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_sum)
{
    dVAR; dXSARGS;
    dXSI32;
    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    {
#line 208 "ListUtil.xs"
{
    dXSTARG;
    SV *sv;
    IV retiv = 0;
    NV retnv = 0.0;
    SV *retsv = NULL;
    int index;
    enum slu_accum accum;
    int is_product = (ix == 2);
    SV *tmpsv;

    if(!items)
        switch(ix) {
            case 0: XSRETURN_UNDEF;
            case 1: ST(0) = sv_2mortal(newSViv(0)); XSRETURN(1);
            case 2: ST(0) = sv_2mortal(newSViv(1)); XSRETURN(1);
        }

    sv    = ST(0);
    SvGETMAGIC(sv);
    switch((accum = accum_type(sv))) {
    case ACC_SV:
        retsv = TARG;
        sv_setsv(retsv, sv);
        break;
    case ACC_IV:
        retiv = SvIV(sv);
        break;
    case ACC_NV:
        retnv = slu_sv_value(sv);
        break;
    }

    for(index = 1 ; index < items ; index++) {
        sv = ST(index);
        SvGETMAGIC(sv);
        if(accum < ACC_SV && SvAMAGIC(sv)){
            if(!retsv)
                retsv = TARG;
            sv_setnv(retsv, accum == ACC_NV ? retnv : retiv);
            accum = ACC_SV;
        }
        switch(accum) {
        case ACC_SV:
            tmpsv = amagic_call(retsv, sv,
                is_product ? mult_amg : add_amg,
                SvAMAGIC(retsv) ? AMGf_assign : 0);
            if(tmpsv) {
                switch((accum = accum_type(tmpsv))) {
                case ACC_SV:
                    retsv = tmpsv;
                    break;
                case ACC_IV:
                    retiv = SvIV(tmpsv);
                    break;
                case ACC_NV:
                    retnv = slu_sv_value(tmpsv);
                    break;
                }
            }
            else {
                /* fall back to default */
                accum = ACC_NV;
                is_product ? (retnv = SvNV(retsv) * SvNV(sv))
                           : (retnv = SvNV(retsv) + SvNV(sv));
            }
            break;
        case ACC_IV:
            if(is_product) {
                /* TODO: Consider if product() should shortcircuit the moment its
                 *   accumulator becomes zero
                 */
                /* XXX testing flags before running get_magic may
                 * cause some valid tied values to fallback to the NV path
                 * - DAPM */
                if(!SvNOK(sv) && SvIOK(sv)) {
                    IV i = SvIV(sv);
                    if (retiv == 0) /* avoid later division by zero */
                        break;
                    if (retiv < 0) {
                        if (i < 0) {
                            if (i >= IV_MAX / retiv) {
                                retiv *= i;
                                break;
                            }
                        }
                        else {
                            if (i <= IV_MIN / retiv) {
                                retiv *= i;
                                break;
                            }
                        }
                    }
                    else {
                        if (i < 0) {
                            if (i >= IV_MIN / retiv) {
                                retiv *= i;
                                break;
                            }
                        }
                        else {
                            if (i <= IV_MAX / retiv) {
                                retiv *= i;
                                break;
                            }
                        }
                    }
                }
                /* else fallthrough */
            }
            else {
                /* XXX testing flags before running get_magic may
                 * cause some valid tied values to fallback to the NV path
                 * - DAPM */
                if(!SvNOK(sv) && SvIOK(sv)) {
                    IV i = SvIV(sv);
                    if (retiv >= 0 && i >= 0) {
                        if (retiv <= IV_MAX - i) {
                            retiv += i;
                            break;
                        }
                        /* else fallthrough */
                    }
                    else if (retiv < 0 && i < 0) {
                        if (retiv >= IV_MIN - i) {
                            retiv += i;
                            break;
                        }
                        /* else fallthrough */
                    }
                    else {
                        /* mixed signs can't overflow */
                        retiv += i;
                        break;
                    }
                }
                /* else fallthrough */
            }

            /* fallthrough to NV now */
            retnv = retiv;
            accum = ACC_NV;
        case ACC_NV:
            is_product ? (retnv *= slu_sv_value(sv))
                       : (retnv += slu_sv_value(sv));
            break;
        }
    }

    if(!retsv)
        retsv = TARG;

    switch(accum) {
    case ACC_SV: /* nothing to do */
        break;
    case ACC_IV:
        sv_setiv(retsv, retiv);
        break;
    case ACC_NV:
        sv_setnv(retsv, retnv);
        break;
    }

    ST(0) = retsv;
    XSRETURN(1);
}
#line 535 "ListUtil.c"
    }
    XSRETURN(1);
}

#define SLU_CMP_LARGER   1
#define SLU_CMP_SMALLER -1

XS_EUPXS(XS_List__Util_minstr); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_minstr)
{
    dVAR; dXSARGS;
    dXSI32;
    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    {
#line 385 "ListUtil.xs"
{
    SV *left;
    int index;

    if(!items)
        XSRETURN_UNDEF;

    left = ST(0);
#ifdef OPpLOCALE
    if(MAXARG & OPpLOCALE) {
        for(index = 1 ; index < items ; index++) {
            SV *right = ST(index);
            if(sv_cmp_locale(left, right) == ix)
                left = right;
        }
    }
    else {
#endif
        for(index = 1 ; index < items ; index++) {
            SV *right = ST(index);
            if(sv_cmp(left, right) == ix)
                left = right;
        }
#ifdef OPpLOCALE
    }
#endif
    ST(0) = left;
    XSRETURN(1);
}
#line 581 "ListUtil.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__Util_reduce); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_reduce)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "block, ...");
    {
	SV *	block = ST(0)
;
#line 423 "ListUtil.xs"
{
    SV *ret = sv_newmortal();
    int index;
    GV *agv,*bgv,*gv;
    HV *stash;
    SV **args = &PL_stack_base[ax];
    CV *cv    = sv_2cv(block, &stash, &gv, 0);

    if(cv == Nullcv)
        croak("Not a subroutine reference");

    if(items <= 1)
        XSRETURN_UNDEF;

    agv = gv_fetchpv("a", GV_ADD, SVt_PV);
    bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
    SAVESPTR(GvSV(agv));
    SAVESPTR(GvSV(bgv));
    GvSV(agv) = ret;
    SvSetMagicSV(ret, args[1]);
#ifdef dMULTICALL
    assert(cv);
    if(!CvISXSUB(cv)) {
        dMULTICALL;
        I32 gimme = G_SCALAR;

        UNUSED_VAR_newsp;
        PUSH_MULTICALL(cv);
        for(index = 2 ; index < items ; index++) {
            GvSV(bgv) = args[index];
            MULTICALL;
            SvSetMagicSV(ret, *PL_stack_sp);
        }
#  ifdef PERL_HAS_BAD_MULTICALL_REFCOUNT
        if(CvDEPTH(multicall_cv) > 1)
            SvREFCNT_inc_simple_void_NN(multicall_cv);
#  endif
        POP_MULTICALL;
    }
    else
#endif
    {
        for(index = 2 ; index < items ; index++) {
            dSP;
            GvSV(bgv) = args[index];

            PUSHMARK(SP);
            call_sv((SV*)cv, G_SCALAR);

            SvSetMagicSV(ret, *PL_stack_sp);
        }
    }

    ST(0) = ret;
    XSRETURN(1);
}
#line 653 "ListUtil.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__Util_first); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_first)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "block, ...");
    {
	SV *	block = ST(0)
;
#line 485 "ListUtil.xs"
{
    int index;
    GV *gv;
    HV *stash;
    SV **args = &PL_stack_base[ax];
    CV *cv    = sv_2cv(block, &stash, &gv, 0);

    if(cv == Nullcv)
        croak("Not a subroutine reference");

    if(items <= 1)
        XSRETURN_UNDEF;

    SAVESPTR(GvSV(PL_defgv));
#ifdef dMULTICALL
    assert(cv);
    if(!CvISXSUB(cv)) {
        dMULTICALL;
        I32 gimme = G_SCALAR;

        UNUSED_VAR_newsp;
        PUSH_MULTICALL(cv);

        for(index = 1 ; index < items ; index++) {
            SV *def_sv = GvSV(PL_defgv) = args[index];
#  ifdef SvTEMP_off
            SvTEMP_off(def_sv);
#  endif
            MULTICALL;
            if(SvTRUEx(*PL_stack_sp)) {
#  ifdef PERL_HAS_BAD_MULTICALL_REFCOUNT
                if(CvDEPTH(multicall_cv) > 1)
                    SvREFCNT_inc_simple_void_NN(multicall_cv);
#  endif
                POP_MULTICALL;
                ST(0) = ST(index);
                XSRETURN(1);
            }
        }
#  ifdef PERL_HAS_BAD_MULTICALL_REFCOUNT
        if(CvDEPTH(multicall_cv) > 1)
            SvREFCNT_inc_simple_void_NN(multicall_cv);
#  endif
        POP_MULTICALL;
    }
    else
#endif
    {
        for(index = 1 ; index < items ; index++) {
            dSP;
            GvSV(PL_defgv) = args[index];

            PUSHMARK(SP);
            call_sv((SV*)cv, G_SCALAR);
            if(SvTRUEx(*PL_stack_sp)) {
                ST(0) = ST(index);
                XSRETURN(1);
            }
        }
    }
    XSRETURN_UNDEF;
}
#line 731 "ListUtil.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__Util_any); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_any)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items < 1)
       croak_xs_usage(cv,  "block, ...");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	SV *	block = ST(0)
;
#line 559 "ListUtil.xs"
{
    int ret_true = !(ix & 2); /* return true at end of loop for none/all; false for any/notall */
    int invert   =  (ix & 1); /* invert block test for all/notall */
    GV *gv;
    HV *stash;
    SV **args = &PL_stack_base[ax];
    CV *cv    = sv_2cv(block, &stash, &gv, 0);

    if(cv == Nullcv)
        croak("Not a subroutine reference");

    SAVESPTR(GvSV(PL_defgv));
#ifdef dMULTICALL
    assert(cv);
    if(!CvISXSUB(cv)) {
        dMULTICALL;
        I32 gimme = G_SCALAR;
        int index;

        UNUSED_VAR_newsp;
        PUSH_MULTICALL(cv);
        for(index = 1; index < items; index++) {
            SV *def_sv = GvSV(PL_defgv) = args[index];
#  ifdef SvTEMP_off
            SvTEMP_off(def_sv);
#  endif

            MULTICALL;
            if(SvTRUEx(*PL_stack_sp) ^ invert) {
                POP_MULTICALL;
                ST(0) = ret_true ? &PL_sv_no : &PL_sv_yes;
                XSRETURN(1);
            }
        }
        POP_MULTICALL;
    }
    else
#endif
    {
        int index;
        for(index = 1; index < items; index++) {
            dSP;
            GvSV(PL_defgv) = args[index];

            PUSHMARK(SP);
            call_sv((SV*)cv, G_SCALAR);
            if(SvTRUEx(*PL_stack_sp) ^ invert) {
                ST(0) = ret_true ? &PL_sv_no : &PL_sv_yes;
                XSRETURN(1);
            }
        }
    }

    ST(0) = ret_true ? &PL_sv_yes : &PL_sv_no;
    XSRETURN(1);
}
#line 806 "ListUtil.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_List__Util_head); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_head)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items < 1)
       croak_xs_usage(cv,  "size, ...");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
#line 623 "ListUtil.xs"
{
    int size = 0;
    int start = 0;
    int end = 0;
    int i = 0;

    size = SvIV( ST(0) );

    if ( ix == 0 ) {
        start = 1;
        end = start + size;
        if ( size < 0 ) {
            end += items - 1;
        }
        if ( end > items ) {
            end = items;
        }
    }
    else {
        end = items;
        if ( size < 0 ) {
            start = -size + 1;
        }
        else {
            start = end - size;
        }
        if ( start < 1 ) {
            start = 1;
        }
    }

    if ( end < start ) {
        XSRETURN(0);
    }
    else {
        EXTEND( SP, end - start );
        for ( i = start; i <= end; i++ ) {
            PUSHs( sv_2mortal( newSVsv( ST(i) ) ) );
        }
        XSRETURN( end - start );
    }
}
#line 866 "ListUtil.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_List__Util_pairs); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_pairs)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
#line 670 "ListUtil.xs"
{
    int argi = 0;
    int reti = 0;
    HV *pairstash = get_hv("List::Util::_Pair::", GV_ADD);

    if(items % 2 && ckWARN(WARN_MISC))
        warn("Odd number of elements in pairs");

    {
        for(; argi < items; argi += 2) {
            SV *a = ST(argi);
            SV *b = argi < items-1 ? ST(argi+1) : &PL_sv_undef;

            AV *av = newAV();
            av_push(av, newSVsv(a));
            av_push(av, newSVsv(b));

            ST(reti) = sv_2mortal(newRV_noinc((SV *)av));
            sv_bless(ST(reti), pairstash);
            reti++;
        }
    }

    XSRETURN(reti);
}
#line 908 "ListUtil.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_List__Util_unpairs); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_unpairs)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
#line 700 "ListUtil.xs"
{
    /* Unlike pairs(), we're going to trash the input values on the stack
     * almost as soon as we start generating output. So clone them first
     */
    int i;
    SV **args_copy;
    Newx(args_copy, items, SV *);
    SAVEFREEPV(args_copy);

    Copy(&ST(0), args_copy, items, SV *);

    for(i = 0; i < items; i++) {
        SV *pair = args_copy[i];
        AV *pairav;

        SvGETMAGIC(pair);

        if(SvTYPE(pair) != SVt_RV)
            croak("Not a reference at List::Util::unpairs() argument %d", i);
        if(SvTYPE(SvRV(pair)) != SVt_PVAV)
            croak("Not an ARRAY reference at List::Util::unpairs() argument %d", i);

        /* TODO: assert pair is an ARRAY ref */
        pairav = (AV *)SvRV(pair);

        EXTEND(SP, 2);

        if(AvFILL(pairav) >= 0)
            mPUSHs(newSVsv(AvARRAY(pairav)[0]));
        else
            PUSHs(&PL_sv_undef);

        if(AvFILL(pairav) >= 1)
            mPUSHs(newSVsv(AvARRAY(pairav)[1]));
        else
            PUSHs(&PL_sv_undef);
    }

    XSRETURN(items * 2);
}
#line 965 "ListUtil.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_List__Util_pairkeys); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_pairkeys)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
#line 745 "ListUtil.xs"
{
    int argi = 0;
    int reti = 0;

    if(items % 2 && ckWARN(WARN_MISC))
        warn("Odd number of elements in pairkeys");

    {
        for(; argi < items; argi += 2) {
            SV *a = ST(argi);

            ST(reti++) = sv_2mortal(newSVsv(a));
        }
    }

    XSRETURN(reti);
}
#line 999 "ListUtil.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_List__Util_pairvalues); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_pairvalues)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
#line 767 "ListUtil.xs"
{
    int argi = 0;
    int reti = 0;

    if(items % 2 && ckWARN(WARN_MISC))
        warn("Odd number of elements in pairvalues");

    {
        for(; argi < items; argi += 2) {
            SV *b = argi < items-1 ? ST(argi+1) : &PL_sv_undef;

            ST(reti++) = sv_2mortal(newSVsv(b));
        }
    }

    XSRETURN(reti);
}
#line 1033 "ListUtil.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_List__Util_pairfirst); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_pairfirst)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "block, ...");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	SV *	block = ST(0)
;
#line 790 "ListUtil.xs"
{
    GV *agv,*bgv,*gv;
    HV *stash;
    CV *cv    = sv_2cv(block, &stash, &gv, 0);
    I32 ret_gimme = GIMME_V;
    int argi = 1; /* "shift" the block */

    if(!(items % 2) && ckWARN(WARN_MISC))
        warn("Odd number of elements in pairfirst");

    agv = gv_fetchpv("a", GV_ADD, SVt_PV);
    bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
    SAVESPTR(GvSV(agv));
    SAVESPTR(GvSV(bgv));
#ifdef dMULTICALL
    assert(cv);
    if(!CvISXSUB(cv)) {
        /* Since MULTICALL is about to move it */
        SV **stack = PL_stack_base + ax;

        dMULTICALL;
        I32 gimme = G_SCALAR;

        UNUSED_VAR_newsp;
        PUSH_MULTICALL(cv);
        for(; argi < items; argi += 2) {
            SV *a = GvSV(agv) = stack[argi];
            SV *b = GvSV(bgv) = argi < items-1 ? stack[argi+1] : &PL_sv_undef;

            MULTICALL;

            if(!SvTRUEx(*PL_stack_sp))
                continue;

            POP_MULTICALL;
            if(ret_gimme == G_ARRAY) {
                ST(0) = sv_mortalcopy(a);
                ST(1) = sv_mortalcopy(b);
                XSRETURN(2);
            }
            else
                XSRETURN_YES;
        }
        POP_MULTICALL;
        XSRETURN(0);
    }
    else
#endif
    {
        for(; argi < items; argi += 2) {
            dSP;
            SV *a = GvSV(agv) = ST(argi);
            SV *b = GvSV(bgv) = argi < items-1 ? ST(argi+1) : &PL_sv_undef;

            PUSHMARK(SP);
            call_sv((SV*)cv, G_SCALAR);

            SPAGAIN;

            if(!SvTRUEx(*PL_stack_sp))
                continue;

            if(ret_gimme == G_ARRAY) {
                ST(0) = sv_mortalcopy(a);
                ST(1) = sv_mortalcopy(b);
                XSRETURN(2);
            }
            else
                XSRETURN_YES;
        }
    }

    XSRETURN(0);
}
#line 1126 "ListUtil.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_List__Util_pairgrep); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_pairgrep)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "block, ...");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	SV *	block = ST(0)
;
#line 870 "ListUtil.xs"
{
    GV *agv,*bgv,*gv;
    HV *stash;
    CV *cv    = sv_2cv(block, &stash, &gv, 0);
    I32 ret_gimme = GIMME_V;

    /* This function never returns more than it consumed in arguments. So we
     * can build the results "live", behind the arguments
     */
    int argi = 1; /* "shift" the block */
    int reti = 0;

    if(!(items % 2) && ckWARN(WARN_MISC))
        warn("Odd number of elements in pairgrep");

    agv = gv_fetchpv("a", GV_ADD, SVt_PV);
    bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
    SAVESPTR(GvSV(agv));
    SAVESPTR(GvSV(bgv));
#ifdef dMULTICALL
    assert(cv);
    if(!CvISXSUB(cv)) {
        /* Since MULTICALL is about to move it */
        SV **stack = PL_stack_base + ax;
        int i;

        dMULTICALL;
        I32 gimme = G_SCALAR;

        UNUSED_VAR_newsp;
        PUSH_MULTICALL(cv);
        for(; argi < items; argi += 2) {
            SV *a = GvSV(agv) = stack[argi];
            SV *b = GvSV(bgv) = argi < items-1 ? stack[argi+1] : &PL_sv_undef;

            MULTICALL;

            if(SvTRUEx(*PL_stack_sp)) {
                if(ret_gimme == G_ARRAY) {
                    /* We can't mortalise yet or they'd be mortal too early */
                    stack[reti++] = newSVsv(a);
                    stack[reti++] = newSVsv(b);
                }
                else if(ret_gimme == G_SCALAR)
                    reti++;
            }
        }
        POP_MULTICALL;

        if(ret_gimme == G_ARRAY)
            for(i = 0; i < reti; i++)
                sv_2mortal(stack[i]);
    }
    else
#endif
    {
        for(; argi < items; argi += 2) {
            dSP;
            SV *a = GvSV(agv) = ST(argi);
            SV *b = GvSV(bgv) = argi < items-1 ? ST(argi+1) : &PL_sv_undef;

            PUSHMARK(SP);
            call_sv((SV*)cv, G_SCALAR);

            SPAGAIN;

            if(SvTRUEx(*PL_stack_sp)) {
                if(ret_gimme == G_ARRAY) {
                    ST(reti++) = sv_mortalcopy(a);
                    ST(reti++) = sv_mortalcopy(b);
                }
                else if(ret_gimme == G_SCALAR)
                    reti++;
            }
        }
    }

    if(ret_gimme == G_ARRAY)
        XSRETURN(reti);
    else if(ret_gimme == G_SCALAR) {
        ST(0) = newSViv(reti);
        XSRETURN(1);
    }
}
#line 1229 "ListUtil.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_List__Util_pairmap); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_pairmap)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "block, ...");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	SV *	block = ST(0)
;
#line 960 "ListUtil.xs"
{
    GV *agv,*bgv,*gv;
    HV *stash;
    CV *cv    = sv_2cv(block, &stash, &gv, 0);
    SV **args_copy = NULL;
    I32 ret_gimme = GIMME_V;

    int argi = 1; /* "shift" the block */
    int reti = 0;

    if(!(items % 2) && ckWARN(WARN_MISC))
        warn("Odd number of elements in pairmap");

    agv = gv_fetchpv("a", GV_ADD, SVt_PV);
    bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
    SAVESPTR(GvSV(agv));
    SAVESPTR(GvSV(bgv));
/* This MULTICALL-based code appears to fail on perl 5.10.0 and 5.8.9
 * Skip it on those versions (RT#87857)
 */
#if defined(dMULTICALL) && (PERL_VERSION_GE(5,10,1) || PERL_VERSION_LE(5,8,8))
    assert(cv);
    if(!CvISXSUB(cv)) {
        /* Since MULTICALL is about to move it */
        SV **stack = PL_stack_base + ax;
        I32 ret_gimme = GIMME_V;
        int i;
        AV *spill = NULL; /* accumulates results if too big for stack */

        dMULTICALL;
        I32 gimme = G_ARRAY;

        UNUSED_VAR_newsp;
        PUSH_MULTICALL(cv);
        for(; argi < items; argi += 2) {
            int count;

            GvSV(agv) = stack[argi];
            GvSV(bgv) = argi < items-1 ? stack[argi+1]: &PL_sv_undef;

            MULTICALL;
            count = PL_stack_sp - PL_stack_base;

            if (count > 2 || spill) {
                /* We can't return more than 2 results for a given input pair
                 * without trashing the remaining arguments on the stack still
                 * to be processed, or possibly overrunning the stack end.
                 * So, we'll accumulate the results in a temporary buffer
                 * instead.
                 * We didn't do this initially because in the common case, most
                 * code blocks will return only 1 or 2 items so it won't be
                 * necessary
                 */
                int fill;

                if (!spill) {
                    spill = newAV();
                    AvREAL_off(spill); /* don't ref count its contents */
                    /* can't mortalize here as every nextstate in the code
                     * block frees temps */
                    SAVEFREESV(spill);
                }

                fill = (int)AvFILL(spill);
                av_extend(spill, fill + count);
                for(i = 0; i < count; i++)
                    (void)av_store(spill, ++fill,
                                    newSVsv(PL_stack_base[i + 1]));
            }
            else
                for(i = 0; i < count; i++)
                    stack[reti++] = newSVsv(PL_stack_base[i + 1]);
        }

        if (spill)
            /* the POP_MULTICALL will trigger the SAVEFREESV above;
             * keep it alive  it on the temps stack instead */
            SvREFCNT_inc_simple_void_NN(spill);
            sv_2mortal((SV*)spill);

        POP_MULTICALL;

        if (spill) {
            int n = (int)AvFILL(spill) + 1;
            SP = &ST(reti - 1);
            EXTEND(SP, n);
            for (i = 0; i < n; i++)
                *++SP = *av_fetch(spill, i, FALSE);
            reti += n;
            av_clear(spill);
        }

        if(ret_gimme == G_ARRAY)
            for(i = 0; i < reti; i++)
                sv_2mortal(ST(i));
    }
    else
#endif
    {
        for(; argi < items; argi += 2) {
            dSP;
            int count;
            int i;

            GvSV(agv) = args_copy ? args_copy[argi] : ST(argi);
            GvSV(bgv) = argi < items-1 ?
                (args_copy ? args_copy[argi+1] : ST(argi+1)) :
                &PL_sv_undef;

            PUSHMARK(SP);
            count = call_sv((SV*)cv, G_ARRAY);

            SPAGAIN;

            if(count > 2 && !args_copy && ret_gimme == G_ARRAY) {
                int n_args = items - argi;
                Newx(args_copy, n_args, SV *);
                SAVEFREEPV(args_copy);

                Copy(&ST(argi), args_copy, n_args, SV *);

                argi = 0;
                items = n_args;
            }

            if(ret_gimme == G_ARRAY)
                for(i = 0; i < count; i++)
                    ST(reti++) = sv_mortalcopy(SP[i - count + 1]);
            else
                reti += count;

            PUTBACK;
        }
    }

    if(ret_gimme == G_ARRAY)
        XSRETURN(reti);

    ST(0) = sv_2mortal(newSViv(reti));
    XSRETURN(1);
}
#line 1389 "ListUtil.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_List__Util_shuffle); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_shuffle)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    {
#line 1106 "ListUtil.xs"
{
    int index;
#if (PERL_VERSION < 9)
    struct op dmy_op;
    struct op *old_op = PL_op;

    /* We call pp_rand here so that Drand01 get initialized if rand()
       or srand() has not already been called
    */
    memzero((char*)(&dmy_op), sizeof(struct op));
    /* we let pp_rand() borrow the TARG allocated for this XS sub */
    dmy_op.op_targ = PL_op->op_targ;
    PL_op = &dmy_op;
    (void)*(PL_ppaddr[OP_RAND])(aTHX);
    PL_op = old_op;
#else
    /* Initialize Drand01 if rand() or srand() has
       not already been called
    */
    if(!PL_srand_called) {
        (void)seedDrand01((Rand_seed_t)Perl_seed(aTHX));
        PL_srand_called = TRUE;
    }
#endif

    for (index = items ; index > 1 ; ) {
        int swap = (int)(Drand01() * (double)(index--));
        SV *tmp = ST(swap);
        ST(swap) = ST(index);
        ST(index) = tmp;
    }

    XSRETURN(items);
}
#line 1438 "ListUtil.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__Util_uniq); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__Util_uniq)
{
    dVAR; dXSARGS;
    dXSI32;
    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    {
#line 1150 "ListUtil.xs"
{
    int retcount = 0;
    int index;
    SV **args = &PL_stack_base[ax];
    HV *seen;

    if(items == 0 || (items == 1 && !SvGAMAGIC(args[0]) && SvOK(args[0]))) {
        /* Optimise for the case of the empty list or a defined nonmagic
         * singleton. Leave a singleton magical||undef for the regular case */
        retcount = items;
        goto finish;
    }

    sv_2mortal((SV *)(seen = newHV()));

    if(ix == 0) {
        /* uniqnum */
        /* A temporary buffer for number stringification */
        SV *keysv = sv_newmortal();

        for(index = 0 ; index < items ; index++) {
            SV *arg = args[index];
#ifdef HV_FETCH_EMPTY_HE
            HE* he;
#endif

            if(SvGAMAGIC(arg))
                /* clone the value so we don't invoke magic again */
                arg = sv_mortalcopy(arg);

            if(SvUOK(arg))
                sv_setpvf(keysv, "%" UVuf, SvUV(arg));
            else if(SvIOK(arg))
                sv_setpvf(keysv, "%" IVdf, SvIV(arg));
            else
                sv_setpvf(keysv, "%" NVgf, SvNV(arg));
#ifdef HV_FETCH_EMPTY_HE
            he = (HE*) hv_common(seen, NULL, SvPVX(keysv), SvCUR(keysv), 0, HV_FETCH_LVALUE | HV_FETCH_EMPTY_HE, NULL, 0);
            if (HeVAL(he))
                continue;

            HeVAL(he) = &PL_sv_undef;
#else
            if(hv_exists(seen, SvPVX(keysv), SvCUR(keysv)))
                continue;

            hv_store(seen, SvPVX(keysv), SvCUR(keysv), &PL_sv_yes, 0);
#endif

            if(GIMME_V == G_ARRAY)
                ST(retcount) = SvOK(arg) ? arg : sv_2mortal(newSViv(0));
            retcount++;
        }
    }
    else {
        /* uniqstr or uniq */
        int seen_undef = 0;

        for(index = 0 ; index < items ; index++) {
            SV *arg = args[index];
#ifdef HV_FETCH_EMPTY_HE
            HE *he;
#endif

            if(SvGAMAGIC(arg))
                /* clone the value so we don't invoke magic again */
                arg = sv_mortalcopy(arg);

            if(ix == 2 && !SvOK(arg)) {
                /* special handling of undef for uniq() */
                if(seen_undef)
                    continue;

                seen_undef++;

                if(GIMME_V == G_ARRAY)
                    ST(retcount) = arg;
                retcount++;
                continue;
            }
#ifdef HV_FETCH_EMPTY_HE
            he = (HE*) hv_common(seen, arg, NULL, 0, 0, HV_FETCH_LVALUE | HV_FETCH_EMPTY_HE, NULL, 0);
            if (HeVAL(he))
                continue;

            HeVAL(he) = &PL_sv_undef;
#else
            if (hv_exists_ent(seen, arg, 0))
                continue;

            hv_store_ent(seen, arg, &PL_sv_yes, 0);
#endif

            if(GIMME_V == G_ARRAY)
                ST(retcount) = SvOK(arg) ? arg : sv_2mortal(newSVpvn("", 0));
            retcount++;
        }
    }

  finish:
    if(GIMME_V == G_ARRAY)
        XSRETURN(retcount);
    else
        ST(0) = sv_2mortal(newSViv(retcount));
}
#line 1558 "ListUtil.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Scalar__Util_dualvar); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_dualvar)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "num, str");
    {
	SV *	num = ST(0)
;
	SV *	str = ST(1)
;
#line 1264 "ListUtil.xs"
{
    dXSTARG;

    (void)SvUPGRADE(TARG, SVt_PVNV);

    sv_copypv(TARG,str);

    if(SvNOK(num) || SvPOK(num) || SvMAGICAL(num)) {
        SvNV_set(TARG, SvNV(num));
        SvNOK_on(TARG);
    }
#ifdef SVf_IVisUV
    else if(SvUOK(num)) {
        SvUV_set(TARG, SvUV(num));
        SvIOK_on(TARG);
        SvIsUV_on(TARG);
    }
#endif
    else {
        SvIV_set(TARG, SvIV(num));
        SvIOK_on(TARG);
    }

    if(PL_tainting && (SvTAINTED(num) || SvTAINTED(str)))
        SvTAINTED_on(TARG);

    ST(0) = TARG;
    XSRETURN(1);
}
#line 1605 "ListUtil.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Scalar__Util_isdual); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_isdual)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
#line 1299 "ListUtil.xs"
    if(SvMAGICAL(sv))
        mg_get(sv);

    ST(0) = boolSV((SvPOK(sv) || SvPOKp(sv)) && (SvNIOK(sv) || SvNIOKp(sv)));
    XSRETURN(1);
#line 1626 "ListUtil.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Scalar__Util_blessed); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_blessed)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
	char *	RETVAL;
	dXSTARG;
#line 1310 "ListUtil.xs"
{
    SvGETMAGIC(sv);

    if(!(SvROK(sv) && SvOBJECT(SvRV(sv))))
        XSRETURN_UNDEF;

    RETVAL = (char*)sv_reftype(SvRV(sv),TRUE);
}
#line 1652 "ListUtil.c"
	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Scalar__Util_reftype); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_reftype)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
	char *	RETVAL;
	dXSTARG;
#line 1326 "ListUtil.xs"
{
    SvGETMAGIC(sv);
    if(!SvROK(sv))
        XSRETURN_UNDEF;

    RETVAL = (char*)sv_reftype(SvRV(sv),FALSE);
}
#line 1678 "ListUtil.c"
	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Scalar__Util_refaddr); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_refaddr)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
	UV	RETVAL;
	dXSTARG;
#line 1341 "ListUtil.xs"
{
    SvGETMAGIC(sv);
    if(!SvROK(sv))
        XSRETURN_UNDEF;

    RETVAL = PTR2UV(SvRV(sv));
}
#line 1704 "ListUtil.c"
	XSprePUSH; PUSHu((UV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Scalar__Util_weaken); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_weaken)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
#line 1356 "ListUtil.xs"
#ifdef SvWEAKREF
    sv_rvweaken(sv);
#else
    croak("weak references are not implemented in this release of perl");
#endif
#line 1726 "ListUtil.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_Scalar__Util_unweaken); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_unweaken)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
#line 1367 "ListUtil.xs"
    SV *tsv;
#line 1743 "ListUtil.c"
#line 1369 "ListUtil.xs"
#if defined(sv_rvunweaken)
    PERL_UNUSED_VAR(tsv);
    sv_rvunweaken(sv);
#elif defined(SvWEAKREF)
    /* This code stolen from core's sv_rvweaken() and modified */
    if (!SvOK(sv))
        return;
    if (!SvROK(sv))
        croak("Can't unweaken a nonreference");
    else if (!SvWEAKREF(sv)) {
        if(ckWARN(WARN_MISC))
            warn("Reference is not weak");
        return;
    }
    else if (SvREADONLY(sv)) croak_no_modify();

    tsv = SvRV(sv);
#if PERL_VERSION >= 14
    SvWEAKREF_off(sv); SvROK_on(sv);
    SvREFCNT_inc_NN(tsv);
    Perl_sv_del_backref(aTHX_ tsv, sv);
#else
    /* Lacking sv_del_backref() the best we can do is clear the old (weak) ref
     * then set a new strong one
     */
    sv_setsv(sv, &PL_sv_undef);
    SvRV_set(sv, SvREFCNT_inc_NN(tsv));
    SvROK_on(sv);
#endif
#else
    croak("weak references are not implemented in this release of perl");
#endif
#line 1777 "ListUtil.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_Scalar__Util_isweak); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_isweak)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
#line 1407 "ListUtil.xs"
#ifdef SvWEAKREF
    ST(0) = boolSV(SvROK(sv) && SvWEAKREF(sv));
    XSRETURN(1);
#else
    croak("weak references are not implemented in this release of perl");
#endif
#line 1799 "ListUtil.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Scalar__Util_readonly); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_readonly)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
	int	RETVAL;
	dXSTARG;
#line 1419 "ListUtil.xs"
    SvGETMAGIC(sv);
    RETVAL = SvREADONLY(sv);
#line 1819 "ListUtil.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Scalar__Util_tainted); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_tainted)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
	int	RETVAL;
	dXSTARG;
#line 1429 "ListUtil.xs"
    SvGETMAGIC(sv);
    RETVAL = SvTAINTED(sv);
#line 1840 "ListUtil.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Scalar__Util_isvstring); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_isvstring)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
#line 1439 "ListUtil.xs"
#ifdef SvVOK
    SvGETMAGIC(sv);
    ST(0) = boolSV(SvVOK(sv));
    XSRETURN(1);
#else
    croak("vstrings are not implemented in this release of perl");
#endif
#line 1864 "ListUtil.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Scalar__Util_looks_like_number); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_looks_like_number)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
	SV *	RETVAL;
#line 1452 "ListUtil.xs"
    SV *tempsv;
    SvGETMAGIC(sv);
    if(SvAMAGIC(sv) && (tempsv = AMG_CALLun(sv, numer))) {
        sv = tempsv;
    }
#if !PERL_VERSION_GE(5,8,5)
    if(SvPOK(sv) || SvPOKp(sv)) {
        RETVAL = looks_like_number(sv) ? &PL_sv_yes : &PL_sv_no;
    }
    else {
        RETVAL = (SvFLAGS(sv) & (SVf_NOK|SVp_NOK|SVf_IOK|SVp_IOK)) ? &PL_sv_yes : &PL_sv_no;
    }
#else
    RETVAL = looks_like_number(sv) ? &PL_sv_yes : &PL_sv_no;
#endif
#line 1896 "ListUtil.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Scalar__Util_openhandle); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Scalar__Util_openhandle)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
#line 1474 "ListUtil.xs"
{
    IO *io = NULL;
    SvGETMAGIC(sv);
    if(SvROK(sv)){
        /* deref first */
        sv = SvRV(sv);
    }

    /* must be GLOB or IO */
    if(isGV(sv)){
        io = GvIO((GV*)sv);
    }
    else if(SvTYPE(sv) == SVt_PVIO){
        io = (IO*)sv;
    }

    if(io){
        /* real or tied filehandle? */
        if(IoIFP(io) || SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)){
            XSRETURN(1);
        }
    }
    XSRETURN_UNDEF;
}
#line 1938 "ListUtil.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_Sub__Util_set_prototype); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Sub__Util_set_prototype)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "proto, code");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	SV *	proto = ST(0)
;
	SV *	code = ST(1)
;
#line 1506 "ListUtil.xs"
    SV *cv; /* not CV * */
#line 1959 "ListUtil.c"
#line 1508 "ListUtil.xs"
    SvGETMAGIC(code);
    if(!SvROK(code))
        croak("set_prototype: not a reference");

    cv = SvRV(code);
    if(SvTYPE(cv) != SVt_PVCV)
        croak("set_prototype: not a subroutine reference");

    if(SvPOK(proto)) {
        /* set the prototype */
        sv_copypv(cv, proto);
    }
    else {
        /* delete the prototype */
        SvPOK_off(cv);
    }

    PUSHs(code);
    XSRETURN(1);
#line 1980 "ListUtil.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_Sub__Util_set_subname); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Sub__Util_set_subname)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "name, sub");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	SV *	name = ST(0)
;
	SV *	sub = ST(1)
;
#line 1533 "ListUtil.xs"
    CV *cv = NULL;
    GV *gv;
    HV *stash = CopSTASH(PL_curcop);
    const char *s, *end = NULL, *begin = NULL;
    MAGIC *mg;
    STRLEN namelen;
    const char* nameptr = SvPV(name, namelen);
    int utf8flag = SvUTF8(name);
    int quotes_seen = 0;
    bool need_subst = FALSE;
#line 2011 "ListUtil.c"
#line 1544 "ListUtil.xs"
    if (!SvROK(sub) && SvGMAGICAL(sub))
        mg_get(sub);
    if (SvROK(sub))
        cv = (CV *) SvRV(sub);
    else if (SvTYPE(sub) == SVt_PVGV)
        cv = GvCVu(sub);
    else if (!SvOK(sub))
        croak(PL_no_usym, "a subroutine");
    else if (PL_op->op_private & HINT_STRICT_REFS)
        croak("Can't use string (\"%.32s\") as %s ref while \"strict refs\" in use",
              SvPV_nolen(sub), "a subroutine");
    else if ((gv = gv_fetchsv(sub, FALSE, SVt_PVCV)))
        cv = GvCVu(gv);
    if (!cv)
        croak("Undefined subroutine %s", SvPV_nolen(sub));
    if (SvTYPE(cv) != SVt_PVCV && SvTYPE(cv) != SVt_PVFM)
        croak("Not a subroutine reference");
    for (s = nameptr; s <= nameptr + namelen; s++) {
        if (s > nameptr && *s == ':' && s[-1] == ':') {
            end = s - 1;
            begin = ++s;
            if (quotes_seen)
                need_subst = TRUE;
        }
        else if (s > nameptr && *s != '\0' && s[-1] == '\'') {
            end = s - 1;
            begin = s;
            if (quotes_seen++)
                need_subst = TRUE;
        }
    }
    s--;
    if (end) {
        SV* tmp;
        if (need_subst) {
            STRLEN length = end - nameptr + quotes_seen - (*end == '\'' ? 1 : 0);
            char* left;
            int i, j;
            tmp = sv_2mortal(newSV(length));
            left = SvPVX(tmp);
            for (i = 0, j = 0; j < end - nameptr; ++i, ++j) {
                if (nameptr[j] == '\'') {
                    left[i] = ':';
                    left[++i] = ':';
                }
                else {
                    left[i] = nameptr[j];
                }
            }
            stash = gv_stashpvn(left, length, GV_ADD | utf8flag);
        }
        else
            stash = gv_stashpvn(nameptr, end - nameptr, GV_ADD | utf8flag);
        nameptr = begin;
        namelen -= begin - nameptr;
    }

    /* under debugger, provide information about sub location */
    if (PL_DBsub && CvGV(cv)) {
        HV* DBsub = GvHV(PL_DBsub);
        HE* old_data;

        GV* oldgv = CvGV(cv);
        HV* oldhv = GvSTASH(oldgv);
        SV* old_full_name = sv_2mortal(newSVpvn_flags(HvNAME(oldhv), HvNAMELEN_get(oldhv), HvNAMEUTF8(oldhv) ? SVf_UTF8 : 0));
        sv_catpvn(old_full_name, "::", 2);
        sv_catpvn_flags(old_full_name, GvNAME(oldgv), GvNAMELEN(oldgv), GvNAMEUTF8(oldgv) ? SV_CATUTF8 : SV_CATBYTES);

        old_data = hv_fetch_ent(DBsub, old_full_name, 0, 0);

        if (old_data && HeVAL(old_data)) {
            SV* new_full_name = sv_2mortal(newSVpvn_flags(HvNAME(stash), HvNAMELEN_get(stash), HvNAMEUTF8(stash) ? SVf_UTF8 : 0));
            sv_catpvn(new_full_name, "::", 2);
            sv_catpvn_flags(new_full_name, nameptr, s - nameptr, utf8flag ? SV_CATUTF8 : SV_CATBYTES);
            SvREFCNT_inc(HeVAL(old_data));
            if (hv_store_ent(DBsub, new_full_name, HeVAL(old_data), 0) != NULL)
                SvREFCNT_inc(HeVAL(old_data));
        }
    }

    gv = (GV *) newSV(0);
    gv_init_pvn(gv, stash, nameptr, s - nameptr, GV_ADDMULTI | utf8flag);

    /*
     * set_subname needs to create a GV to store the name. The CvGV field of a
     * CV is not refcounted, so perl wouldn't know to SvREFCNT_dec() this GV if
     * it destroys the containing CV. We use a MAGIC with an empty vtable
     * simply for the side-effect of using MGf_REFCOUNTED to store the
     * actually-counted reference to the GV.
     */
    mg = SvMAGIC(cv);
    while (mg && mg->mg_virtual != &subname_vtbl)
        mg = mg->mg_moremagic;
    if (!mg) {
        Newxz(mg, 1, MAGIC);
        mg->mg_moremagic = SvMAGIC(cv);
        mg->mg_type = PERL_MAGIC_ext;
        mg->mg_virtual = &subname_vtbl;
        SvMAGIC_set(cv, mg);
    }
    if (mg->mg_flags & MGf_REFCOUNTED)
        SvREFCNT_dec(mg->mg_obj);
    mg->mg_flags |= MGf_REFCOUNTED;
    mg->mg_obj = (SV *) gv;
    SvRMAGICAL_on(cv);
    CvANON_off(cv);
#ifndef CvGV_set
    CvGV(cv) = gv;
#else
    CvGV_set(cv, gv);
#endif
    PUSHs(sub);
#line 2125 "ListUtil.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_Sub__Util_subname); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Sub__Util_subname)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "code");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	SV *	code = ST(0)
;
#line 1661 "ListUtil.xs"
    CV *cv;
    GV *gv;
#line 2146 "ListUtil.c"
#line 1664 "ListUtil.xs"
    if (!SvROK(code) && SvGMAGICAL(code))
        mg_get(code);

    if(!SvROK(code) || SvTYPE(cv = (CV *)SvRV(code)) != SVt_PVCV)
        croak("Not a subroutine reference");

    if(!(gv = CvGV(cv)))
        XSRETURN(0);

    mPUSHs(newSVpvf("%s::%s", HvNAME(GvSTASH(gv)), GvNAME(gv)));
    XSRETURN(1);
#line 2159 "ListUtil.c"
	PUTBACK;
	return;
    }
}

#ifdef __cplusplus
extern "C"
#endif
XS_EXTERNAL(boot_List__Util); /* prototype to pass -Wmissing-prototypes */
XS_EXTERNAL(boot_List__Util)
{
#if PERL_VERSION_LE(5, 21, 5)
    dVAR; dXSARGS;
#else
    dVAR; dXSBOOTARGSXSAPIVERCHK;
#endif
#if (PERL_REVISION == 5 && PERL_VERSION < 9)
    char* file = __FILE__;
#else
    const char* file = __FILE__;
#endif

    PERL_UNUSED_VAR(file);

    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
#if PERL_VERSION_LE(5, 21, 5)
    XS_VERSION_BOOTCHECK;
#  ifdef XS_APIVERSION_BOOTCHECK
    XS_APIVERSION_BOOTCHECK;
#  endif
#endif

        cv = newXSproto_portable("List::Util::max", XS_List__Util_min, file, "@");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("List::Util::min", XS_List__Util_min, file, "@");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("List::Util::product", XS_List__Util_sum, file, "@");
        XSANY.any_i32 = 2;
        cv = newXSproto_portable("List::Util::sum", XS_List__Util_sum, file, "@");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("List::Util::sum0", XS_List__Util_sum, file, "@");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("List::Util::maxstr", XS_List__Util_minstr, file, "@");
        XSANY.any_i32 = SLU_CMP_SMALLER;
        cv = newXSproto_portable("List::Util::minstr", XS_List__Util_minstr, file, "@");
        XSANY.any_i32 = SLU_CMP_LARGER;
        (void)newXSproto_portable("List::Util::reduce", XS_List__Util_reduce, file, "&@");
        (void)newXSproto_portable("List::Util::first", XS_List__Util_first, file, "&@");
        cv = newXSproto_portable("List::Util::all", XS_List__Util_any, file, "&@");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("List::Util::any", XS_List__Util_any, file, "&@");
        XSANY.any_i32 = 2;
        cv = newXSproto_portable("List::Util::none", XS_List__Util_any, file, "&@");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("List::Util::notall", XS_List__Util_any, file, "&@");
        XSANY.any_i32 = 3;
        cv = newXSproto_portable("List::Util::head", XS_List__Util_head, file, "$@");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("List::Util::tail", XS_List__Util_head, file, "$@");
        XSANY.any_i32 = 1;
        (void)newXSproto_portable("List::Util::pairs", XS_List__Util_pairs, file, "@");
        (void)newXSproto_portable("List::Util::unpairs", XS_List__Util_unpairs, file, "@");
        (void)newXSproto_portable("List::Util::pairkeys", XS_List__Util_pairkeys, file, "@");
        (void)newXSproto_portable("List::Util::pairvalues", XS_List__Util_pairvalues, file, "@");
        (void)newXSproto_portable("List::Util::pairfirst", XS_List__Util_pairfirst, file, "&@");
        (void)newXSproto_portable("List::Util::pairgrep", XS_List__Util_pairgrep, file, "&@");
        (void)newXSproto_portable("List::Util::pairmap", XS_List__Util_pairmap, file, "&@");
        (void)newXSproto_portable("List::Util::shuffle", XS_List__Util_shuffle, file, "@");
        cv = newXSproto_portable("List::Util::uniq", XS_List__Util_uniq, file, "@");
        XSANY.any_i32 = 2;
        cv = newXSproto_portable("List::Util::uniqnum", XS_List__Util_uniq, file, "@");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("List::Util::uniqstr", XS_List__Util_uniq, file, "@");
        XSANY.any_i32 = 1;
        (void)newXSproto_portable("Scalar::Util::dualvar", XS_Scalar__Util_dualvar, file, "$$");
        (void)newXSproto_portable("Scalar::Util::isdual", XS_Scalar__Util_isdual, file, "$");
        (void)newXSproto_portable("Scalar::Util::blessed", XS_Scalar__Util_blessed, file, "$");
        (void)newXSproto_portable("Scalar::Util::reftype", XS_Scalar__Util_reftype, file, "$");
        (void)newXSproto_portable("Scalar::Util::refaddr", XS_Scalar__Util_refaddr, file, "$");
        (void)newXSproto_portable("Scalar::Util::weaken", XS_Scalar__Util_weaken, file, "$");
        (void)newXSproto_portable("Scalar::Util::unweaken", XS_Scalar__Util_unweaken, file, "$");
        (void)newXSproto_portable("Scalar::Util::isweak", XS_Scalar__Util_isweak, file, "$");
        (void)newXSproto_portable("Scalar::Util::readonly", XS_Scalar__Util_readonly, file, "$");
        (void)newXSproto_portable("Scalar::Util::tainted", XS_Scalar__Util_tainted, file, "$");
        (void)newXSproto_portable("Scalar::Util::isvstring", XS_Scalar__Util_isvstring, file, "$");
        (void)newXSproto_portable("Scalar::Util::looks_like_number", XS_Scalar__Util_looks_like_number, file, "$");
        (void)newXSproto_portable("Scalar::Util::openhandle", XS_Scalar__Util_openhandle, file, "$");
        newXS_deffile("Sub::Util::set_prototype", XS_Sub__Util_set_prototype);
        newXS_deffile("Sub::Util::set_subname", XS_Sub__Util_set_subname);
        newXS_deffile("Sub::Util::subname", XS_Sub__Util_subname);

    /* Initialisation Section */

#line 1677 "ListUtil.xs"
{
    HV *lu_stash = gv_stashpvn("List::Util", 10, TRUE);
    GV *rmcgv = *(GV**)hv_fetch(lu_stash, "REAL_MULTICALL", 14, TRUE);
    SV *rmcsv;
#if !defined(SvWEAKREF) || !defined(SvVOK)
    HV *su_stash = gv_stashpvn("Scalar::Util", 12, TRUE);
    GV *vargv = *(GV**)hv_fetch(su_stash, "EXPORT_FAIL", 11, TRUE);
    AV *varav;
    if(SvTYPE(vargv) != SVt_PVGV)
        gv_init(vargv, su_stash, "Scalar::Util", 12, TRUE);
    varav = GvAVn(vargv);
#endif
    if(SvTYPE(rmcgv) != SVt_PVGV)
        gv_init(rmcgv, lu_stash, "List::Util", 10, TRUE);
    rmcsv = GvSVn(rmcgv);
#ifndef SvWEAKREF
    av_push(varav, newSVpv("weaken",6));
    av_push(varav, newSVpv("isweak",6));
#endif
#ifndef SvVOK
    av_push(varav, newSVpv("isvstring",9));
#endif
#ifdef REAL_MULTICALL
    sv_setsv(rmcsv, &PL_sv_yes);
#else
    sv_setsv(rmcsv, &PL_sv_no);
#endif
}

#line 2284 "ListUtil.c"

    /* End of Initialisation Section */

#if PERL_VERSION_LE(5, 21, 5)
#  if PERL_VERSION_GE(5, 9, 0)
    if (PL_unitcheckav)
        call_list(PL_scopestack_ix, PL_unitcheckav);
#  endif
    XSRETURN_YES;
#else
    Perl_xs_boot_epilog(aTHX_ ax);
#endif
}

