template<typename T, typename PairCmp = std::less<std::pair<T,T>> >
struct symmetric_pair_sort {
bool operator()( std::pair<T,T> const& left, std::pair<T,T> const& right ) const {
if (left.second<left.first) {
return (*this)(std::make_pair( left.second, left.first ), right );
}
if (right.second<right.first) {
return (*this)(left, std::make_pair( right.second, right.first ) );
}
return PairCmp()(left, right);
}
};
// or, the far bulkier yet more efficient:
template<typename T, typename PairCmp = std::less<std::pair<T&, T&>> >
struct symmetric_pair_sort {
template<bool left_reversed, bool right_reversed>
bool Helper( std::pair<T,T> const& left, std::pair<T,T> const& right ) const {
std::pair<T&, T&> left_ordered( left_reversed?left.first:left.second, left_reversed?left.second:left.first );
std::pair<T&, T&> right_ordered( right_reversed?right.first:right.second, right_reversed?right.second:right.first );
return PairCmp()( left_ordered, right_ordered );
}
bool operator()( std::pair<T,T> const& left, std::pair<T,T> const& right ) const {
if (left.second<left.first) {
if (right.second<right.first) {
return Helper<true, true>(left, right);
} else {
return Helper<true, false>(left, right);
}
} else {
if (right.second<right.first) {
return Helper<false, true>(left, right);
} else {
return Helper<false, false>(left, right);
}
}
};
std::map<std::pair<int, int>, int*, symmetric_pair_sort<int> > m;