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

#line 1 "XS.xs"
/**
 * List::MoreUtils::XS
 * Copyright 2004 - 2010 by by Tassilo von Parseval
 * Copyright 2013 - 2017 by Jens Rehsack
 *
 * All code added with 0.417 or later is licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * All code until 0.416 is licensed under the same terms as Perl itself,
 * either Perl version 5.8.4 or, at your option, any later version of
 * Perl 5 you may have available.
 */

#include "LMUconfig.h"

#ifdef HAVE_TIME_H
# include <time.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif

#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "multicall.h"

#define NEED_gv_fetchpvn_flags
#include "ppport.h"

#ifndef MAX
# define MAX(a,b) ((a)>(b)?(a):(b))
#endif
#ifndef MIN
# define MIN(a,b) (((a)<(b))?(a):(b))
#endif

#ifndef aTHX
#  define aTHX
#  define pTHX
#endif

#ifndef croak_xs_usage

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

static void
S_croak_xs_usage(pTHX_ 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);
    }
}

# define croak_xs_usage(a,b)     S_croak_xs_usage(aTHX_ a,b)
#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

/*
 * Perl < 5.18 had some kind of different SvIV_please_nomg
 */
#if PERL_VERSION_LE(5,18,0)
#undef SvIV_please_nomg
#  define SvIV_please_nomg(sv) \
        (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv)) \
            ? (SvIV_nomg(sv), SvIOK(sv))          \
            : SvIOK(sv))
#endif

#ifndef MUTABLE_GV
# define MUTABLE_GV(a) (GV *)(a)
#endif

#if !defined(HAS_BUILTIN_EXPECT) && defined(HAVE_BUILTIN_EXPECT)
# ifdef LIKELY
#  undef LIKELY
# endif
# ifdef UNLIKELY
#  undef UNLIKELY
# endif
# define LIKELY(x) __builtin_expect(!!(x), 1)
# define UNLIKELY(x) __builtin_expect(!!(x), 0)
#endif

#ifndef LIKELY
# define LIKELY(x) (x)
#endif
#ifndef UNLIKELY
# define UNLIKELY(x) (x)
#endif
#ifndef GV_NOTQUAL
# define GV_NOTQUAL 0
#endif

#ifdef _MSC_VER
# define inline __inline
#endif

#ifndef HAVE_SIZE_T
# if SIZEOF_PTR == SIZEOF_LONG_LONG
typedef unsigned long long size_t;
# elif SIZEOF_PTR == SIZEOF_LONG
typedef unsigned long size_t;
# elif SIZEOF_PTR == SIZEOF_INT
typedef unsigned int size_t;
# else
#  error "Can't determine type for size_t"
# endif
#endif

#ifndef HAVE_SSIZE_T
# if SIZEOF_PTR == SIZEOF_LONG_LONG
typedef signed long long ssize_t;
# elif SIZEOF_PTR == SIZEOF_LONG
typedef signed long ssize_t;
# elif SIZEOF_PTR == SIZEOF_INT
typedef signed int ssize_t;
# else
#  error "Can't determine type for ssize_t"
# endif
#endif


/* compare left and right SVs. Returns:
 * -1: <
 *  0: ==
 *  1: >
 *  2: left or right was a NaN
 */
static I32
LMUncmp(pTHX_ SV* left, SV * right)
{
    /* Fortunately it seems NaN isn't IOK */
    if(SvAMAGIC(left) || SvAMAGIC(right))
        return SvIVX(amagic_call(left, right, ncmp_amg, 0));

    if (SvIV_please_nomg(right) && SvIV_please_nomg(left))
    {
        if (!SvUOK(left))
        {
            const IV leftiv = SvIVX(left);
            if (!SvUOK(right))
            {
                /* ## IV <=> IV ## */
                const IV rightiv = SvIVX(right);
                return (leftiv > rightiv) - (leftiv < rightiv);
            }
            /* ## IV <=> UV ## */
            if (leftiv < 0)
                /* As (b) is a UV, it's >=0, so it must be < */
                return -1;

            return ((UV)leftiv > SvUVX(right)) - ((UV)leftiv < SvUVX(right));
        }

        if (SvUOK(right))
        {
            /* ## UV <=> UV ## */
            const UV leftuv = SvUVX(left);
            const UV rightuv = SvUVX(right);
            return (leftuv > rightuv) - (leftuv < rightuv);
        }

        /* ## UV <=> IV ## */
        if (SvIVX(right) < 0)
            /* As (a) is a UV, it's >=0, so it cannot be < */
            return 1;

        return (SvUVX(left) > SvUVX(right)) - (SvUVX(left) < SvUVX(right));
    }
    else
    {
#ifdef SvNV_nomg
        NV const rnv = SvNV_nomg(right);
        NV const lnv = SvNV_nomg(left);
#else
        NV const rnv = slu_sv_value(right);
        NV const lnv = slu_sv_value(left);
#endif

#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
        if (Perl_isnan(lnv) || Perl_isnan(rnv))
            return 2;
        return (lnv > rnv) - (lnv < rnv);
#else
        if (lnv < rnv)
            return -1;
        if (lnv > rnv)
            return 1;
        if (lnv == rnv)
            return 0;
        return 2;
#endif
    }
}

#define ncmp(left,right) LMUncmp(aTHX_ left,right)

#define FUNC_NAME GvNAME(GvEGV(ST(items)))

/* shameless stolen from PadWalker */
#ifndef PadARRAY
typedef AV PADNAMELIST;
typedef SV PADNAME;
# if PERL_VERSION_LE(5,8,0)
typedef AV PADLIST;
typedef AV PAD;
# endif
# define PadlistARRAY(pl)       ((PAD **)AvARRAY(pl))
# define PadlistMAX(pl)         av_len(pl)
# define PadlistNAMES(pl)       (*PadlistARRAY(pl))
# define PadnamelistARRAY(pnl)  ((PADNAME **)AvARRAY(pnl))
# define PadnamelistMAX(pnl)    av_len(pnl)
# define PadARRAY               AvARRAY
# define PadnameIsOUR(pn)       !!(SvFLAGS(pn) & SVpad_OUR)
# define PadnameOURSTASH(pn)    SvOURSTASH(pn)
# define PadnameOUTER(pn)       !!SvFAKE(pn)
# define PadnamePV(pn)          (SvPOKp(pn) ? SvPVX(pn) : NULL)
#endif

static int 
in_pad (pTHX_ SV *code)
{
    GV *gv;
    HV *stash;
    CV *cv = sv_2cv(code, &stash, &gv, 0);
    PADLIST *pad_list = (CvPADLIST(cv));
    PADNAMELIST *pad_namelist = PadlistNAMES(pad_list);
    int i;

    for (i=PadnamelistMAX(pad_namelist); i>=0; --i)
    {
        PADNAME* name_sv = PadnamelistARRAY(pad_namelist)[i];
        if (name_sv)
        {
            char *name_str = PadnamePV(name_sv);
            if (name_str) {

                /* perl < 5.6.0 does not yet have our */
#               ifdef SVpad_OUR
                if(PadnameIsOUR(name_sv))
                    continue;
#               endif

#if PERL_VERSION_LT(5,21,7)
                if (!SvOK(name_sv))
                    continue;
#endif

                if (strEQ(name_str, "$a") || strEQ(name_str, "$b"))
                    return 1;
            }
        }
    }
    return 0;
}

#define WARN_OFF \
    SV *oldwarn = PL_curcop->cop_warnings; \
    PL_curcop->cop_warnings = pWARN_NONE;

#define WARN_ON \
    PL_curcop->cop_warnings = oldwarn;

#define EACH_ARRAY_BODY \
        int i;                                                                          \
        arrayeach_args * args;                                                          \
        HV *stash = gv_stashpv("List::MoreUtils::XS_ea", TRUE);                         \
        CV *closure = newXS(NULL, XS_List__MoreUtils__XS__array_iterator, __FILE__);    \
                                                                                        \
        /* prototype */                                                                 \
        sv_setpv((SV*)closure, ";$");                                                   \
                                                                                        \
        New(0, args, 1, arrayeach_args);                                                \
        New(0, args->avs, items, AV*);                                                  \
        args->navs = items;                                                             \
        args->curidx = 0;                                                               \
                                                                                        \
        for (i = 0; i < items; i++) {                                                   \
            if(UNLIKELY(!arraylike(ST(i))))                                             \
               croak_xs_usage(cv,  "\\@;\\@\\@...");                                    \
            args->avs[i] = (AV*)SvRV(ST(i));                                            \
            SvREFCNT_inc(args->avs[i]);                                                 \
        }                                                                               \
                                                                                        \
        CvXSUBANY(closure).any_ptr = args;                                              \
        RETVAL = newRV_noinc((SV*)closure);                                             \
                                                                                        \
        /* in order to allow proper cleanup in DESTROY-handler */                       \
        sv_bless(RETVAL, stash)

#define LMUFECPY(a) (a)
#define dMULTICALLSVCV                          \
        HV *stash;                              \
        GV *gv;                                 \
        I32 gimme = G_SCALAR;                   \
        CV *mc_cv = sv_2cv(code, &stash, &gv, 0)


#define FOR_EACH(on_item)                       \
    if(!codelike(code))                         \
       croak_xs_usage(cv,  "code, ...");        \
                                                \
    if (items > 1) {                            \
        dMULTICALL;                             \
        dMULTICALLSVCV;                         \
        int i;                                  \
        SV **args = &PL_stack_base[ax];         \
        PUSH_MULTICALL(mc_cv);                  \
        SAVESPTR(GvSV(PL_defgv));               \
                                                \
        for(i = 1 ; i < items ; ++i) {          \
            GvSV(PL_defgv) = LMUFECPY(args[i]); \
            MULTICALL;                          \
            on_item;                            \
        }                                       \
        POP_MULTICALL;                          \
    }

#define TRUE_JUNCTION                             \
    FOR_EACH(if (SvTRUE(*PL_stack_sp)) ON_TRUE)   \
    else ON_EMPTY;

#define FALSE_JUNCTION                            \
    FOR_EACH(if (!SvTRUE(*PL_stack_sp)) ON_FALSE) \
    else ON_EMPTY;

