#pragma once #include #include #include namespace xrpl { class ReadView; namespace detail { // A type-erased ForwardIterator // template class ReadViewFwdIter { public: using base_type = ReadViewFwdIter; using value_type = ValueType; ReadViewFwdIter() = default; ReadViewFwdIter(ReadViewFwdIter const&) = default; ReadViewFwdIter& operator=(ReadViewFwdIter const&) = default; virtual ~ReadViewFwdIter() = default; [[nodiscard]] virtual std::unique_ptr copy() const = 0; [[nodiscard]] virtual bool equal(ReadViewFwdIter const& impl) const = 0; virtual void increment() = 0; [[nodiscard]] virtual value_type dereference() const = 0; }; // A range using type-erased ForwardIterator // template class ReadViewFwdRange { public: using iter_base = ReadViewFwdIter; static_assert( std::is_nothrow_move_constructible{}, "ReadViewFwdRange move and move assign constructors should be " "noexcept"); class iterator { public: using value_type = ValueType; using pointer = value_type const*; using reference = value_type const&; using difference_type = std::ptrdiff_t; using iterator_category = std::forward_iterator_tag; iterator() = default; iterator(iterator const& other); iterator(iterator&& other) noexcept; // Used by the implementation explicit iterator(ReadView const* view, std::unique_ptr impl); iterator& operator=(iterator const& other); iterator& operator=(iterator&& other) noexcept; bool operator==(iterator const& other) const; bool operator!=(iterator const& other) const; // Can throw reference operator*() const; // Can throw pointer operator->() const; iterator& operator++(); iterator operator++(int); private: ReadView const* view_ = nullptr; std::unique_ptr impl_{}; std::optional mutable cache_; }; static_assert(std::is_nothrow_move_constructible{}, ""); static_assert(std::is_nothrow_move_assignable{}, ""); using const_iterator = iterator; using value_type = ValueType; ReadViewFwdRange() = delete; ReadViewFwdRange(ReadViewFwdRange const&) = default; ReadViewFwdRange& operator=(ReadViewFwdRange const&) = default; explicit ReadViewFwdRange(ReadView const& view) : view_(&view) { } protected: ReadView const* view_; }; } // namespace detail } // namespace xrpl