#pragma once namespace types { template struct EqualityComparable { friend bool operator==(Self const & lhs, Self const & rhs) { return lhs.get() == rhs.get(); } friend bool operator!=(Self const & lhs, Self const & rhs) { return !(lhs == rhs); } }; template struct Comparable : EqualityComparable { friend bool operator<(Self const & lhs, Self const & rhs) { return lhs.get() < rhs.get(); } friend bool operator>(Self const & lhs, Self const & rhs) { return rhs.get() < lhs.get(); } friend bool operator<=(Self const & lhs, Self const & rhs) { return !(rhs.get() < lhs.get()); } friend bool operator>=(Self const & lhs, Self const & rhs) { return !(lhs.get() < rhs.get()); } }; }