@@ -13,7 +13,7 @@ namespace msd {
1313 *
1414 * Used to implement channel range-based for loop.
1515 *
16- * @tparam Channel Instance of channel.
16+ * @tparam Channel Type of channel being iterated .
1717 */
1818template <typename Channel>
1919class blocking_iterator {
@@ -47,41 +47,146 @@ class blocking_iterator {
4747 * @brief Constructs a blocking iterator from a channel reference.
4848 *
4949 * @param chan Reference to the channel this iterator will iterate over.
50+ * @param is_end If true, the iterator is in an end state (no elements to read).
5051 */
51- explicit blocking_iterator (Channel& chan) : chan_{chan} {}
52+ explicit blocking_iterator (Channel& chan, bool is_end = false ) : chan_{&chan}, is_end_{is_end}
53+ {
54+ if (!is_end_ && !chan_->read (value_)) {
55+ is_end_ = true ;
56+ }
57+ }
5258
5359 /* *
54- * @brief Advances the iterator to the next element .
60+ * @brief Retrieves the next element from the channel .
5561 *
5662 * @return The iterator itself.
5763 */
58- blocking_iterator<Channel> operator ++() const noexcept { return *this ; }
64+ blocking_iterator<Channel> operator ++() noexcept
65+ {
66+ if (!chan_->read (value_)) {
67+ is_end_ = true ;
68+ }
69+ return *this ;
70+ }
5971
6072 /* *
61- * @brief Retrieves and returns the next element from the channel.
73+ * @brief Returns the latest element retrieved from the channel.
6274 *
63- * @return A const reference to the current element.
75+ * @return A const reference to the element.
6476 */
65- reference operator *()
66- {
67- chan_.read (value_);
68-
69- return value_;
70- }
77+ reference operator *() { return value_; }
7178
7279 /* *
7380 * @brief Makes iteration continue until the channel is closed and empty.
7481 *
82+ * @param other Another blocking_iterator to compare with.
83+ *
7584 * @return true if the channel is not closed or not empty (continue iterating).
7685 * @return false if the channel is closed and empty (stop iterating).
7786 */
78- bool operator !=(blocking_iterator<Channel>) const { return !chan_. drained () ; }
87+ bool operator !=(const blocking_iterator& other) { return is_end_ != other. is_end_ ; }
7988
8089 private:
81- Channel& chan_;
90+ Channel* chan_;
8291 value_type value_{};
92+ bool is_end_{false };
93+ };
94+
95+ /* *
96+ * @brief An output iterator pushes elements into a channel. Blocking until the channel is not full.
97+ *
98+ * Used to integrate with standard algorithms that require an output iterator.
99+ *
100+ * @tparam Channel Type of channel being iterated.
101+ */
102+ template <typename Channel>
103+ class blocking_writer_iterator {
104+ public:
105+ /* *
106+ * @brief The type of the elements stored in the channel.
107+ */
108+ using value_type = typename Channel::value_type;
109+
110+ /* *
111+ * @brief Constant reference to the type of the elements stored in the channel.
112+ */
113+ using reference = const value_type&;
114+
115+ /* *
116+ * @brief Supporting writing of elements.
117+ */
118+ using iterator_category = std::output_iterator_tag;
119+
120+ /* *
121+ * @brief Signed integral type for iterator difference.
122+ */
123+ using difference_type = std::ptrdiff_t ;
124+
125+ /* *
126+ * @brief Pointer type to the value_type.
127+ */
128+ using pointer = const value_type*;
129+
130+ /* *
131+ * @brief Constructs a blocking iterator from a channel reference.
132+ *
133+ * @param chan Reference to the channel this iterator will write into.
134+ */
135+ explicit blocking_writer_iterator (Channel& chan) : chan_{&chan} {}
136+
137+ /* *
138+ * @brief Writes an element into the channel, blocking until space is available.
139+ *
140+ * @param val The value to be written into the channel.
141+ *
142+ * @return The iterator itself.
143+ */
144+ blocking_writer_iterator& operator =(const value_type& val)
145+ {
146+ chan_->write (val);
147+ return *this ;
148+ }
149+
150+ /* *
151+ * @brief Not applicable (handled by operator=).
152+ *
153+ * @return The iterator itself.
154+ */
155+ blocking_writer_iterator& operator *() { return *this ; }
156+
157+ /* *
158+ * @brief Not applicable (handled by operator=).
159+ *
160+ * @return The iterator itself.
161+ */
162+ blocking_writer_iterator& operator ++() { return *this ; }
163+
164+ /* *
165+ * @brief Not applicable (handled by operator=).
166+ *
167+ * @return The iterator itself.
168+ */
169+ blocking_writer_iterator operator ++(int ) { return *this ; }
170+
171+ private:
172+ Channel* chan_;
83173};
84174
175+ /* *
176+ * @brief Creates a blocking iterator for the given channel.
177+ *
178+ * @tparam Channel Type of channel being iterated.
179+ *
180+ * @param chan Reference to the channel this iterator will iterate over.
181+ *
182+ * @return A blocking iterator for the specified channel.
183+ */
184+ template <typename Channel>
185+ blocking_writer_iterator<Channel> back_inserter (Channel& chan)
186+ {
187+ return blocking_writer_iterator<Channel>{chan};
188+ }
189+
85190} // namespace msd
86191
87192#endif // MSD_CHANNEL_BLOCKING_ITERATOR_HPP_
0 commit comments