#ifndef PYTHONIC_NUMPY_LEXSORT_HPP #define PYTHONIC_NUMPY_LEXSORT_HPP #include "pythonic/include/numpy/lexsort.hpp" #include "pythonic/utils/functor.hpp" #include "pythonic/types/ndarray.hpp" #include "pythonic/utils/pdqsort.hpp" PYTHONIC_NS_BEGIN namespace numpy { namespace details { template struct lexcmp_nth { template bool operator()(K const &keys, long i0, long i1) const { if (std::get(keys)[i0] < std::get(keys)[i1]) return true; else if (std::get(keys)[i0] > std::get(keys)[i1]) return false; else return lexcmp_nth{}(keys, i0, i1); } }; template <> struct lexcmp_nth<0> { template bool operator()(K const &keys, long i0, long i1) const { return false; } }; template struct lexcmp { K const &keys; lexcmp(K const &keys) : keys(keys) { } bool operator()(long i0, long i1) { return lexcmp_nth::value>{}(keys, i0, i1); } }; } template types::ndarray> lexsort(pS const &keys) { long n = std::get<0>(keys).size(); types::ndarray> out(types::pshape(n), builtins::None); // fill with the original indices std::iota(out.buffer, out.buffer + n, 0L); // then sort using keys as the comparator pdqsort(out.buffer, out.buffer + n, details::lexcmp(keys)); return out; } } PYTHONIC_NS_END #endif