diff --git a/Kernel/include_std/iterator b/Kernel/include_std/iterator index 22136cf1..72106a7d 100644 --- a/Kernel/include_std/iterator +++ b/Kernel/include_std/iterator @@ -17,6 +17,8 @@ #pragma once +#include + namespace std { struct input_iterator_tag @@ -54,28 +56,31 @@ namespace std using iterator_category = typename Iter::iterator_category; }; - template - constexpr typename std::iterator_traits::difference_type __do_distance(InputIt first, InputIt last, std::input_iterator_tag) + namespace detail { - typename std::iterator_traits::difference_type result = 0; - while (first != last) + template + constexpr typename std::iterator_traits::difference_type do_distance(It first, It last, std::input_iterator_tag) { - ++first; - ++result; + 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; } - return result; } - template - constexpr typename std::iterator_traits::difference_type __do_distance(InputIt first, InputIt last, std::random_access_iterator_tag) + template + constexpr typename std::iterator_traits::difference_type distance(It first, It last) { - return last - first; - } - - template - constexpr typename std::iterator_traits::difference_type distance(InputIt first, InputIt last) - { - return __do_distance(first, last, typename std::iterator_traits::iterator_category()); + return detail::do_distance(first, last, typename std::iterator_traits::iterator_category()); } template @@ -135,4 +140,118 @@ namespace std }; 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; + } + }; }