Listing 5: Merging template functions


        // TEMPLATE FUNCTION merge
template<class InIt1, class InIt2, class OutIt> inline
    OutIt merge(InIt1 first1, InIt1 last1,
        InIt2 first2, InIt2 last2, OutIt x)
    {for (; first1 != last1 && first2 != last2; ++x)
        if (*first2 < *first1)
            *x = *first2++;
        else
            *x = *first1++;
    x = copy(first1, last1, x);
    return (copy(first2, last2, x)); } 

        // TEMPLATE FUNCTION inplace_merge
template<class BidIt> inline
    void inplace_merge(BidIt first, BidIt mid, BidIt last)
    {if (first != last)
        _Inplace_merge(first, mid, last,
            _Dist_type(first), _Val_type(first)); }
template<class BidIt, class Diff, class T> inline
    void _Inplace_merge(BidIt first, BidIt mid, BidIt last,
        Diff *, T *)
    {Diff d1 = 0;
    _Distance(first, mid, d1);
    Diff d2 = 0;
    _Distance(mid, last, d2);
    _Temp_iterator<T> xb(d1 < d2 ? d1 : d2);
    _Buffered_merge(first, mid, last, d1, d2, xb); }
template<class BidIt, class Diff, class T> inline
    void _Buffered_merge(BidIt first, BidIt mid, BidIt last,
        Diff d1, Diff d2, _Temp_iterator<T>& xb)
    {if (d1 == 0 || d2 == 0)
        ;
    else if (d1 + d2 == 2)
        {if (*mid < *first)
            iter_swap(first, mid); }
    else if (d1 <= d2 && d1 <= xb.Maxlen())
        {copy(first, mid, xb.Init());
        merge(xb.First(), xb.Last(), mid, last, first); }
    else if (d2 <= xb.Maxlen())
        {copy(mid, last, xb.Init());
        _Merge_backward(first, mid, xb.First(), xb.Last(),
            last); }
    else
        {BidIt firstn, lastn;
        Diff d1n = 0, d2n = 0;
        if (d2 < d1)
            {d1n = d1 / 2;
            firstn = first;
            advance(firstn, d1n);
            lastn = lower_bound(mid, last, T(*firstn));
            _Distance(mid, lastn, d2n); }
        else
            {d2n = d2 / 2;
            lastn = mid;
            advance(lastn, d2n);
            firstn = upper_bound(first, mid, T(*lastn));
            _Distance(first, firstn, d1n); }
        BidIt midn = _Buffered_rotate(firstn, mid, lastn,
            d1 - d1n, d2n, xb);
        _Buffered_merge(first, firstn, midn, d1n, d2n, xb);
        _Buffered_merge(midn, lastn, last,
            d1 - d1n, d2 - d2n, xb); }}
template<class BidIt1, class BidIt2, class BidIt3> inline
    BidIt3 _Merge_backward(BidIt1 first1, BidIt1 last1,
        BidIt2 first2, BidIt2 last2, BidIt3 x)
    {for (; ; )
        if (first1 == last1)
            return (copy_backward(first2, last2, x));
        else if (first2 == last2)
            return (copy_backward(first1, last1, x));
        else if (*--last2 < *--last1)
            *--x = *last1, ++last2;
        else
            *--x = *last2, ++last1; }
template<class BidIt, class Diff, class T> inline
    BidIt _Buffered_rotate(BidIt first, BidIt mid, BidIt last,
        Diff d1, Diff d2, _Temp_iterator<T>& xb)
    {if (d1 <= d2 && d1 <= xb.Maxlen())
        {copy(first, mid, xb.Init());
        copy(mid, last, first);
        return (copy_backward(xb.First(), xb.Last(), last)); }
    else if (d2 <= xb.Maxlen())
        {copy(mid, last, xb.Init());
        copy_backward(first, mid, last);
        return (copy(xb.First(), xb.Last(), first)); }
    else
        {rotate(first, mid, last);
        advance(first, d2);
        return (first); }}

//End of File