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