Skip to content

Commit c28f293

Browse files
committed
Fix type hash map
1 parent 847c000 commit c28f293

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

include/jlcxx/jlcxx_config.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#endif
1515

1616
#define JLCXX_VERSION_MAJOR 0
17-
#define JLCXX_VERSION_MINOR 10
17+
#define JLCXX_VERSION_MINOR 11
1818
#define JLCXX_VERSION_PATCH 0
1919

2020
// From https://stackoverflow.com/questions/5459868/concatenate-int-to-string-using-c-preprocessor

include/jlcxx/type_conversion.hpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <complex>
77
#include <map>
8+
#include <unordered_map>
89
#include <memory>
910
#include <stack>
1011
#include <stdexcept>
@@ -335,6 +336,27 @@ struct CachedDatatype
335336
// Work around the fact that references aren't part of the typeid result
336337
using type_hash_t = std::pair<std::type_index, std::size_t>;
337338

339+
} // namespace jlcxx
340+
341+
namespace std {
342+
343+
// Hash implementation from https://en.cppreference.com/w/cpp/utility/hash
344+
template<>
345+
struct hash<jlcxx::type_hash_t>
346+
{
347+
std::size_t operator()(const jlcxx::type_hash_t& h) const noexcept
348+
{
349+
std::size_t h1 = std::hash<std::type_index>{}(h.first);
350+
std::size_t h2 = std::hash<std::size_t>{}(h.second);
351+
return h1 ^ (h2 << 1);
352+
}
353+
};
354+
355+
}
356+
357+
namespace jlcxx
358+
{
359+
338360
namespace detail
339361
{
340362

@@ -373,7 +395,7 @@ inline type_hash_t type_hash()
373395
return detail::TypeHash<T>::value();
374396
}
375397

376-
JLCXX_API std::map<type_hash_t, CachedDatatype>& jlcxx_type_map();
398+
JLCXX_API std::unordered_map<type_hash_t, CachedDatatype>& jlcxx_type_map();
377399

378400
/// Store the Julia datatype linked to SourceT
379401
template<typename SourceT>
@@ -393,10 +415,15 @@ class JuliaTypeCache
393415

394416
static inline void set_julia_type(jl_datatype_t* dt, bool protect = true)
395417
{
396-
const auto insresult = jlcxx_type_map().insert(std::make_pair(type_hash<SourceT>(), CachedDatatype(dt, protect)));
397-
if(!insresult.second)
418+
type_hash_t new_hash = type_hash<SourceT>();
419+
const auto [inserted_it, insert_success] = jlcxx_type_map().insert(std::make_pair(new_hash, CachedDatatype(dt, protect)));
420+
if(!insert_success)
398421
{
399-
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;
422+
type_hash_t old_hash = inserted_it->first;
423+
std::cout << "Warning: Type " << new_hash.first.name() << " already had a mapped type set as "
424+
<< julia_type_name(inserted_it->second.get_dt()) << " and const-ref indicator " << old_hash.second << " and C++ type name " << old_hash.first.name()
425+
<< ". Hash comparison: old(" << old_hash.first.hash_code() << "," << old_hash.second << ") == new(" << old_hash.first.hash_code() << "," << old_hash.second << ") == "
426+
<< std::boolalpha << (old_hash == new_hash) << std::endl;
400427
return;
401428
}
402429
}

src/jlcxx.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,9 @@ namespace detail
341341
};
342342
}
343343

344-
JLCXX_API std::map<type_hash_t, CachedDatatype>& jlcxx_type_map()
344+
JLCXX_API std::unordered_map<type_hash_t, CachedDatatype>& jlcxx_type_map()
345345
{
346-
static std::map<type_hash_t, CachedDatatype> m_map;
346+
static std::unordered_map<type_hash_t, CachedDatatype> m_map;
347347
return m_map;
348348
}
349349

0 commit comments

Comments
 (0)