| 747 | */ |
| 748 | template <typename MapObjType> |
| 749 | static ObjectPtr<Object> Empty(uint32_t fib_shift, uint64_t n_slots) { |
| 750 | // Ensure even slot count (power-of-two expected by callers; this guard |
| 751 | // makes the method robust if a non-even value slips through). |
| 752 | ObjectPtr<DenseMapBaseObj> p = make_object<DenseMapBaseObj>(); |
| 753 | uint64_t n_blocks = CalcNumBlocks(n_slots); |
| 754 | Block* block = new Block[n_blocks]; |
| 755 | p->data_ = block; |
| 756 | // assign block deleter so even if we take re-alloc data |
| 757 | // in another shared-lib that may have different malloc/free behavior |
| 758 | // it will still be safe. |
| 759 | p->data_deleter_ = BlockDeleter; |
| 760 | p->SetSlotsAndDenseLayoutTag(n_slots); |
| 761 | p->size_ = 0; |
| 762 | p->fib_shift_ = fib_shift; |
| 763 | p->iter_list_head_ = kInvalidIndex; |
| 764 | p->iter_list_tail_ = kInvalidIndex; |
| 765 | // manually set the type index to specialized subclass |
| 766 | // data layout is ensured to be the same except for the type index |
| 767 | static_assert(std::is_base_of_v<MapBaseObj, MapObjType>); |
| 768 | static_assert(sizeof(MapObjType) == sizeof(MapBaseObj)); |
| 769 | p->header_.type_index = MapObjType::RuntimeTypeIndex(); |
| 770 | for (uint64_t i = 0; i < n_blocks; ++i, ++block) { |
| 771 | std::fill(block->bytes, block->bytes + kBlockCap, kEmptySlot); |
| 772 | } |
| 773 | return p; |
| 774 | } |
| 775 | /*! |
| 776 | * \brief Create an empty container with elements copying from another DenseMapBaseObj |
| 777 | * \param from The source container |
nothing calls this directly
no test coverage detected