diff --git a/source/mijin/async/message_queue.hpp b/source/mijin/async/message_queue.hpp index a48791d..90dc4d2 100644 --- a/source/mijin/async/message_queue.hpp +++ b/source/mijin/async/message_queue.hpp @@ -25,9 +25,59 @@ namespace mijin // public types // +template +class MessageQueueIterator +{ +public: + using value_type = typename TMessageQueue::message_t; + using reference = value_type&; + using pointer = value_type*; +private: + TMessageQueue* queue_ = nullptr; + std::optional message_; +public: + MessageQueueIterator() = default; + explicit MessageQueueIterator(TMessageQueue& queue) noexcept : queue_(&queue) { + message_ = queue_->tryPop(); + } + MessageQueueIterator(const MessageQueueIterator&) = delete; + MessageQueueIterator(MessageQueueIterator&&) = default; + + MessageQueueIterator& operator=(const MessageQueueIterator&) = delete; + MessageQueueIterator& operator=(MessageQueueIterator&&) = default; + + bool operator==(const MessageQueueIterator& other) noexcept + { + return message_.has_value() == other.message_.has_value(); + } + bool operator!=(const MessageQueueIterator& other) noexcept + { + return !(*this == other); + } + + reference operator*() noexcept + { + return message_.value(); + } + + pointer operator->() noexcept + { + return &message_.value(); + } + + MessageQueueIterator& operator++() noexcept + { + message_ = queue_->tryPop(); + return *this; + } +}; + template class MessageQueue { +public: + using message_t = TMessage; + using iterator_t = MessageQueueIterator>; private: std::array messages; mijin::BitArray messageReady; @@ -48,6 +98,9 @@ public: void push(TMessage message); [[nodiscard]] std::optional tryPop(); [[nodiscard]] TMessage wait(); + + iterator_t begin() noexcept { return iterator_t(*this); } + iterator_t end() noexcept { return iterator_t(); } }; template