Loading...
Searching...
No Matches
random_access_iterator.hpp
Go to the documentation of this file.
// SPDX-FileCopyrightText: 2006-2025 Knut Reinert & Freie Universität Berlin
// SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: BSD-3-Clause
#pragma once
#include <cassert>
#include <iterator>
#include <type_traits>
#include <seqan3/core/platform.hpp>
namespace seqan3::detail
{
template <typename range_type, template <typename...> typename derived_t_template, typename... args_t>
class random_access_iterator_base
{
protected:
typename std::add_pointer_t<range_type> host{nullptr};
using position_type = std::make_unsigned_t<typename range_type::difference_type>;
position_type pos{static_cast<position_type>(0)};
template <typename range_type2, template <typename...> typename derived_t_template2, typename... args2_t>
friend class random_access_iterator_base;
using derived_t = derived_t_template<range_type>;
public:
using difference_type = typename range_type::difference_type; // TODO should be range_ but is broken in ranges
using value_type = typename range_type::value_type;
using reference = std::conditional_t<std::is_const_v<range_type>,
typename range_type::const_reference,
typename range_type::reference>;
using const_reference = typename range_type::const_reference; //TODO: there is no type trait for this, yet :o
using pointer = value_type *;
using iterator_category = std::random_access_iterator_tag;
constexpr random_access_iterator_base() = default;
constexpr random_access_iterator_base(random_access_iterator_base const &) = default;
constexpr random_access_iterator_base & operator=(random_access_iterator_base const &) = default;
constexpr random_access_iterator_base(random_access_iterator_base &&) = default;
constexpr random_access_iterator_base & operator=(random_access_iterator_base &&) = default;
~random_access_iterator_base() = default;
explicit constexpr random_access_iterator_base(range_type & host) noexcept : host{&host}
{}
constexpr random_access_iterator_base(range_type & host, position_type const pos) noexcept : host{&host}, pos{pos}
{}
template <typename range_type2>
requires std::is_const_v<range_type> && (!std::is_const_v<range_type2>)
&& std::is_same_v<std::remove_const_t<range_type>, range_type2>
constexpr random_access_iterator_base(
random_access_iterator_base<range_type2, derived_t_template> const & rhs) noexcept :
host{rhs.host},
pos{rhs.pos}
{}
template <typename range_type2>
requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
constexpr bool operator==(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
{
return pos == rhs.pos;
}
template <typename range_type2>
requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
constexpr bool operator!=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
{
return !(*this == rhs);
}
template <typename range_type2>
requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
constexpr bool operator<(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
{
return static_cast<bool>(pos < rhs.pos);
}
template <typename range_type2>
requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
constexpr bool operator>(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
{
return pos > rhs.pos;
}
template <typename range_type2>
requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
constexpr bool operator<=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
{
return pos <= rhs.pos;
}
template <typename range_type2>
requires std::is_same_v<std::remove_const_t<range_type>, std::remove_const_t<range_type2>>
constexpr bool operator>=(random_access_iterator_base<range_type2, derived_t_template> const & rhs) const noexcept
{
return pos >= rhs.pos;
}
constexpr derived_t & operator++() noexcept
{
++pos;
return *this_derived();
}
constexpr derived_t operator++(int) noexcept
{
derived_t cpy{*this_derived()};
++pos;
return cpy;
}
constexpr derived_t & operator--() noexcept
{
--pos;
return *this_derived();
}
constexpr derived_t operator--(int) noexcept
{
derived_t cpy{*this_derived()};
--pos;
return cpy;
}
constexpr derived_t & operator+=(difference_type const skip) noexcept
{
pos += skip;
return *this_derived();
}
constexpr derived_t operator+(difference_type const skip) const noexcept
{
derived_t cpy{*this_derived()};
return cpy += skip;
}
constexpr friend derived_t operator+(difference_type const skip, derived_t const & it) noexcept
{
return it + skip;
}
constexpr derived_t & operator-=(difference_type const skip) noexcept
{
pos -= skip;
return *this_derived();
}
constexpr derived_t operator-(difference_type const skip) const noexcept
{
derived_t cpy{*this_derived()};
return cpy -= skip;
}
constexpr friend derived_t operator-(difference_type const skip, derived_t const & it) noexcept
{
return it - skip;
}
constexpr friend difference_type operator-(derived_t const & lhs, derived_t const & rhs) noexcept
{
return static_cast<difference_type>(lhs.pos - rhs.pos);
}
constexpr reference operator*() const noexcept(noexcept((*host)[pos]))
{
return (*host)[pos];
}
constexpr pointer operator->() const noexcept(noexcept((&host)[pos]))
{
return &host[pos];
}
constexpr reference operator[](position_type const n) const noexcept(noexcept((*host)[pos + n]))
{
return (*host)[pos + n];
}
private:
constexpr derived_t * this_derived()
{
return static_cast<derived_t *>(this);
}
constexpr derived_t const * this_derived() const
{
return static_cast<derived_t const *>(this);
}
};
template <typename range_type>
class random_access_iterator : public random_access_iterator_base<range_type, random_access_iterator>
{
private:
using base = random_access_iterator_base<range_type, random_access_iterator>;
using typename base::position_type;
public:
using typename base::const_reference;
using typename base::difference_type;
using typename base::iterator_category;
using typename base::pointer;
using typename base::reference;
using typename base::value_type;
using base::base;
};
} // namespace seqan3::detail
cassert
std::is_const_v
T is_const_v
std::is_same_v
T is_same_v
iterator
platform.hpp
Provides platform and dependency checks.
type_traits
Hide me