//#include "stdafx.h"
#include <iostream>
#include <stack>
#include <queue>
#include <typeinfo>
#include <string.h>

using namespace std;

template <class T, class S, class C> S& Container(priority_queue<T, S, C>& pq) 
{
	struct hpQueue : private priority_queue<T, S, C> {static S& Container(priority_queue<T, S, C>& pq){return pq.*&hpQueue::c;}};
	return hpQueue::Container(pq);
}

template <class T, class S> S& Container(stack<T, S>& s)
{
	struct hStack : private stack<T, S>{static S& Container(stack<T, S>& s){return s.*&hStack::c;}};
	return hStack::Container(s);
}

template <class T, class S> S& Container(queue<T, S>& q)
{
	struct hQueue : private queue<T, S> {static S& Container(queue<T, S>& q){return q.*&hQueue::c;}};
	return hQueue::Container(q);
}

template<class ContainerAdapter>
void print_sqp(ContainerAdapter& cad)
{
	bool isStack = (strstr(typeid(cad).name(), "class std::stack") != NULL);
	while (!cad.empty())
	{
		auto container = Container(cad);
		auto value = isStack ? container.back() : container.front();
		cout << value << " ";
		cad.pop();
    }
	cout << endl;
}

int main()
{
	std::stack<int> foo;
	std::queue<int> bar;
	std::priority_queue<int> baz;
	
	for(int n : {1,8,5,6,3,4,0,9,7,2})
	{
        foo.push(n);
        bar.push(n);
        baz.push(n);
	}   
	print_sqp(foo);
	print_sqp(bar);
	print_sqp(baz);

	return 0;
}
