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

using namespace std;

struct Account
{
    string Name;
    int Position;
    int Score;
};

//overloading bool operator sorting by position
bool operator<(const Account& lhs, const Account& rhs)
{
    return lhs.Position < rhs.Position;
}

//comparing using predicate
bool compare_by_score(const Account& lhs, const Account& rhs)
{
    return lhs.Score < rhs.Score;
}


void print_account(const Account& acc)
{
    std::cout << std::setw(6) << acc.Name << " holds " << acc.Position <<
                 " position with score " << acc.Score << '\n';
}

int main()
{
    std::vector<Account> data {{"John", 2, 56}, {"Sarah", 3, 12}, {"Rick", 5, 3},
                               {"Miles", 1, 41}, {"Jane", 4, 60} };
    for(const auto& acc: data)
        print_account(acc);

    std::cout << "\nDefault sorting, sorts using operator <:\n";
    std::sort(data.begin(), data.end());
    for(const auto& acc: data)
        print_account(acc);

    std::cout << "\nSorting using predicate:\n";
    std::sort(data.begin(), data.end(), compare_by_score);
    for(const auto& acc: data)
        print_account(acc);

    std::cout << "\nSorting using lambdas:\n";
    std::sort(data.begin(), data.end(),
              [](const Account& lhs, const Account& rhs){return lhs.Name < rhs.Name;});
    for(const auto& acc: data)
        print_account(acc);
}