#include <iostream>
#include <queue>
#include <tuple>
#include <boost/ptr_container/ptr_vector.hpp>

struct point
{
    int x;
    int y;
};

bool operator<(const point& lhs, const point& rhs)
{
    return std::tie(lhs.x, lhs.y) < std::tie(rhs.x, rhs.y);
}

std::ostream& operator<<(std::ostream& out, const point& p)
{
    return out << p.x << ' ' << p.y;
}

namespace detail
{
    template<typename>
    struct ptr_less;

    template<typename T>
    struct ptr_less<T*>
    {
        bool operator()(const T& lhs, const T& rhs)
        {
            return lhs < rhs;
        }
    };
}

template<typename T>
using ptr_priority_queue = std::priority_queue<T*, boost::ptr_vector<T>, detail::ptr_less<T*>>;

int main()
{
    // std::priority_queue<point*, boost::ptr_vector<point>, detail::ptr_less<point*>> points;
    ptr_priority_queue<point> points;

    points.push(new point{4, 1});
    points.push(new point{3, 2});
    points.push(new point{1, 6});
    points.push(new point{3, 4});

    while (!points.empty())
    {
        std::cout << points.top() << std::endl;
        points.pop();
    }

    return 0;
}

// Sample output:
// 4 1
// 3 4
// 3 2
// 1 6