Program Listing for File IteratorAdapter.hpp

Return to documentation for file (src/navtk/utils/IteratorAdapter.hpp)

#pragma once

#include <cstddef>
#include <iterator>
#include <type_traits>

namespace navtk {
namespace utils {

template <typename Iterator, typename T, T (*get_value)(Iterator)>
class IteratorAdapter {
private:
    Iterator it;

public:
    using difference_type = std::ptrdiff_t;
    using value_type = std::remove_const_t<T>;
    using pointer = value_type*;
    using reference = value_type&;
    using iterator_category = std::random_access_iterator_tag;

    explicit IteratorAdapter(Iterator it) : it(it) {}

    operator Iterator() { return it; }

    bool operator==(const IteratorAdapter& rhs) { return it == rhs.it; }

    bool operator!=(const IteratorAdapter& rhs) { return !(it == rhs.it); }

    IteratorAdapter& operator++() {
        ++it;
        return *this;
    }

    IteratorAdapter operator++(int) {
        auto t = *this;
        ++it;
        return t;
    }

    IteratorAdapter operator+(int amount) const { return IteratorAdapter(it + amount); }

    IteratorAdapter operator-(int amount) const { return IteratorAdapter(it - amount); }

    IteratorAdapter& operator--() {
        --it;
        return *this;
    }

    IteratorAdapter operator--(int) {
        auto t = *this;
        --it;
        return t;
    }

    std::ptrdiff_t operator-(IteratorAdapter const& rhs) const { return it - rhs.it; }

    IteratorAdapter& operator+=(int amount) {
        it += amount;
        return *this;
    }

    IteratorAdapter& operator-=(int amount) {
        it -= amount;
        return *this;
    }

    bool operator<(IteratorAdapter const& rhs) const { return it < rhs.it; }

    bool operator<=(IteratorAdapter const& rhs) const { return it <= rhs.it; }

    bool operator>(IteratorAdapter const& rhs) const { return it > rhs.it; }

    bool operator>=(IteratorAdapter const& rhs) const { return it >= rhs.it; }

    auto operator[](int index) const { return get_value(it + index); }

    auto operator*() const { return get_value(it); }

    auto operator->() const { return &get_value(it); }
};

}  // namespace utils
}  // namespace navtk