/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #pragma once #include #include namespace std { struct input_iterator_tag { }; struct output_iterator_tag { }; struct forward_iterator_tag : public input_iterator_tag { }; struct bidirectional_iterator_tag : public forward_iterator_tag { }; struct random_access_iterator_tag : public bidirectional_iterator_tag { }; struct contiguous_iterator_tag : public random_access_iterator_tag { }; template struct iterator_traits { public: using difference_type = typename Iter::difference_type; using value_type = typename Iter::value_type; using pointer = typename Iter::pointer; using reference = typename Iter::reference; using iterator_category = typename Iter::iterator_category; }; template struct iterator_traits { public: using difference_type = std::ptrdiff_t; using value_type = std::remove_cv_t; using pointer = T *; using reference = T &; using iterator_category = std::random_access_iterator_tag; using iterator_concept = std::contiguous_iterator_tag; }; namespace detail { template constexpr typename std::iterator_traits::difference_type do_distance(It first, It last, std::input_iterator_tag) { typename std::iterator_traits::difference_type result = 0; while (first != last) { ++first; ++result; } return result; } template constexpr typename std::iterator_traits::difference_type do_distance(It first, It last, std::random_access_iterator_tag) { return last - first; } } template constexpr typename std::iterator_traits::difference_type distance(It first, It last) { return detail::do_distance(first, last, typename std::iterator_traits::iterator_category()); } template void __do_advance(InputIt &it, typename std::iterator_traits::difference_type n, std::input_iterator_tag) { while (n > 0) { --n; ++it; } } template void __do_advance(InputIt &it, typename std::iterator_traits::difference_type n, std::bidirectional_iterator_tag) { while (n > 0) { --n; ++it; } while (n < 0) { ++n; --it; } } template void __do_advance(InputIt &it, typename std::iterator_traits::difference_type n, std::random_access_iterator_tag) { it += n; } template constexpr void advance(InputIt &it, Distance n) { __do_advance(it, typename std::iterator_traits::difference_type(n), typename std::iterator_traits::iterator_category()); } template constexpr BidirIt prev(BidirIt it, typename std::iterator_traits::difference_type n = 1) { std::advance(it, -n); return it; } template constexpr InputIt next(InputIt it, typename std::iterator_traits::difference_type n = 1) { std::advance(it, n); return it; } struct default_sentinel_t { }; inline constexpr default_sentinel_t default_sentinel{}; template using iter_value_t = typename std::iterator_traits::value_type; template using iter_difference_t = typename std::iterator_traits::difference_type; template using iter_reference_t = decltype(*std::declval()); template class reverse_iterator { public: using iterator_type = Iter; using iterator_concept = std::bidirectional_iterator_tag; using iterator_category = std::iterator_traits::iterator_category; using value_type = std::iter_value_t; using difference_type = std::iter_difference_t; using pointer = std::iterator_traits::pointer; using reference = std::iter_reference_t; protected: Iter current = Iter(); public: reverse_iterator() = default; constexpr explicit reverse_iterator(Iter x) : current(x) {} // template // requires(!std::is_same_v && std::convertible_to) // constexpr explicit reverse_iterator(const U &other) : current(other.base()) // { // } template reverse_iterator(const reverse_iterator &other) : current(other.base()) {} template reverse_iterator &operator=(const reverse_iterator &other) { current = other.base(); return *this; } constexpr Iter base() const { return current; } constexpr decltype(auto) operator*() const { return *std::prev(current); // Iter tmp = current; // return *--tmp; } pointer operator->() const { if constexpr (std::is_pointer_v) return current - 1; else return std::prev(current).operator->(); } constexpr decltype(auto) operator[](difference_type n) const { return current[-n - 1]; } constexpr reverse_iterator &operator++() { --current; return *this; } constexpr reverse_iterator operator++(int) { auto tmp = *this; --current; return tmp; } constexpr reverse_iterator &operator--() { ++current; return *this; } constexpr reverse_iterator operator--(int) { auto tmp = *this; ++current; return tmp; } constexpr reverse_iterator operator+(difference_type n) const { return reverse_iterator(current - n); } constexpr reverse_iterator operator-(difference_type n) const { return reverse_iterator(current + n); } constexpr reverse_iterator &operator+=(difference_type n) { current -= n; return *this; } constexpr reverse_iterator &operator-=(difference_type n) { current += n; return *this; } }; }