#ifndef XGBOOST_COMMON_TRANSFORM_ITERATOR_H_
#define XGBOOST_COMMON_TRANSFORM_ITERATOR_H_
#include <cstddef>
#include <iterator>
#include <type_traits>
#include <utility>
#include "xgboost/span.h"
namespace xgboost {
namespace common {
template <typename Fn>
class IndexTransformIter {
std::size_t iter_{0};
Fn fn_;
public:
using iterator_category = std::random_access_iterator_tag; using reference = std::invoke_result_t<Fn, std::size_t>; using value_type = std::remove_cv_t<std::remove_reference_t<reference>>; using difference_type = detail::ptrdiff_t; using pointer = std::add_pointer_t<value_type>;
public:
explicit IndexTransformIter(Fn &&op) : fn_{op} {}
IndexTransformIter(IndexTransformIter const &) = default;
IndexTransformIter &operator=(IndexTransformIter &&) = default;
IndexTransformIter &operator=(IndexTransformIter const &that) {
iter_ = that.iter_;
return *this;
}
reference operator*() const { return fn_(iter_); }
reference operator[](std::size_t i) const {
auto iter = *this + i;
return *iter;
}
auto operator-(IndexTransformIter const &that) const { return iter_ - that.iter_; }
bool operator==(IndexTransformIter const &that) const { return iter_ == that.iter_; }
bool operator!=(IndexTransformIter const &that) const { return !(*this == that); }
IndexTransformIter &operator++() {
iter_++;
return *this;
}
IndexTransformIter operator++(int) {
auto ret = *this;
++(*this);
return ret;
}
IndexTransformIter &operator--() {
iter_--;
return *this;
}
IndexTransformIter operator--(int) {
auto ret = *this;
--(*this);
return ret;
}
IndexTransformIter &operator+=(difference_type n) {
iter_ += n;
return *this;
}
IndexTransformIter &operator-=(difference_type n) {
(*this) += -n;
return *this;
}
IndexTransformIter operator+(difference_type n) const {
auto ret = *this;
return ret += n;
}
IndexTransformIter operator-(difference_type n) const {
auto ret = *this;
return ret -= n;
}
};
template <typename Fn>
auto MakeIndexTransformIter(Fn &&fn) {
return IndexTransformIter<Fn>(std::forward<Fn>(fn));
}
} } #endif