#include<iostream>
using namespace std;
template <class Ty>
class D{
long long int frn,bac;
long long int s,len;
Ty *dq;
public:
D()
{
frn=-1;
bac=-1;
s=0;
len=0;
}
D(long long int si,Ty x)
{
frn=-1;
bac=-1;
s=0;
s=si;
dq=new Ty[s];
len=1;
frn=0;
bac=0;
dq[bac]=x;
for(long long int i=1;i<si;i++)
{
bac=(bac+1)%s;
dq[bac]=x;
len++;
}
}
bool empty()
{
return frn==-1;
}
bool isFull()
{
return (bac+1)%s==frn;
}
void resize(long long int x)
{
Ty *tem,*t1;
long long int os=s;
//cout<<"os="<<os<<endl;
//cout<<"s="<<s<<endl;
t1=new Ty[os];
tem=dq;
long long int k=0;
for(long long int i=frn;i!=(bac+1)%os;i=(i+1)%os)
{
t1[k++]=tem[i];
}
frn=0;
bac=k-1;
if(os<=x){
s=x;
//cout<<"in line 62 bac= s= len="<<bac<<s<<len<<endl;
dq=new Ty[s];
for(long long int i=frn;i!=(bac+1)%os;i=(i+1)%os)
{
dq[i]=t1[i];
}
delete [] t1;
for(long long int i=bac+1;i<s;i++)
{
dq[i]=0;
bac++;
len++;
}
}
else
{
s=x;
//cout<<"in line 79 s="<<s<<endl;
dq=new Ty[s];
for(long long int i=frn;i!=(bac+1)%os;i=(i+1)%os)
{
dq[i]=t1[i];
}
delete [] t1;
if(len>s){
//cout<<"in line 87 len= s="<<len<<"" ""<<s<<endl;
long long int count=len-s;
for(long long int i=0;i<count;i++)
{
bac--;
s--;
len--;
}
}
else
{
long long int count =s-len;
for(long long int i=0;i<count;i++)
{
dq[i+bac+1]=0;
len++;
}
bac=bac+count;
}
}
}
void resize_ar()
{
Ty *tem;
long long int os=s;
s=2*s;
tem=dq;
dq=new Ty[s];
for(long long int i=0;i<os;i++)
{
dq[i]=tem[i];
}
delete [] tem;
if(bac<frn)
{
//cout<<"in line 56\n";
for(long long int i=0;i<frn;i++)
{
dq[i+os]=this->dq[i];
}
bac=(bac+os)%s;
}
}
void push_back(Ty x)
{
if(isFull())
{
resize_ar();
bac=(bac+1)%s;
dq[bac]=x;
//cout<<"in line 70\n";
len++;
}
else
{
if(frn==-1)
{
frn=0;
bac=0;
dq[bac]=x;
len=1;
}
else
{
bac=(bac+1)%s;
dq[bac]=x;
len++;
}
}
}
void pop_front()
{
if(empty())
{
//cout<<"Queue is empty"<<endl;
}
else
{
len--;
if(frn==bac)
{
frn=-1;
bac=-1;
}
else
{
frn=(frn+1)%s;
}
}
}
void pop_back()
{
if(empty())
{
//cout<<"Queue is empty"<<endl;
}
else
{
len--;
if(frn==bac)
{
frn=-1;
bac=-1;
}
else
{
if(bac==0)
bac=s-1;
else
bac=(bac-1)%s;
}
}
}
void push_front(Ty x)
{
if(isFull())
{
resize_ar();
if(frn!=0){
frn=(frn-1)%s;
dq[frn]=x;
len++;
}
else{
frn=s-1;
dq[frn] =x;
len++;
}
}
else
{
if(frn==-1)
{
frn=0;
bac=0;
dq[bac]=x;
len=1;
}
else
{
if(frn!=0){
frn=(frn-1)%s;
dq[frn]=x;
len++;
}
else{
frn=s-1;
dq[frn] =x;
len++;
}
}
}
}
Ty operator [] (long long int x)
{
return dq[x];
}
Ty front()
{
return dq[frn];
}
Ty back()
{
return dq[bac];
}
void display()
{
cout<<"frn="<<frn<<" "<<"bac="<<bac<<" "<<"s="<<s<<" "<<"len="<<len<<endl;
for(long long int i=0;i<len;i++)
{
cout<<dq[(frn+i)%s]<<endl;
}
}
};
int main()
{
D<int>q(5,4);
q.display();
//cout<<"Pushback60"<<endl;
q.push_back(60);
q.display();
q.resize(6);
q.display();
//cout<<"popback"<<endl;
q.pop_back();
q.display();
//cout<<"popfront"<<endl;
q.pop_front();
q.display();
//cout<<"push_front70"<<endl;
q.push_front(70);
q.display();
//cout<<"push_front70"<<endl;
q.push_front(70);
q.display();
//cout<<"push_front80,90,100,63"<<endl;
q.push_back(80);
q.push_back(90);
q.push_back(100);
q.push_back(63);
q.display();
//cout<<"push_back65"<<endl;
q.push_back(65);
q.display();
//cout<<"pop_back()*2"<<endl;
q.pop_back();
q.pop_back();
q.display();
q.resize(11);
q.display();
}