#define ROF_EACH(on_item)                       \
    if(!codelike(code))                         \
       croak_xs_usage(cv,  "code, ...");        \
                                                \
    if (items > 1) {                            \
        dMULTICALL;                             \
        dMULTICALLSVCV;                         \
        int i;                                  \
        SV **args = &PL_stack_base[ax];         \
        PUSH_MULTICALL(mc_cv);                  \
        SAVESPTR(GvSV(PL_defgv));               \
                                                \
        for(i = items-1; i > 0; --i) {          \
            GvSV(PL_defgv) = LMUFECPY(args[i]); \
            MULTICALL;                          \
            on_item;                            \
        }                                       \
        POP_MULTICALL;                          \
    }

#define REDUCE_WITH(init)                            \
    dMULTICALL;                                      \
    dMULTICALLSVCV;                                  \
    SV *rc, **args = &PL_stack_base[ax];             \
    IV i;                                            \
                                                     \
    if(!codelike(code))                              \
       croak_xs_usage(cv,  "code, list, list");      \
                                                     \
    if (in_pad(aTHX_ code)) {                        \
        croak("Can't use lexical $a or $b in pairwise code block"); \
    }                                                \
                                                     \
    rc = (init);                                     \
    sv_2mortal(newRV_noinc(rc));                     \
                                                     \
    PUSH_MULTICALL(mc_cv);                           \
    SAVESPTR(GvSV(PL_defgv));                        \
                                                     \
    /* Following code is stolen on request of */     \
    /* Zefram from pp_sort.c of perl core 16ada23 */ \
    /* I have no idea why it's necessary and there */\
    /* is no reasonable documentation regarding */   \
    /* deal with localized $a/$b/$_ */               \
    SAVEGENERICSV(PL_firstgv);                       \
    SAVEGENERICSV(PL_secondgv);                      \
    PL_firstgv = MUTABLE_GV(SvREFCNT_inc(            \
        gv_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV)  \
    ));                                              \
    PL_secondgv = MUTABLE_GV(SvREFCNT_inc(           \
        gv_fetchpvs("b", GV_ADD|GV_NOTQUAL, SVt_PV)  \
    ));                                              \
    save_gp(PL_firstgv, 0); save_gp(PL_secondgv, 0); \
    GvINTRO_off(PL_firstgv);                         \
    GvINTRO_off(PL_secondgv);                        \
    SAVEGENERICSV(GvSV(PL_firstgv));                 \
    SvREFCNT_inc(GvSV(PL_firstgv));                  \
    SAVEGENERICSV(GvSV(PL_secondgv));                \
    SvREFCNT_inc(GvSV(PL_secondgv));                 \
                                                     \
    for (i = 1; i < items; ++i)                      \
    {                                                \
        SV *olda, *oldb;                             \
        sv_setiv(GvSV(PL_defgv), i-1);               \
                                                     \
        olda = GvSV(PL_firstgv);                     \
        oldb = GvSV(PL_secondgv);                    \
        GvSV(PL_firstgv) = SvREFCNT_inc_simple_NN(rc); \
        GvSV(PL_secondgv) = SvREFCNT_inc_simple_NN(args[i]); \
        SvREFCNT_dec(olda);                          \
        SvREFCNT_dec(oldb);                          \
        MULTICALL;                                   \
                                                     \
        SvSetMagicSV(rc, *PL_stack_sp);              \
    }                                                \
                                                     \
    POP_MULTICALL;                                   \
                                                     \
    EXTEND(SP, 1);                                   \
    ST(0) = sv_2mortal(newSVsv(rc));                 \
    XSRETURN(1)


#define COUNT_ARGS                                    \
    for (i = 0; i < items; i++) {                     \
        SvGETMAGIC(args[i]);                          \
        if(SvOK(args[i])) {                           \
            HE *he;                                   \
            SvSetSV_nosteal(tmp, args[i]);            \
            he = hv_fetch_ent(hv, tmp, 0, 0);         \
            if (NULL == he) {                         \
                args[count++] = args[i];              \
                hv_store_ent(hv, tmp, newSViv(1), 0); \
            }                                         \
            else {                                    \
                SV *v = HeVAL(he);                    \
                IV how_many = SvIVX(v);               \
                sv_setiv(v, ++how_many);              \
            }                                         \
        }                                             \
        else if(0 == seen_undef++) {                  \
            args[count++] = args[i];                  \
        }                                             \
    }

#define COUNT_ARGS_MAX                                    \
    do {                                                  \
        for (i = 0; i < items; i++) {                     \
            SvGETMAGIC(args[i]);                          \
            if(SvOK(args[i])) {                           \
                HE *he;                                   \
                SvSetSV_nosteal(tmp, args[i]);            \
                he = hv_fetch_ent(hv, tmp, 0, 0);         \
                if (NULL == he) {                         \
                    args[count++] = args[i];              \
                    hv_store_ent(hv, tmp, newSViv(1), 0); \
                }                                         \
                else {                                    \
                    SV *v = HeVAL(he);                    \
                    IV how_many = SvIVX(v);               \
                    if(UNLIKELY(max < ++how_many))        \
                        max = how_many;                   \
                    sv_setiv(v, how_many);                \
                }                                         \
            }                                             \
            else if(0 == seen_undef++) {                  \
                args[count++] = args[i];                  \
            }                                             \
        }                                                 \
        if(UNLIKELY(max < seen_undef)) max = seen_undef;  \
    } while(0)


/* need this one for array_each() */
typedef struct
{
    AV **avs;       /* arrays over which to iterate in parallel */
    int navs;       /* number of arrays */
    int curidx;     /* the current index of the iterator */
} arrayeach_args;

/* used for natatime */
typedef struct
{
    SV **svs;
    int nsvs;
    int curidx;
    int natatime;
} natatime_args;

static void
insert_after (pTHX_ int idx, SV *what, AV *av)
{
    int i, len;
    av_extend(av, (len = av_len(av) + 1));

    for (i = len; i > idx+1; i--)
    {
        SV **sv = av_fetch(av, i-1, FALSE);
        SvREFCNT_inc(*sv);
        av_store(av, i, *sv);
    }

    if (!av_store(av, idx+1, what))
        SvREFCNT_dec(what);
}

static int
is_like(pTHX_ SV *sv, const char *like)
{
    int likely = 0;
    if( sv_isobject( sv ) )
    {
        dSP;
        int count;

        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        XPUSHs( sv_2mortal( newSVsv( sv ) ) );
        XPUSHs( sv_2mortal( newSVpv( like, strlen(like) ) ) );
        PUTBACK;

        if( ( count = call_pv("overload::Method", G_SCALAR) ) )
        {
            I32 ax;
            SPAGAIN;

            SP -= count;
            ax = (SP - PL_stack_base) + 1;
            if( SvTRUE(ST(0)) )
                ++likely;
        }

        FREETMPS;
        LEAVE;
    }

    return likely;
}

static int
is_array(SV *sv)
{
    return SvROK(sv) && ( SVt_PVAV == SvTYPE(SvRV(sv) ) );
}

static int
LMUcodelike(pTHX_ SV *code)
{
    SvGETMAGIC(code);
    return SvROK(code) && ( ( SVt_PVCV == SvTYPE(SvRV(code)) ) || ( is_like(aTHX_ code, "&{}" ) ) );
}

#define codelike(code) LMUcodelike(aTHX_ code)

static int
LMUarraylike(pTHX_ SV *array)
{
    SvGETMAGIC(array);
    return is_array(array) || is_like(aTHX_ array, "@{}" );
}

#define arraylike(array) LMUarraylike(aTHX_ array)

static void
LMUav2flat(pTHX_ AV *tgt, AV *args)
{
    I32 k = 0, j = av_len(args) + 1;

    av_extend(tgt, AvFILLp(tgt) + j);

    while( --j >= 0 )
    {
        SV *sv = *av_fetch(args, k++, FALSE);
        if(arraylike(sv))
        {
            AV *av = (AV *)SvRV(sv);
            LMUav2flat(aTHX_ tgt, av);
        }
        else
        {
            // av_push(tgt, newSVsv(sv));
            av_push(tgt, SvREFCNT_inc(sv));
        }
    }
}

/*-
 * Copyright (c) 1992, 1993
 *      The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * FreeBSD's Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
 * Modified for using Perl Sub (no XSUB) via MULTICALL and all values are SV **
 */
static inline void
swapfunc(SV **a, SV **b, size_t n)
{
    SV **pa = a;
    SV **pb = b;
    while(n-- > 0)
    {
        SV *t = *pa;
        *pa++ = *pb;
        *pb++ = t;
    }
}

#define swap(a, b)    \
    do {              \
        SV *t = *(a); \
        *(a) = *(b);  \
        *(b) = t;     \
    } while(0)

#define vecswap(a, b, n)  \
    if ((n) > 0) swapfunc(a, b, n)

#if HAVE_FEATURE_STATEMENT_EXPRESSION
# define CMP(x, y) ({ \
        GvSV(PL_firstgv) = *(x); \
        GvSV(PL_secondgv) = *(y); \
        MULTICALL; \
        SvIV(*PL_stack_sp); \
    })
#else
static inline int _cmpsvs(pTHX_ SV *x, SV *y, OP *multicall_cop )
{
    GvSV(PL_firstgv) = x;
    GvSV(PL_secondgv) = y;
    MULTICALL;
    return SvIV(*PL_stack_sp);
}
# define CMP(x, y) _cmpsvs(aTHX_ *(x), *(y), multicall_cop)
#endif

#define MED3(a, b, c) ( \
    CMP(a, b) < 0 ? \
       (CMP(b, c) < 0 ? b : (CMP(a, c) < 0 ? c : a )) \
      :(CMP(b, c) > 0 ? b : (CMP(a, c) < 0 ? a : c )) \
)

