// Copyright (C) 2015 The Android Open Source Project
//
// 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.

#pragma once

#include <algorithm>

namespace android {
namespace base {

// Template class used to implement quick-sort for arrays of type |T|.
// Usage is the following:
//
//    1) Define a TRAITS structure type that implements two methods
//       as follows:
//
//           // Compare two items |a| and |b| and return -1, 0 or +1
//           static int compare(const T* a, const T* b);
//
//           // Swap items |a| and |b| in-place.
//           static void swap(T* a, T* b);
//
//    2) Call ::android::base::QSort<Foo, FooTraits>::sort()
//

template <typename T, typename TRAITS>
class QSort {
public:
    // Sort an array of |n| items of type |T| starting at |base|.
    // Using the comparison and swap functions provided by |TRAITS|.
    static void sort(T* base, size_t n) {
        for (;;) {
            T* pm;
            if (n < 7) {
                insertionSort(base, n);
                return;
            }
            pm = base + (n / 2);
            if (n > 7) {
                T* pl = base;
                T* pn = base + (n - 1);
                if (n > 40) {
                    size_t d = (n / 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);
            }
            TRAITS::swap(base, pm);
            T* pa = base + 1;
            T* pb = pa;

            T* pc = base + (n - 1);
            T* pd = pc;

            int swap_cnt = 0;
            for (;;) {
                int r;
                while (pb <= pc && (r = TRAITS::compare(pb, base)) <= 0) {
                    if (r == 0) {
                        swap_cnt = 1;
                        TRAITS::swap(pa, pb);
                        pa += 1;
                    }
                    pb += 1;
                }
                while (pb <= pc && (r = TRAITS::compare(pc, base)) >= 0) {
                    if (r == 0) {
                        swap_cnt = 1;
                        TRAITS::swap(pc, pd);
                        pd -= 1;
                    }
                    pc -= 1;
                }
                if (pb > pc) {
                    break;
                }
                TRAITS::swap(pb, pc);
                swap_cnt = 1;
                pb += 1;
                pc -= 1;
            }
            if (swap_cnt == 0) {  /* Switch to insertion sort */
                insertionSort(base, n);
                return;
            }

            T* pn = base + n;
            int r = std::min(pa - base, pb - pa);
            vecswap(base, pb - r, r);
            r = std::min(pd - pc, pn - pd - 1);
            vecswap(pb, pn - r, r);
            if ((r = pb - pa) > 1) {
                    sort(base, r);
            }
            if ((r = pd - pc) > 1) {
                /* Iterate rather than recurse to save stack space */
                base = pn - r;
                n = r;
                continue;
            }
            break;
        }
    }

private:
    // Used internally to perform insertion sort.
    static void insertionSort(T* base, size_t n) {
        for (T* pm = base + 1; pm < base + n; pm++) {
            T* pl = pm;
            while (pl > base && TRAITS::compare(pl - 1, pl) > 0) {
                TRAITS::swap(pl, pl - 1);
                pl -= 1;
            }
        }
    }

    // Used internally to return the median of three items |a|, |b| and |c|.
    static T* med3(T* a, T* b, T* c) {
        return TRAITS::compare(a, b) < 0
                ? (TRAITS::compare(b, c) < 0
                    ? b : (TRAITS::compare(a, c) < 0 ? c : a))
               : (TRAITS::compare(b, c) > 0
                    ? b : (TRAITS::compare(a, c) < 0 ? a : c));
    }

    // Used internally to swap |n| items from slices starting at |pi| and |pj|
    // respectively.
    static void vecswap(T* pi, T* pj, size_t n) {
        for (size_t i = 0; i < n; ++i) {
            TRAITS::swap(pi + i, pj + i);
        }
    }
};

}  // namespace base
}  // namespace android
