8#ifndef INCLUDED_BDLC_FLATHASHTABLE
9#define INCLUDED_BDLC_FLATHASHTABLE
167#include <bdlscm_version.h>
201#include <bsl_cstddef.h>
202#include <bsl_cstdint.h>
203#include <bsl_cstring.h>
204#include <bsl_iterator.h>
205#include <bsl_limits.h>
206#include <bsl_type_traits.h>
207#include <bsl_utility.h>
209#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
215# define COMPILING_BDLC_FLATHASHTABLE_H
217# undef COMPILING_BDLC_FLATHASHTABLE_H
226struct FlatHashTable_ImplUtil;
228template <
class ENTRY>
229class FlatHashTable_IteratorImp;
231template <
class ENTRY>
243template <
class ENTRY>
251 const bsl::uint8_t *d_controls_p;
252 bsl::size_t d_additionalLength;
273 const bsl::uint8_t *controls,
274 bsl::size_t additionalLength);
314template <
class ENTRY>
324template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
348 bsl::uint8_t *d_controls_p;
350 bsl::size_t d_capacity;
351 int d_groupControlShift;
364 static bsl::size_t findAvailable(bsl::uint8_t *
controls,
381 bsl::size_t indexOfKey(
bool *notFound,
383 bsl::size_t hashValue);
396 template <
class LOOKUP_KEY>
398 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
399 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value
401 indexOfKeyTransparent(
bool *notFound,
402 const LOOKUP_KEY& key,
403 bsl::size_t hashValue)
407 bsl::size_t index = findTransparentKey(key, hashValue);
409 if (index == d_capacity) {
418 index = findAvailable(d_controls_p, index, d_capacity);
433 void rehashRaw(bsl::size_t newCapacity);
442 bsl::size_t findKey(
const KEY& key, bsl::size_t hashValue)
const;
449 template <
class LOOKUP_KEY>
451 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
452 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value
454 findTransparentKey(
const LOOKUP_KEY& key, bsl::size_t hashValue)
const
460 bsl::size_t index = (hashValue >> d_groupControlShift)
462 bsl::uint8_t hashlet =
static_cast<bsl::uint8_t
>(
466 bsl::uint8_t *controlStart = d_controls_p + index;
467 ENTRY *entryStart = d_entries_p + index;
469 GroupControl groupControl(controlStart);
470 bsl::uint32_t candidates = groupControl.match(hashlet);
474 ENTRY *entry = entryStart + offset;
477 d_equal(ENTRY_UTIL::key(*entry), key))) {
478 return index + offset;
495 bsl::size_t minimumCompliantCapacity(bsl::size_t minimumCapacity)
const;
592 template <
class KEY_TYPE>
621 template <
class LOOKUP_KEY>
623 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
624 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value
635 return bsl::make_pair(it1, it2);
638#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
645 template<
class... ARGS>
655#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
660 template <
class LOOKUP_KEY>
662 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
663 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value
707 template <
class LOOKUP_KEY>
709 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
710 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value
716 bsl::size_t index = findTransparentKey(key, d_hasher(key));
717 if (index < d_capacity) {
718 return iterator(IteratorImp(d_entries_p + index,
719 d_controls_p + index,
720 d_capacity - index - 1));
738#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
749 template <
class LOOKUP_KEY>
751 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
752 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value
760 bsl::size_t hashValue = d_hasher(key);
761 bsl::size_t index = indexOfKeyTransparent(¬Found,
766 ENTRY_UTIL::construct(
771 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
778 d_controls_p + index,
779 d_capacity - index - 1),
795 template <
class INPUT_ITERATOR>
796 void insert(INPUT_ITERATOR first, INPUT_ITERATOR last);
805 void rehash(bsl::size_t minimumCapacity);
825#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
835 template<
class... ARGS>
847 template <
class... ARGS>
849 BloombergLP::bslmf::MovableRef<KEY> key,
861 template <
class LOOKUP_KEY,
class... ARGS>
863 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
864 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value
870 bsl::size_t hashValue = d_hasher(key);
871 bsl::size_t index = indexOfKeyTransparent(¬Found, key, hashValue);
874 ENTRY_UTIL::construct(d_entries_p + index,
878 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
884 d_controls_p + index,
885 d_capacity - index - 1),
932 bsl::size_t
count(
const KEY& key)
const;
956 const KEY& key)
const;
967 template <
class LOOKUP_KEY>
969 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
970 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value
981 return bsl::make_pair(cit1, cit2);
992 template <
class LOOKUP_KEY>
994 BloombergLP::bslmf::IsTransparentPredicate<HASH, LOOKUP_KEY>::value
995 && BloombergLP::bslmf::IsTransparentPredicate<EQUAL,LOOKUP_KEY>::value
997 find(
const LOOKUP_KEY& key)
const
1001 bsl::size_t index = findTransparentKey(key, d_hasher(key));
1002 if (index < d_capacity) {
1004 d_controls_p + index,
1005 d_capacity - index - 1));
1066template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1077template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1086template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1110 template <
class ENTRY_TYPE>
1111 class DestroyEntryArrayProctor;
1146 template <
class ENTRY_TYPE>
1147 static void copyEntryAndControlArrays(
1148 ENTRY_TYPE *firstDestinationEntry,
1149 bsl::uint8_t *firstDestinationControl,
1150 const ENTRY_TYPE *firstSourceEntry,
1151 const ENTRY_TYPE *lastSourceEntry,
1152 const bsl::uint8_t *firstSourceControl,
1153 const bsl::uint8_t *lastSourceControl,
1156 template <
class ENTRY_TYPE>
1157 static void copyEntryAndControlArrays(
1158 ENTRY_TYPE *firstDestinationEntry,
1159 bsl::uint8_t *firstDestinationControl,
1160 const ENTRY_TYPE *firstSourceEntry,
1161 const ENTRY_TYPE *lastSourceEntry,
1162 const bsl::uint8_t *firstSourceControl,
1163 const bsl::uint8_t *lastSourceControl,
1185 template <
class ENTRY_TYPE>
1186 static void destroyEntryArray(ENTRY_TYPE *firstEntry,
1187 ENTRY_TYPE *lastEntry,
1188 const bsl::uint8_t *firstControl,
1189 const bsl::uint8_t *lastControl,
1191 template <
class ENTRY_TYPE>
1192 static void destroyEntryArray(ENTRY_TYPE *firstEntry,
1193 ENTRY_TYPE *lastEntry,
1194 const bsl::uint8_t *firstControl,
1195 const bsl::uint8_t *lastControl,
1229 template <
class ENTRY_TYPE>
1231 copyEntryAndControlArrays(ENTRY_TYPE *firstDestinationEntry,
1232 bsl::uint8_t *firstDestinationControl,
1233 const ENTRY_TYPE *firstSourceEntry,
1234 const ENTRY_TYPE *lastSourceEntry,
1235 const bsl::uint8_t *firstSourceControl,
1236 const bsl::uint8_t *lastSourceControl,
1254 template <
class ENTRY_TYPE>
1255 static void destroyEntryArray(ENTRY_TYPE *firstEntry,
1256 ENTRY_TYPE *lastEntry,
1257 const bsl::uint8_t *firstControl,
1258 const bsl::uint8_t *lastControl);
1270template <
class ENTRY_TYPE>
1271class FlatHashTable_ImplUtil::DestroyEntryArrayProctor {
1280 ENTRY_TYPE *d_firstEntry_p;
1283 ENTRY_TYPE *d_lastEntry_p;
1286 const bsl::uint8_t *d_firstControl_p;
1289 const bsl::uint8_t *d_lastControl_p;
1293 DestroyEntryArrayProctor(
const DestroyEntryArrayProctor&);
1294 DestroyEntryArrayProctor& operator=(
const DestroyEntryArrayProctor&);
1309 DestroyEntryArrayProctor(ENTRY_TYPE *firstEntry,
1310 ENTRY_TYPE *lastEntry,
1311 const bsl::uint8_t *firstControl,
1312 const bsl::uint8_t *lastControl);
1317 ~DestroyEntryArrayProctor();
1323 void moveEnd(bsl::ptrdiff_t offset);
1342template <
class ENTRY>
1347, d_additionalLength(0)
1351template <
class ENTRY>
1355 const bsl::uint8_t *controls,
1356 bsl::size_t additionalLength)
1357: d_entries_p(entries)
1358, d_controls_p(controls)
1359, d_additionalLength(additionalLength)
1363template <
class ENTRY>
1367: d_entries_p(original.d_entries_p)
1368, d_controls_p(original.d_controls_p)
1369, d_additionalLength(original.d_additionalLength)
1374template <
class ENTRY>
1379 d_entries_p = rhs.d_entries_p;
1380 d_controls_p = rhs.d_controls_p;
1381 d_additionalLength = rhs.d_additionalLength;
1386template <
class ENTRY>
1393 while (d_additionalLength) {
1396 --d_additionalLength;
1397 if (0 == (*d_controls_p & 0x80)) {
1407template <
class ENTRY>
1414 return *d_entries_p;
1420template <
class ENTRY>
1423 const FlatHashTable_IteratorImp<ENTRY>& b)
1425 return a.d_entries_p == b.d_entries_p
1426 && a.d_controls_p == b.d_controls_p
1427 && a.d_additionalLength == b.d_additionalLength;
1437template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1438bsl::size_t FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::findAvailable(
1439 bsl::uint8_t *controls,
1441 bsl::size_t capacity)
1445 for (bsl::size_t i = 0; i < capacity; i += GroupControl::k_SIZE) {
1446 bsl::uint8_t *controlStart = controls + index;
1448 GroupControl groupControl(controlStart);
1449 bsl::uint32_t candidates = groupControl.available();
1456 index = (index + GroupControl::k_SIZE) & (capacity - 1);
1460 " even though it should have found one");
1465template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1466bsl::size_t FlatHashTable<KEY,
1470 EQUAL>::indexOfKey(
bool *notFound,
1472 bsl::size_t hashValue)
1476 bsl::size_t index = findKey(key, hashValue);
1478 if (index == d_capacity) {
1481 if (d_size >= k_MAX_LOAD_FACTOR_NUMERATOR
1482 * (d_capacity / k_MAX_LOAD_FACTOR_DENOMINATOR)) {
1483 rehashRaw(d_capacity > 0 ? 2 * d_capacity : k_MIN_CAPACITY);
1486 index = (hashValue >> d_groupControlShift) * GroupControl::k_SIZE;
1487 index = findAvailable(d_controls_p, index, d_capacity);
1496template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1497void FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::rehashRaw(
1498 bsl::size_t newCapacity)
1503 FlatHashTable tmp(newCapacity,
1508 for (bsl::size_t i = 0; i < d_capacity; i += GroupControl::k_SIZE) {
1509 bsl::uint8_t *controlStart = d_controls_p + i;
1510 ENTRY *entryStart = d_entries_p + i;
1512 GroupControl groupControl(controlStart);
1513 bsl::uint32_t candidates = groupControl.inUse();
1514 while (candidates) {
1516 ENTRY *entry = entryStart + offset;
1522 *(controlStart + offset) = GroupControl::k_ERASED;
1526 bsl::size_t hashValue = tmp.d_hasher(ENTRY_UTIL::key(*entry));
1527 bsl::size_t index = (hashValue >> tmp.d_groupControlShift)
1528 * GroupControl::k_SIZE;
1530 index = findAvailable(tmp.d_controls_p, index, tmp.d_capacity);
1539 tmp.d_controls_p[index] =
static_cast<bsl::uint8_t
>(
1540 hashValue & k_HASHLET_MASK);
1554 d_groupControlShift = 0;
1564template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1565bsl::size_t FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>::findKey(
1567 bsl::size_t hashValue)
const
1571 bsl::size_t index = (hashValue >> d_groupControlShift)
1572 * GroupControl::k_SIZE;
1573 bsl::uint8_t hashlet =
static_cast<bsl::uint8_t
>(
1574 hashValue & k_HASHLET_MASK);
1576 for (bsl::size_t i = 0; i < d_capacity; i += GroupControl::k_SIZE) {
1577 bsl::uint8_t *controlStart = d_controls_p + index;
1578 ENTRY *entryStart = d_entries_p + index;
1580 GroupControl groupControl(controlStart);
1581 bsl::uint32_t candidates = groupControl.match(hashlet);
1582 while (candidates) {
1585 ENTRY *entry = entryStart + offset;
1588 d_equal(ENTRY_UTIL::key(*entry), key))) {
1589 return index + offset;
1597 index = (index + GroupControl::k_SIZE) & (d_capacity - 1);
1603template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1604bsl::size_t FlatHashTable<KEY,
1608 EQUAL>::minimumCompliantCapacity(
1609 bsl::size_t minimumCapacity)
const
1611 bsl::size_t minForEntries = ((d_size + k_MAX_LOAD_FACTOR_NUMERATOR - 1)
1612 / k_MAX_LOAD_FACTOR_NUMERATOR)
1613 * k_MAX_LOAD_FACTOR_DENOMINATOR;
1615 bsl::size_t capacity = minimumCapacity >= minForEntries
1620 capacity = capacity > k_MIN_CAPACITY
1622 static_cast<bsl::uint64_t
>(capacity)))
1630template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1633 bsl::size_t capacity,
1641, d_groupControlShift(0)
1644, d_allocator_p(
bslma::Default::allocator(basicAllocator))
1649 static_cast<bsl::uint64_t
>(
capacity)))
1652 d_groupControlShift =
static_cast<int>(
1653 sizeof(bsl::size_t) * 8
1658 ENTRY *
entries =
static_cast<ENTRY *
>(
1659 d_allocator_p->
allocate(d_capacity *
sizeof(ENTRY)));
1664 d_controls_p =
static_cast<bsl::uint8_t *
>(
1665 d_allocator_p->
allocate(d_capacity));
1673template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1682, d_groupControlShift(0)
1683, d_hasher(original.hash_function())
1684, d_equal(original.key_eq())
1685, d_allocator_p(
bslma::Default::allocator(basicAllocator))
1687 if (0 != original.d_capacity) {
1688 bsl::uint8_t *
const controls =
static_cast<bsl::uint8_t *
>(
1689 d_allocator_p->
allocate(original.d_capacity));
1694 ENTRY *
const entries =
static_cast<ENTRY *
>(
1695 d_allocator_p->
allocate(original.d_capacity *
sizeof(ENTRY)));
1700 ImplUtil::copyEntryAndControlArrays(
1703 original.d_entries_p,
1704 original.d_entries_p + original.d_capacity,
1705 original.d_controls_p,
1706 original.d_controls_p + original.d_capacity,
1714 d_size = original.d_size;
1715 d_capacity = original.d_capacity;
1716 d_groupControlShift = original.d_groupControlShift;
1720template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1724: d_entries_p(
bslmf::MovableRefUtil::access(original).d_entries_p)
1725, d_controls_p(
bslmf::MovableRefUtil::access(original).d_controls_p)
1726, d_size(
bslmf::MovableRefUtil::access(original).d_size)
1727, d_capacity(
bslmf::MovableRefUtil::access(original).d_capacity)
1728, d_groupControlShift(
1729 bslmf::MovableRefUtil::access(original).d_groupControlShift)
1730, d_hasher(
bslmf::MovableRefUtil::access(original).d_hasher)
1731, d_equal(
bslmf::MovableRefUtil::access(original).d_equal)
1732, d_allocator_p(
bslmf::MovableRefUtil::access(original).d_allocator_p)
1736 reference.d_entries_p = 0;
1737 reference.d_controls_p = 0;
1738 reference.d_size = 0;
1739 reference.d_capacity = 0;
1740 reference.d_groupControlShift = 0;
1743template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1751, d_groupControlShift(0)
1752, d_hasher(
bslmf::MovableRefUtil::access(original).d_hasher)
1753, d_equal(
bslmf::MovableRefUtil::access(original).d_equal)
1754, d_allocator_p(
bslma::Default::allocator(basicAllocator))
1757 if (d_allocator_p == reference.d_allocator_p) {
1763 &reference.d_groupControlShift);
1765 else if (reference.d_capacity) {
1766 bsl::uint8_t *
const controls =
static_cast<bsl::uint8_t *
>(
1767 d_allocator_p->
allocate(reference.d_capacity));
1772 ENTRY *
const entries =
static_cast<ENTRY *
>(
1773 d_allocator_p->
allocate(reference.d_capacity *
sizeof(ENTRY)));
1778 ImplUtil::copyEntryAndControlArrays(
1781 reference.d_entries_p,
1782 reference.d_entries_p + reference.d_capacity,
1783 reference.d_controls_p,
1784 reference.d_controls_p + reference.d_capacity,
1792 d_size = reference.d_size;
1793 d_capacity = reference.d_capacity;
1794 d_groupControlShift = reference.d_groupControlShift;
1798template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1803 (d_capacity == 0 && d_groupControlShift == 0) ||
1804 (d_groupControlShift ==
1805 static_cast<int>(
sizeof(bsl::size_t) * 8 -
1807 d_capacity / GroupControl::k_SIZE)))));
1809 if (0 != d_entries_p) {
1810 ImplUtil::destroyEntryArray(d_entries_p,
1811 d_entries_p + d_capacity,
1813 d_controls_p + d_capacity);
1821template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1834template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1841 if (
this != &reference) {
1849template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1850template <
class KEY_TYPE>
1856 bsl::size_t hashValue = d_hasher(key);
1857 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
1860 ENTRY_UTIL::constructFromKey(d_entries_p + index,
1864 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
1865 hashValue & k_HASHLET_MASK);
1870 return d_entries_p[index];
1873template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1877 ImplUtil::destroyEntryArray(d_entries_p,
1878 d_entries_p + d_capacity,
1880 d_controls_p + d_capacity);
1883 bsl::memset(d_controls_p, GroupControl::k_EMPTY, d_capacity);
1889template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1898 return bsl::make_pair(it1, it1);
1902 return bsl::make_pair(it1, it2);
1905#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1906template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1907template<
class... ARGS>
1915 ENTRY_UTIL::construct(value.
address(),
1925template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1938template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1946 EQUAL>::const_iterator position)
1950 bsl::size_t index = &*position - d_entries_p;
1951 bslma::DestructionUtil::destroy(d_entries_p + index);
1952 d_controls_p[index] = GroupControl::k_ERASED;
1956 for (bsl::size_t i = index + 1; i < d_capacity; ++i) {
1957 if (0 == (d_controls_p[i] & GroupControl::k_EMPTY)) {
1958 return iterator(IteratorImp(d_entries_p + i,
1960 d_capacity - i - 1));
1967template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
1971 typename FlatHashTable<KEY,
1975 EQUAL>::iterator position)
1982 bsl::size_t index = &*position - d_entries_p;
1983 bslma::DestructionUtil::destroy(d_entries_p + index);
1984 d_controls_p[index] = GroupControl::k_ERASED;
1988 for (bsl::size_t i = index + 1; i < d_capacity; ++i) {
1989 if (0 == (d_controls_p[i] & GroupControl::k_EMPTY)) {
1990 return iterator(IteratorImp(d_entries_p + i,
1992 d_capacity - i - 1));
1999template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2002 typename FlatHashTable<KEY,
2006 EQUAL>::const_iterator first,
2007 typename FlatHashTable<KEY,
2011 EQUAL>::const_iterator last)
2015 if (last !=
end()) {
2016 bsl::size_t index = &*last - d_entries_p;
2017 rv = iterator(IteratorImp(d_entries_p + index,
2018 d_controls_p + index,
2019 d_capacity - index - 1));
2026 for (; first != last; ++first) {
2033template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2038 bsl::size_t index = findKey(key, d_hasher(key));
2039 if (index < d_capacity) {
2040 return iterator(IteratorImp(d_entries_p + index,
2041 d_controls_p + index,
2042 d_capacity - index - 1));
2047template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2053 bsl::size_t hashValue = d_hasher(ENTRY_UTIL::key(entry));
2054 bsl::size_t index = indexOfKey(¬Found,
2055 ENTRY_UTIL::key(entry),
2059 ENTRY_UTIL::construct(d_entries_p + index, d_allocator_p, entry);
2060 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2061 hashValue & k_HASHLET_MASK);
2066 d_controls_p + index,
2067 d_capacity - index - 1),
2071template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2078 bsl::size_t hashValue = d_hasher(ENTRY_UTIL::key(entry));
2079 bsl::size_t index = indexOfKey(¬Found,
2080 ENTRY_UTIL::key(entry),
2084 ENTRY_UTIL::construct(d_entries_p + index,
2088 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2089 hashValue & k_HASHLET_MASK);
2095 d_controls_p + index,
2096 d_capacity - index - 1),
2100template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2101template <
class INPUT_ITERATOR>
2104 INPUT_ITERATOR first,
2105 INPUT_ITERATOR last)
2107 for (; first != last; ++first) {
2112template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2115 bsl::size_t minimumCapacity)
2117 minimumCapacity = minimumCompliantCapacity(minimumCapacity);
2119 if (0 < minimumCapacity) {
2120 rehashRaw(minimumCapacity);
2129 d_groupControlShift = 0;
2133template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2136 bsl::size_t numEntries)
2138 if (0 == d_capacity && 0 == numEntries) {
2145 bsl::size_t minForEntries = ((numEntries + k_MAX_LOAD_FACTOR_NUMERATOR - 1)
2146 / k_MAX_LOAD_FACTOR_NUMERATOR)
2147 * k_MAX_LOAD_FACTOR_DENOMINATOR;
2149 rehash(minForEntries);
2152template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2156 if (0 != d_entries_p) {
2157 ImplUtil::destroyEntryArray(d_entries_p,
2158 d_entries_p + d_capacity,
2160 d_controls_p + d_capacity);
2169 d_groupControlShift = 0;
2173#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2175template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2176template<
class... ARGS>
2185 bsl::size_t hashValue = d_hasher(key);
2186 bsl::size_t index = indexOfKey(¬Found, key, hashValue);
2189 ENTRY_UTIL::construct(d_entries_p + index,
2193 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2194 hashValue & k_HASHLET_MASK);
2199 d_controls_p + index,
2200 d_capacity - index - 1),
2205template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2206template<
class... ARGS>
2211 BloombergLP::bslmf::MovableRef<KEY> key,
2216 bsl::size_t hashValue = d_hasher(k);
2217 bsl::size_t index = indexOfKey(¬Found, k, hashValue);
2220 ENTRY_UTIL::construct(d_entries_p + index,
2224 d_controls_p[index] =
static_cast<bsl::uint8_t
>(
2225 hashValue & k_HASHLET_MASK);
2229 d_controls_p + index,
2230 d_capacity - index - 1),
2237template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2243 for (bsl::size_t i = 0; i < d_capacity; ++i) {
2244 if (0 == (d_controls_p[i] & GroupControl::k_EMPTY)) {
2245 return iterator(IteratorImp(d_entries_p + i,
2247 d_capacity - i - 1));
2254template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2264template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2281template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2289template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2292 const KEY& key)
const
2294 return find(key) != end();
2297template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2303 EQUAL>::controls()
const
2305 return d_controls_p;
2308template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2311 const KEY& key)
const
2313 return contains(key) ? 1 : 0;
2316template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2323template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2329 EQUAL>::entries()
const
2334template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2340 EQUAL>::const_iterator,
2345 EQUAL>::const_iterator>
2347 const KEY& key)
const
2351 if (cit1 != end()) {
2354 return bsl::make_pair(cit1, cit2);
2357template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2362 bsl::size_t index = findKey(key, d_hasher(key));
2363 if (index < d_capacity) {
2365 d_controls_p + index,
2366 d_capacity - index - 1));
2371template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2378template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2385template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2391 EQUAL>::load_factor()
const
2393 return d_capacity > 0
2394 ?
static_cast<float>(d_size) /
static_cast<float>(d_capacity)
2398template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2404 EQUAL>::max_load_factor()
const
2406 return static_cast<float>(k_MAX_LOAD_FACTOR_NUMERATOR)
2407 /
static_cast<float>(k_MAX_LOAD_FACTOR_DENOMINATOR);
2410template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2419template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2425 for (bsl::size_t i = 0; i < d_capacity; ++i) {
2426 if (0 == (d_controls_p[i] & GroupControl::k_EMPTY)) {
2428 IteratorImp(d_entries_p + i,
2430 d_capacity - i - 1));
2437template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2445template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2453template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2463template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2468 return d_allocator_p;
2474template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2480 const FlatHashTable<KEY,
2486 typedef typename FlatHashTable<KEY,
2490 EQUAL>::const_iterator ConstIterator;
2492 if (lhs.size() == rhs.size()) {
2493 ConstIterator lhsEnd = lhs.end();
2494 ConstIterator rhsEnd = rhs.end();
2496 if (lhs.capacity() <= rhs.capacity()) {
2497 for (ConstIterator it = lhs.begin(); it != lhsEnd; ++it) {
2498 ConstIterator i = rhs.find(ENTRY_UTIL::key(*it));
2499 if (i == rhsEnd || *i != *it) {
2506 for (ConstIterator it =
rhs.begin(); it != rhsEnd; ++it) {
2507 ConstIterator i =
lhs.find(ENTRY_UTIL::key(*it));
2508 if (i == lhsEnd || *i != *it) {
2518template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2524 const FlatHashTable<KEY,
2534template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2536void bdlc::swap(FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>& a,
2537 FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL>& b)
2539 if (a.allocator() == b.allocator()) {
2545 typedef FlatHashTable<KEY, ENTRY, ENTRY_UTIL, HASH, EQUAL> Table;
2547 Table futureA(b, a.allocator());
2548 Table futureB(a, b.allocator());
2556template <
class KEY,
class ENTRY,
class ENTRY_UTIL,
class HASH,
class EQUAL>
2573template <
class ENTRY_TYPE>
2575void FlatHashTable_ImplUtil::copyEntryAndControlArrays(
2576 ENTRY_TYPE *firstDestinationEntry,
2577 bsl::uint8_t *firstDestinationControl,
2578 const ENTRY_TYPE *firstSourceEntry,
2579 const ENTRY_TYPE *lastSourceEntry,
2580 const bsl::uint8_t *firstSourceControl,
2581 const bsl::uint8_t *lastSourceControl,
2585 (void) isBitwiseCopyable;
2589 bsl::memcpy(firstDestinationControl,
2591 bsl::distance(firstSourceControl, lastSourceControl) *
2592 sizeof(bsl::uint8_t));
2594 const bsl::size_t numEntries =
static_cast<bsl::size_t
>(
2595 bsl::distance(firstSourceEntry, lastSourceEntry));
2597 DestroyEntryArrayProctor<ENTRY_TYPE> destroyEntriesProctor(
2598 firstDestinationEntry,
2599 firstDestinationEntry,
2600 firstDestinationControl,
2601 firstDestinationControl);
2603 for (bsl::size_t idx = 0; idx != numEntries; ++idx) {
2604 ENTRY_TYPE& destinationEntry = *(firstDestinationEntry + idx);
2605 const bsl::uint8_t& sourceControl = *(firstSourceControl + idx);
2606 const ENTRY_TYPE& sourceEntry = *(firstSourceEntry + idx);
2610 &destinationEntry, entryAllocator, sourceEntry);
2613 destroyEntriesProctor.moveEnd(1);
2616 destroyEntriesProctor.release();
2619template <
class ENTRY_TYPE>
2621void FlatHashTable_ImplUtil::copyEntryAndControlArrays(
2622 ENTRY_TYPE *firstDestinationEntry,
2623 bsl::uint8_t *firstDestinationControl,
2624 const ENTRY_TYPE *firstSourceEntry,
2625 const ENTRY_TYPE *lastSourceEntry,
2626 const bsl::uint8_t *firstSourceControl,
2627 const bsl::uint8_t *lastSourceControl,
2631 (void) isBitwiseCopyable;
2635 bsl::memcpy(firstDestinationControl,
2637 bsl::distance(firstSourceControl, lastSourceControl) *
2638 sizeof(bsl::uint8_t));
2640#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 80000
2641#pragma GCC diagnostic push
2642#pragma GCC diagnostic ignored "-Wclass-memaccess"
2645 bsl::memcpy(firstDestinationEntry,
2647 bsl::distance(firstSourceEntry, lastSourceEntry) *
2648 sizeof(ENTRY_TYPE));
2650#if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 80000
2651#pragma GCC diagnostic pop
2655template <
class ENTRY_TYPE>
2657void FlatHashTable_ImplUtil::destroyEntryArray(
2658 ENTRY_TYPE *firstEntry,
2659 ENTRY_TYPE *lastEntry,
2660 const bsl::uint8_t *firstControl,
2661 const bsl::uint8_t *lastControl,
2664 (void) triviallyDestructible;
2684 static_cast<void>(lastControl);
2686 const bsl::size_t numEntries =
2687 static_cast<bsl::size_t
>(bsl::distance(firstEntry, lastEntry));
2688 const bsl::size_t numGroupedEntries =
2691 for (bsl::size_t idx = 0;
2692 idx != numGroupedEntries;
2694 GroupControl groupControl(firstControl + idx);
2695 bsl::uint32_t candidates = groupControl.inUse();
2696 while (candidates) {
2698 bslma::DestructionUtil::destroy(firstEntry + idx + offset);
2703 for (bsl::size_t idx = numGroupedEntries; idx != numEntries; ++idx) {
2704 ENTRY_TYPE& entry = *(firstEntry + idx);
2705 const bsl::uint8_t& control = *(firstControl + idx);
2708 bslma::DestructionUtil::destroy(&entry);
2713template <
class ENTRY_TYPE>
2715void FlatHashTable_ImplUtil::destroyEntryArray(
2718 const bsl::uint8_t *,
2719 const bsl::uint8_t *,
2722 (void) triviallyDestructible;
2728template <
class ENTRY_TYPE>
2730void FlatHashTable_ImplUtil::copyEntryAndControlArrays(
2731 ENTRY_TYPE *firstDestinationEntry,
2732 bsl::uint8_t *firstDestinationControl,
2733 const ENTRY_TYPE *firstSourceEntry,
2734 const ENTRY_TYPE *lastSourceEntry,
2735 const bsl::uint8_t *firstSourceControl,
2736 const bsl::uint8_t *lastSourceControl,
2740 bsl::distance(firstSourceControl, lastSourceControl));
2742 FlatHashTable_ImplUtil::copyEntryAndControlArrays(
2743 firstDestinationEntry,
2744 firstDestinationControl,
2753template <
class ENTRY_TYPE>
2755void FlatHashTable_ImplUtil::destroyEntryArray(
2756 ENTRY_TYPE *firstEntry,
2757 ENTRY_TYPE *lastEntry,
2758 const bsl::uint8_t *firstControl,
2759 const bsl::uint8_t *lastControl)
2762 bsl::distance(firstControl, lastControl));
2775 IsEntryTypeTriviallyDestructible;
2777 FlatHashTable_ImplUtil::destroyEntryArray(
2782 IsEntryTypeTriviallyDestructible());
2790template <
class ENTRY_TYPE>
2792FlatHashTable_ImplUtil::DestroyEntryArrayProctor<
2793 ENTRY_TYPE>::DestroyEntryArrayProctor(ENTRY_TYPE *firstEntry,
2794 ENTRY_TYPE *lastEntry,
2795 const bsl::uint8_t *firstControl,
2796 const bsl::uint8_t *lastControl)
2797: d_firstEntry_p(firstEntry)
2798, d_lastEntry_p(lastEntry)
2799, d_firstControl_p(firstControl)
2800, d_lastControl_p(lastControl)
2804template <
class ENTRY_TYPE>
2806FlatHashTable_ImplUtil::DestroyEntryArrayProctor<
2807 ENTRY_TYPE>::~DestroyEntryArrayProctor()
2809 ImplUtil::destroyEntryArray(d_firstEntry_p,
2816template <
class ENTRY_TYPE>
2818void FlatHashTable_ImplUtil::DestroyEntryArrayProctor<ENTRY_TYPE>::moveEnd(
2819 bsl::ptrdiff_t offset)
2821 d_lastEntry_p += offset;
2822 d_lastControl_p += offset;
2825template <
class ENTRY_TYPE>
2827void FlatHashTable_ImplUtil::DestroyEntryArrayProctor<ENTRY_TYPE>::release()
2831 d_firstControl_p = 0;
2832 d_lastControl_p = 0;
Definition bdlc_flathashtable_groupcontrol.h:91
static const bsl::uint8_t k_EMPTY
Definition bdlc_flathashtable_groupcontrol.h:125
static const bsl::size_t k_SIZE
Definition bdlc_flathashtable_groupcontrol.h:127
Definition bdlc_flathashtable.h:245
FlatHashTable_IteratorImp & operator=(const FlatHashTable_IteratorImp &rhs)
Definition bdlc_flathashtable.h:1376
~FlatHashTable_IteratorImp()=default
FlatHashTable_IteratorImp()
Definition bdlc_flathashtable.h:1344
void operator++()
Definition bdlc_flathashtable.h:1388
ENTRY & operator*() const
Definition bdlc_flathashtable.h:1409
Definition bdlc_flathashtable.h:326
void clear()
Definition bdlc_flathashtable.h:1875
bsl::size_t erase(const KEY &key)
Definition bdlc_flathashtable.h:1927
iterator erase(const_iterator first, const_iterator last)
const ENTRY * entries() const
Definition bdlc_flathashtable.h:2329
static const bsl::size_t k_MIN_CAPACITY
Definition bdlc_flathashtable.h:503
bsl::pair< iterator, bool > try_emplace(BloombergLP::bslmf::MovableRef< KEY > key, ARGS &&... args)
float max_load_factor() const
Definition bdlc_flathashtable.h:2404
const_iterator cbegin() const
Definition bdlc_flathashtable.h:2440
iterator erase(const_iterator position)
void swap(FlatHashTable &other)
Definition bdlc_flathashtable.h:2266
FlatHashTable(bsl::size_t capacity, const HASH &hash, const EQUAL &equal, bslma::Allocator *basicAllocator=0)
Definition bdlc_flathashtable.h:1632
FlatHashTable(bslmf::MovableRef< FlatHashTable > original)
Definition bdlc_flathashtable.h:1722
HASH hash_type
Definition bdlc_flathashtable.h:337
bsl::pair< iterator, bool > insert(const ENTRY &entry)
Definition bdlc_flathashtable.h:2050
EQUAL key_equal_type
Definition bdlc_flathashtable.h:338
static const bsl::size_t k_MAX_LOAD_FACTOR_NUMERATOR
Definition bdlc_flathashtable.h:508
void reset()
Definition bdlc_flathashtable.h:2154
bsl::pair< iterator, bool > emplace(ARGS &&... args)
iterator find(const KEY &key)
Definition bdlc_flathashtable.h:2036
iterator end()
Definition bdlc_flathashtable.h:2257
bsl::pair< const_iterator, const_iterator > equal_range(const KEY &key) const
Definition bdlc_flathashtable.h:2346
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, bsl::size_t >::type erase(LOOKUP_KEY &&key)
Definition bdlc_flathashtable.h:665
FlatHashTable & operator=(bslmf::MovableRef< FlatHashTable > rhs)
Definition bdlc_flathashtable.h:1837
bool empty() const
Definition bdlc_flathashtable.h:2318
bsl::pair< iterator, bool > try_emplace(const KEY &key, ARGS &&... args)
void insert(INPUT_ITERATOR first, INPUT_ITERATOR last)
Definition bdlc_flathashtable.h:2103
static const bsl::size_t k_MAX_LOAD_FACTOR_DENOMINATOR
Definition bdlc_flathashtable.h:513
ENTRY_UTIL entry_util_type
Definition bdlc_flathashtable.h:336
static const bsl::int8_t k_HASHLET_MASK
Definition bdlc_flathashtable.h:506
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, bsl::pair< const_iterator, const_iterator > >::type equal_range(const LOOKUP_KEY &key) const
Definition bdlc_flathashtable.h:972
bslma::Allocator * allocator() const
Return the allocator used by this hash table to supply memory.
Definition bdlc_flathashtable.h:2466
bsl::size_t capacity() const
Definition bdlc_flathashtable.h:2284
bslstl::ForwardIterator< const ENTRY, IteratorImp > const_iterator
Definition bdlc_flathashtable.h:343
bslstl::ForwardIterator< ENTRY, IteratorImp > iterator
Definition bdlc_flathashtable.h:341
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, iterator >::type find(const LOOKUP_KEY &key)
Definition bdlc_flathashtable.h:712
const bsl::uint8_t * controls() const
Definition bdlc_flathashtable.h:2303
ENTRY entry_type
Definition bdlc_flathashtable.h:335
ENTRY & operator[](BSLS_COMPILERFEATURES_FORWARD_REF(KEY_TYPE) key)
Definition bdlc_flathashtable.h:1852
const_iterator find(const KEY &key) const
Definition bdlc_flathashtable.h:2360
FlatHashTable(bslmf::MovableRef< FlatHashTable > original, bslma::Allocator *basicAllocator)
Definition bdlc_flathashtable.h:1744
KEY key_type
Definition bdlc_flathashtable.h:334
EQUAL key_eq() const
Definition bdlc_flathashtable.h:2380
bsl::pair< iterator, bool > insert(bslmf::MovableRef< ENTRY > entry)
Definition bdlc_flathashtable.h:2074
bool contains(const KEY &key) const
Definition bdlc_flathashtable.h:2291
const_iterator begin() const
Definition bdlc_flathashtable.h:2422
iterator begin()
Definition bdlc_flathashtable.h:2240
void reserve(bsl::size_t numEntries)
Definition bdlc_flathashtable.h:2135
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, bsl::pair< iterator, bool > >::type insertTransparent(LOOKUP_KEY &&key)
Definition bdlc_flathashtable.h:754
const_iterator cend() const
Definition bdlc_flathashtable.h:2448
bsl::size_t size() const
Return the number of entries in this table.
Definition bdlc_flathashtable.h:2412
bsl::size_t count(const KEY &key) const
Definition bdlc_flathashtable.h:2310
FlatHashTable & operator=(const FlatHashTable &rhs)
Definition bdlc_flathashtable.h:1824
~FlatHashTable()
Destroy this object and each of its entries.
Definition bdlc_flathashtable.h:1800
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, bsl::pair< iterator, iterator > >::type equal_range(const LOOKUP_KEY &key)
Definition bdlc_flathashtable.h:626
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, const_iterator >::type find(const LOOKUP_KEY &key) const
Definition bdlc_flathashtable.h:997
const_iterator end() const
Definition bdlc_flathashtable.h:2456
HASH hash_function() const
Definition bdlc_flathashtable.h:2373
float load_factor() const
Definition bdlc_flathashtable.h:2391
void rehash(bsl::size_t minimumCapacity)
Definition bdlc_flathashtable.h:2114
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASH, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< EQUAL, LOOKUP_KEY >::value, bsl::pair< iterator, bool > >::type try_emplace(LOOKUP_KEY &&key, ARGS &&... args)
Definition bdlc_flathashtable.h:866
FlatHashTable(const FlatHashTable &original, bslma::Allocator *basicAllocator=0)
Definition bdlc_flathashtable.h:1675
iterator erase(iterator position)
bsl::pair< iterator, iterator > equal_range(const KEY &key)
Definition bdlc_flathashtable.h:1894
Definition bslstl_pair.h:1280
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:182
Definition bslma_allocator.h:545
virtual void deallocate(void *address)=0
virtual void * allocate(size_type size)=0
Definition bslma_deallocatorproctor.h:312
void release()
Definition bslma_deallocatorproctor.h:389
Definition bslma_destructorguard.h:132
Definition bslma_destructorproctor.h:259
Definition bslmf_movableref.h:752
Definition bslstl_forwarditerator.h:171
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_ASSERT_OPT_UNREACHABLE(X)
Definition bsls_assert.h:2065
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2343
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlc_bitarray.h:506
void swap(BitArray &a, BitArray &b)
bool operator==(const BitArray &lhs, const BitArray &rhs)
bool operator!=(const BitArray &lhs, const BitArray &rhs)
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
deque< VALUE_TYPE, ALLOCATOR >::size_type erase(deque< VALUE_TYPE, ALLOCATOR > &deq, const BDE_OTHER_TYPE &value)
Definition bslstl_deque.h:4424
ALLOCATOR & lhs
Definition bslstl_string.h:3917
T::iterator end(T &container)
Definition bslstl_iterator.h:1621
Definition baljsn_encoder_testtypes.h:76
Definition bdlbb_blob.h:579
static int numTrailingUnsetBits(unsigned int value)
Definition bdlb_bitutil.h:456
static unsigned int withBitCleared(unsigned int value, int index)
Definition bdlb_bitutil.h:571
static int log2(unsigned int value)
Definition bdlb_bitutil.h:340
static unsigned int roundUpToBinaryPower(unsigned int value)
Definition bdlb_bitutil.h:540
Definition bdlc_flathashtable.h:1099
Definition bslmf_enableif.h:530
Definition bslmf_integralconstant.h:261
static void construct(TARGET_TYPE *address, const ALLOCATOR &allocator)
Definition bslma_constructionutil.h:1244
static void destructiveMove(TARGET_TYPE *address, const ALLOCATOR &allocator, TARGET_TYPE *original)
Definition bslma_constructionutil.h:1296
Definition bslma_usesbslmaallocator.h:344
Definition bslmf_isbitwisecopyable.h:298
static MovableRef< t_TYPE > move(t_TYPE &reference) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1067
Definition bsls_objectbuffer.h:277
TYPE * address()
Definition bsls_objectbuffer.h:335
TYPE & object()
Definition bsls_objectbuffer.h:352