#include <iostream>
#include <memory>

template<typename T, typename ...Args>
std::unique_ptr<T> make_unique( Args&& ...args )
{
    return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) );
}

class StateManager;

class State
{
public:
    virtual void update(StateManager &manager)= 0;
    virtual ~State(){}
};




class StateManager
{
public:
    void setState(std::unique_ptr<State> && newState )
    {
        currentState = std::move(newState);
    }
    std::unique_ptr<State> currentState;
    
    void run()
    {
        currentState->update(*this);
    }
};


class SecondState : public State
{
public:
    SecondState()
    {
        std::cout<<"CONSTRUCTOR: Second State"<<std::endl;
    }

    virtual void update(StateManager &manager)
    {
        std::cout<<"UPDATE: Second State"<<std::endl;
    }
    
    virtual ~SecondState()
    {
        std::cout<<"DESTRUCTOR: Second State"<<std::endl;
    }
};


class FirstState : public State
{
public:
    FirstState()
    {
        std::cout<<"CONSTRUCTOR: FirstState"<<std::endl;
    }

    virtual void update(StateManager &manager)
    {
        std::cout<<"UPDATE: FirstState"<<std::endl;
        manager.setState(make_unique<SecondState>());
        std::cout<<"UPDATE-ENDING: FirstState"<<std::endl;
        
    }
    
    virtual ~FirstState()
    {
        std::cout<<"DESTRUCTOR: FirstState"<<std::endl;
    }
};


int main()
{
    
    StateManager manager;
    manager.setState(make_unique<FirstState>());
    manager.run();
    manager.run();

}