#pragma once namespace xrpl::detail { template ReadViewFwdRange::Iterator::Iterator(Iterator const& other) : view_(other.view_), impl_(other.impl_ ? other.impl_->copy() : nullptr), cache_(other.cache_) { } template ReadViewFwdRange::Iterator::Iterator(Iterator&& other) noexcept : view_(other.view_), impl_(std::move(other.impl_)), cache_(std::move(other.cache_)) { } template ReadViewFwdRange::Iterator::Iterator( ReadView const* view, std::unique_ptr impl) : view_(view), impl_(std::move(impl)) { } template auto ReadViewFwdRange::Iterator::operator=(Iterator const& other) -> Iterator& { if (this != &other) { view_ = other.view_; impl_ = other.impl_ ? other.impl_->copy() : nullptr; cache_ = other.cache_; } return *this; } template auto ReadViewFwdRange::Iterator::operator=(Iterator&& other) noexcept -> Iterator& { if (this != &other) { view_ = other.view_; impl_ = std::move(other.impl_); cache_ = std::move(other.cache_); } return *this; } template bool ReadViewFwdRange::Iterator::operator==(Iterator const& other) const { XRPL_ASSERT( view_ == other.view_, "xrpl::detail::ReadViewFwdRange::iterator::operator==(iterator) " "const : input view match"); if (impl_ != nullptr && other.impl_ != nullptr) return impl_->equal(*other.impl_); return impl_ == other.impl_; } template bool ReadViewFwdRange::Iterator::operator!=(Iterator const& other) const { return !(*this == other); } template auto ReadViewFwdRange::Iterator::operator*() const -> reference { if (!cache_) cache_ = impl_->dereference(); return *cache_; } template auto ReadViewFwdRange::Iterator::operator->() const -> pointer { return &**this; } template auto ReadViewFwdRange::Iterator::operator++() -> Iterator& { impl_->increment(); cache_.reset(); return *this; } template auto ReadViewFwdRange::Iterator::operator++(int) -> Iterator { Iterator prev(view_, impl_->copy()); prev.cache_ = std::move(cache_); ++(*this); return prev; } } // namespace xrpl::detail