reserves space for at least the specified number of elements. only works if numBuckets if power of two True on success, false otherwise
| 2214 | // only works if numBuckets if power of two |
| 2215 | // True on success, false otherwise |
| 2216 | void rehashPowerOfTwo(size_t numBuckets, bool forceFree) { |
| 2217 | ROBIN_HOOD_TRACE(this) |
| 2218 | |
| 2219 | Node* const oldKeyVals = mKeyVals; |
| 2220 | uint8_t const* const oldInfo = mInfo; |
| 2221 | |
| 2222 | const size_t oldMaxElementsWithBuffer = calcNumElementsWithBuffer(mMask + 1); |
| 2223 | |
| 2224 | // resize operation: move stuff |
| 2225 | initData(numBuckets); |
| 2226 | if (oldMaxElementsWithBuffer > 1) { |
| 2227 | for (size_t i = 0; i < oldMaxElementsWithBuffer; ++i) { |
| 2228 | if (oldInfo[i] != 0) { |
| 2229 | // might throw an exception, which is really bad since we are in the middle of |
| 2230 | // moving stuff. |
| 2231 | insert_move(std::move(oldKeyVals[i])); |
| 2232 | // destroy the node but DON'T destroy the data. |
| 2233 | oldKeyVals[i].~Node(); |
| 2234 | } |
| 2235 | } |
| 2236 | |
| 2237 | // this check is not necessary as it's guarded by the previous if, but it helps |
| 2238 | // silence g++'s overeager "attempt to free a non-heap object 'map' |
| 2239 | // [-Werror=free-nonheap-object]" warning. |
| 2240 | if (oldKeyVals != reinterpret_cast_no_cast_align_warning<Node*>(&mMask)) { |
| 2241 | // don't destroy old data: put it into the pool instead |
| 2242 | if (forceFree) { |
| 2243 | std::free(oldKeyVals); |
| 2244 | } else { |
| 2245 | DataPool::addOrFree(oldKeyVals, calcNumBytesTotal(oldMaxElementsWithBuffer)); |
| 2246 | } |
| 2247 | } |
| 2248 | } |
| 2249 | } |
| 2250 | |
| 2251 | ROBIN_HOOD(NOINLINE) void throwOverflowError() const { |
| 2252 | #if ROBIN_HOOD(HAS_EXCEPTIONS) |