#pragma once #include "Vector.h" #include namespace Aftr { class ModelDataSharedID { public: ModelDataSharedID(); ModelDataSharedID( const ModelDataSharedID& toCopy ); ModelDataSharedID( const std::string& fileName, const Vector& scale ); ~ModelDataSharedID(); ModelDataSharedID& operator =( const ModelDataSharedID& id ); bool operator ==( const ModelDataSharedID& id ) const; bool operator < ( const ModelDataSharedID& id ) const; std::string toString() const; const std::string& getFileName() const { return this->fileName; } const Vector& getScaleFactor() const { return this->scale; } unsigned int getInstanceCount() const { return this->instanceCount; } void incrementInstanceCount() const { ++this->instanceCount; } void decrementInstanceCount() const { --this->instanceCount; } private: std::string fileName; Vector scale; mutable unsigned int instanceCount; }; } //namespace Aftr namespace std { //Create a custom hash function for ModelDataSharedID and place it in the std namespace // so the std::unordered_multi_map can find this template specialization automatically. //https://stackoverflow.com/questions/17016175/c-unordered-map-using-a-custom-class-type-as-the-key //Sine we are using a hash function, we are combining a string and vector (3 floats), so // we want a good hash function. //https://stackoverflow.com/questions/1646807/quick-and-simple-hash-code-combinations/1646913#1646913 template<> struct hash< Aftr::ModelDataSharedID > { size_t operator()( const Aftr::ModelDataSharedID& k ) const { std::hash str_hasher; //uses underlying type of Vector (either float or double or long double, etc) using vec_type = std::remove_cvref_t< decltype(std::declval().getScaleFactor()) >::value_type; std::hash vec_hasher; size_t hash = 17; hash = hash * 31 + str_hasher( k.getFileName() ); const auto& v = k.getScaleFactor(); hash = hash * 31 + vec_hasher( v.x ); hash = hash * 31 + vec_hasher( v.y ); hash = hash * 31 + vec_hasher( v.z ); return hash; } }; //template<> //struct equal< Aftr::ModelDataSharedID > //{ // size_t operator()( const Aftr::ModelDataSharedID& a, const Aftr::ModelDataSharedID& b ) const // { // return a == b; // } //}; }