#include<atomic>
#include<utility>
#include<stdexcept>
#include<thread>
#include<iostream>
#include<atomic>
#include<utility>
#include<stdexcept>
#include<thread>
#include<iostream>
#include<vector>
template <typename T, size_t max_size = 20>
class lf_queue{
T queue[max_size];
std::atomic<size_t> _size;
const size_t _maxs;
size_t _read_pos;
size_t _write_pos;
public:
//constructor
lf_queue()
: _maxs(max_size), _size(0), _read_pos(0), _write_pos(0)
{}
void push( const T& item ) {
if (_size.load() == _maxs) {
std::cout<<"queue is full" <<std::endl;
//throw exception
}
queue[_write_pos]= item;
_write_pos = (_write_pos+1) % _maxs;
_size.fetch_add(1);
}
T& front() {
if(_size.load()>0) {
return queue[_read_pos];
}
}
void pop() {
if(_size.load()>0) {
_read_pos = (_read_pos + 1) % _maxs;
_size.fetch_sub(1);
}
}
size_t size() {
return _size.load();
}
bool full() {
return _size.load() == _maxs;
}
bool empty() {
return _size.load() == 0;
}
};
#endif
//main
int main(){
const int sz = 100;
lf_queue<int,sz> q;
std::vector<int> res;
auto reader = [&res,&q](){
for(int i=0; i<sz;){
if( !q.empty() ){
auto k = q.front();
q.pop();
res.push_back(k);
std::cout<< "front :" << k << std::endl;
++i;
}
}
};
auto writer = [&q](){
for(int i=0; i< sz;) {
if( !q.full() ) {
q.push(i);
std::cout<< "push: " << i << std::endl;
++i;
}
}
};
auto t1 = std::thread(writer);
auto t2 = std::thread(reader);
t1.join();
t2.join();
std::cout<<"queue size " << q.size()<<std::endl;
if( !q.empty() ) {
std::cout<<"queue front: " << q.front()<< std::endl;
}
std::cout<<"All elements:"<<std::endl;
for(auto& it : res) {
std::cout<< it <<std::endl;
}
}