#include <algorithm>
#include <iterator>
#include <type_traits>
#include "map.hpp"

namespace sjtu {
template <typename _Tp>
static constexpr bool is_iterator_v = requires() {
  typename std::iterator_traits<_Tp>::iterator_category;
  typename std::iterator_traits<_Tp>::difference_type;
  typename std::iterator_traits<_Tp>::value_type;
  typename std::iterator_traits<_Tp>::pointer;
  typename std::iterator_traits<_Tp>::reference;
};

template <typename _Iter>
void my_sort(_Iter __first, _Iter __last) {
  if constexpr (is_iterator_v<_Iter>) {
    using category = typename std::iterator_traits<_Iter>::iterator_category;
    if constexpr (std::is_same_v<sjtu::map_iterator_tag, category>) {
      return;
    } else if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>) {
      std::sort(__first, __last);
      return;
    } else
      static_assert(std::is_base_of_v<std::random_access_iterator_tag, category>,
                    "Not a random access iterator or a iterator from already sorted container.");
  } else
    static_assert(sjtu::is_iterator_v<_Iter>, "Not an iterator.");
}

}  // namespace sjtu