Skip to content

Instantly share code, notes, and snippets.

@sjolsen
Created March 5, 2014 04:45
Show Gist options
  • Save sjolsen/9361337 to your computer and use it in GitHub Desktop.
Save sjolsen/9361337 to your computer and use it in GitHub Desktop.
#include <stack>
#include <unordered_map>
#include <typeindex>
class MultiStack
{
class MultiStackBase
{
public:
virtual ~MultiStackBase () = default;
};
template <typename T>
class MultiStackImpl
: public MultiStackBase
{
std::stack <T> _stack;
public:
virtual ~MultiStackImpl () = default;
template <typename U>
void push (U&& new_element)
{ _stack.push (std::forward <U> (new_element)); }
void pop ()
{ _stack.pop (); }
T& top ()
{ return _stack.top (); }
const T& top () const
{ return _stack.top (); }
};
std::unordered_map <std::type_index, std::unique_ptr <MultiStackBase>> stacks;
protected:
template <typename T>
static std::type_index index ()
{ return std::type_index {typeid (T)}; }
template <typename T>
MultiStackImpl <T>& stack_cast ()
{
if (stacks.count (index <T> ()) == 0)
stacks [index <T> ()] = std::make_unique <MultiStackImpl <T>> ();
return dynamic_cast <MultiStackImpl <T>&> (*stacks [index <T> ()]);
}
template <typename T>
const MultiStackImpl <T>& stack_cast () const
{
if (stacks.count (index <T> ()) == 0)
stacks [index <T> ()] = std::make_unique <MultiStackImpl <T>> ();
return dynamic_cast <MultiStackImpl <T>&> (*stacks [index <T> ()]);
}
public:
template <typename T, typename U>
void push (U&& new_element)
{ stack_cast <T> ().push (std::forward <U> (new_element)); }
template <typename T>
void pop ()
{ stack_cast <T> ().pop (); }
template <typename T>
T& top ()
{ return stack_cast <T> ().top (); }
template <typename T>
const T& top () const
{ return stack_cast <T> ().top (); }
};
#include <iostream>
int main ()
{
MultiStack m;
m.push <int> (42);
m.push <float> (3.14);
std::cout << m.top <int> () << std::endl
<< m.top <float> () << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment