* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef API_BASE_CONTAINERS_ITERATOR_H
#define API_BASE_CONTAINERS_ITERATOR_H
#define BASE_STD_COMPATIBILITY
#ifdef BASE_STD_COMPATIBILITY
#include <iterator>
#endif
#include <base/namespace.h>
BASE_BEGIN_NAMESPACE()
#ifdef BASE_STD_COMPATIBILITY
using random_access_iterator_tag = std::random_access_iterator_tag;
#else
struct random_access_iterator_tag {};
#endif
template<class T>
class const_iterator {
public:
using base_container = T;
using base_iterator = typename T::iterator;
using const_base_iterator = typename T::const_iterator;
using iterator_category = random_access_iterator_tag;
using value_type = typename T::value_type;
using difference_type = typename T::difference_type;
using pointer = typename T::const_pointer;
using reference = typename T::const_reference;
constexpr const_iterator() noexcept = default;
constexpr explicit const_iterator(const pointer ptr) noexcept : it_{ptr}
{}
constexpr const_iterator(const base_iterator& other) noexcept : it_{other.ptr()}
{}
constexpr const_iterator& operator++() noexcept
{
++it_;
return *this;
}
constexpr const_iterator operator++(int) noexcept
{
const_iterator t(*this);
++*this;
return t;
}
constexpr const_iterator& operator--() noexcept
{
--it_;
return *this;
}
constexpr const_iterator operator--(int) noexcept
{
const_iterator t(*this);
--*this;
return t;
}
constexpr reference operator*() const noexcept
{
return *it_;
}
constexpr pointer operator->() const noexcept
{
return it_;
}
constexpr const_iterator operator+(difference_type n) const noexcept
{
return const_iterator(it_ + n);
}
constexpr const_iterator& operator+=(difference_type n) noexcept
{
it_ += n;
return *this;
}
constexpr const_iterator operator-(difference_type n) const noexcept
{
return const_iterator(it_ - n);
}
constexpr const_iterator& operator-=(difference_type n) noexcept
{
it_ -= n;
return *this;
}
constexpr bool operator==(const const_iterator& other) const noexcept
{
return it_ == other.it_;
}
constexpr bool operator!=(const const_iterator& other) const noexcept
{
return it_ != other.it_;
}
constexpr difference_type operator-(const const_iterator& other) const noexcept
{
return static_cast<difference_type>(it_ - other.it_);
}
constexpr bool operator<(const const_iterator& other) const noexcept
{
return it_ < other.it_;
}
constexpr bool operator<=(const const_iterator& other) const noexcept
{
return it_ <= other.it_;
}
constexpr bool operator>(const const_iterator& other) const noexcept
{
return it_ > other.it_;
}
constexpr bool operator>=(const const_iterator& other) const noexcept
{
return it_ >= other.it_;
}
pointer ptr() const
{
return it_;
}
protected:
pointer it_;
};
template<class T>
class iterator {
public:
using base_container = T;
using iterator_category = random_access_iterator_tag;
using base_iterator = typename T::iterator;
using const_base_iterator = typename T::const_iterator;
using value_type = typename T::value_type;
using difference_type = typename T::difference_type;
using pointer = typename T::pointer;
using reference = typename T::reference;
constexpr iterator() noexcept = default;
constexpr explicit iterator(const pointer ptr) noexcept : it_{ptr}
{}
constexpr iterator& operator++() noexcept
{
++it_;
return *this;
}
constexpr iterator operator++(int) noexcept
{
iterator t(*this);
++*this;
return t;
}
constexpr iterator& operator--() noexcept
{
--it_;
return *this;
}
constexpr iterator operator--(int) noexcept
{
iterator t(*this);
--*this;
return t;
}
constexpr reference operator*() const noexcept
{
return *it_;
}
constexpr pointer operator->() const noexcept
{
return it_;
}
constexpr reference operator*() noexcept
{
return *it_;
}
constexpr pointer operator->() noexcept
{
return it_;
}
constexpr iterator operator+(difference_type n) const noexcept
{
return iterator(it_ + n);
}
constexpr iterator& operator+=(difference_type n) noexcept
{
it_ += n;
return *this;
}
constexpr iterator operator-(difference_type n) const noexcept
{
return iterator(it_ - n);
}
constexpr iterator& operator-=(difference_type n) noexcept
{
it_ -= n;
return *this;
}
constexpr bool operator==(const iterator& other) const noexcept
{
return it_ == other.it_;
}
constexpr bool operator!=(const iterator& other) const noexcept
{
return it_ != other.it_;
}
constexpr difference_type operator-(const iterator& other) const noexcept
{
return static_cast<difference_type>(it_ - other.it_);
}
constexpr bool operator<(const iterator& other) const noexcept
{
return it_ < other.it_;
}
constexpr bool operator<=(const iterator& other) const noexcept
{
return it_ <= other.it_;
}
constexpr bool operator>(const iterator& other) const noexcept
{
return it_ > other.it_;
}
constexpr bool operator>=(const iterator& other) const noexcept
{
return it_ >= other.it_;
}
pointer ptr() const
{
return it_;
}
protected:
pointer it_;
};
template<typename Iter>
class reverse_iterator {
public:
using base_container = typename Iter::base_container;
using iterator = typename base_container::iterator;
using const_iterator = typename base_container::const_iterator;
using iterator_type = Iter;
using iterator_category = typename Iter::iterator_category;
using value_type = typename Iter::value_type;
using difference_type = typename Iter::difference_type;
using pointer = typename Iter::pointer;
using reference = typename Iter::reference;
constexpr reverse_iterator() = default;
constexpr explicit reverse_iterator(iterator_type it) noexcept : it_(it)
{}
constexpr reverse_iterator(const reverse_iterator& other) noexcept = default;
constexpr reverse_iterator& operator=(const reverse_iterator& other) noexcept = default;
constexpr reverse_iterator(reverse_iterator&& other) noexcept = default;
constexpr reverse_iterator& operator=(reverse_iterator&& other) noexcept = default;
template<class U>
constexpr reverse_iterator& operator=(const reverse_iterator<U>& other)
{
it_ = other.base();
return *this;
}
constexpr reverse_iterator& operator++()
{
--it_;
return *this;
}
constexpr reverse_iterator operator++(int)
{
reverse_iterator t(*this);
--it_;
return t;
}
constexpr reverse_iterator& operator--()
{
++it_;
return *this;
}
constexpr reverse_iterator operator--(int)
{
reverse_iterator t(*this);
++it_;
return t;
}
constexpr reference operator*() const
{
iterator_type it = it_;
return (--it).operator*();
}
constexpr pointer operator->() const
{
iterator_type it = it_;
return (--it).operator->();
}
constexpr reverse_iterator operator+(difference_type n) const
{
return reverse_iterator(it_ - n);
}
constexpr reverse_iterator& operator+=(difference_type n)
{
it_ -= n;
return *this;
}
constexpr reverse_iterator operator-(difference_type n) const
{
return reverse_iterator(it_ + n);
}
constexpr reverse_iterator& operator-=(difference_type n)
{
it_ += n;
return *this;
}
constexpr difference_type operator-(const reverse_iterator& other) const
{
return other.it_ - it_;
}
constexpr bool operator==(const reverse_iterator& other) const
{
return it_ == other.it_;
}
constexpr bool operator!=(const reverse_iterator& other) const
{
return it_ != other.it_;
}
constexpr iterator_type base() const
{
return it_;
}
constexpr bool operator<(const reverse_iterator& other) const noexcept
{
return it_ > other.it_;
}
constexpr bool operator<=(const reverse_iterator& other) const noexcept
{
return it_ >= other.it_;
}
constexpr bool operator>(const reverse_iterator& other) const noexcept
{
return it_ < other.it_;
}
constexpr bool operator>=(const reverse_iterator& other) const noexcept
{
return it_ <= other.it_;
}
private:
Iter it_;
};
template<class Iter>
class move_iterator {
public:
using iterator_type = Iter;
using iterator_category = typename Iter::iterator_category;
using value_type = typename Iter::value_type;
using difference_type = typename Iter::difference_type;
using pointer = Iter;
using reference = value_type&&;
constexpr move_iterator() = default;
constexpr explicit move_iterator(iterator_type x) : current_(x)
{}
template<class U>
constexpr move_iterator(const move_iterator<U>& other) : current_(other.current)
{}
template<class U>
constexpr move_iterator& operator=(const move_iterator<U>& other)
{
current_ = other.current;
return *this;
}
constexpr iterator_type base() const
{
return current_;
}
constexpr reference operator*() const
{
return static_cast<reference>(*current_);
}
constexpr pointer operator->() const
{
return current_;
}
constexpr reference operator[](difference_type n) const
{
return static_cast<reference>(current_[n]);
}
constexpr move_iterator& operator++()
{
++current_;
return *this;
}
constexpr move_iterator& operator--()
{
--current_;
return *this;
}
constexpr move_iterator operator++(int)
{
move_iterator before(*this);
++current_;
return before;
}
constexpr move_iterator operator--(int)
{
move_iterator before(*this);
--current_;
return before;
}
constexpr move_iterator operator+(difference_type n) const
{
return move_iterator(current_ + n);
}
constexpr move_iterator operator-(difference_type n) const
{
return move_iterator(current_ - n);
}
constexpr move_iterator& operator+=(difference_type n)
{
current_ += n;
return *this;
}
constexpr move_iterator& operator-=(difference_type n)
{
current_ -= n;
return *this;
}
private:
Iter current_;
};
template<class Iterator1, class Iterator2>
constexpr bool operator==(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
{
return lhs.base() == rhs.base();
}
template<class Iterator1, class Iterator2>
constexpr bool operator!=(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
{
return lhs.base() != rhs.base();
}
template<class Iterator1, class Iterator2>
constexpr bool operator<(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
{
return lhs.base() < rhs.base();
}
template<class Iterator1, class Iterator2>
constexpr bool operator<=(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
{
return lhs.base() <= rhs.base();
}
template<class Iterator1, class Iterator2>
constexpr bool operator>(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
{
return lhs.base() > rhs.base();
}
template<class Iterator1, class Iterator2>
constexpr bool operator>=(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
{
return lhs.base() >= rhs.base();
}
template<class Iter>
constexpr move_iterator<Iter> operator+(typename move_iterator<Iter>::difference_type n, const move_iterator<Iter>& it)
{
return move_iterator(it.base() + n);
}
template<class Iterator1, class Iterator2>
constexpr auto operator-(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
-> decltype(lhs.base() - rhs.base())
{
return lhs.base() - rhs.base();
}
template<class Iter>
constexpr move_iterator<Iter> make_move_iterator(Iter i)
{
return move_iterator<Iter>{i};
}
BASE_END_NAMESPACE()
#endif