#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <random>
#include <algorithm>

struct Card
{
    enum Suit { Spades, Hearts, Clubs, Diamonds };
    enum Face { Ace, Deuce, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King };

    static const unsigned longestFace = 5;

    Suit suit;
    Face face;
};

std::string as_string(Card::Suit suit)
{
    static const char* suit_str[] = { "Spades", "Hearts", "Clubs", "Diamonds" };
    return suit_str[suit];
}

std::string as_string(Card::Face face)
{
    static const char* face_str[] = { 
        "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
        "Eight", "Nine", "Ten", "Jack", "Queen", "King" 
    };

    return face_str[face];
}

std::ostream& operator<<(std::ostream& os, Card c)
{
    os << std::right << std::setw(Card::longestFace);
    os << as_string(c.face) << " of " << as_string(c.suit) ;

    return os;
}

template <typename iter_type>
void printCards(iter_type beg, iter_type end)
{
    while (beg != end)
        std::cout << *beg++ << '\n';
}

int main()
{
    std::vector<Card> cards;
    for ( unsigned s=0; s<4; ++s)
        for (unsigned f = 0; f < 13; ++f)
            cards.push_back({ Card::Suit(s), Card::Face(f) });

    std::mt19937 rng((std::random_device())());

    for (unsigned runs = 0; runs < 5; ++runs)
    {
        std::shuffle(cards.begin(), cards.end(), rng);
        printCards(cards.begin(), cards.begin() + 5);
        std::cout << '\n';
    }
}