diff --git a/include/jlcxx/jlcxx_config.hpp b/include/jlcxx/jlcxx_config.hpp index faca892..f711d6d 100644 --- a/include/jlcxx/jlcxx_config.hpp +++ b/include/jlcxx/jlcxx_config.hpp @@ -14,7 +14,7 @@ #endif #define JLCXX_VERSION_MAJOR 0 -#define JLCXX_VERSION_MINOR 10 +#define JLCXX_VERSION_MINOR 11 #define JLCXX_VERSION_PATCH 0 // From https://stackoverflow.com/questions/5459868/concatenate-int-to-string-using-c-preprocessor diff --git a/include/jlcxx/type_conversion.hpp b/include/jlcxx/type_conversion.hpp index 1dab240..bbb991f 100644 --- a/include/jlcxx/type_conversion.hpp +++ b/include/jlcxx/type_conversion.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -335,6 +336,27 @@ struct CachedDatatype // Work around the fact that references aren't part of the typeid result using type_hash_t = std::pair; +} // namespace jlcxx + +namespace std { + +// Hash implementation from https://en.cppreference.com/w/cpp/utility/hash +template<> +struct hash +{ + std::size_t operator()(const jlcxx::type_hash_t& h) const noexcept + { + std::size_t h1 = std::hash{}(h.first); + std::size_t h2 = std::hash{}(h.second); + return h1 ^ (h2 << 1); + } +}; + +} + +namespace jlcxx +{ + namespace detail { @@ -373,7 +395,7 @@ inline type_hash_t type_hash() return detail::TypeHash::value(); } -JLCXX_API std::map& jlcxx_type_map(); +JLCXX_API std::unordered_map& jlcxx_type_map(); /// Store the Julia datatype linked to SourceT template @@ -393,10 +415,15 @@ class JuliaTypeCache static inline void set_julia_type(jl_datatype_t* dt, bool protect = true) { - const auto insresult = jlcxx_type_map().insert(std::make_pair(type_hash(), CachedDatatype(dt, protect))); - if(!insresult.second) + type_hash_t new_hash = type_hash(); + const auto [inserted_it, insert_success] = jlcxx_type_map().insert(std::make_pair(new_hash, CachedDatatype(dt, protect))); + if(!insert_success) { - std::cout << "Warning: Type " << typeid(SourceT).name() << " already had a mapped type set as " << julia_type_name(insresult.first->second.get_dt()) << " using hash " << insresult.first->first.first.hash_code() << " and const-ref indicator " << insresult.first->first.second << std::endl; + type_hash_t old_hash = inserted_it->first; + std::cout << "Warning: Type " << new_hash.first.name() << " already had a mapped type set as " + << julia_type_name(inserted_it->second.get_dt()) << " and const-ref indicator " << old_hash.second << " and C++ type name " << old_hash.first.name() + << ". Hash comparison: old(" << old_hash.first.hash_code() << "," << old_hash.second << ") == new(" << old_hash.first.hash_code() << "," << old_hash.second << ") == " + << std::boolalpha << (old_hash == new_hash) << std::endl; return; } } diff --git a/src/jlcxx.cpp b/src/jlcxx.cpp index 6bc5ba6..6316e22 100644 --- a/src/jlcxx.cpp +++ b/src/jlcxx.cpp @@ -341,9 +341,9 @@ namespace detail }; } -JLCXX_API std::map& jlcxx_type_map() +JLCXX_API std::unordered_map& jlcxx_type_map() { - static std::map m_map; + static std::unordered_map m_map; return m_map; }