diff -r 7c27cda03747 -r 97df974b5ed5 src/main.h --- a/src/main.h Fri Mar 06 23:45:44 2020 +0200 +++ b/src/main.h Mon Mar 09 14:21:54 2020 +0200 @@ -35,25 +35,65 @@ namespace ldraw { + class Object; + // Uniquely identifies a model body object + template struct Id { std::int32_t value; - constexpr bool operator<(ldraw::Id other) const + template + static constexpr bool is_base_or_base_of = std::disjunction_v, std::is_base_of>; + template>> + constexpr bool operator<(ldraw::Id other) const { return this->value < other.value; } - friend constexpr unsigned int qHash(ldraw::Id id) + friend constexpr unsigned int qHash(ldraw::Id id) { return qHash(id.value); } - friend bool operator==(ldraw::Id one, ldraw::Id other) + // Allow comparing ids as long as they are related + template>> + friend bool operator==(ldraw::Id one, ldraw::Id other) { return one.value == other.value; } + // Allow upcasting + template>> + constexpr operator Id() const + { + return Id{this->value}; + } }; - using id_t = Id; - constexpr id_t NULL_ID = id_t{0}; + + using id_t = Id; + using triangleid_t = Id; + using quadrilateralid_t = Id; + using edgeid_t = Id; + using conditionaledgeid_t = Id; + using subfileid_t = Id; + + constexpr struct + { + template + constexpr operator Id() const + { + return Id{0}; + } + } NULL_ID = {}; + + template + inline bool operator==(Id one, decltype(NULL_ID)) + { + return one.value == 0; + } + + template + inline bool operator<(Id one, decltype(NULL_ID)) + { + return one.value < 0; + } } constexpr std::size_t operator""_z(const unsigned long long int x)