#pragma once #include #include namespace arti::lang { struct Tokenizer; struct [[nodiscard]] TokenizerRange { friend struct Tokenizer; struct Iterator; struct Sentinel; using iterator_type = Iterator; using sentinel_type = Sentinel; TokenizerRange(TokenizerRange &&) noexcept; TokenizerRange &operator=(TokenizerRange &&) noexcept; TokenizerRange(const TokenizerRange &) noexcept = delete; TokenizerRange &operator=(const TokenizerRange &) noexcept = delete; Iterator begin(); Sentinel end() const noexcept; struct Iterator { friend struct TokenizerRange; using iterator_category = std::input_iterator_tag; using difference_type = std::ptrdiff_t; using ValueType = Expected; using ReferenceType = ValueType &; using PointerType = ValueType *; using value_type = ValueType; using pointer_type = PointerType; Iterator(Iterator &&) noexcept; Iterator &operator=(Iterator &&) noexcept; Iterator(const Iterator &) noexcept = delete; Iterator &operator=(const Iterator &) noexcept = delete; Iterator &operator++(); void operator++(int); ReferenceType operator*() const noexcept; PointerType operator->() const noexcept; friend bool operator==(const Iterator &, Sentinel); friend bool operator==(Sentinel, const Iterator &); friend bool operator!=(const Iterator &, Sentinel); friend bool operator!=(Sentinel, const Iterator &); private: Iterator(Tokenizer *tokenizer) noexcept; Tokenizer *tokenizer; mutable Expected cvalue; }; struct Sentinel {}; private: TokenizerRange(Tokenizer *tokenizer); Tokenizer *tokenizer; }; }