I just learned Adapter Pattern, and I have used STL for some time. I know that the std::stack is a adapter for sequence container (say, vector, list, etc,). So I try to implement a naive stack alike class. Here is the code snippet below.
How to make it better? I have three main concerns.
For
template <typename T, class Container=std::vector<T>>
void test_mulit_lower_container()
- How to limit
Tto numeric type and theContainerto sequence container? - how to make the type of Container is depend on the type of T?
About unique pointer
- Comparing use an instance of an instance of container(say, make the said instance as an object, but it seems impossible because the
stackhave many different kinds of ctors, so the lower container should be created dynamically), is it the right choice to use the unique_ptr?
#include <vector>
#include <memory>
#include <iostream>
#include <list>
#include <deque>
template<class T, class Container=std::vector<T>>
class AdapterForStack
{
public:
using value_type = T;
AdapterForStack()
{
m_continer_ptr = std::unique_ptr<Container>(new Container());
}
bool empty()
{
return m_continer_ptr->empty();
}
size_t size()
{
return m_continer_ptr->size();
}
void push( const value_type& value )
{
m_continer_ptr->insert(m_continer_ptr->begin(), value);
return;
}
void push(value_type&& value )
{
m_continer_ptr->push_front(std::move(value));
return;
}
const value_type& top()
{
return m_continer_ptr->front();
}
void pop()
{
m_continer_ptr->erase(m_continer_ptr->begin());
return;
}
private:
std::unique_ptr<Container> m_continer_ptr;
};
template <typename T, class Container=std::vector<T>> //How to make it better?
void test_mulit_lower_container() //1. limit T to numberic type and the cont to seq cont
{ // 2. how to make the type of Container is depend on the type of T?
{
AdapterForStack<T, std::list<T>> stack{};
T default_val{};
for(int i=0; i<9; i++, default_val++)
{
stack.push(default_val);
}
while(!stack.empty())
{
std::cout << stack.top() << std::endl;
stack.pop();
}
}
}
int main()
{
#if 1
std::cout << "underline type is vector" << std::endl;
test_mulit_lower_container<int, std::vector<int>>();
std::cout << "underline type is list" << std::endl;
test_mulit_lower_container<int, std::list<int>>();
std::cout << "underline type is deque" << std::endl;
test_mulit_lower_container<int, std::deque<int>>();
#else
std::cout << "lower type is vector" << std::endl;
{
AdapterForStack<int> stack{};
for(int i=0; i<9; i++)
{
stack.push(i);
}
while(!stack.empty())
{
std::cout << stack.top() << std::endl;
stack.pop();
}
}
std::cout << "lower type is list" << std::endl;
{
AdapterForStack<int, std::list<int>> stack{};
for(int i=0; i<9; i++)
{
stack.push(i);
}
while(!stack.empty())
{
std::cout << stack.top() << std::endl;
stack.pop();
}
}
std::cout << "lower type is deque" << std::endl;
{
AdapterForStack<int, std::deque<int>> stack{};
for(int i=0; i<9; i++)
{
stack.push(i);
}
while(!stack.empty())
{
std::cout << stack.top() << std::endl;
stack.pop();
}
}
#endif
}