#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
template<typename T>
class BoundedBlockingQueue {
private:
std::vector<T> buffer; // Fixed-size buffer (circular)
int capacity; // Maximum size
int head = 0; // Index to dequeue from
int tail = 0; // Index to enqueue to
int count = 0; // Number of elements
std::mutex mtx;
std::condition_variable not_full;
std::condition_variable not_empty;
public:
BoundedBlockingQueue(int cap) : capacity(cap), buffer(cap) {}
void enqueue(T item) {
std::unique_lock<std::mutex> lock(mtx);
// Wait until there's space
not_full.wait(lock, [this]() { return count < capacity; });
buffer[tail] = item;
tail = (tail + 1) % capacity;
count++;
// Notify one waiting consumer
not_empty.notify_one();
}
T dequeue() {
std::unique_lock<std::mutex> lock(mtx);
// Wait until there's at least one item
not_empty.wait(lock, [this]() { return count > 0; });
T item = buffer[head];
head = (head + 1) % capacity;
count--;
// Notify one waiting producer
not_full.notify_one();
return item;
}
int size() {
std::lock_guard<std::mutex> lock(mtx);
return count;
}
};
int main() {
BoundedBlockingQueue<int> bbq(3);
std::thread producer([&]() {
for (int i = 1; i <= 6; ++i) {
bbq.enqueue(i);
std::cout << "Produced: " << i << std::endl;
}
});
std::thread consumer([&]() {
for (int i = 1; i <= 6; ++i) {
int val = bbq.dequeue();
std::cout << "Consumed: " << val << std::endl;
}
});
producer.join();
consumer.join();
return 0;
}
| Operation | Time | Space |
| --------- | ---- | ----- |
| `enqueue` | O(1) | O(N) |
| `dequeue` | O(1) | O(N) |