static void
bsd_qsort_r(pTHX_ SV **ary, size_t nelem, OP *multicall_cop)
{
    SV **pa, **pb, **pc, **pd, **pl, **pm, **pn;
    size_t d1, d2;
    int cmp_result, swap_cnt = 0;

loop:
    if (nelem < 7)
    {
        for (pm = ary + 1; pm < ary + nelem; ++pm)
            for (pl = pm; 
                 pl > ary && CMP(pl - 1, pl) > 0;
                 pl -= 1)
                swap(pl, pl - 1);

        return;
    }

    pm = ary + (nelem / 2);
    if (nelem > 7)
    {
        pl = ary;
        pn = ary + (nelem - 1);
        if (nelem > 40)
        {
            size_t d = (nelem / 8);

            pl = MED3(pl, pl + d, pl + 2 * d);
            pm = MED3(pm - d, pm, pm + d);
            pn = MED3(pn - 2 * d, pn - d, pn);
        }
        pm = MED3(pl, pm, pn);
    }
    swap(ary, pm);
    pa = pb = ary + 1;

    pc = pd = ary + (nelem - 1);
    for (;;)
    {
        while (pb <= pc && (cmp_result = CMP(pb, ary)) <= 0)
        {
            if (cmp_result == 0)
            {
                swap_cnt = 1;
                swap(pa, pb);
                pa += 1;
            }

            pb += 1;
        }

        while (pb <= pc && (cmp_result = CMP(pc, ary)) >= 0)
        {
            if (cmp_result == 0)
            {
                swap_cnt = 1;
                swap(pc, pd);
                pd -= 1;
            }
            pc -= 1;
        }

        if (pb > pc)
            break;

        swap(pb, pc);
        swap_cnt = 1;
        pb += 1;
        pc -= 1;
    }
    if (swap_cnt == 0)
    {  /* Switch to insertion sort */
        for (pm = ary + 1; pm < ary + nelem; pm += 1)
            for (pl = pm; 
                 pl > ary && CMP(pl - 1, pl) > 0;
                 pl -= 1)
                swap(pl, pl - 1);
        return;
    }

    pn = ary + nelem;
    d1 = MIN(pa - ary, pb - pa);
    vecswap(ary, pb - d1, d1);
    d1 = MIN(pd - pc, pn - pd - 1);
    vecswap(pb, pn - d1, d1);

    d1 = pb - pa;
    d2 = pd - pc;
    if (d1 <= d2)
    {
        /* Recurse on left partition, then iterate on right partition */
        if (d1 > 1)
            bsd_qsort_r(aTHX_ ary, d1, multicall_cop);

        if (d2 > 1)
        {
            /* Iterate rather than recurse to save stack space */
            /* qsort(pn - d2, d2, multicall_cop); */
            ary = pn - d2;
            nelem = d2;
            goto loop;
        }
    }
    else
    {
        /* Recurse on right partition, then iterate on left partition */
        if (d2 > 1)
            bsd_qsort_r(aTHX_ pn - d2, d2, multicall_cop);

        if (d1 > 1)
        {
            /* Iterate rather than recurse to save stack space */
            /* qsort(ary, d1, multicall_cop); */
            nelem = d1;
            goto loop;
        }
    }
}

/* lower_bound algorithm from STL - see http://en.cppreference.com/w/cpp/algorithm/lower_bound */
#define LOWER_BOUND(at)               \
    while (count > 0) {               \
        ssize_t step = count / 2;     \
        ssize_t it = first + step;    \
                                      \
        GvSV(PL_defgv) = at;          \
        MULTICALL;                    \
        cmprc = SvIV(*PL_stack_sp);   \
        if (cmprc < 0) {              \
            first = ++it;             \
            count -= step + 1;        \
        }                             \
        else                          \
            count = step;             \
    }

#define LOWER_BOUND_QUICK(at)         \
    while (count > 0) {               \
        ssize_t step = count / 2;     \
        ssize_t it = first + step;    \
                                      \
        GvSV(PL_defgv) = at;          \
        MULTICALL;                    \
        cmprc = SvIV(*PL_stack_sp);   \
        if(UNLIKELY(0 == cmprc)) {    \
            first = it;               \
            break;                    \
        }                             \
        if (cmprc < 0) {              \
            first = ++it;             \
            count -= step + 1;        \
        }                             \
        else                          \
            count = step;             \
    }

/* upper_bound algorithm from STL - see http://en.cppreference.com/w/cpp/algorithm/upper_bound */
#define UPPER_BOUND(at)                 \
    while (count > 0) {                 \
        ssize_t step = count / 2;       \
        ssize_t it = first + step;      \
                                        \
        GvSV(PL_defgv) = at;            \
        MULTICALL;                      \
        cmprc = SvIV(*PL_stack_sp); \
        if (cmprc <= 0) {               \
            first = ++it;               \
            count -= step + 1;          \
        }                               \
        else                            \
            count = step;               \
    }


#line 872 "XS.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 1016 "XS.c"

