#pragma once #include #include /** https://svn.boost.org/trac/boost/ticket/5182 */ template struct StrongTypedef : boost::totally_ordered1< StrongTypedef , boost::totally_ordered2< StrongTypedef, T> > { using Self = StrongTypedef; T t; template ::type> explicit StrongTypedef(const T & t_) : t(t_) {}; template ::type> explicit StrongTypedef(T && t_) : t(std::move(t_)) {}; template ::type> StrongTypedef(): t() {}; StrongTypedef(const Self &) = default; StrongTypedef(Self &&) = default; Self & operator=(const Self &) = default; Self & operator=(Self &&) = default; template ::type> Self & operator=(const T & rhs) { t = rhs; return *this;} template ::type> Self & operator=(T && rhs) { t = std::move(rhs); return *this;} operator const T & () const {return t; } operator T & () { return t; } bool operator==(const Self & rhs) const { return t == rhs.t; } bool operator<(const Self & rhs) const { return t < rhs.t; } T & toUnderType() { return t; } const T & toUnderType() const { return t; } }; namespace std { template struct hash> { size_t operator()(const StrongTypedef & x) const { return std::hash()(x.toUnderType()); } }; } #define STRONG_TYPEDEF(T, D) \ struct D ## Tag {}; \ using D = StrongTypedef; \