typeindices.hpp - start index from 0

Starting it from 1 makes it more error-prone to use.
This commit is contained in:
Nekotekina 2019-08-16 00:59:30 +03:00
parent 92e6dee60f
commit 11a43e25d7
2 changed files with 14 additions and 37 deletions

View file

@ -117,12 +117,6 @@ namespace utils
} }
}; };
template <typename T>
uint get_typeid() noexcept
{
return stx::type_counter<typeinfo_base>::type<std::decay_t<T>>.index();
}
// Internal, control block for a particular object // Internal, control block for a particular object
class typemap_block class typemap_block
{ {
@ -448,7 +442,7 @@ namespace utils
static_assert(std::is_same_v<New, T>); static_assert(std::is_same_v<New, T>);
// Set type; zero value shall not be observed in the case of recreation // Set type; zero value shall not be observed in the case of recreation
if (m_block->m_type.exchange(type_index()) != 0) if (m_block->m_type.exchange(1) != 0)
{ {
// Destroy object if it exists // Destroy object if it exists
m_block->get_ptr<T>()->~T(); m_block->get_ptr<T>()->~T();
@ -492,17 +486,6 @@ namespace utils
return static_cast<uint>(quot) * step + bias; return static_cast<uint>(quot) * step + bias;
} }
// Get current type
uint get_type() const
{
return m_block->m_type;
}
static uint type_index()
{
return get_typeid<T>();
}
static constexpr bool type_const() static constexpr bool type_const()
{ {
return std::is_const_v<std::remove_reference_t<T>>; return std::is_const_v<std::remove_reference_t<T>>;
@ -529,7 +512,7 @@ namespace utils
template <typename T> template <typename T>
typemap_head* get_head() const typemap_head* get_head() const
{ {
return &m_map[get_typeid<T>() - 1]; return &m_map[stx::type_counter<typeinfo_base>::type<std::decay_t<T>>.index()];
} }
public: public:
@ -585,9 +568,9 @@ namespace utils
{ {
const auto block = reinterpret_cast<typemap_block*>(m_map[i].m_ptr + j * m_map[i].m_ssize); const auto block = reinterpret_cast<typemap_block*>(m_map[i].m_ptr + j * m_map[i].m_ssize);
if (const uint type_id = block->m_type) if (block->m_type)
{ {
m_map[type_id - 1].clean(block); m_map[i].clean(block);
} }
} }
@ -666,8 +649,6 @@ namespace utils
return {}; return {};
} }
const uint type_id = get_typeid<Type>();
using id_tag = std::decay_t<Arg>; using id_tag = std::decay_t<Arg>;
typemap_head* head = get_head<Type>(); typemap_head* head = get_head<Type>();
@ -735,11 +716,11 @@ namespace utils
{ {
block = reinterpret_cast<typemap_block*>(head->m_ptr + j * head->m_ssize); block = reinterpret_cast<typemap_block*>(head->m_ptr + j * head->m_ssize);
if (block->m_type == type_id) if (block->m_type)
{ {
std::lock_guard lock(block->m_mutex); std::lock_guard lock(block->m_mutex);
if (block->m_type == type_id) if (block->m_type)
{ {
if (std::invoke(std::forward<Arg>(id), std::as_const(*block->get_ptr<Type>()))) if (std::invoke(std::forward<Arg>(id), std::as_const(*block->get_ptr<Type>())))
{ {
@ -786,8 +767,6 @@ namespace utils
{ {
using id_tag = std::decay_t<Arg>; using id_tag = std::decay_t<Arg>;
const uint type_id = get_typeid<Type>();
if constexpr (std::is_same_v<id_tag, id_new_t>) if constexpr (std::is_same_v<id_tag, id_new_t>)
{ {
// No action for id_new // No action for id_new
@ -800,7 +779,7 @@ namespace utils
} }
else if constexpr (std::is_same_v<id_tag, id_always_t>) else if constexpr (std::is_same_v<id_tag, id_always_t>)
{ {
if (block->m_type == 0 && block->m_type.compare_and_swap_test(0, type_id)) if (block->m_type == 0 && block->m_type.compare_and_swap_test(0, 1))
{ {
// Initialize object if necessary // Initialize object if necessary
static_assert(!std::is_const_v<std::remove_reference_t<Type>>); static_assert(!std::is_const_v<std::remove_reference_t<Type>>);
@ -817,7 +796,7 @@ namespace utils
return; return;
} }
if (LIKELY(block->m_type == type_id)) if (LIKELY(block->m_type))
{ {
if (std::invoke(std::forward<Arg>(id), std::as_const(*block->get_ptr<Type>()))) if (std::invoke(std::forward<Arg>(id), std::as_const(*block->get_ptr<Type>())))
{ {
@ -1026,8 +1005,6 @@ namespace utils
static_assert(!std::is_array_v<Type>); static_assert(!std::is_array_v<Type>);
static_assert(!std::is_void_v<Type>); static_assert(!std::is_void_v<Type>);
const uint type_id = get_typeid<decode_t<Type>>();
typemap_head* head = get_head<decode_t<Type>>(); typemap_head* head = get_head<decode_t<Type>>();
const ullong ix = head->m_create_count; const ullong ix = head->m_create_count;
@ -1036,11 +1013,11 @@ namespace utils
{ {
const auto block = reinterpret_cast<typemap_block*>(head->m_ptr + j * head->m_ssize); const auto block = reinterpret_cast<typemap_block*>(head->m_ptr + j * head->m_ssize);
if (block->m_type == type_id) if (block->m_type)
{ {
std::lock_guard lock(block->m_mutex); std::lock_guard lock(block->m_mutex);
if (block->m_type == type_id) if (block->m_type)
{ {
std::invoke(std::forward<F>(func), *block->get_ptr<decode_t<Type>>()); std::invoke(std::forward<F>(func), *block->get_ptr<decode_t<Type>>());
} }

View file

@ -9,8 +9,8 @@ namespace stx
template <typename Info> template <typename Info>
class type_info final : public Info class type_info final : public Info
{ {
// Current type id (non-zero) // Current type id (starts from 0)
unsigned type = 0; unsigned type = 0u - 1;
// Next typeinfo in linked list // Next typeinfo in linked list
type_info* next = nullptr; type_info* next = nullptr;
@ -45,7 +45,7 @@ namespace stx
unsigned count() const unsigned count() const
{ {
return next->index(); return next->index() + 1;
} }
class const_iterator class const_iterator
@ -114,7 +114,7 @@ namespace stx
template <typename Info> template <typename Info>
type_info<Info>::type_info(Info info, decltype(sizeof(int))) noexcept type_info<Info>::type_info(Info info, decltype(sizeof(int))) noexcept
: Info(info) : Info(info)
, type(typeinfo_v<Info>.count() + 1) , type(typeinfo_v<Info>.count())
{ {
// Update linked list // Update linked list
typeinfo_v<Info>.next->next = this; typeinfo_v<Info>.next->next = this;