Spaces:
Running
Running
namespace c10 { | |
/** | |
* This template simplifies generation of simple classes that wrap an id | |
* in a typesafe way. Namely, you can use it to create a very lightweight | |
* type that only offers equality comparators and hashing. Example: | |
* | |
* struct MyIdType final : IdWrapper<MyIdType, uint32_t> { | |
* constexpr explicit MyIdType(uint32_t id): IdWrapper(id) {} | |
* }; | |
* | |
* Then in the global top level namespace: | |
* | |
* C10_DEFINE_HASH_FOR_IDWRAPPER(MyIdType); | |
* | |
* That's it - equality operators and hash functions are automatically defined | |
* for you, given the underlying type supports it. | |
*/ | |
template <class ConcreteType, class UnderlyingType> | |
class IdWrapper { | |
public: | |
using underlying_type = UnderlyingType; | |
using concrete_type = ConcreteType; | |
protected: | |
constexpr explicit IdWrapper(underlying_type id) noexcept( | |
noexcept(underlying_type(std::declval<underlying_type>()))) | |
: id_(id) {} | |
constexpr underlying_type underlyingId() const | |
noexcept(noexcept(underlying_type(std::declval<underlying_type>()))) { | |
return id_; | |
} | |
private: | |
friend size_t hash_value(const concrete_type& v) { | |
return std::hash<underlying_type>()(v.id_); | |
} | |
// TODO Making operator== noexcept if underlying type is noexcept equality | |
// comparable doesn't work with GCC 4.8. | |
// Fix this once we don't need GCC 4.8 anymore. | |
friend constexpr bool operator==( | |
const concrete_type& lhs, | |
const concrete_type& rhs) noexcept { | |
return lhs.id_ == rhs.id_; | |
} | |
// TODO Making operator!= noexcept if operator== is noexcept doesn't work with | |
// GCC 4.8. | |
// Fix this once we don't need GCC 4.8 anymore. | |
friend constexpr bool operator!=( | |
const concrete_type& lhs, | |
const concrete_type& rhs) noexcept { | |
return !(lhs == rhs); | |
} | |
underlying_type id_; | |
}; | |
} // namespace c10 | |
namespace std { \ | |
template <> \ | |
struct hash<ClassName> { \ | |
size_t operator()(ClassName x) const { \ | |
return hash_value(x); \ | |
} \ | |
}; \ | |
} | |