refine type hash indexing model

This commit is contained in:
Michele Caini 2021-05-09 23:42:16 +02:00
parent 010d8de944
commit aea6671b14
2 changed files with 87 additions and 24 deletions

View File

@ -8,22 +8,12 @@
#include <utility>
#include <cstddef>
#include <unordered_map>
#include <string>
#include <memory>
#include <list>
#include <uv.h>
#include "type_info.hpp"
#if defined __clang__ || defined __GNUC__
# define UVW_PRETTY_FUNCTION __PRETTY_FUNCTION__
# define UVW_PRETTY_FUNCTION_PREFIX '='
# define UVW_PRETTY_FUNCTION_SUFFIX ']'
#elif defined _MSC_VER
# define UVW_PRETTY_FUNCTION __FUNCSIG__
# define UVW_PRETTY_FUNCTION_PREFIX '<'
# define UVW_PRETTY_FUNCTION_SUFFIX '>'
#endif
namespace uvw {
@ -168,20 +158,15 @@ class Emitter {
ListenerList onL{};
};
template <typename E>
std::string event_type() const noexcept {
return UVW_PRETTY_FUNCTION;
}
template<typename E>
Handler<E> & handler() noexcept {
auto type = event_type<E>();
auto id = type<E>();
if(!handlers.count(type)) {
handlers[type] = std::make_unique<Handler<E>>();
if(!handlers.count(id)) {
handlers[id] = std::make_unique<Handler<E>>();
}
return static_cast<Handler<E>&>(*handlers.at(type));
return static_cast<Handler<E>&>(*handlers.at(id));
}
protected:
@ -293,10 +278,10 @@ public:
*/
template<typename E>
bool empty() const noexcept {
auto type = event_type<E>();
auto id = type<E>();
return (!handlers.count(type) ||
static_cast<Handler<E>&>(*handlers.at(type)).empty());
return (!handlers.count(id) ||
static_cast<Handler<E>&>(*handlers.at(id)).empty());
}
/**
@ -310,7 +295,7 @@ public:
}
private:
std::unordered_map<std::string, std::unique_ptr<BaseHandler>> handlers{};
std::unordered_map<std::uint32_t, std::unique_ptr<BaseHandler>> handlers{};
};

78
src/uvw/type_info.hpp Normal file
View File

@ -0,0 +1,78 @@
#ifndef UVW_TYPE_INFO_INCLUDE_HPP
#define UVW_TYPE_INFO_INCLUDE_HPP
#include <cstddef>
#include <string_view>
namespace uvw {
/**
* @cond TURN_OFF_DOXYGEN
* Internal details not to be documented.
*/
namespace internal {
// FowlerNollVo hash function v. 1a - the good
[[nodiscard]] static constexpr std::uint32_t fnv1a(const char *curr) noexcept {
constexpr std::uint32_t offset = 2166136261;
constexpr std::uint32_t prime = 16777619;
auto value = offset;
while(*curr != 0) {
value = (value ^ static_cast<std::uint32_t>(*(curr++))) * prime;
}
return value;
}
[[nodiscard]] static std::uint32_t counter() noexcept {
static std::uint32_t cnt{};
return cnt++;
}
template<typename Type>
[[nodiscard]] static std::uint32_t fake() noexcept {
static std::uint32_t local = counter();
return local;
}
}
/**
* Internal details not to be documented.
* @endcond
*/
/**
* @brief Returns a numerical identifier for a given type.
* @tparam Type The type for which to return the numerical identifier.
* @return The numerical identifier of the give type.
*/
template<typename Type>
[[nodiscard]] static constexpr std::uint32_t type() noexcept {
#if defined __clang__ || defined __GNUC__
constexpr auto value = internal::fnv1a(__PRETTY_FUNCTION__);
return value;
#elif defined _MSC_VER
constexpr auto value = internal::fnv1a(__FUNCSIG__);
return value;
#else
return internal::fake();
#endif
}
}
#endif // UVW_TYPE_INFO_INCLUDE_HPP