11#ifndef INCLUDED_BDLC_FLATHASHTABLE_CPP03
12#define INCLUDED_BDLC_FLATHASHTABLE_CPP03
63#ifdef COMPILING_BDLC_FLATHASHTABLE_H
69struct FlatHashTable_ImplUtil;
72class FlatHashTable_IteratorImp;
75bool operator==(
const class FlatHashTable_IteratorImp<ENTRY>&,
76 const class FlatHashTable_IteratorImp<ENTRY>&);
87class FlatHashTable_IteratorImp
90 typedef FlatHashTable_GroupControl GroupControl;
94 const bsl::uint8_t *d_controls_p;
95 bsl::size_t d_additionalLength;
115 const bsl::uint8_t *controls,
116 bsl::size_t additionalLength);
153template <
class ENTRY>
154bool operator==(
const FlatHashTable_IteratorImp<ENTRY>& a,
155 const FlatHashTable_IteratorImp<ENTRY>& b);
163template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
167 typedef FlatHashTable_GroupControl GroupControl;
168 typedef FlatHashTable_ImplUtil ImplUtil;
169 typedef FlatHashTable_IteratorImp<ENTRY> IteratorImp;
187 bsl::uint8_t *d_controls_p;
189 bsl::size_t d_capacity;
190 int d_groupControlShift;
202 static bsl::size_t findAvailable(bsl::uint8_t *
controls,
218 bsl::size_t indexOfKey(
bool *notFound,
220 bsl::size_t hashValue);
227 void rehashRaw(bsl::size_t newCapacity);
235 bsl::size_t findKey(
const KEY& key, bsl::size_t hashValue)
const;
239 bsl::size_t minimumCompliantCapacity(bsl::size_t minimumCapacity)
const;
281 FlatHashTable(
const FlatHashTable& original,
318 FlatHashTable&
operator=(
const FlatHashTable& rhs);
335 template <
class KEY_TYPE>
353#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
356#ifndef BDLC_FLATHASHTABLE_VARIADIC_LIMIT
357#define BDLC_FLATHASHTABLE_VARIADIC_LIMIT 10
359#ifndef BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A
360#define BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A BDLC_FLATHASHTABLE_VARIADIC_LIMIT
362#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A >= 0
367#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A >= 1
368 template<
class ARGS_01>
373#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A >= 2
374 template<
class ARGS_01,
381#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A >= 3
382 template<
class ARGS_01,
391#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A >= 4
392 template<
class ARGS_01,
403#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A >= 5
404 template<
class ARGS_01,
417#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A >= 6
418 template<
class ARGS_01,
433#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A >= 7
434 template<
class ARGS_01,
451#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A >= 8
452 template<
class ARGS_01,
471#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A >= 9
472 template<
class ARGS_01,
493#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_A >= 10
494 template<
class ARGS_01,
520 template<
class... ARGS>
530 bsl::size_t
erase(
const KEY& key);
556#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
557 template <
class ENTRY_TYPE>
571 template <
class ENTRY_TYPE>
581 bsl::size_t hashValue = d_hasher(ENTRY_UTIL::key(entry));
582 bsl::size_t index = indexOfKey(¬Found,
583 ENTRY_UTIL::key(entry),
587 ENTRY_UTIL::construct(
592 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
599 d_controls_p + index,
600 d_capacity - index - 1),
614 template <
class INPUT_ITERATOR>
615 void insert(INPUT_ITERATOR first, INPUT_ITERATOR last);
624 void rehash(bsl::size_t minimumCapacity);
637 void reserve(bsl::size_t numEntries);
643#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
646#ifndef BDLC_FLATHASHTABLE_VARIADIC_LIMIT
647#define BDLC_FLATHASHTABLE_VARIADIC_LIMIT 10
649#ifndef BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B
650#define BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B BDLC_FLATHASHTABLE_VARIADIC_LIMIT
652#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 0
656#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 1
657 template<
class ARGS_01>
662#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 2
663 template<
class ARGS_01,
670#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 3
671 template<
class ARGS_01,
680#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 4
681 template<
class ARGS_01,
692#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 5
693 template<
class ARGS_01,
706#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 6
707 template<
class ARGS_01,
722#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 7
723 template<
class ARGS_01,
740#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 8
741 template<
class ARGS_01,
760#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 9
761 template<
class ARGS_01,
782#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 10
783 template<
class ARGS_01,
807#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 0
809 BloombergLP::bslmf::MovableRef<KEY> key);
812#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 1
813 template <
class ARGS_01>
815 BloombergLP::bslmf::MovableRef<KEY> key,
819#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 2
820 template <
class ARGS_01,
823 BloombergLP::bslmf::MovableRef<KEY> key,
828#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 3
829 template <
class ARGS_01,
833 BloombergLP::bslmf::MovableRef<KEY> key,
839#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 4
840 template <
class ARGS_01,
845 BloombergLP::bslmf::MovableRef<KEY> key,
852#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 5
853 template <
class ARGS_01,
859 BloombergLP::bslmf::MovableRef<KEY> key,
867#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 6
868 template <
class ARGS_01,
875 BloombergLP::bslmf::MovableRef<KEY> key,
884#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 7
885 template <
class ARGS_01,
893 BloombergLP::bslmf::MovableRef<KEY> key,
903#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 8
904 template <
class ARGS_01,
913 BloombergLP::bslmf::MovableRef<KEY> key,
924#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 9
925 template <
class ARGS_01,
935 BloombergLP::bslmf::MovableRef<KEY> key,
947#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_B >= 10
948 template <
class ARGS_01,
959 BloombergLP::bslmf::MovableRef<KEY> key,
975 template<
class... ARGS>
979 template <
class... ARGS>
981 BloombergLP::bslmf::MovableRef<KEY> key,
1002 void swap(FlatHashTable& other);
1012 bool contains(
const KEY& key)
const;
1020 const bsl::uint8_t *
controls()
const;
1025 bsl::size_t
count(
const KEY& key)
const;
1047 const KEY& key)
const;
1077 bsl::size_t
size()
const;
1107template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1108bool operator==(
const FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>& lhs,
1109 const FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>& rhs);
1117template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1118bool operator!=(
const FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>& lhs,
1119 const FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>& rhs);
1126template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1127void swap(FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>& a,
1128 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>& b);
1137struct FlatHashTable_ImplUtil {
1141 typedef FlatHashTable_GroupControl GroupControl;
1148 template <
class ENTRY_TYPE>
1149 class DestroyEntryArrayProctor;
1183 template <
class ENTRY_TYPE>
1184 static void copyEntryAndControlArrays(
1185 ENTRY_TYPE *firstDestinationEntry,
1186 bsl::uint8_t *firstDestinationControl,
1187 const ENTRY_TYPE *firstSourceEntry,
1188 const ENTRY_TYPE *lastSourceEntry,
1189 const bsl::uint8_t *firstSourceControl,
1190 const bsl::uint8_t *lastSourceControl,
1193 template <
class ENTRY_TYPE>
1194 static void copyEntryAndControlArrays(
1195 ENTRY_TYPE *firstDestinationEntry,
1196 bsl::uint8_t *firstDestinationControl,
1197 const ENTRY_TYPE *firstSourceEntry,
1198 const ENTRY_TYPE *lastSourceEntry,
1199 const bsl::uint8_t *firstSourceControl,
1200 const bsl::uint8_t *lastSourceControl,
1221 template <
class ENTRY_TYPE>
1222 static void destroyEntryArray(ENTRY_TYPE *firstEntry,
1223 ENTRY_TYPE *lastEntry,
1224 const bsl::uint8_t *firstControl,
1225 const bsl::uint8_t *lastControl,
1227 template <
class ENTRY_TYPE>
1228 static void destroyEntryArray(ENTRY_TYPE *firstEntry,
1229 ENTRY_TYPE *lastEntry,
1230 const bsl::uint8_t *firstControl,
1231 const bsl::uint8_t *lastControl,
1264 template <
class ENTRY_TYPE>
1266 copyEntryAndControlArrays(ENTRY_TYPE *firstDestinationEntry,
1267 bsl::uint8_t *firstDestinationControl,
1268 const ENTRY_TYPE *firstSourceEntry,
1269 const ENTRY_TYPE *lastSourceEntry,
1270 const bsl::uint8_t *firstSourceControl,
1271 const bsl::uint8_t *lastSourceControl,
1288 template <
class ENTRY_TYPE>
1289 static void destroyEntryArray(ENTRY_TYPE *firstEntry,
1290 ENTRY_TYPE *lastEntry,
1291 const bsl::uint8_t *firstControl,
1292 const bsl::uint8_t *lastControl);
1304template <
class ENTRY_TYPE>
1305class FlatHashTable_ImplUtil::DestroyEntryArrayProctor {
1308 typedef FlatHashTable_GroupControl GroupControl;
1309 typedef FlatHashTable_ImplUtil ImplUtil;
1314 ENTRY_TYPE *d_firstEntry_p;
1317 ENTRY_TYPE *d_lastEntry_p;
1320 const bsl::uint8_t *d_firstControl_p;
1323 const bsl::uint8_t *d_lastControl_p;
1326 DestroyEntryArrayProctor(
const DestroyEntryArrayProctor&);
1327 DestroyEntryArrayProctor& operator=(
const DestroyEntryArrayProctor&);
1340 DestroyEntryArrayProctor(ENTRY_TYPE *firstEntry,
1341 ENTRY_TYPE *lastEntry,
1342 const bsl::uint8_t *firstControl,
1343 const bsl::uint8_t *lastControl);
1348 ~DestroyEntryArrayProctor();
1354 void moveEnd(bsl::ptrdiff_t offset);
1373template <
class ENTRY>
1378, d_additionalLength(0)
1382template <
class ENTRY>
1384FlatHashTable_IteratorImp<ENTRY>::FlatHashTable_IteratorImp(
1386 const bsl::uint8_t *controls,
1387 bsl::size_t additionalLength)
1388: d_entries_p(entries)
1389, d_controls_p(controls)
1390, d_additionalLength(additionalLength)
1394template <
class ENTRY>
1396FlatHashTable_IteratorImp<ENTRY>::FlatHashTable_IteratorImp(
1397 const FlatHashTable_IteratorImp& original)
1398: d_entries_p(original.d_entries_p)
1399, d_controls_p(original.d_controls_p)
1400, d_additionalLength(original.d_additionalLength)
1405template <
class ENTRY>
1407FlatHashTable_IteratorImp<ENTRY>& FlatHashTable_IteratorImp<ENTRY>::operator=(
1408 const FlatHashTable_IteratorImp& rhs)
1410 d_entries_p = rhs.d_entries_p;
1411 d_controls_p = rhs.d_controls_p;
1412 d_additionalLength = rhs.d_additionalLength;
1417template <
class ENTRY>
1419void FlatHashTable_IteratorImp<ENTRY>::operator++()
1424 while (d_additionalLength) {
1427 --d_additionalLength;
1428 if (0 == (*d_controls_p & 0x80)) {
1438template <
class ENTRY>
1440ENTRY& FlatHashTable_IteratorImp<ENTRY>::operator*()
const
1445 return *d_entries_p;
1451template <
class ENTRY>
1454 const FlatHashTable_IteratorImp<ENTRY>& b)
1456 return a.d_entries_p == b.d_entries_p
1457 && a.d_controls_p == b.d_controls_p
1458 && a.d_additionalLength == b.d_additionalLength;
1468template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1469bsl::size_t FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::findAvailable(
1470 bsl::uint8_t *controls,
1472 bsl::size_t capacity)
1476 for (bsl::size_t i = 0; i < capacity; i += GroupControl::k_SIZE) {
1477 bsl::uint8_t *controlStart = controls + index;
1479 GroupControl groupControl(controlStart);
1480 bsl::uint32_t candidates = groupControl.available();
1487 index = (index + GroupControl::k_SIZE) & (capacity - 1);
1490 BSLS_ASSERT_OPT(
false &&
"execution should never reach this location");
1495template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1496bsl::size_t FlatHashTable<KEY,
1500 EQUAL>::indexOfKey(
bool *notFound,
1502 bsl::size_t hashValue)
1506 bsl::size_t index = findKey(key, hashValue);
1508 if (index == d_capacity) {
1511 if (d_size >= k_MAX_LOAD_FACTOR_NUMERATOR
1512 * (d_capacity / k_MAX_LOAD_FACTOR_DENOMINATOR)) {
1513 rehashRaw(d_capacity > 0 ? 2 * d_capacity : k_MIN_CAPACITY);
1516 index = (hashValue >> d_groupControlShift) * GroupControl::k_SIZE;
1517 index = findAvailable(d_controls_p, index, d_capacity);
1526template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1527void FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::rehashRaw(
1528 bsl::size_t newCapacity)
1533 FlatHashTable tmp(newCapacity,
1538 for (bsl::size_t i = 0; i < d_capacity; i += GroupControl::k_SIZE) {
1539 bsl::uint8_t *controlStart = d_controls_p + i;
1540 ENTRY *entryStart = d_entries_p + i;
1542 GroupControl groupControl(controlStart);
1543 bsl::uint32_t candidates = groupControl.inUse();
1544 while (candidates) {
1546 ENTRY *entry = entryStart + offset;
1552 *(controlStart + offset) = GroupControl::k_ERASED;
1556 bsl::size_t hashValue = tmp.d_hasher(ENTRY_UTIL::key(*entry));
1557 bsl::size_t index = (hashValue >> tmp.d_groupControlShift)
1558 * GroupControl::k_SIZE;
1560 index = findAvailable(tmp.d_controls_p, index, tmp.d_capacity);
1569 tmp.d_controls_p[index] =
static_cast<bsl::uint8_t
>(
1570 hashValue & k_HASHLET_MASK);
1584 d_groupControlShift = 0;
1594template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1595bsl::size_t FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::findKey(
1597 bsl::size_t hashValue)
const
1601 bsl::size_t index = (hashValue >> d_groupControlShift)
1602 * GroupControl::k_SIZE;
1603 bsl::uint8_t hashlet =
static_cast<bsl::uint8_t
>(
1604 hashValue & k_HASHLET_MASK);
1606 for (bsl::size_t i = 0; i < d_capacity; i += GroupControl::k_SIZE) {
1607 bsl::uint8_t *controlStart = d_controls_p + index;
1608 ENTRY *entryStart = d_entries_p + index;
1610 GroupControl groupControl(controlStart);
1611 bsl::uint32_t candidates = groupControl.match(hashlet);
1612 while (candidates) {
1615 ENTRY *entry = entryStart + offset;
1618 d_equal(ENTRY_UTIL::key(*entry), key))) {
1619 return index + offset;
1627 index = (index + GroupControl::k_SIZE) & (d_capacity - 1);
1633template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1634bsl::size_t FlatHashTable<KEY,
1638 EQUAL>::minimumCompliantCapacity(
1639 bsl::size_t minimumCapacity)
const
1641 bsl::size_t minForEntries = ((d_size + k_MAX_LOAD_FACTOR_NUMERATOR - 1)
1642 / k_MAX_LOAD_FACTOR_NUMERATOR)
1643 * k_MAX_LOAD_FACTOR_DENOMINATOR;
1645 bsl::size_t capacity = minimumCapacity >= minForEntries
1650 capacity = capacity > k_MIN_CAPACITY
1652 static_cast<bsl::uint64_t
>(capacity)))
1660template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1662FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::FlatHashTable(
1663 bsl::size_t capacity,
1671, d_groupControlShift(0)
1674, d_allocator_p(
bslma::Default::allocator(basicAllocator))
1677 d_capacity = capacity > k_MIN_CAPACITY
1679 static_cast<bsl::uint64_t
>(capacity)))
1682 d_groupControlShift =
static_cast<int>(
1683 sizeof(bsl::size_t) * 8
1686 / GroupControl::k_SIZE)));
1688 ENTRY *entries =
static_cast<ENTRY *
>(
1689 d_allocator_p->
allocate(d_capacity *
sizeof(ENTRY)));
1694 d_controls_p =
static_cast<bsl::uint8_t *
>(
1695 d_allocator_p->
allocate(d_capacity));
1696 bsl::memset(d_controls_p, GroupControl::k_EMPTY, d_capacity);
1699 d_entries_p = entries;
1703template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1705FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::FlatHashTable(
1706 const FlatHashTable& original,
1712, d_groupControlShift(0)
1713, d_hasher(original.hash_function())
1714, d_equal(original.key_eq())
1715, d_allocator_p(
bslma::Default::allocator(basicAllocator))
1717 if (0 != original.d_capacity) {
1718 bsl::uint8_t *
const controls =
static_cast<bsl::uint8_t *
>(
1719 d_allocator_p->
allocate(original.d_capacity));
1724 ENTRY *
const entries =
static_cast<ENTRY *
>(
1725 d_allocator_p->
allocate(original.d_capacity *
sizeof(ENTRY)));
1730 ImplUtil::copyEntryAndControlArrays(
1733 original.d_entries_p,
1734 original.d_entries_p + original.d_capacity,
1735 original.d_controls_p,
1736 original.d_controls_p + original.d_capacity,
1739 entriesProctor.release();
1740 controlsProctor.release();
1742 d_entries_p = entries;
1743 d_controls_p = controls;
1744 d_size = original.d_size;
1745 d_capacity = original.d_capacity;
1746 d_groupControlShift = original.d_groupControlShift;
1750template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1752FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::FlatHashTable(
1754: d_entries_p(
bslmf::MovableRefUtil::access(original).d_entries_p)
1755, d_controls_p(
bslmf::MovableRefUtil::access(original).d_controls_p)
1756, d_size(
bslmf::MovableRefUtil::access(original).d_size)
1757, d_capacity(
bslmf::MovableRefUtil::access(original).d_capacity)
1758, d_groupControlShift(
1759 bslmf::MovableRefUtil::access(original).d_groupControlShift)
1760, d_hasher(
bslmf::MovableRefUtil::access(original).d_hasher)
1761, d_equal(
bslmf::MovableRefUtil::access(original).d_equal)
1762, d_allocator_p(
bslmf::MovableRefUtil::access(original).d_allocator_p)
1764 FlatHashTable& reference = original;
1766 reference.d_entries_p = 0;
1767 reference.d_controls_p = 0;
1768 reference.d_size = 0;
1769 reference.d_capacity = 0;
1770 reference.d_groupControlShift = 0;
1773template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1774FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::FlatHashTable(
1781, d_groupControlShift(0)
1782, d_hasher(
bslmf::MovableRefUtil::access(original).d_hasher)
1783, d_equal(
bslmf::MovableRefUtil::access(original).d_equal)
1784, d_allocator_p(
bslma::Default::allocator(basicAllocator))
1786 FlatHashTable& reference = original;
1787 if (d_allocator_p == reference.d_allocator_p) {
1793 &reference.d_groupControlShift);
1795 else if (reference.d_capacity) {
1796 bsl::uint8_t *
const controls =
static_cast<bsl::uint8_t *
>(
1797 d_allocator_p->
allocate(reference.d_capacity));
1802 ENTRY *
const entries =
static_cast<ENTRY *
>(
1803 d_allocator_p->
allocate(reference.d_capacity *
sizeof(ENTRY)));
1808 ImplUtil::copyEntryAndControlArrays(
1811 reference.d_entries_p,
1812 reference.d_entries_p + reference.d_capacity,
1813 reference.d_controls_p,
1814 reference.d_controls_p + reference.d_capacity,
1817 entriesProctor.release();
1818 controlsProctor.release();
1820 d_entries_p = entries;
1821 d_controls_p = controls;
1822 d_size = reference.d_size;
1823 d_capacity = reference.d_capacity;
1824 d_groupControlShift = reference.d_groupControlShift;
1828template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1830FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::~FlatHashTable()
1833 (d_capacity == 0 && d_groupControlShift == 0) ||
1834 (d_groupControlShift ==
1835 static_cast<int>(
sizeof(bsl::size_t) * 8 -
1837 d_capacity / GroupControl::k_SIZE)))));
1839 if (0 != d_entries_p) {
1840 ImplUtil::destroyEntryArray(d_entries_p,
1841 d_entries_p + d_capacity,
1843 d_controls_p + d_capacity);
1851template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1853FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>&
1854FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::operator=(
1855 const FlatHashTable& rhs)
1858 FlatHashTable tmp(rhs, d_allocator_p);
1864template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1866FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>&
1867FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::operator=(
1870 FlatHashTable& reference = rhs;
1871 if (
this != &reference) {
1879template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1880template <
class KEY_TYPE>
1882ENTRY& FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::operator[](
1886 bsl::size_t hashValue = d_hasher(key);
1887 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
1890 ENTRY_UTIL::constructFromKey(d_entries_p + index,
1894 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
1895 hashValue & k_HASHLET_MASK);
1900 return d_entries_p[index];
1903template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1905void FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::clear()
1907 ImplUtil::destroyEntryArray(d_entries_p,
1908 d_entries_p + d_capacity,
1910 d_controls_p + d_capacity);
1913 bsl::memset(d_controls_p, GroupControl::k_EMPTY, d_capacity);
1919template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1922 typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
1923 typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator>
1924FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::equal_range(
const KEY& key)
1926 iterator it1 = find(key);
1928 return bsl::make_pair(it1, it1);
1932 return bsl::make_pair(it1, it2);
1935#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
1938#ifndef BDLC_FLATHASHTABLE_VARIADIC_LIMIT
1939#define BDLC_FLATHASHTABLE_VARIADIC_LIMIT 10
1941#ifndef BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C
1942#define BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C BDLC_FLATHASHTABLE_VARIADIC_LIMIT
1944#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C >= 0
1945template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1948 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
1950FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
1954 ENTRY_UTIL::construct(value.
address(),
1962#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C >= 1
1963template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1964template<
class ARGS_01>
1967 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
1969FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
1973 ENTRY_UTIL::construct(value.
address(),
1982#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C >= 2
1983template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1984template<
class ARGS_01,
1988 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
1990FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
1995 ENTRY_UTIL::construct(value.
address(),
2005#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C >= 3
2006template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2007template<
class ARGS_01,
2012 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2014FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
2020 ENTRY_UTIL::construct(value.
address(),
2031#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C >= 4
2032template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2033template<
class ARGS_01,
2039 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2041FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
2048 ENTRY_UTIL::construct(value.
address(),
2060#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C >= 5
2061template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2062template<
class ARGS_01,
2069 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2071FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
2079 ENTRY_UTIL::construct(value.
address(),
2092#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C >= 6
2093template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2094template<
class ARGS_01,
2102 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2104FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
2113 ENTRY_UTIL::construct(value.
address(),
2127#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C >= 7
2128template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2129template<
class ARGS_01,
2138 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2140FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
2150 ENTRY_UTIL::construct(value.
address(),
2165#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C >= 8
2166template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2167template<
class ARGS_01,
2177 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2179FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
2190 ENTRY_UTIL::construct(value.
address(),
2206#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C >= 9
2207template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2208template<
class ARGS_01,
2219 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2221FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
2233 ENTRY_UTIL::construct(value.
address(),
2250#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_C >= 10
2251template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2252template<
class ARGS_01,
2264 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2266FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
2279 ENTRY_UTIL::construct(value.
address(),
2300template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2301template<
class... ARGS>
2304 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2306FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::emplace(
2310 ENTRY_UTIL::construct(value.
address(),
2321template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2323bsl::size_t FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::erase(
2326 iterator it = find(key);
2334template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2336typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator
2337FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::erase(
2338 typename FlatHashTable<KEY,
2342 EQUAL>::const_iterator position)
2346 bsl::size_t index = &*position - d_entries_p;
2347 bslma::DestructionUtil::destroy(d_entries_p + index);
2348 d_controls_p[index] = GroupControl::k_ERASED;
2352 for (bsl::size_t i = index + 1; i < d_capacity; ++i) {
2353 if (0 == (d_controls_p[i] & GroupControl::k_EMPTY)) {
2354 return iterator(IteratorImp(d_entries_p + i,
2356 d_capacity - i - 1));
2363template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2365typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator
2366FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::erase(
2367 typename FlatHashTable<KEY,
2371 EQUAL>::iterator position)
2378 bsl::size_t index = &*position - d_entries_p;
2379 bslma::DestructionUtil::destroy(d_entries_p + index);
2380 d_controls_p[index] = GroupControl::k_ERASED;
2384 for (bsl::size_t i = index + 1; i < d_capacity; ++i) {
2385 if (0 == (d_controls_p[i] & GroupControl::k_EMPTY)) {
2386 return iterator(IteratorImp(d_entries_p + i,
2388 d_capacity - i - 1));
2395template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2396typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator
2397FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::erase(
2398 typename FlatHashTable<KEY,
2402 EQUAL>::const_iterator first,
2403 typename FlatHashTable<KEY,
2407 EQUAL>::const_iterator last)
2411 if (last !=
end()) {
2412 bsl::size_t index = &*last - d_entries_p;
2413 rv = iterator(IteratorImp(d_entries_p + index,
2414 d_controls_p + index,
2415 d_capacity - index - 1));
2422 for (; first != last; ++first) {
2429template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2431typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator
2432FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::find(
const KEY& key)
2434 bsl::size_t index = findKey(key, d_hasher(key));
2435 if (index < d_capacity) {
2436 return iterator(IteratorImp(d_entries_p + index,
2437 d_controls_p + index,
2438 d_capacity - index - 1));
2443template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2444template <
class INPUT_ITERATOR>
2446void FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::insert(
2447 INPUT_ITERATOR first,
2448 INPUT_ITERATOR last)
2450 for (; first != last; ++first) {
2455template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2457void FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::rehash(
2458 bsl::size_t minimumCapacity)
2460 minimumCapacity = minimumCompliantCapacity(minimumCapacity);
2462 if (0 < minimumCapacity) {
2463 rehashRaw(minimumCapacity);
2472 d_groupControlShift = 0;
2476template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2478void FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::reserve(
2479 bsl::size_t numEntries)
2481 if (0 == d_capacity && 0 == numEntries) {
2488 bsl::size_t minForEntries = ((numEntries + k_MAX_LOAD_FACTOR_NUMERATOR - 1)
2489 / k_MAX_LOAD_FACTOR_NUMERATOR)
2490 * k_MAX_LOAD_FACTOR_DENOMINATOR;
2492 rehash(minForEntries);
2495template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2497void FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::reset()
2499 if (0 != d_entries_p) {
2500 ImplUtil::destroyEntryArray(d_entries_p,
2501 d_entries_p + d_capacity,
2503 d_controls_p + d_capacity);
2512 d_groupControlShift = 0;
2516#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
2519#ifndef BDLC_FLATHASHTABLE_VARIADIC_LIMIT
2520#define BDLC_FLATHASHTABLE_VARIADIC_LIMIT 10
2522#ifndef BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D
2523#define BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D BDLC_FLATHASHTABLE_VARIADIC_LIMIT
2525#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 0
2526template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2528 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2530FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
2534 bsl::size_t hashValue = d_hasher(key);
2535 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2538 ENTRY_UTIL::construct(d_entries_p + index,
2541 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2542 hashValue & k_HASHLET_MASK);
2547 d_controls_p + index,
2548 d_capacity - index - 1),
2553#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 1
2554template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2555template<
class ARGS_01>
2557 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2559FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
2564 bsl::size_t hashValue = d_hasher(key);
2565 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2568 ENTRY_UTIL::construct(d_entries_p + index,
2572 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2573 hashValue & k_HASHLET_MASK);
2578 d_controls_p + index,
2579 d_capacity - index - 1),
2584#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 2
2585template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2586template<
class ARGS_01,
2589 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2591FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
2597 bsl::size_t hashValue = d_hasher(key);
2598 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2601 ENTRY_UTIL::construct(d_entries_p + index,
2606 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2607 hashValue & k_HASHLET_MASK);
2612 d_controls_p + index,
2613 d_capacity - index - 1),
2618#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 3
2619template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2620template<
class ARGS_01,
2624 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2626FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
2633 bsl::size_t hashValue = d_hasher(key);
2634 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2637 ENTRY_UTIL::construct(d_entries_p + index,
2643 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2644 hashValue & k_HASHLET_MASK);
2649 d_controls_p + index,
2650 d_capacity - index - 1),
2655#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 4
2656template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2657template<
class ARGS_01,
2662 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2664FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
2672 bsl::size_t hashValue = d_hasher(key);
2673 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2676 ENTRY_UTIL::construct(d_entries_p + index,
2683 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2684 hashValue & k_HASHLET_MASK);
2689 d_controls_p + index,
2690 d_capacity - index - 1),
2695#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 5
2696template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2697template<
class ARGS_01,
2703 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2705FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
2714 bsl::size_t hashValue = d_hasher(key);
2715 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2718 ENTRY_UTIL::construct(d_entries_p + index,
2726 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2727 hashValue & k_HASHLET_MASK);
2732 d_controls_p + index,
2733 d_capacity - index - 1),
2738#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 6
2739template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2740template<
class ARGS_01,
2747 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2749FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
2759 bsl::size_t hashValue = d_hasher(key);
2760 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2763 ENTRY_UTIL::construct(d_entries_p + index,
2772 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2773 hashValue & k_HASHLET_MASK);
2778 d_controls_p + index,
2779 d_capacity - index - 1),
2784#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 7
2785template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2786template<
class ARGS_01,
2794 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2796FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
2807 bsl::size_t hashValue = d_hasher(key);
2808 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2811 ENTRY_UTIL::construct(d_entries_p + index,
2821 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2822 hashValue & k_HASHLET_MASK);
2827 d_controls_p + index,
2828 d_capacity - index - 1),
2833#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 8
2834template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2835template<
class ARGS_01,
2844 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2846FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
2858 bsl::size_t hashValue = d_hasher(key);
2859 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2862 ENTRY_UTIL::construct(d_entries_p + index,
2873 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2874 hashValue & k_HASHLET_MASK);
2879 d_controls_p + index,
2880 d_capacity - index - 1),
2885#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 9
2886template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2887template<
class ARGS_01,
2897 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2899FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
2912 bsl::size_t hashValue = d_hasher(key);
2913 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2916 ENTRY_UTIL::construct(d_entries_p + index,
2928 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2929 hashValue & k_HASHLET_MASK);
2934 d_controls_p + index,
2935 d_capacity - index - 1),
2940#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 10
2941template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2942template<
class ARGS_01,
2953 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
2955FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
2969 bsl::size_t hashValue = d_hasher(key);
2970 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2973 ENTRY_UTIL::construct(d_entries_p + index,
2986 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2987 hashValue & k_HASHLET_MASK);
2992 d_controls_p + index,
2993 d_capacity - index - 1),
2999#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 0
3000template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3002 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3004FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3005 BloombergLP::bslmf::MovableRef<KEY> key)
3009 bsl::size_t hashValue = d_hasher(k);
3010 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3013 ENTRY_UTIL::construct(d_entries_p + index,
3016 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3017 hashValue & k_HASHLET_MASK);
3021 d_controls_p + index,
3022 d_capacity - index - 1),
3027#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 1
3028template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3029template<
class ARGS_01>
3031 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3033FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3034 BloombergLP::bslmf::MovableRef<KEY> key,
3039 bsl::size_t hashValue = d_hasher(k);
3040 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3043 ENTRY_UTIL::construct(d_entries_p + index,
3047 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3048 hashValue & k_HASHLET_MASK);
3052 d_controls_p + index,
3053 d_capacity - index - 1),
3058#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 2
3059template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3060template<
class ARGS_01,
3063 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3065FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3066 BloombergLP::bslmf::MovableRef<KEY> key,
3072 bsl::size_t hashValue = d_hasher(k);
3073 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3076 ENTRY_UTIL::construct(d_entries_p + index,
3081 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3082 hashValue & k_HASHLET_MASK);
3086 d_controls_p + index,
3087 d_capacity - index - 1),
3092#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 3
3093template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3094template<
class ARGS_01,
3098 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3100FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3101 BloombergLP::bslmf::MovableRef<KEY> key,
3108 bsl::size_t hashValue = d_hasher(k);
3109 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3112 ENTRY_UTIL::construct(d_entries_p + index,
3118 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3119 hashValue & k_HASHLET_MASK);
3123 d_controls_p + index,
3124 d_capacity - index - 1),
3129#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 4
3130template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3131template<
class ARGS_01,
3136 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3138FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3139 BloombergLP::bslmf::MovableRef<KEY> key,
3147 bsl::size_t hashValue = d_hasher(k);
3148 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3151 ENTRY_UTIL::construct(d_entries_p + index,
3158 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3159 hashValue & k_HASHLET_MASK);
3163 d_controls_p + index,
3164 d_capacity - index - 1),
3169#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 5
3170template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3171template<
class ARGS_01,
3177 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3179FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3180 BloombergLP::bslmf::MovableRef<KEY> key,
3189 bsl::size_t hashValue = d_hasher(k);
3190 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3193 ENTRY_UTIL::construct(d_entries_p + index,
3201 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3202 hashValue & k_HASHLET_MASK);
3206 d_controls_p + index,
3207 d_capacity - index - 1),
3212#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 6
3213template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3214template<
class ARGS_01,
3221 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3223FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3224 BloombergLP::bslmf::MovableRef<KEY> key,
3234 bsl::size_t hashValue = d_hasher(k);
3235 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3238 ENTRY_UTIL::construct(d_entries_p + index,
3247 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3248 hashValue & k_HASHLET_MASK);
3252 d_controls_p + index,
3253 d_capacity - index - 1),
3258#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 7
3259template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3260template<
class ARGS_01,
3268 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3270FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3271 BloombergLP::bslmf::MovableRef<KEY> key,
3282 bsl::size_t hashValue = d_hasher(k);
3283 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3286 ENTRY_UTIL::construct(d_entries_p + index,
3296 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3297 hashValue & k_HASHLET_MASK);
3301 d_controls_p + index,
3302 d_capacity - index - 1),
3307#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 8
3308template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3309template<
class ARGS_01,
3318 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3320FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3321 BloombergLP::bslmf::MovableRef<KEY> key,
3333 bsl::size_t hashValue = d_hasher(k);
3334 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3337 ENTRY_UTIL::construct(d_entries_p + index,
3348 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3349 hashValue & k_HASHLET_MASK);
3353 d_controls_p + index,
3354 d_capacity - index - 1),
3359#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 9
3360template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3361template<
class ARGS_01,
3371 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3373FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3374 BloombergLP::bslmf::MovableRef<KEY> key,
3387 bsl::size_t hashValue = d_hasher(k);
3388 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3391 ENTRY_UTIL::construct(d_entries_p + index,
3403 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3404 hashValue & k_HASHLET_MASK);
3408 d_controls_p + index,
3409 d_capacity - index - 1),
3414#if BDLC_FLATHASHTABLE_VARIADIC_LIMIT_D >= 10
3415template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3416template<
class ARGS_01,
3427 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3429FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3430 BloombergLP::bslmf::MovableRef<KEY> key,
3444 bsl::size_t hashValue = d_hasher(k);
3445 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3448 ENTRY_UTIL::construct(d_entries_p + index,
3461 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3462 hashValue & k_HASHLET_MASK);
3466 d_controls_p + index,
3467 d_capacity - index - 1),
3475template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3476template<
class... ARGS>
3478 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3480FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3485 bsl::size_t hashValue = d_hasher(key);
3486 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
3489 ENTRY_UTIL::construct(d_entries_p + index,
3493 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3494 hashValue & k_HASHLET_MASK);
3499 d_controls_p + index,
3500 d_capacity - index - 1),
3504template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3505template<
class... ARGS>
3507 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator,
3509FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::try_emplace(
3510 BloombergLP::bslmf::MovableRef<KEY> key,
3515 bsl::size_t hashValue = d_hasher(k);
3516 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
3519 ENTRY_UTIL::construct(d_entries_p + index,
3523 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
3524 hashValue & k_HASHLET_MASK);
3528 d_controls_p + index,
3529 d_capacity - index - 1),
3537template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3539typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator
3540FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::begin()
3543 for (bsl::size_t i = 0; i < d_capacity; ++i) {
3544 if (0 == (d_controls_p[i] & GroupControl::k_EMPTY)) {
3545 return iterator(IteratorImp(d_entries_p + i,
3547 d_capacity - i - 1));
3554template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3556typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::iterator
3557FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::end()
3564template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3566void FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::swap(
3567 FlatHashTable& other)
3581template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3583bsl::size_t FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::
3589template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3591bool FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::contains(
3592 const KEY& key)
const
3594 return find(key) !=
end();
3597template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3599const bsl::uint8_t *FlatHashTable<KEY,
3603 EQUAL>::controls()
const
3605 return d_controls_p;
3608template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3610bsl::size_t FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::count(
3611 const KEY& key)
const
3613 return contains(key) ? 1 : 0;
3616template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3618bool FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::empty()
const
3623template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3625const ENTRY *FlatHashTable<KEY,
3629 EQUAL>::entries()
const
3634template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3640 EQUAL>::const_iterator,
3641 typename FlatHashTable<KEY,
3645 EQUAL>::const_iterator>
3646FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::equal_range(
3647 const KEY& key)
const
3649 const_iterator cit1 = find(key);
3650 const_iterator cit2 = cit1;
3651 if (cit1 !=
end()) {
3654 return bsl::make_pair(cit1, cit2);
3657template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3659typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::const_iterator
3660FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::find(
const KEY& key)
const
3662 bsl::size_t index = findKey(key, d_hasher(key));
3663 if (index < d_capacity) {
3664 return const_iterator(IteratorImp(d_entries_p + index,
3665 d_controls_p + index,
3666 d_capacity - index - 1));
3671template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3673HASH FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::hash_function()
const
3678template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3680EQUAL FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::key_eq()
const
3685template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3691 EQUAL>::load_factor()
const
3693 return d_capacity > 0
3694 ?
static_cast<float>(d_size) /
static_cast<float>(d_capacity)
3698template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3704 EQUAL>::max_load_factor()
const
3706 return static_cast<float>(k_MAX_LOAD_FACTOR_NUMERATOR)
3707 /
static_cast<float>(k_MAX_LOAD_FACTOR_DENOMINATOR);
3710template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3712bsl::size_t FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::size()
const
3719template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3721typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::const_iterator
3722FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::begin()
const
3725 for (bsl::size_t i = 0; i < d_capacity; ++i) {
3726 if (0 == (d_controls_p[i] & GroupControl::k_EMPTY)) {
3727 return const_iterator(
3728 IteratorImp(d_entries_p + i,
3730 d_capacity - i - 1));
3734 return const_iterator();
3737template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3739typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::const_iterator
3740FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::cbegin()
const
3745template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3747typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::const_iterator
3748FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::cend()
const
3753template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3755typename FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::const_iterator
3756FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::end()
const
3758 return const_iterator();
3763template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3768 return d_allocator_p;
3774template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3780 const FlatHashTable<KEY,
3786 typedef typename FlatHashTable<KEY,
3790 EQUAL>::const_iterator ConstIterator;
3792 if (lhs.size() == rhs.size()) {
3793 ConstIterator lhsEnd = lhs.end();
3794 ConstIterator rhsEnd = rhs.end();
3796 if (lhs.capacity() <= rhs.capacity()) {
3797 for (ConstIterator it = lhs.begin(); it != lhsEnd; ++it) {
3798 ConstIterator i = rhs.find(ENTRY_UTIL::key(*it));
3799 if (i == rhsEnd || *i != *it) {
3806 for (ConstIterator it = rhs.begin(); it != rhsEnd; ++it) {
3807 ConstIterator i = lhs.find(ENTRY_UTIL::key(*it));
3808 if (i == lhsEnd || *i != *it) {
3818template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3824 const FlatHashTable<KEY,
3830 return !(lhs == rhs);
3834template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3836void bdlc::swap(FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>& a,
3837 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>& b)
3839 if (a.allocator() == b.allocator()) {
3845 typedef FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL> Table;
3847 Table futureA(b, a.allocator());
3848 Table futureB(a, b.allocator());
3856template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
3857struct UsesBslmaAllocator<
bdlc::FlatHashTable<KEY,
3873template <
class ENTRY_TYPE>
3875void FlatHashTable_ImplUtil::copyEntryAndControlArrays(
3876 ENTRY_TYPE *firstDestinationEntry,
3877 bsl::uint8_t *firstDestinationControl,
3878 const ENTRY_TYPE *firstSourceEntry,
3879 const ENTRY_TYPE *lastSourceEntry,
3880 const bsl::uint8_t *firstSourceControl,
3881 const bsl::uint8_t *lastSourceControl,
3885 (void) isBitwiseCopyable;
3889 bsl::memcpy(firstDestinationControl,
3891 bsl::distance(firstSourceControl, lastSourceControl) *
3892 sizeof(bsl::uint8_t));
3894 const bsl::size_t numEntries =
static_cast<bsl::size_t
>(
3895 bsl::distance(firstSourceEntry, lastSourceEntry));
3897 DestroyEntryArrayProctor<ENTRY_TYPE> destroyEntriesProctor(
3898 firstDestinationEntry,
3899 firstDestinationEntry,
3900 firstDestinationControl,
3901 firstDestinationControl);
3903 for (bsl::size_t idx = 0; idx != numEntries; ++idx) {
3904 ENTRY_TYPE& destinationEntry = *(firstDestinationEntry + idx);
3905 const bsl::uint8_t& sourceControl = *(firstSourceControl + idx);
3906 const ENTRY_TYPE& sourceEntry = *(firstSourceEntry + idx);
3910 &destinationEntry, entryAllocator, sourceEntry);
3913 destroyEntriesProctor.moveEnd(1);
3916 destroyEntriesProctor.release();
3919template <
class ENTRY_TYPE>
3921void FlatHashTable_ImplUtil::copyEntryAndControlArrays(
3922 ENTRY_TYPE *firstDestinationEntry,
3923 bsl::uint8_t *firstDestinationControl,
3924 const ENTRY_TYPE *firstSourceEntry,
3925 const ENTRY_TYPE *lastSourceEntry,
3926 const bsl::uint8_t *firstSourceControl,
3927 const bsl::uint8_t *lastSourceControl,
3931 (void) isBitwiseCopyable;
3935 bsl::memcpy(firstDestinationControl,
3937 bsl::distance(firstSourceControl, lastSourceControl) *
3938 sizeof(bsl::uint8_t));
3940#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 80000
3941#pragma GCC diagnostic push
3942#pragma GCC diagnostic ignored "-Wclass-memaccess"
3945 bsl::memcpy(firstDestinationEntry,
3947 bsl::distance(firstSourceEntry, lastSourceEntry) *
3948 sizeof(ENTRY_TYPE));
3950#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 80000
3951#pragma GCC diagnostic pop
3955template <
class ENTRY_TYPE>
3957void FlatHashTable_ImplUtil::destroyEntryArray(
3958 ENTRY_TYPE *firstEntry,
3959 ENTRY_TYPE *lastEntry,
3960 const bsl::uint8_t *firstControl,
3961 const bsl::uint8_t *lastControl,
3964 (void) triviallyDestructible;
3984 static_cast<void>(lastControl);
3986 const bsl::size_t numEntries =
3987 static_cast<bsl::size_t
>(bsl::distance(firstEntry, lastEntry));
3988 const bsl::size_t numGroupedEntries =
3991 for (bsl::size_t idx = 0;
3992 idx != numGroupedEntries;
3994 GroupControl groupControl(firstControl + idx);
3995 bsl::uint32_t candidates = groupControl.inUse();
3996 while (candidates) {
3998 bslma::DestructionUtil::destroy(firstEntry + idx + offset);
4003 for (bsl::size_t idx = numGroupedEntries; idx != numEntries; ++idx) {
4004 ENTRY_TYPE& entry = *(firstEntry + idx);
4005 const bsl::uint8_t& control = *(firstControl + idx);
4008 bslma::DestructionUtil::destroy(&entry);
4013template <
class ENTRY_TYPE>
4015void FlatHashTable_ImplUtil::destroyEntryArray(
4018 const bsl::uint8_t *,
4019 const bsl::uint8_t *,
4022 (void) triviallyDestructible;
4028template <
class ENTRY_TYPE>
4030void FlatHashTable_ImplUtil::copyEntryAndControlArrays(
4031 ENTRY_TYPE *firstDestinationEntry,
4032 bsl::uint8_t *firstDestinationControl,
4033 const ENTRY_TYPE *firstSourceEntry,
4034 const ENTRY_TYPE *lastSourceEntry,
4035 const bsl::uint8_t *firstSourceControl,
4036 const bsl::uint8_t *lastSourceControl,
4040 bsl::distance(firstSourceControl, lastSourceControl));
4042 FlatHashTable_ImplUtil::copyEntryAndControlArrays(
4043 firstDestinationEntry,
4044 firstDestinationControl,
4053template <
class ENTRY_TYPE>
4055void FlatHashTable_ImplUtil::destroyEntryArray(
4056 ENTRY_TYPE *firstEntry,
4057 ENTRY_TYPE *lastEntry,
4058 const bsl::uint8_t *firstControl,
4059 const bsl::uint8_t *lastControl)
4062 bsl::distance(firstControl, lastControl));
4075 IsEntryTypeTriviallyDestructible;
4077 FlatHashTable_ImplUtil::destroyEntryArray(
4082 IsEntryTypeTriviallyDestructible());
4090template <
class ENTRY_TYPE>
4092FlatHashTable_ImplUtil::DestroyEntryArrayProctor<
4093 ENTRY_TYPE>::DestroyEntryArrayProctor(ENTRY_TYPE *firstEntry,
4094 ENTRY_TYPE *lastEntry,
4095 const bsl::uint8_t *firstControl,
4096 const bsl::uint8_t *lastControl)
4097: d_firstEntry_p(firstEntry)
4098, d_lastEntry_p(lastEntry)
4099, d_firstControl_p(firstControl)
4100, d_lastControl_p(lastControl)
4104template <
class ENTRY_TYPE>
4106FlatHashTable_ImplUtil::DestroyEntryArrayProctor<
4107 ENTRY_TYPE>::~DestroyEntryArrayProctor()
4109 ImplUtil::destroyEntryArray(d_firstEntry_p,
4116template <
class ENTRY_TYPE>
4118void FlatHashTable_ImplUtil::DestroyEntryArrayProctor<ENTRY_TYPE>::moveEnd(
4119 bsl::ptrdiff_t offset)
4121 d_lastEntry_p += offset;
4122 d_lastControl_p += offset;
4125template <
class ENTRY_TYPE>
4127void FlatHashTable_ImplUtil::DestroyEntryArrayProctor<ENTRY_TYPE>::release()
4131 d_firstControl_p = 0;
4132 d_lastControl_p = 0;
4139# error Not valid except when included from bdlc_flathashtable.h
static const bsl::uint8_t k_EMPTY
Definition bdlc_flathashtable_groupcontrol.h:124
static const bsl::size_t k_SIZE
Definition bdlc_flathashtable_groupcontrol.h:126
FlatHashTable_IteratorImp & operator=(const FlatHashTable_IteratorImp &rhs)
Definition bdlc_flathashtable.h:1082
~FlatHashTable_IteratorImp()=default
FlatHashTable_IteratorImp()
Definition bdlc_flathashtable.h:1050
void operator++()
Definition bdlc_flathashtable.h:1094
ENTRY & operator*() const
Definition bdlc_flathashtable.h:1115
Definition bdlc_flathashtable.h:317
void clear()
Definition bdlc_flathashtable.h:1580
bsl::size_t erase(const KEY &key)
Definition bdlc_flathashtable.h:1632
const ENTRY * entries() const
Definition bdlc_flathashtable.h:1981
static const bsl::size_t k_MIN_CAPACITY
Definition bdlc_flathashtable.h:398
float max_load_factor() const
Definition bdlc_flathashtable.h:2056
const_iterator cbegin() const
Definition bdlc_flathashtable.h:2092
void swap(FlatHashTable &other)
Definition bdlc_flathashtable.h:1918
HASH hash_type
Definition bdlc_flathashtable.h:328
EQUAL key_equal_type
Definition bdlc_flathashtable.h:329
static const bsl::size_t k_MAX_LOAD_FACTOR_NUMERATOR
Definition bdlc_flathashtable.h:403
void reset()
Definition bdlc_flathashtable.h:1806
bsl::pair< iterator, bool > emplace(ARGS &&... args)
iterator find(const KEY &key)
Definition bdlc_flathashtable.h:1741
iterator end()
Definition bdlc_flathashtable.h:1909
bool empty() const
Definition bdlc_flathashtable.h:1970
bsl::pair< iterator, bool > try_emplace(const KEY &key, ARGS &&... args)
static const bsl::size_t k_MAX_LOAD_FACTOR_DENOMINATOR
Definition bdlc_flathashtable.h:408
ENTRY_UTIL entry_util_type
Definition bdlc_flathashtable.h:327
static const bsl::int8_t k_HASHLET_MASK
Definition bdlc_flathashtable.h:401
bsl::enable_if< bsl::is_convertible< ENTRY_TYPE, ENTRY >::value, bsl::pair< iterator, bool > >::type insert(BSLS_COMPILERFEATURES_FORWARD_REF(ENTRY_TYPE) entry)
Definition bdlc_flathashtable.h:564
bslma::Allocator * allocator() const
Return the allocator used by this hash table to supply memory.
Definition bdlc_flathashtable.h:2118
bsl::size_t capacity() const
Definition bdlc_flathashtable.h:1936
bslstl::ForwardIterator< const ENTRY, IteratorImp > const_iterator
Definition bdlc_flathashtable.h:334
bslstl::ForwardIterator< ENTRY, IteratorImp > iterator
Definition bdlc_flathashtable.h:332
const bsl::uint8_t * controls() const
Definition bdlc_flathashtable.h:1955
ENTRY entry_type
Definition bdlc_flathashtable.h:326
ENTRY & operator[](BSLS_COMPILERFEATURES_FORWARD_REF(KEY_TYPE) key)
Definition bdlc_flathashtable.h:1557
KEY key_type
Definition bdlc_flathashtable.h:325
EQUAL key_eq() const
Definition bdlc_flathashtable.h:2032
bool contains(const KEY &key) const
Definition bdlc_flathashtable.h:1943
iterator begin()
Definition bdlc_flathashtable.h:1892
void reserve(bsl::size_t numEntries)
Definition bdlc_flathashtable.h:1787
const_iterator cend() const
Definition bdlc_flathashtable.h:2100
bsl::size_t size() const
Return the number of entries in this table.
Definition bdlc_flathashtable.h:2064
bsl::size_t count(const KEY &key) const
Definition bdlc_flathashtable.h:1962
FlatHashTable & operator=(const FlatHashTable &rhs)
Definition bdlc_flathashtable.h:1529
~FlatHashTable()
Destroy this object and each of its entries.
Definition bdlc_flathashtable.h:1505
HASH hash_function() const
Definition bdlc_flathashtable.h:2025
float load_factor() const
Definition bdlc_flathashtable.h:2043
void rehash(bsl::size_t minimumCapacity)
Definition bdlc_flathashtable.h:1766
bsl::pair< iterator, iterator > equal_range(const KEY &key)
Definition bdlc_flathashtable.h:1599
Definition bslstl_pair.h:1210
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:194
Definition bslma_allocator.h:457
virtual void deallocate(void *address)=0
virtual void * allocate(size_type size)=0
Definition bslma_deallocatorproctor.h:312
Definition bslma_destructorguard.h:132
Definition bslma_destructorproctor.h:259
Definition bslmf_movableref.h:751
Definition bslstl_forwarditerator.h:169
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_ASSERT_OPT(X)
Definition bsls_assert.h:1856
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2012
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
bool operator!=(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
bool operator==(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
void swap(OptionValue &a, OptionValue &b)
Definition bdlc_bitarray.h:503
void swap(BitArray &a, BitArray &b)
bool operator==(const BitArray &lhs, const BitArray &rhs)
bool operator!=(const BitArray &lhs, const BitArray &rhs)
deque< VALUE_TYPE, ALLOCATOR >::size_type erase(deque< VALUE_TYPE, ALLOCATOR > &deq, const BDE_OTHER_TYPE &value)
Definition bslstl_deque.h:4126
T::iterator begin(T &container)
Definition bslstl_iterator.h:1495
T::iterator end(T &container)
Definition bslstl_iterator.h:1523
Definition balxml_encoderoptions.h:68
Definition bdlbb_blob.h:576
static int numTrailingUnsetBits(unsigned int value)
Definition bdlb_bitutil.h:462
static unsigned int withBitCleared(unsigned int value, int index)
Definition bdlb_bitutil.h:581
static int log2(unsigned int value)
Definition bdlb_bitutil.h:338
static unsigned int roundUpToBinaryPower(unsigned int value)
Definition bdlb_bitutil.h:550
Definition bslmf_enableif.h:525
Definition bslmf_integralconstant.h:244
static void construct(TARGET_TYPE *address, const ALLOCATOR &allocator)
Definition bslma_constructionutil.h:1243
static void destructiveMove(TARGET_TYPE *address, const ALLOCATOR &allocator, TARGET_TYPE *original)
Definition bslma_constructionutil.h:1295
Definition bslmf_isbitwisecopyable.h:298
static MovableRef< t_TYPE > move(t_TYPE &reference) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1060
Definition bsls_objectbuffer.h:276
TYPE * address()
Definition bsls_objectbuffer.h:334
TYPE & object()
Definition bsls_objectbuffer.h:351