#ifndef PYTHONIC_NUMPY_SEARCHSORTED_HPP #define PYTHONIC_NUMPY_SEARCHSORTED_HPP #include "pythonic/include/numpy/searchsorted.hpp" #include "pythonic/utils/functor.hpp" #include "pythonic/utils/numpy_conversion.hpp" #include "pythonic/utils/int_.hpp" #include "pythonic/types/ndarray.hpp" #include "pythonic/types/str.hpp" #include "pythonic/builtins/None.hpp" #include "pythonic/builtins/ValueError.hpp" #include "pythonic/numpy/asarray.hpp" #include PYTHONIC_NS_BEGIN namespace numpy { namespace details { template long searchsorted(U const &a, T const &v, bool left) { if (left) return std::lower_bound(a.begin(), a.end(), v) - a.begin(); else return std::upper_bound(a.begin(), a.end(), v) - a.begin(); } bool issearchsortedleft(types::str const &side) { if (side[0] == "l") return true; else if (side[0] == "r") return false; else throw types::ValueError("'" + side + "' is an invalid value for keyword 'side'"); } } template typename std::enable_if::value, long>::type searchsorted(U const &a, T const &v, types::str const &side) { bool left = details::issearchsortedleft(side); return details::searchsorted(a, v, left); } namespace { template void _search_sorted(E const &a, I0 ibegin, I0 iend, I1 obegin, bool left, utils::int_<1>) { for (; ibegin != iend; ++ibegin, ++obegin) *obegin = details::searchsorted(a, *ibegin, left); } template void _search_sorted(E const &a, I0 ibegin, I0 iend, I1 obegin, bool left, utils::int_) { for (; ibegin != iend; ++ibegin, ++obegin) _search_sorted(a, (*ibegin).begin(), (*ibegin).end(), (*obegin).begin(), left, utils::int_()); } } template typename std::enable_if< types::is_numexpr_arg::value, types::ndarray>>::type searchsorted(T const &a, E const &v, types::str const &side) { static_assert(T::value == 1, "Not Implemented : searchsorted for dimension != 1"); bool left = details::issearchsortedleft(side); types::ndarray> out(asarray(v)._shape, builtins::None); _search_sorted(a, v.begin(), v.end(), out.begin(), left, utils::int_()); return out; } } PYTHONIC_NS_END #endif