It is not totally complete and a bit late (because of Deus Ex:HR).. but posting to see if I'm on the right track:

1.Are iterators supposed to be implemented the way I've done in this?

2.Is the design better compared to my earlier list ? Any more leaks?

< Doubly linked list... nitpick and test if possible >

3. The remove function works okay when in the middle, but at the extreme positions, it leaves a 0. I know this is because I'm not reseting the first and last pointers; but whenever I do so, the loop(for(auto x = foo.begin();x!=foo.end();x++)) runs forever.

Code:

namespace mm
{
template<typename T> class list
{
template <typename X> class node
{
public:
X val;
node<X>* next;
node<X>* prev;
node<X>(const T& t,node<T>* n,node<T>* p )
{
val =t;next = n;prev =p;
n->prev=this;
p->next=this;
};
node<X>(){prev = next = nullptr;};
~node<X>(){next->prev = prev;prev->next = next;}
};
node<T>* first;
node<T>* last;
node<T>* end_it;
node<T>* rend_it;
int size_val;
public:
class iterator
{
public:
node<T>* n;
iterator(node <T>* arg){n=arg;};
T& operator*(){return n->val;}
iterator operator++(int){n=n->next;return *this;};
iterator operator--(int){n=n->prev;return *this;};
bool operator!=(iterator it){return n!=it.n;};
bool operator==(iterator it){return n==it.n;};
};
iterator begin(){return iterator(first);};
iterator end(){return iterator(end_it);};
iterator rbegin(){return iterator(last);};
iterator rend(){return iterator(rend_it);};
list()
{
first= last = nullptr;size_val=0;
end_it = new node<T>();rend_it=new node<T>();
end_it->next = rend_it;
rend_it->prev = end_it;
}
void push_back(const T& t)
{
if(size_val==0)
{
auto new_node = new node<T>(t,end_it,rend_it);
first = last = new_node;
}
else
{
auto new_node = new node<T>(t,end_it,last);
last = new_node;
}
size_val++;
}
iterator insert(iterator& pos,const T& t)//Insert t before pos
{
auto new_node = new node<T>(t,pos.n,pos.n->prev);
if(pos.n==first)first= new_node;
else if(pos.n==end_it)last = new_node;
//else if (pos.n==rend_it) throw "<<something>>";
size_val++;
return iterator(new_node);
};
void remove(iterator pos){delete pos.n;}
};
}