XS_EUPXS(XS_List__MoreUtils__XS_ea_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_ea_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
#line 868 "XS.xs"
{
    int i;
    CV *code = (CV*)SvRV(sv);
    arrayeach_args *args = (arrayeach_args *)(CvXSUBANY(code).any_ptr);
    if (args)
    {
        for (i = 0; i < args->navs; ++i)
            SvREFCNT_dec(args->avs[i]);

        Safefree(args->avs);
        Safefree(args);
        CvXSUBANY(code).any_ptr = NULL;
    }
}
#line 1042 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_na_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_na_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "sv");
    {
	SV *	sv = ST(0)
;
#line 890 "XS.xs"
{
    int i;
    CV *code = (CV*)SvRV(sv);
    natatime_args *args = (natatime_args *)(CvXSUBANY(code).any_ptr);
    if (args)
    {
        for (i = 0; i < args->nsvs; ++i)
            SvREFCNT_dec(args->svs[i]);

        Safefree(args->svs);
        Safefree(args);
        CvXSUBANY(code).any_ptr = NULL;
    }
}
#line 1072 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_any); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_any)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 912 "XS.xs"
{
#define ON_TRUE { POP_MULTICALL; XSRETURN_YES; }
#define ON_EMPTY XSRETURN_NO
    TRUE_JUNCTION;
    XSRETURN_NO;
#undef ON_EMPTY
#undef ON_TRUE
}
#line 1096 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_all); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_all)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 926 "XS.xs"
{
#define ON_FALSE { POP_MULTICALL; XSRETURN_NO; }
#define ON_EMPTY XSRETURN_YES
    FALSE_JUNCTION;
    XSRETURN_YES;
#undef ON_EMPTY
#undef ON_FALSE
}
#line 1120 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_none); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_none)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 941 "XS.xs"
{
#define ON_TRUE { POP_MULTICALL; XSRETURN_NO; }
#define ON_EMPTY XSRETURN_YES
    TRUE_JUNCTION;
    XSRETURN_YES;
#undef ON_EMPTY
#undef ON_TRUE
}
#line 1144 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_notall); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_notall)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 955 "XS.xs"
{
#define ON_FALSE { POP_MULTICALL; XSRETURN_YES; }
#define ON_EMPTY XSRETURN_NO
    FALSE_JUNCTION;
    XSRETURN_NO;
#undef ON_EMPTY
#undef ON_FALSE
}
#line 1168 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_one); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_one)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 969 "XS.xs"
{
    int found = 0;
#define ON_TRUE { if (found++) { POP_MULTICALL; XSRETURN_NO; }; }
#define ON_EMPTY XSRETURN_NO
    TRUE_JUNCTION;
    if (found)
        XSRETURN_YES;
    XSRETURN_NO;
#undef ON_EMPTY
#undef ON_TRUE
}
#line 1195 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_any_u); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_any_u)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 986 "XS.xs"
{
#define ON_TRUE { POP_MULTICALL; XSRETURN_YES; }
#define ON_EMPTY XSRETURN_UNDEF
    TRUE_JUNCTION;
    XSRETURN_NO;
#undef ON_EMPTY
#undef ON_TRUE
}
#line 1219 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_all_u); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_all_u)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1000 "XS.xs"
{
#define ON_FALSE { POP_MULTICALL; XSRETURN_NO; }
#define ON_EMPTY XSRETURN_UNDEF
    FALSE_JUNCTION;
    XSRETURN_YES;
#undef ON_EMPTY
#undef ON_FALSE
}
#line 1243 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_none_u); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_none_u)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1015 "XS.xs"
{
#define ON_TRUE { POP_MULTICALL; XSRETURN_NO; }
#define ON_EMPTY XSRETURN_UNDEF
    TRUE_JUNCTION;
    XSRETURN_YES;
#undef ON_EMPTY
#undef ON_TRUE
}
#line 1267 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_notall_u); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_notall_u)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1029 "XS.xs"
{
#define ON_FALSE { POP_MULTICALL; XSRETURN_YES; }
#define ON_EMPTY XSRETURN_UNDEF
    FALSE_JUNCTION;
    XSRETURN_NO;
#undef ON_EMPTY
#undef ON_FALSE
}
#line 1291 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_one_u); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_one_u)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1043 "XS.xs"
{
    int found = 0;
#define ON_TRUE { if (found++) { POP_MULTICALL; XSRETURN_NO; }; }
#define ON_EMPTY XSRETURN_UNDEF
    TRUE_JUNCTION;
    if (found)
        XSRETURN_YES;
    XSRETURN_NO;
#undef ON_EMPTY
#undef ON_TRUE
}
#line 1318 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_reduce_u); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_reduce_u)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1060 "XS.xs"
{
    REDUCE_WITH(newSVsv(&PL_sv_undef));
}
#line 1337 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_reduce_0); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_reduce_0)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1069 "XS.xs"
{
    REDUCE_WITH(newSViv(0));
}
#line 1356 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_reduce_1); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_reduce_1)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1078 "XS.xs"
{
    REDUCE_WITH(newSViv(1));
}
#line 1375 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_true); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_true)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	int	RETVAL;
	dXSTARG;
#line 1087 "XS.xs"
{
    I32 count = 0;
    FOR_EACH(if (SvTRUE(*PL_stack_sp)) count++);
    RETVAL = count;
}
#line 1398 "XS.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_false); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_false)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	int	RETVAL;
	dXSTARG;
#line 1100 "XS.xs"
{
    I32 count = 0;
    FOR_EACH(if (!SvTRUE(*PL_stack_sp)) count++);
    RETVAL = count;
}
#line 1422 "XS.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_firstidx); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_firstidx)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	int	RETVAL;
	dXSTARG;
#line 1113 "XS.xs"
{
    RETVAL = -1;
    FOR_EACH(if (SvTRUE(*PL_stack_sp)) { RETVAL = i-1; break; });
}
#line 1445 "XS.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_firstval); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_firstval)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	SV *	RETVAL;
#line 1125 "XS.xs"
{
    RETVAL = &PL_sv_undef;
    FOR_EACH(if (SvTRUE(*PL_stack_sp)) { SvREFCNT_inc(RETVAL = args[i]); break; });
}
#line 1467 "XS.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_firstres); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_firstres)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	SV *	RETVAL;
#line 1137 "XS.xs"
{
    RETVAL = &PL_sv_undef;
    FOR_EACH(if (SvTRUE(*PL_stack_sp)) { SvREFCNT_inc(RETVAL = *PL_stack_sp); break; });
}
#line 1490 "XS.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_onlyidx); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_onlyidx)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	int	RETVAL;
	dXSTARG;
#line 1149 "XS.xs"
{
    int found = 0;
    RETVAL = -1;
    FOR_EACH(if (SvTRUE(*PL_stack_sp)) { if (found++) {RETVAL = -1; break;} RETVAL = i-1; });
}
#line 1515 "XS.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_onlyval); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_onlyval)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	SV *	RETVAL;
#line 1162 "XS.xs"
{
    int found = 0;
    RETVAL = &PL_sv_undef;
    FOR_EACH(if (SvTRUE(*PL_stack_sp)) { if (found++) {SvREFCNT_dec(RETVAL); RETVAL = &PL_sv_undef; break;} SvREFCNT_inc(RETVAL = args[i]); });
}
#line 1538 "XS.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_onlyres); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_onlyres)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	SV *	RETVAL;
#line 1175 "XS.xs"
{
    int found = 0;
    RETVAL = &PL_sv_undef;
    FOR_EACH(if (SvTRUE(*PL_stack_sp)) { if (found++) {SvREFCNT_dec(RETVAL); RETVAL = &PL_sv_undef; break;}SvREFCNT_inc(RETVAL = *PL_stack_sp); });
}
#line 1562 "XS.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_lastidx); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_lastidx)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	int	RETVAL;
	dXSTARG;
#line 1188 "XS.xs"
{
    RETVAL = -1;
    ROF_EACH(if (SvTRUE(*PL_stack_sp)){RETVAL = i-1;break;})
}
#line 1586 "XS.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_lastval); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_lastval)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	SV *	RETVAL;
#line 1200 "XS.xs"
{
    RETVAL = &PL_sv_undef;
    ROF_EACH(if (SvTRUE(*PL_stack_sp)) { /* see comment in indexes() */ SvREFCNT_inc(RETVAL = args[i]); break; });
}
#line 1608 "XS.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_lastres); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_lastres)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	SV *	RETVAL;
#line 1212 "XS.xs"
{
    RETVAL = &PL_sv_undef;
    ROF_EACH(if (SvTRUE(*PL_stack_sp)) { SvREFCNT_inc(RETVAL = *PL_stack_sp); break; });
}
#line 1631 "XS.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_insert_after); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_insert_after)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "code, val, avref");
    {
	SV *	code = ST(0)
;
	SV *	val = ST(1)
;
	SV *	avref = ST(2)
;
	int	RETVAL;
	dXSTARG;
#line 1226 "XS.xs"
{
    dMULTICALL;
    dMULTICALLSVCV;
    int i;
    int len;
    AV *av;

    if(!codelike(code))
       croak_xs_usage(cv,  "code, val, \\@area_of_operation");
    if(!arraylike(avref))
       croak_xs_usage(cv,  "code, val, \\@area_of_operation");

    av = (AV*)SvRV(avref);
    len = av_len(av);
    RETVAL = 0;

    PUSH_MULTICALL(mc_cv);
    SAVESPTR(GvSV(PL_defgv));

    for (i = 0; i <= len ; ++i)
    {
        GvSV(PL_defgv) = *av_fetch(av, i, FALSE);
        MULTICALL;
        if (SvTRUE(*PL_stack_sp))
        {
            RETVAL = 1;
            break;
        }
    }

    POP_MULTICALL;

    if (RETVAL)
    {
        SvREFCNT_inc(val);
        insert_after(aTHX_ i, val, av);
    }
}
#line 1693 "XS.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_insert_after_string); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_insert_after_string)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "string, val, avref");
    {
	SV *	string = ST(0)
;
	SV *	val = ST(1)
;
	SV *	avref = ST(2)
;
	int	RETVAL;
	dXSTARG;
#line 1274 "XS.xs"
{
    int i, len;
    AV *av;
    RETVAL = 0;

    if(!arraylike(avref))
       croak_xs_usage(cv,  "string, val, \\@area_of_operation");

    av = (AV*)SvRV(avref);
    len = av_len(av);

    for (i = 0; i <= len ; i++)
    {
        SV **sv = av_fetch(av, i, FALSE);
        if((SvFLAGS(*sv) & (SVf_OK & ~SVf_ROK)) && (0 == sv_cmp_locale(string, *sv)))
        {
            RETVAL = 1;
            break;
        }
    }

    if (RETVAL)
    {
        SvREFCNT_inc(val);
        insert_after(aTHX_ i, val, av);
    }
}
#line 1743 "XS.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_apply); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_apply)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1309 "XS.xs"
{
    if(!codelike(code))
       croak_xs_usage(cv,  "code, ...");

    if (items > 1) {
        dMULTICALL;
        dMULTICALLSVCV;
        int i;
        SV **args = &PL_stack_base[ax];
        AV *rc = newAV();

        sv_2mortal(newRV_noinc((SV*)rc));
        av_extend(rc, items-1);

        PUSH_MULTICALL(mc_cv);
        SAVESPTR(GvSV(PL_defgv));

        for(i = 1 ; i < items ; ++i) {
            av_push(rc, newSVsv(args[i]));
            GvSV(PL_defgv) = AvARRAY(rc)[AvFILLp(rc)];
            MULTICALL;
        }
        POP_MULTICALL;

        for(i = items - 1; i > 0; --i)
        {
            ST(i-1) = sv_2mortal(AvARRAY(rc)[i-1]);
            AvARRAY(rc)[i-1] = NULL;
        }

        AvFILLp(rc) = -1;
    }

    XSRETURN(items-1);
}
#line 1795 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_after); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_after)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1350 "XS.xs"
{
    int k = items, j;
    FOR_EACH(if (SvTRUE(*PL_stack_sp)) {k=i; break;});
    for (j = k + 1; j < items; ++j)
        ST(j-k-1) = ST(j);

    j = items-k-1;
    XSRETURN(j > 0 ? j : 0);
}
#line 1820 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_after_incl); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_after_incl)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1365 "XS.xs"
{
    int k = items, j;
    FOR_EACH(if (SvTRUE(*PL_stack_sp)) {k=i; break;});
    for (j = k; j < items; j++)
        ST(j-k) = ST(j);

    XSRETURN(items-k);
}
#line 1844 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_before); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_before)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1379 "XS.xs"
{
    int k = items - 1;
    FOR_EACH(if (SvTRUE(*PL_stack_sp)) {k=i-1; break;}; args[i-1] = args[i];);

    XSRETURN(k);
}
#line 1866 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_before_incl); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_before_incl)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1391 "XS.xs"
{
    int k = items - 1;
    FOR_EACH(args[i-1] = args[i]; if (SvTRUE(*PL_stack_sp)) {k=i; break;});

    XSRETURN(k);
}
#line 1888 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS_indexes); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_indexes)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 1403 "XS.xs"
{
    if(!codelike(code))
       croak_xs_usage(cv,  "code, ...");

    if (items > 1) {
        dMULTICALL;
        dMULTICALLSVCV;
        int i;
        SV **args = &PL_stack_base[ax];
        AV *rc = newAV();

        sv_2mortal(newRV_noinc((SV*)rc));
        av_extend(rc, items-1);

        PUSH_MULTICALL(mc_cv);
        SAVESPTR(GvSV(PL_defgv));

        for(i = 1 ; i < items ; ++i)
        {
            GvSV(PL_defgv) = args[i];
            MULTICALL;
            if (SvTRUE(*PL_stack_sp))
                av_push(rc, newSViv(i-1));
        }
        POP_MULTICALL;

        for(i = av_len(rc); i >= 0; --i)
        {
            ST(i) = sv_2mortal(AvARRAY(rc)[i]);
            AvARRAY(rc)[i] = NULL;
        }

        i = AvFILLp(rc) + 1;
        AvFILLp(rc) = -1;

        XSRETURN(i);
    }

    XSRETURN_EMPTY;
}
#line 1944 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS__array_iterator); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS__array_iterator)
{
    dVAR; dXSARGS;
    if (items < 0 || items > 1)
       croak_xs_usage(cv,  "method = \"\"");
    {
	const char *	method;

	if (items < 1)
	    method = "";
	else {
	    method = (const char *)SvPV_nolen(ST(0))
;
	}
#line 1449 "XS.xs"
{
    int i;
    int exhausted = 1;

    /* 'cv' is the hidden argument with which XS_List__MoreUtils__array_iterator (this XSUB)
     * is called. The closure_arg struct is stored in this CV. */

    arrayeach_args *args = (arrayeach_args *)(CvXSUBANY(cv).any_ptr);

    if (strEQ(method, "index"))
    {
        EXTEND(SP, 1);
        ST(0) = args->curidx > 0 ? sv_2mortal(newSViv(args->curidx-1)) : &PL_sv_undef;
        XSRETURN(1);
    }

    EXTEND(SP, args->navs);

    for (i = 0; i < args->navs; i++)
    {
        AV *av = args->avs[i];
        if (args->curidx <= av_len(av))
        {
            ST(i) = sv_2mortal(newSVsv(*av_fetch(av, args->curidx, FALSE)));
            exhausted = 0;
            continue;
        }
        ST(i) = &PL_sv_undef;
    }

    if (exhausted)
        XSRETURN_EMPTY;

    args->curidx++;
    XSRETURN(args->navs);
}
#line 2002 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_each_array); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_each_array)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
	SV *	RETVAL;
#line 1490 "XS.xs"
{
    EACH_ARRAY_BODY;
}
#line 2019 "XS.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_each_arrayref); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_each_arrayref)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
	SV *	RETVAL;
#line 1499 "XS.xs"
{
    EACH_ARRAY_BODY;
}
#line 2038 "XS.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_pairwise); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_pairwise)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "code, list1, list2");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	SV *	code = ST(0)
;
	AV *	list1;
	AV *	list2;

	STMT_START {
		SV* const xsub_tmp_sv = ST(1);
		SvGETMAGIC(xsub_tmp_sv);
		if (SvROK(xsub_tmp_sv) && SvTYPE(SvRV(xsub_tmp_sv)) == SVt_PVAV){
		    list1 = (AV*)SvRV(xsub_tmp_sv);
		}
		else{
		    Perl_croak_nocontext("%s: %s is not an ARRAY reference",
				"List::MoreUtils::XS::pairwise",
				"list1");
		}
	} STMT_END
;

	STMT_START {
		SV* const xsub_tmp_sv = ST(2);
		SvGETMAGIC(xsub_tmp_sv);
		if (SvROK(xsub_tmp_sv) && SvTYPE(SvRV(xsub_tmp_sv)) == SVt_PVAV){
		    list2 = (AV*)SvRV(xsub_tmp_sv);
		}
		else{
		    Perl_croak_nocontext("%s: %s is not an ARRAY reference",
				"List::MoreUtils::XS::pairwise",
				"list2");
		}
	} STMT_END
;
#line 1512 "XS.xs"
{
    dMULTICALL;
    dMULTICALLSVCV;
    int i, maxitems;
    AV *rc = newAV();
    sv_2mortal(newRV_noinc((SV*)rc));

    if(!codelike(code))
       croak_xs_usage(cv,  "code, list, list");

    if (in_pad(aTHX_ code)) {
        croak("Can't use lexical $a or $b in pairwise code block");
    }

    /* deref AV's for convenience and
     * get maximum items */
    maxitems = MAX(av_len(list1),av_len(list2))+1;
    av_extend(rc, maxitems);

    gimme = G_ARRAY;
    PUSH_MULTICALL(mc_cv);

    if (!PL_firstgv || !PL_secondgv)
    {
        SAVESPTR(PL_firstgv);
        SAVESPTR(PL_secondgv);
        PL_firstgv = gv_fetchpv("a", TRUE, SVt_PV);
        PL_secondgv = gv_fetchpv("b", TRUE, SVt_PV);
    }

    for (i = 0; i < maxitems; ++i)
    {
        SV **j;
        SV **svp = av_fetch(list1, i, FALSE);
        GvSV(PL_firstgv) = svp ? *svp : &PL_sv_undef;
        svp = av_fetch(list2, i, FALSE);
        GvSV(PL_secondgv) = svp ? *svp : &PL_sv_undef;
        MULTICALL;

        for (j = PL_stack_base+1; j <= PL_stack_sp; ++j)
            av_push(rc, newSVsv(*j));
    }

    POP_MULTICALL;

    SPAGAIN;
    EXTEND(SP, AvFILLp(rc) + 1);

    for(i = AvFILLp(rc); i >= 0; --i)
    {
        ST(i) = sv_2mortal(AvARRAY(rc)[i]);
        AvARRAY(rc)[i] = NULL;
    }

    i = AvFILLp(rc) + 1;
    AvFILLp(rc) = -1;

    XSRETURN(i);
}
#line 2147 "XS.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_List__MoreUtils__XS__natatime_iterator); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS__natatime_iterator)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
#line 1576 "XS.xs"
{
    int i, nret;

    /* 'cv' is the hidden argument with which XS_List__MoreUtils__array_iterator (this XSUB)
     * is called. The closure_arg struct is stored in this CV. */

    natatime_args *args = (natatime_args*)CvXSUBANY(cv).any_ptr;
    nret = args->natatime;

    EXTEND(SP, nret);

    for (i = 0; i < args->natatime; i++)
        if (args->curidx < args->nsvs)
            ST(i) = sv_2mortal(newSVsv(args->svs[args->curidx++]));
        else
            XSRETURN(i);

    XSRETURN(nret);
}
#line 2181 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_natatime); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_natatime)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "n, ...");
    {
	int	n = (int)SvIV(ST(0))
;
	SV *	RETVAL;
#line 1601 "XS.xs"
{
    int i;
    natatime_args *args;
    HV *stash = gv_stashpv("List::MoreUtils::XS_na", TRUE);

    CV *closure = newXS(NULL, XS_List__MoreUtils__XS__natatime_iterator, __FILE__);

    /* must NOT set prototype on iterator:
     * otherwise one cannot write: &$it */
    /* !! sv_setpv((SV*)closure, ""); !! */

    New(0, args, 1, natatime_args);
    New(0, args->svs, items-1, SV*);
    args->nsvs = items-1;
    args->curidx = 0;
    args->natatime = n;

    for (i = 1; i < items; i++)
        SvREFCNT_inc(args->svs[i-1] = ST(i));

    CvXSUBANY(closure).any_ptr = args;
    RETVAL = newRV_noinc((SV*)closure);

    /* in order to allow proper cleanup in DESTROY-handler */
    sv_bless(RETVAL, stash);
}
#line 2224 "XS.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_arrayify); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_arrayify)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 1633 "XS.xs"
{
    I32 i;
    AV *rc = newAV();
    AV *args = av_make(items, &PL_stack_base[ax]);
    sv_2mortal(newRV_noinc((SV *)rc));
    sv_2mortal(newRV_noinc((SV *)args));

    LMUav2flat(aTHX_ rc, args);

    i = AvFILLp(rc);
    EXTEND(SP, i+1);
    for(; i >= 0; --i)
    {
        ST(i) = sv_2mortal(AvARRAY(rc)[i]);
        AvARRAY(rc)[i] = NULL;
    }

    i = AvFILLp(rc) + 1;
    AvFILLp(rc) = -1;

    XSRETURN(i);
}
#line 2261 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_mesh); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_mesh)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 1660 "XS.xs"
{
    int i, j, maxidx = -1;
    AV **avs;
    New(0, avs, items, AV*);

    for (i = 0; i < items; i++)
    {
        if(!arraylike(ST(i)))
           croak_xs_usage(cv,  "\\@\\@;\\@...");

        avs[i] = (AV*)SvRV(ST(i));
        if (av_len(avs[i]) > maxidx)
            maxidx = av_len(avs[i]);
    }

    EXTEND(SP, items * (maxidx + 1));
    for (i = 0; i <= maxidx; i++)
        for (j = 0; j < items; j++)
        {
            SV **svp = av_fetch(avs[j], i, FALSE);
            ST(i*items + j) = svp ? sv_2mortal(newSVsv(*svp)) : &PL_sv_undef;
        }

    Safefree(avs);
    XSRETURN(items * (maxidx + 1));
}
#line 2300 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_zip6); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_zip6)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 1691 "XS.xs"
{
    int i, j, maxidx = -1;
    AV **src;
    New(0, src, items, AV*);

    for (i = 0; i < items; i++)
    {
        if(!arraylike(ST(i)))
           croak_xs_usage(cv,  "\\@\\@;\\@...");

        src[i] = (AV*)SvRV(ST(i));
        if (av_len(src[i]) > maxidx)
            maxidx = av_len(src[i]);
    }

    EXTEND(SP, maxidx + 1);
    for (i = 0; i <= maxidx; i++)
    {
        AV *av;
        ST(i) = sv_2mortal(newRV_noinc((SV *)(av = newAV())));

        for (j = 0; j < items; j++)
        {
            SV **svp = av_fetch(src[j], i, FALSE);
            av_push(av, newSVsv( svp ? *svp : &PL_sv_undef ));
        }
    }

    Safefree(src);
    XSRETURN(maxidx + 1);
}
#line 2344 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_listcmp); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_listcmp)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 1727 "XS.xs"
{
    I32 i;
    SV *tmp = sv_newmortal();
    HV *rc = newHV();
    SV *ret = sv_2mortal (newRV_noinc((SV *)rc));
    HV *distinct = newHV();
    sv_2mortal(newRV_noinc((SV*)distinct));

    for (i = 0; i < items; i++)
    {
        AV *av;
        I32 j;

        if(!arraylike(ST(i)))
           croak_xs_usage(cv,  "\\@\\@;\\@...");
        av = (AV*)SvRV(ST(i));

        hv_clear(distinct);

        for(j = 0; j <= av_len(av); ++j)
        {
            SV **sv = av_fetch(av, j, FALSE);
            AV *store;

            if(NULL == sv)
                continue;

            SvGETMAGIC(*sv);
            if(SvOK(*sv))
            {
                SvSetSV_nosteal(tmp, *sv);
                if(hv_exists_ent(distinct, tmp, 0))
                    continue;

                hv_store_ent(distinct, tmp, &PL_sv_yes, 0);

                if(hv_exists_ent(rc, *sv, 0))
                {
                    HE *he = hv_fetch_ent(rc, *sv, 1, 0);
                    store = (AV*)SvRV(HeVAL(he));
                    av_push(store, newSViv(i));
                }
                else
                {
                    store = newAV();
                    av_push(store, newSViv(i));
                    hv_store_ent(rc, tmp, newRV_noinc((SV *)store), 0);
                }
            }
        }
    }

    i = HvUSEDKEYS(rc);
    EXTEND(SP, i * 2);

    i = 0;
    hv_iterinit(rc);
    for(;;)
    {
        HE *he = hv_iternext(rc);
        SV *key, *val;
        if(NULL == he)
            break;

        if(UNLIKELY(( NULL == (key = HeSVKEY_force(he)) ) || ( NULL == (val = HeVAL(he)) )))
            continue;

        ST(i++) = key;
        ST(i++) = val;
    }

    XSRETURN(i);
}
#line 2430 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_uniq); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_uniq)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 1805 "XS.xs"
{
    I32 i;
    IV count = 0, seen_undef = 0;
    HV *hv = newHV();
    SV **args = &PL_stack_base[ax];
    SV *tmp = sv_newmortal();
    sv_2mortal(newRV_noinc((SV*)hv));

    /* don't build return list in scalar context */
    if (GIMME_V == G_SCALAR)
    {
        for (i = 0; i < items; i++)
        {
            SvGETMAGIC(args[i]);
            if(SvOK(args[i]))
            {
                sv_setsv_nomg(tmp, args[i]);
                if (!hv_exists_ent(hv, tmp, 0))
                {
                    ++count;
                    hv_store_ent(hv, tmp, &PL_sv_yes, 0);
                }
            }
            else if(0 == seen_undef++)
                ++count;
        }
        ST(0) = sv_2mortal(newSVuv(count));
        XSRETURN(1);
    }

    /* list context: populate SP with mortal copies */
    for (i = 0; i < items; i++)
    {
        SvGETMAGIC(args[i]);
        if(SvOK(args[i]))
        {
            SvSetSV_nosteal(tmp, args[i]);
            if (!hv_exists_ent(hv, tmp, 0))
            {
                /*ST(count) = sv_2mortal(newSVsv(ST(i)));
                ++count;*/
                args[count++] = args[i];
                hv_store_ent(hv, tmp, &PL_sv_yes, 0);
            }
        }
        else if(0 == seen_undef++)
            args[count++] = args[i];
    }

    XSRETURN(count);
}
#line 2494 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_singleton); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_singleton)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 1861 "XS.xs"
{
    I32 i;
    IV cnt = 0, count = 0, seen_undef = 0;
    HV *hv = newHV();
    SV **args = &PL_stack_base[ax];
    SV *tmp = sv_newmortal();

    sv_2mortal(newRV_noinc((SV*)hv));

    COUNT_ARGS

    /* don't build return list in scalar context */
    if (GIMME_V == G_SCALAR)
    {
        for (i = 0; i < count; i++)
        {
            if(SvOK(args[i]))
            {
                HE *he;
                sv_setsv_nomg(tmp, args[i]);
                he = hv_fetch_ent(hv, tmp, 0, 0);
                if (he)
                    if( 1 == SvIVX(HeVAL(he)) )
                        ++cnt;
            }
            else if(1 == seen_undef)
                ++cnt;
        }
        ST(0) = sv_2mortal(newSViv(cnt));
        XSRETURN(1);
    }

    /* list context: populate SP with mortal copies */
    for (i = 0; i < count; i++)
    {
        if(SvOK(args[i]))
        {
            HE *he;
            SvSetSV_nosteal(tmp, args[i]);
            he = hv_fetch_ent(hv, tmp, 0, 0);
            if (he)
                if( 1 == SvIVX(HeVAL(he)) )
                    args[cnt++] = args[i];
        }
        else if(1 == seen_undef)
            args[cnt++] = args[i];
    }

    XSRETURN(cnt);
}
#line 2557 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_duplicates); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_duplicates)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 1916 "XS.xs"
{
    I32 i;
    IV cnt = 0, count = 0, seen_undef = 0;
    HV *hv = newHV();
    SV **args = &PL_stack_base[ax];
    SV *tmp = sv_newmortal();

    sv_2mortal(newRV_noinc((SV*)hv));

    COUNT_ARGS

    /* don't build return list in scalar context */
    if (GIMME_V == G_SCALAR)
    {
        for (i = 0; i < count; i++)
        {
            if(SvOK(args[i]))
            {
                HE *he;
                sv_setsv_nomg(tmp, args[i]);
                he = hv_fetch_ent(hv, tmp, 0, 0);
                if (he)
                    if( 1 < SvIVX(HeVAL(he)) )
                        ++cnt;
            }
            else if(1 < seen_undef)
                ++cnt;
        }
        ST(0) = sv_2mortal(newSViv(cnt));
        XSRETURN(1);
    }

    /* list context: populate SP with mortal copies */
    for (i = 0; i < count; i++)
    {
        if(SvOK(args[i]))
        {
            HE *he;
            SvSetSV_nosteal(tmp, args[i]);
            he = hv_fetch_ent(hv, tmp, 0, 0);
            if (he)
                if( 1 < SvIVX(HeVAL(he)) )
                    args[cnt++] = args[i];
        }
        else if(1 < seen_undef) {
            args[cnt++] = args[i];
        }
    }

    XSRETURN(cnt);
}
#line 2621 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_frequency); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_frequency)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 1972 "XS.xs"
{
    I32 i;
    IV count = 0, seen_undef = 0;
    HV *hv = newHV();
    SV **args = &PL_stack_base[ax];
    SV *tmp = sv_newmortal();

    sv_2mortal(newRV_noinc((SV*)hv));

    COUNT_ARGS

    i = HvUSEDKEYS(hv);
    if(seen_undef)
        ++i;

    /* don't build return list in scalar context */
    if (GIMME_V == G_SCALAR)
    {
        ST(0) = sv_2mortal(newSViv(i));
        XSRETURN(1);
    }

    EXTEND(SP, i * 2);

    i = 0;
    hv_iterinit(hv);
    for(;;)
    {
        HE *he = hv_iternext(hv);
        SV *key, *val;
        if(NULL == he)
            break;

        if(UNLIKELY(( NULL == (key = HeSVKEY_force(he)) ) || ( NULL == (val = HeVAL(he)) )))
            continue;

        ST(i++) = key;
        ST(i++) = val;
    }

    if(seen_undef)
    {
        ST(i++) = sv_2mortal(newRV(newSVsv(&PL_sv_undef)));
        ST(i++) = sv_2mortal(newSViv(seen_undef));;
    }

    XSRETURN(i);
}
#line 2682 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_occurrences); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_occurrences)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 2025 "XS.xs"
{
    I32 i;
    IV count = 0, seen_undef = 0, max = items > 0 ? 1 : 0;
    HV *hv = newHV();
    SV **args = &PL_stack_base[ax];
    SV *tmp = sv_newmortal();

    sv_2mortal(newRV_noinc((SV*)hv));

    COUNT_ARGS_MAX;

    /* don't build return list in scalar context */
    if (GIMME_V == G_SCALAR)
    {
        ST(0) = sv_2mortal(newSViv(i));
        XSRETURN(1);
    }

    EXTEND(SP, max + 1);
    for(i = 0; i <= max; ++i)
        ST(i) = &PL_sv_undef;

    hv_iterinit(hv);
    for(;;)
    {
        HE *he = hv_iternext(hv);
        SV *key, *val;
        AV *store;
        if(NULL == he)
            break;

        if(UNLIKELY(( NULL == (key = HeSVKEY_force(he)) ) || ( NULL == (val = HeVAL(he)) )))
            continue;

        i = SvIVX(val);
        if(ST(i) == &PL_sv_undef)
        {
            store = newAV();
            ST(i) = sv_2mortal(newRV_noinc((SV *)store));
        }
        else
            store = (AV *)SvRV(ST(i));
        av_push(store, newSVsv(key));
    }

    if(seen_undef)
    {
        AV *store;
        if(ST(seen_undef) == &PL_sv_undef)
        {
            store = newAV();
            ST(seen_undef) = sv_2mortal(newRV_noinc((SV *)store));
        }
        else
        {
            store = (AV *)SvRV(ST(seen_undef));
        }
        av_push(store, &PL_sv_undef);
    }

    XSRETURN(max+1);
}
#line 2757 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_mode); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_mode)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 2092 "XS.xs"
{
    I32 i;
    IV count = 0, seen_undef = 0, max = items > 0 ? 1 : 0;
    HV *hv = newHV();
    SV **args = &PL_stack_base[ax];
    SV *tmp = sv_newmortal();

    sv_2mortal(newRV_noinc((SV*)hv));

    COUNT_ARGS_MAX;

    EXTEND(SP, count = 1);
    ST(0) = sv_2mortal(newSViv(max));

    /* don't build return list in scalar context */
    if (GIMME_V == G_SCALAR)
        XSRETURN(1);


    hv_iterinit(hv);
    for(;;)
    {
        HE *he = hv_iternext(hv);
        SV *key, *val;
        if(NULL == he)
            break;

        if(UNLIKELY(( NULL == (key = HeSVKEY_force(he)) ) || ( NULL == (val = HeVAL(he)) )))
            continue;

        i = SvIVX(val);
        if(max == i)
        {
            ++count;
            EXTEND(SP, count);
            ST(count-1) = sv_mortalcopy(key);
        }
    }

    if(seen_undef == max)
    {
        ++count;
        EXTEND(SP, count);
        ST(count-1) = &PL_sv_undef;
    }

    XSRETURN(count);
}
#line 2818 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_samples); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_samples)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "k, ...");
    {
	I32	k = (I32)SvIV(ST(0))
;
#line 2146 "XS.xs"
{
    I32 i;

    if( k > (items - 1) )
        croak("Cannot get %" IVdf " samples from %" IVdf " elements", (IV)k, (IV)(items-1));

    /* Initialize Drand01 unless rand() or srand() has already been called */
    if(!PL_srand_called)
    {
#ifdef HAVE_TIME
        /* using time(NULL) as seed seems to get better random numbers ... */
        (void)seedDrand01((Rand_seed_t)time(NULL));
#else
        (void)seedDrand01((Rand_seed_t)Perl_seed(aTHX));
#endif
        PL_srand_called = TRUE;
    }

    /* optimzed Knuth-Shuffle since we move our stack one item downwards
       with each exchange */
    for (i = items ; items - i < k ; )
    {
        I32 index = items - i + 1;
        I32 swap = index + (I32)(Drand01() * (double)(--i));
        ST(index-1) = ST(swap);
        ST(swap) = ST(index);
    }

    XSRETURN(k);
}
#line 2864 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_minmax); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_minmax)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 2181 "XS.xs"
{
    I32 i;
    SV *minsv, *maxsv;

    if (!items)
        XSRETURN_EMPTY;

    if (items == 1)
    {
        EXTEND(SP, 1);
        ST(1) = sv_2mortal(newSVsv(ST(0)));
        XSRETURN(2);
    }

    minsv = maxsv = ST(0);

    for (i = 1; i < items; i += 2)
    {
        SV *asv = ST(i-1);
        SV *bsv = ST(i);
        int cmp = ncmp(asv, bsv);
        if (cmp < 0)
        {
            int min_cmp = ncmp(minsv, asv);
            int max_cmp = ncmp(maxsv, bsv);
            if (min_cmp > 0)
                minsv = asv;
            if (max_cmp < 0)
                maxsv = bsv;
        }
        else
        {
            int min_cmp = ncmp(minsv, bsv);
            int max_cmp = ncmp(maxsv, asv);
            if (min_cmp > 0)
                minsv = bsv;
            if (max_cmp < 0)
                maxsv = asv;
        }
    }

    if (items & 1)
    {
        SV *rsv = ST(items-1);
        if (ncmp(minsv, rsv) > 0)
            minsv = rsv;
        else if (ncmp(maxsv, rsv) < 0)
            maxsv = rsv;
    }

    ST(0) = minsv;
    ST(1) = maxsv;

    XSRETURN(2);
}
#line 2932 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_minmaxstr); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_minmaxstr)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
#line 2241 "XS.xs"
{
    I32 i;
    SV *minsv, *maxsv;

    if (!items)
        XSRETURN_EMPTY;

    if (items == 1)
    {
        EXTEND(SP, 1);
        ST(1) = sv_2mortal(newSVsv(ST(0)));
        XSRETURN(2);
    }

    minsv = maxsv = ST(0);

    for (i = 1; i < items; i += 2)
    {
        SV *asv = ST(i-1);
        SV *bsv = ST(i);
        int cmp = sv_cmp_locale(asv, bsv);
        if (cmp < 0)
        {
            int min_cmp = sv_cmp_locale(minsv, asv);
            int max_cmp = sv_cmp_locale(maxsv, bsv);
            if (min_cmp > 0)
                minsv = asv;
            if (max_cmp < 0)
                maxsv = bsv;
        }
        else
        {
            int min_cmp = sv_cmp_locale(minsv, bsv);
            int max_cmp = sv_cmp_locale(maxsv, asv);
            if (min_cmp > 0)
                minsv = bsv;
            if (max_cmp < 0)
                maxsv = asv;
        }
    }

    if (items & 1)
    {
        SV *rsv = ST(items-1);
        if (sv_cmp_locale(minsv, rsv) > 0)
            minsv = rsv;
        else if (sv_cmp_locale(maxsv, rsv) < 0)
            maxsv = rsv;
    }

    ST(0) = minsv;
    ST(1) = maxsv;

    XSRETURN(2);
}
#line 3000 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_part); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_part)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 2302 "XS.xs"
{
    dMULTICALL;
    dMULTICALLSVCV;
    int i;
    SV **args = &PL_stack_base[ax];
    AV *tmp = newAV();
    sv_2mortal(newRV_noinc((SV*)tmp));

    if(!codelike(code))
       croak_xs_usage(cv,  "code, ...");

    if (items == 1)
        XSRETURN_EMPTY;

    PUSH_MULTICALL(mc_cv);
    SAVESPTR(GvSV(PL_defgv));

    for(i = 1 ; i < items ; ++i)
    {
        IV idx;
        SV **inner;
        AV *av;

        GvSV(PL_defgv) = args[i];
        MULTICALL;
        idx = SvIV(*PL_stack_sp);

        if (UNLIKELY(idx < 0 && (idx += (AvFILLp(tmp)+1)) < 0))
            croak("Modification of non-creatable array value attempted, subscript %" IVdf, idx);

        if(UNLIKELY(NULL == (inner = av_fetch(tmp, idx, FALSE))))
        {
            av = newAV();
            av_push(av, newSVsv(args[i]));
            av_store(tmp, idx, newRV_noinc((SV *)av));
        }
        else
        {
            av = (AV*)SvRV(*inner);
            av_push(av, newSVsv(args[i]));
        }
    }
    POP_MULTICALL;

    EXTEND(SP, AvFILLp(tmp)+1);
    for(i = AvFILLp(tmp); i >= 0; --i)
    {
        SV *v = AvARRAY(tmp)[i];
        ST(i) = v && is_array(v) ? sv_2mortal(v) : &PL_sv_undef;
        AvARRAY(tmp)[i] = NULL;
    }

    i = AvFILLp(tmp) + 1;
    AvFILLp(tmp) = -1;

    XSRETURN(i);
}
#line 3073 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_bsearch); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_bsearch)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 2365 "XS.xs"
{
    I32 ret_gimme = GIMME_V;
    if(!codelike(code))
       croak_xs_usage(cv,  "code, ...");

    if (items > 1)
    {
        dMULTICALL;
        dMULTICALLSVCV;
        ssize_t count = items - 1, first = 1;
        int cmprc = -1;
        SV **args = &PL_stack_base[ax];

        PUSH_MULTICALL(mc_cv);
        SAVESPTR(GvSV(PL_defgv));

        LOWER_BOUND_QUICK(args[it])

        if(cmprc < 0 && first < items)
        {
            GvSV(PL_defgv) = args[first];
            MULTICALL;
            cmprc = SvIV(*PL_stack_sp);
        }

        POP_MULTICALL;

        if(0 == cmprc)
        {
            if (ret_gimme != G_ARRAY)
                XSRETURN_YES;
            ST(0) = args[first];
            XSRETURN(1);
        }
    }

    if(ret_gimme == G_ARRAY)
        XSRETURN_EMPTY;
    XSRETURN_UNDEF;
}
#line 3129 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_bsearchidx); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_bsearchidx)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	int	RETVAL;
	dXSTARG;
#line 2411 "XS.xs"
{
    I32 ret_gimme = GIMME_V;
    if(!codelike(code))
       croak_xs_usage(cv,  "code, ...");

    RETVAL = -1;
    if (items > 1)
    {
        dMULTICALL;
        dMULTICALLSVCV;
        ssize_t count = items - 1, first = 1;
        int cmprc = -1;
        SV **args = &PL_stack_base[ax];

        PUSH_MULTICALL(mc_cv);
        SAVESPTR(GvSV(PL_defgv));

        LOWER_BOUND_QUICK(args[it])

        if(cmprc < 0 && first < items)
        {
            GvSV(PL_defgv) = args[first];
            MULTICALL;
            cmprc = SvIV(*PL_stack_sp);
        }

        POP_MULTICALL;

        if(0 == cmprc)
            RETVAL = --first;
    }
}
#line 3179 "XS.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_lower_bound); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_lower_bound)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	int	RETVAL;
	dXSTARG;
#line 2451 "XS.xs"
{
    if(!codelike(code))
       croak_xs_usage(cv,  "code, ...");

    if (items > 1)
    {
        dMULTICALL;
        dMULTICALLSVCV;
        ssize_t count = items - 1, first = 1;
        int cmprc = -1;
        SV **args = &PL_stack_base[ax];

        PUSH_MULTICALL(mc_cv);
        SAVESPTR(GvSV(PL_defgv));

        LOWER_BOUND(args[it])

        POP_MULTICALL;

        RETVAL = --first;
    }
    else
        RETVAL = -1;
}
#line 3222 "XS.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_upper_bound); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_upper_bound)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
	int	RETVAL;
	dXSTARG;
#line 2483 "XS.xs"
{
    if(!codelike(code))
       croak_xs_usage(cv,  "code, ...");

    if (items > 1)
    {
        dMULTICALL;
        dMULTICALLSVCV;
        ssize_t count = items - 1, first = 1;
        int cmprc = -1;
        SV **args = &PL_stack_base[ax];

        PUSH_MULTICALL(mc_cv);
        SAVESPTR(GvSV(PL_defgv));

        UPPER_BOUND(args[it])

        POP_MULTICALL;

        RETVAL = --first;
    }
    else
        RETVAL = -1;
}
#line 3265 "XS.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_equal_range); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_equal_range)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "code, ...");
    {
	SV *	code = ST(0)
;
#line 2515 "XS.xs"
{
    if(!codelike(code))
       croak_xs_usage(cv,  "code, ...");

    if (items > 1)
    {
        dMULTICALL;
        dMULTICALLSVCV;
        ssize_t count = items - 1, first = 1;
        ssize_t lb;
        int cmprc = -1;
        SV **args = &PL_stack_base[ax];

        PUSH_MULTICALL(mc_cv);
        SAVESPTR(GvSV(PL_defgv));

        LOWER_BOUND(args[it])
        lb = first - 1;

        count = items - first;
        UPPER_BOUND(args[it])

        POP_MULTICALL;

        EXTEND(SP, 2);
        ST(0) = sv_2mortal(newSViv(lb));
        ST(1) = sv_2mortal(newSViv(first - 1));
        XSRETURN(2);
    }

    XSRETURN_EMPTY;
}
#line 3314 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_binsert); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_binsert)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "code, item, list");
    {
	SV *	code = ST(0)
;
	SV *	item = ST(1)
;
	AV *	list;
	int	RETVAL;
	dXSTARG;

	STMT_START {
		SV* const xsub_tmp_sv = ST(2);
		SvGETMAGIC(xsub_tmp_sv);
		if (SvROK(xsub_tmp_sv) && SvTYPE(SvRV(xsub_tmp_sv)) == SVt_PVAV){
		    list = (AV*)SvRV(xsub_tmp_sv);
		}
		else{
		    Perl_croak_nocontext("%s: %s is not an ARRAY reference",
				"List::MoreUtils::XS::binsert",
				"list");
		}
	} STMT_END
;
#line 2555 "XS.xs"
{
    if(!codelike(code))
       croak_xs_usage(cv,  "code, val, list");

    RETVAL = -1;

    if (AvFILLp(list) == -1)
    {
        av_push(list, newSVsv(item));
        RETVAL = 0;
    }
    else if (AvFILLp(list) >= 0)
    {
        dMULTICALL;
        dMULTICALLSVCV;
        ssize_t count = AvFILLp(list) + 1, first = 0;
        int cmprc = -1;
        SV **btree = AvARRAY(list);

        PUSH_MULTICALL(mc_cv);
        SAVESPTR(GvSV(PL_defgv));

        LOWER_BOUND(btree[it])

        POP_MULTICALL;

        SvREFCNT_inc(item);
        insert_after(aTHX_ (RETVAL = first) - 1, item, list);
    }
}
#line 3379 "XS.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_bremove); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_bremove)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "code, list");
    {
	SV *	code = ST(0)
;
	AV *	list;

	STMT_START {
		SV* const xsub_tmp_sv = ST(1);
		SvGETMAGIC(xsub_tmp_sv);
		if (SvROK(xsub_tmp_sv) && SvTYPE(SvRV(xsub_tmp_sv)) == SVt_PVAV){
		    list = (AV*)SvRV(xsub_tmp_sv);
		}
		else{
		    Perl_croak_nocontext("%s: %s is not an ARRAY reference",
				"List::MoreUtils::XS::bremove",
				"list");
		}
	} STMT_END
;
#line 2594 "XS.xs"
{
    I32 ret_gimme = GIMME_V;
    if(!codelike(code))
       croak_xs_usage(cv,  "code, ...");

    if (AvFILLp(list) >= 0)
    {
        dMULTICALL;
        dMULTICALLSVCV;
        ssize_t count = AvFILLp(list) + 1, first = 0;
        int cmprc = -1;
        SV **btree = AvARRAY(list);

        PUSH_MULTICALL(mc_cv);
        SAVESPTR(GvSV(PL_defgv));

        LOWER_BOUND_QUICK(btree[it])

        if(cmprc < 0 && first < items)
        {
            GvSV(PL_defgv) = btree[first];
            MULTICALL;
            cmprc = SvIV(*PL_stack_sp);
        }

        POP_MULTICALL;

        if(0 == cmprc)
        {
            if(AvFILLp(list) == first)
            {
                ST(0) = sv_2mortal(av_pop(list));
                XSRETURN(1);
            }

            if(0 == first)
            {
                ST(0) = sv_2mortal(av_shift(list));
                XSRETURN(1);
            }

            ST(0) = av_delete(list, first, 0);
            count = AvFILLp(list);
            while(first < count)
            {
                btree[first] = btree[first+1];
                ++first;
            }
            SvREFCNT_inc(btree[count]);
            av_delete(list, count, G_DISCARD);
#if PERL_VERSION_LE(5,8,5)
            sv_2mortal(ST(0));
#endif
            XSRETURN(1);
        }
    }

    if (ret_gimme == G_ARRAY)
        XSRETURN_EMPTY;
    else
        XSRETURN_UNDEF;
}
#line 3473 "XS.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_List__MoreUtils__XS_qsort); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS_qsort)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "code, list");
    {
	SV *	code = ST(0)
;
	AV *	list;

	STMT_START {
		SV* const xsub_tmp_sv = ST(1);
		SvGETMAGIC(xsub_tmp_sv);
		if (SvROK(xsub_tmp_sv) && SvTYPE(SvRV(xsub_tmp_sv)) == SVt_PVAV){
		    list = (AV*)SvRV(xsub_tmp_sv);
		}
		else{
		    Perl_croak_nocontext("%s: %s is not an ARRAY reference",
				"List::MoreUtils::XS::qsort",
				"list");
		}
	} STMT_END
;
#line 2663 "XS.xs"
{
    I32 gimme = GIMME_V; /* perl-5.5.4 bus-errors out later when using GIMME
                            therefore we save its value in a fresh variable */
    dMULTICALL;

    if(!codelike(code))
       croak_xs_usage(cv,  "code, ...");

    if (in_pad(aTHX_ code))
        croak("Can't use lexical $a or $b in qsort's cmp code block");

    if (av_len(list) > 0)
    {
        HV *stash;
        GV *gv;
        CV *_cv = sv_2cv(code, &stash, &gv, 0);

        PUSH_MULTICALL(_cv);

        SAVEGENERICSV(PL_firstgv);
        SAVEGENERICSV(PL_secondgv);
        PL_firstgv = MUTABLE_GV(SvREFCNT_inc(
            gv_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV)
        ));
        PL_secondgv = MUTABLE_GV(SvREFCNT_inc(
            gv_fetchpvs("b", GV_ADD|GV_NOTQUAL, SVt_PV)
        ));
        /* make sure the GP isn't removed out from under us for
         * the SAVESPTR() */
        save_gp(PL_firstgv, 0);
        save_gp(PL_secondgv, 0);
        /* we don't want modifications localized */
        GvINTRO_off(PL_firstgv);
        GvINTRO_off(PL_secondgv);
        SAVESPTR(GvSV(PL_firstgv));
        SAVESPTR(GvSV(PL_secondgv));

        bsd_qsort_r(aTHX_ AvARRAY(list), av_len(list) + 1, multicall_cop);
        POP_MULTICALL;
    }
}
#line 3545 "XS.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_List__MoreUtils__XS__XScompiled); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_List__MoreUtils__XS__XScompiled)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
#line 2708 "XS.xs"
       XSRETURN_YES;
#line 3560 "XS.c"
    }
    XSRETURN_EMPTY;
}

#ifdef __cplusplus
extern "C"
#endif
XS_EXTERNAL(boot_List__MoreUtils__XS); /* prototype to pass -Wmissing-prototypes */
XS_EXTERNAL(boot_List__MoreUtils__XS)
{
#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

        newXS_deffile("List::MoreUtils::XS_ea::DESTROY", XS_List__MoreUtils__XS_ea_DESTROY);
        newXS_deffile("List::MoreUtils::XS_na::DESTROY", XS_List__MoreUtils__XS_na_DESTROY);
        (void)newXSproto_portable("List::MoreUtils::XS::any", XS_List__MoreUtils__XS_any, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::all", XS_List__MoreUtils__XS_all, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::none", XS_List__MoreUtils__XS_none, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::notall", XS_List__MoreUtils__XS_notall, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::one", XS_List__MoreUtils__XS_one, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::any_u", XS_List__MoreUtils__XS_any_u, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::all_u", XS_List__MoreUtils__XS_all_u, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::none_u", XS_List__MoreUtils__XS_none_u, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::notall_u", XS_List__MoreUtils__XS_notall_u, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::one_u", XS_List__MoreUtils__XS_one_u, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::reduce_u", XS_List__MoreUtils__XS_reduce_u, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::reduce_0", XS_List__MoreUtils__XS_reduce_0, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::reduce_1", XS_List__MoreUtils__XS_reduce_1, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::true", XS_List__MoreUtils__XS_true, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::false", XS_List__MoreUtils__XS_false, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::firstidx", XS_List__MoreUtils__XS_firstidx, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::firstval", XS_List__MoreUtils__XS_firstval, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::firstres", XS_List__MoreUtils__XS_firstres, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::onlyidx", XS_List__MoreUtils__XS_onlyidx, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::onlyval", XS_List__MoreUtils__XS_onlyval, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::onlyres", XS_List__MoreUtils__XS_onlyres, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::lastidx", XS_List__MoreUtils__XS_lastidx, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::lastval", XS_List__MoreUtils__XS_lastval, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::lastres", XS_List__MoreUtils__XS_lastres, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::insert_after", XS_List__MoreUtils__XS_insert_after, file, "&$\\@");
        (void)newXSproto_portable("List::MoreUtils::XS::insert_after_string", XS_List__MoreUtils__XS_insert_after_string, file, "$$\\@");
        (void)newXSproto_portable("List::MoreUtils::XS::apply", XS_List__MoreUtils__XS_apply, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::after", XS_List__MoreUtils__XS_after, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::after_incl", XS_List__MoreUtils__XS_after_incl, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::before", XS_List__MoreUtils__XS_before, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::before_incl", XS_List__MoreUtils__XS_before_incl, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::indexes", XS_List__MoreUtils__XS_indexes, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::_array_iterator", XS_List__MoreUtils__XS__array_iterator, file, ";$");
        (void)newXSproto_portable("List::MoreUtils::XS::each_array", XS_List__MoreUtils__XS_each_array, file, "\\@;\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@");
        newXS_deffile("List::MoreUtils::XS::each_arrayref", XS_List__MoreUtils__XS_each_arrayref);
        (void)newXSproto_portable("List::MoreUtils::XS::pairwise", XS_List__MoreUtils__XS_pairwise, file, "&\\@\\@");
        (void)newXSproto_portable("List::MoreUtils::XS::_natatime_iterator", XS_List__MoreUtils__XS__natatime_iterator, file, "");
        (void)newXSproto_portable("List::MoreUtils::XS::natatime", XS_List__MoreUtils__XS_natatime, file, "$@");
        newXS_deffile("List::MoreUtils::XS::arrayify", XS_List__MoreUtils__XS_arrayify);
        (void)newXSproto_portable("List::MoreUtils::XS::mesh", XS_List__MoreUtils__XS_mesh, file, "\\@\\@;\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@");
        (void)newXSproto_portable("List::MoreUtils::XS::zip6", XS_List__MoreUtils__XS_zip6, file, "\\@\\@;\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@");
        (void)newXSproto_portable("List::MoreUtils::XS::listcmp", XS_List__MoreUtils__XS_listcmp, file, "\\@\\@;\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@");
        (void)newXSproto_portable("List::MoreUtils::XS::uniq", XS_List__MoreUtils__XS_uniq, file, "@");
        (void)newXSproto_portable("List::MoreUtils::XS::singleton", XS_List__MoreUtils__XS_singleton, file, "@");
        (void)newXSproto_portable("List::MoreUtils::XS::duplicates", XS_List__MoreUtils__XS_duplicates, file, "@");
        (void)newXSproto_portable("List::MoreUtils::XS::frequency", XS_List__MoreUtils__XS_frequency, file, "@");
        (void)newXSproto_portable("List::MoreUtils::XS::occurrences", XS_List__MoreUtils__XS_occurrences, file, "@");
        (void)newXSproto_portable("List::MoreUtils::XS::mode", XS_List__MoreUtils__XS_mode, file, "@");
        (void)newXSproto_portable("List::MoreUtils::XS::samples", XS_List__MoreUtils__XS_samples, file, "$@");
        (void)newXSproto_portable("List::MoreUtils::XS::minmax", XS_List__MoreUtils__XS_minmax, file, "@");
        (void)newXSproto_portable("List::MoreUtils::XS::minmaxstr", XS_List__MoreUtils__XS_minmaxstr, file, "@");
        (void)newXSproto_portable("List::MoreUtils::XS::part", XS_List__MoreUtils__XS_part, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::bsearch", XS_List__MoreUtils__XS_bsearch, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::bsearchidx", XS_List__MoreUtils__XS_bsearchidx, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::lower_bound", XS_List__MoreUtils__XS_lower_bound, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::upper_bound", XS_List__MoreUtils__XS_upper_bound, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::equal_range", XS_List__MoreUtils__XS_equal_range, file, "&@");
        (void)newXSproto_portable("List::MoreUtils::XS::binsert", XS_List__MoreUtils__XS_binsert, file, "&$\\@");
        (void)newXSproto_portable("List::MoreUtils::XS::bremove", XS_List__MoreUtils__XS_bremove, file, "&\\@");
        (void)newXSproto_portable("List::MoreUtils::XS::qsort", XS_List__MoreUtils__XS_qsort, file, "&\\@");
        newXS_deffile("List::MoreUtils::XS::_XScompiled", XS_List__MoreUtils__XS__XScompiled);
#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
}

