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