#pragma once #include "gp/algorithm/move.hpp" namespace gp{ template struct pair{ T1 first; T2 second; pair() : first(), second() {} pair(T1& a, T2& b) : first(a), second(b) {} pair(T1& a, T2&& b) : first(a), second(gp::move(b)) {} pair(T1&& a, T2& b) : first(gp::move(a)), second(b) {} pair(T1&& a, T2&& b) : first(gp::move(a)), second(gp::move(b)) {} pair(const pair& v) : first(v.first) , second(v.second) {} pair(pair& v) : first(v.first) , second(v.second) {} pair(pair&& v) : first(gp::move(v.first)) , second(gp::move(v.second)) {} template pair(pair&& v) : first(gp::move(v.first)) , second(gp::move(v.second)) {} pair& operator=(pair&& v) { first = gp::move(v.first); second = gp::move(v.second); return *this; } }; template bool operator==(const pair& lhs, const pair& rhs) { return lhs.first == rhs.first and lhs.second == rhs.second; } template bool operator!=(const pair& lhs, const pair& rhs) { return lhs.first != rhs.first or lhs.second != rhs.second; } template bool operator<=(const pair& lhs, const pair& rhs) { if(lhs.first > rhs.first) { return false; } else if(lhs.first == rhs.first) { return lhs.second <= rhs.second; } return true; } template bool operator>=(const pair& lhs, const pair& rhs) { if(lhs.first < rhs.first) { return false; } else if(lhs.first == rhs.first) { return lhs.second >= rhs.second; } return true; } template bool operator<(const pair& lhs, const pair& rhs) { return !(lhs >= rhs); } template bool operator>(const pair& lhs, const pair& rhs) { return !(lhs <= rhs); } }