A channel is a thread-safe queue which uses semaphores to synchronize access. The underlying queue in this implementation is the C++ std::queue container. It uses two semaphores sem_free_spaces_ to count the free spaces in the queue and avoid overflow and sem_size_ to count the elements in the queue and prevent underflow. In addition a std::mutex is used to synchronize access to the queue.
To enqueue an element to the channel the sem_free_spaces_ semaphore is first decremented which will block on a full queue and then increments the sem_size_ semaphore after adding the element to the queue.
Dequeuing works the opposite way by first decrementing sem_size_ to block on an empty queue.
In addition the << operator has been overloaded to move items into the channel or out of it. It also supports moving an item directly from one channel to another.