Skip to content

Commit b81a2f0

Browse files
author
Julian LALU
committed
Improve MSVC coverage with clang-cl
1 parent e4eb5fe commit b81a2f0

File tree

2 files changed

+214
-144
lines changed

2 files changed

+214
-144
lines changed

interface/core/containers/hashset.h

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "../hash.h"
1111
#include "../bits.h"
1212
#include "../traits/is_comparable_with_equal.h"
13+
#include "../traits/is_trivially_copy_constructible.h"
1314
#include "tuple_size.h"
1415
#include "tuple_element.h"
1516

@@ -584,9 +585,78 @@ namespace hud
584585

585586
constexpr explicit hashset_impl(const hashset_impl &other) noexcept
586587
: allocator_(other.allocator())
588+
, max_slot_count_(other.max_count())
589+
, count_(other.count())
590+
, free_slot_before_grow_(max_slot_before_grow(max_slot_count_) - count_)
587591
{
588-
// Grow the capacity
589-
grow_capacity(&other, other.max_slot_count_);
592+
593+
// Allocate the buffer that will contain controls and aligned slots
594+
// In a constant-evaluated context, bit_cast cannot be used with pointers
595+
// To satisfy the compiler, allocate controls and slots in two separate allocations
596+
usize control_size = allocate_control_and_slot(max_slot_count_);
597+
598+
// If constant evaluated context
599+
// loop through all slot and construct them regardless of the trivially constructible ( Maybe only for control_ptr_ ) like like grow_capacity
600+
// In a non constant evaluated context
601+
// If type is trivially copy constructible, just memcpy control and slot
602+
// else do like grow_capacity
603+
if (hud::is_constant_evaluated() || hud::is_trivially_copy_constructible_v<slot_type>)
604+
{
605+
// slot_ptr_ = nullptr;
606+
607+
// Set control to empty ending with sentinel
608+
hud::memory::set(control_ptr_, control_size, empty_byte);
609+
control_ptr_[max_slot_count_] = sentinel_byte;
610+
611+
// Copy slots to newly allocated buffer
612+
for (auto &slot : other)
613+
{
614+
// Compute the hash
615+
u64 hash = hasher_type {}(slot.key());
616+
// Find H1 slot index
617+
u64 h1 = H1(hash);
618+
usize slot_index = find_first_empty_or_deleted(control_ptr_, max_slot_count_, h1);
619+
// Save h2 in control h1 index
620+
control::set_h2(control_ptr_, slot_index, H2(hash), max_slot_count_);
621+
// Copy slot
622+
hud::memory::construct_at(slot_ptr_ + slot_index, slot);
623+
}
624+
}
625+
626+
// Set control to empty ending with sentinel only if type is not trivially copyable
627+
// Int he case of trivially copyable type we just memcpy control and slots
628+
// if (!hud::is_trivially_copy_constructible_v<slot_type>)
629+
// {
630+
// hud::memory::set(control_ptr_, control_size, empty_byte);
631+
// control_ptr_[max_slot_count_] = sentinel_byte;
632+
// }
633+
634+
// If we have elements, insert them to the new buffer
635+
// if (other.count() > 0)
636+
// {
637+
// if (hud::is_trivially_copy_constructible_v<slot_type>)
638+
// {
639+
// hud::memory::copy_construct_array(control_ptr_, other.control_ptr_, other.max_slot_count_);
640+
// hud::memory::copy_construct_array(slot_ptr_, other.slot_ptr_, other.max_slot_count_);
641+
// }
642+
// else
643+
// {
644+
// // Move elements to new buffer if any
645+
// // Relocate slots to newly allocated buffer
646+
// for (auto &slot : other)
647+
// {
648+
// // Compute the hash
649+
// u64 hash = hasher_type {}(slot.key());
650+
// // Find H1 slot index
651+
// u64 h1 = H1(hash);
652+
// usize slot_index = find_first_empty_or_deleted(control_ptr_, max_slot_count_, h1);
653+
// // Save h2 in control h1 index
654+
// control::set_h2(control_ptr_, slot_index, H2(hash), max_slot_count_);
655+
// // Copy slot
656+
// hud::memory::construct_at(slot_ptr_ + slot_index, slot);
657+
// }
658+
// }
659+
// }
590660
}
591661

592662
constexpr ~hashset_impl() noexcept
@@ -599,7 +669,7 @@ namespace hud
599669
{
600670
if (count > max_slot_count_)
601671
{
602-
grow_capacity(this, hud::math::next_power_of_two(count + 1) - 1);
672+
grow_capacity(hud::math::next_power_of_two(count + 1) - 1);
603673
}
604674
}
605675

@@ -840,7 +910,7 @@ namespace hud
840910
// If we reach the load factor grow the table and retrieves the new slot, else use the given slot
841911
if (free_slot_before_grow() == 0)
842912
{
843-
grow_capacity(this, next_capacity());
913+
grow_capacity(next_capacity());
844914
}
845915

846916
// Find the first empty of deleted slot that can be used for this h1 hash
@@ -853,7 +923,7 @@ namespace hud
853923
return slot_index;
854924
}
855925

856-
constexpr void grow_capacity(hashset_impl *hashset_to_grow, usize new_max_slot_count) noexcept
926+
constexpr void grow_capacity(usize new_max_slot_count) noexcept
857927
{
858928
hud::check(new_max_slot_count > max_slot_count_ && "Grow need a bigger value");
859929
hud::check(hud::bits::is_valid_power_of_two_mask(max_slot_count_) && "Not a mask");

0 commit comments

Comments
 (0)