#pragma once #include "gp/algorithm/move.hpp" namespace gp{ template struct pair{ T1 first; T2 second; constexpr pair() : first() , second() {} constexpr pair(const T1& a, const T2& b) : first(a) , second(b) {} constexpr pair(pair&& v) : first(gp::move(v.first)) , second(gp::move(v.second)) {} template constexpr pair(U1&& a, U2&& b) : first(gp::forward(a)) , second(gp::forward(b)) {} template constexpr pair(pair&& v) : first(gp::move(v.first)) , second(gp::move(v.second)) {} constexpr pair& operator=(pair&& v) { first = gp::move(v.first); second = gp::move(v.second); return *this; } }; template constexpr bool operator==(const pair& lhs, const pair& rhs) { return lhs.first == rhs.first and lhs.second == rhs.second; } template constexpr bool operator!=(const pair& lhs, const pair& rhs) { return lhs.first != rhs.first or lhs.second != rhs.second; } template constexpr 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 constexpr 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 constexpr bool operator<(const pair& lhs, const pair& rhs) { return !(lhs >= rhs); } template constexpr bool operator>(const pair& lhs, const pair& rhs) { return !(lhs <= rhs); } }