41 #if !FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE 46 #include <unordered_map> 52 template <
typename K,
typename M,
typename H,
typename E,
typename A>
53 class F14BasicMap :
public std::unordered_map<K, M, H, E, A> {
54 using Super = std::unordered_map<K, M, H, E, A>;
57 using typename Super::pointer;
58 using typename Super::value_type;
70 [&](std::size_t bytes, std::size_t n) { rv += bytes * n; });
77 auto bc = this->bucket_count();
79 visitor(bc *
sizeof(pointer), 1);
81 if (this->
size() > 0) {
88 for (value_type
const& entry : *
this) {
89 value_type
const*
b = std::addressof(entry);
108 using typename Super::value_type;
115 Super::operator=(ilist);
131 using typename Super::value_type;
138 Super::operator=(ilist);
154 using typename Super::value_type;
161 Super::operator=(ilist);
168 #else // FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE 176 template <
typename Policy>
178 template <
typename K,
typename T>
179 using EnableHeterogeneousFind = std::enable_if_t<
180 EligibleForHeterogeneousFind<
182 typename Policy::Hasher,
183 typename Policy::KeyEqual,
187 template <
typename K,
typename T>
188 using EnableHeterogeneousInsert = std::enable_if_t<
189 EligibleForHeterogeneousInsert<
191 typename Policy::Hasher,
192 typename Policy::KeyEqual,
196 template <
typename K,
typename T>
197 using EnableHeterogeneousErase = std::enable_if_t<
198 EligibleForHeterogeneousFind<
200 typename Policy::Hasher,
201 typename Policy::KeyEqual,
203 !std::is_same<typename Policy::Iter, remove_cvref_t<K>>::value &&
204 !std::is_same<typename Policy::ConstIter, remove_cvref_t<K>>
::value,
211 using mapped_type =
typename Policy::Mapped;
213 using size_type = std::size_t;
214 using difference_type = std::ptrdiff_t;
215 using hasher =
typename Policy::Hasher;
216 using key_equal =
typename Policy::KeyEqual;
217 using allocator_type =
typename Policy::Alloc;
218 using reference = value_type&;
219 using const_reference = value_type
const&;
220 using pointer =
typename Policy::AllocTraits::pointer;
221 using const_pointer =
typename Policy::AllocTraits::const_pointer;
223 using const_iterator =
typename Policy::ConstIter;
226 using ItemIter =
typename Policy::ItemIter;
235 std::size_t initialCapacity,
237 key_equal
const&
eq = key_equal{},
238 allocator_type
const& alloc = allocator_type{})
239 : table_{initialCapacity, hash, eq, alloc} {}
241 explicit F14BasicMap(std::size_t initialCapacity, allocator_type
const& alloc)
245 std::size_t initialCapacity,
247 allocator_type
const& alloc)
248 :
F14BasicMap(initialCapacity, hash, key_equal{}, alloc) {}
253 template <
typename InputIt>
257 std::size_t initialCapacity = 0,
259 key_equal
const& eq = key_equal{},
260 allocator_type
const& alloc = allocator_type{})
261 : table_{initialCapacity, hash, eq, alloc} {
262 initialInsert(first, last, initialCapacity);
265 template <
typename InputIt>
269 std::size_t initialCapacity,
270 allocator_type
const& alloc)
271 : table_{initialCapacity,
hasher{}, key_equal{}, alloc} {
272 initialInsert(first, last, initialCapacity);
275 template <
typename InputIt>
279 std::size_t initialCapacity,
281 allocator_type
const& alloc)
282 : table_{initialCapacity, hash, key_equal{}, alloc} {
283 initialInsert(first, last, initialCapacity);
289 : table_{rhs.table_, alloc} {}
294 Policy::kAllocIsAlwaysEqual)
295 : table_{
std::move(rhs.table_), alloc} {}
298 std::initializer_list<value_type>
init,
299 std::size_t initialCapacity = 0,
301 key_equal
const& eq = key_equal{},
302 allocator_type
const& alloc = allocator_type{})
303 : table_{initialCapacity, hash, eq, alloc} {
304 initialInsert(init.begin(), init.end(), initialCapacity);
308 std::initializer_list<value_type> init,
309 std::size_t initialCapacity,
310 allocator_type
const& alloc)
311 : table_{initialCapacity,
hasher{}, key_equal{}, alloc} {
312 initialInsert(init.begin(), init.end(), initialCapacity);
316 std::initializer_list<value_type> init,
317 std::size_t initialCapacity,
319 allocator_type
const& alloc)
320 : table_{initialCapacity, hash, key_equal{}, alloc} {
321 initialInsert(init.begin(), init.end(), initialCapacity);
324 F14BasicMap& operator=(F14BasicMap
const&) =
default;
326 F14BasicMap& operator=(F14BasicMap&&) =
default;
328 F14BasicMap& operator=(std::initializer_list<value_type> ilist) {
330 bulkInsert(ilist.begin(), ilist.end(),
false);
334 allocator_type get_allocator()
const noexcept {
335 return table_.alloc();
341 return table_.makeIter(table_.begin());
347 return table_.makeConstIter(table_.begin());
351 return table_.makeIter(table_.end());
357 return table_.makeConstIter(table_.end());
363 return table_.empty();
367 return table_.size();
370 std::size_t max_size()
const noexcept {
371 return table_.max_size();
380 std::pair<iterator, bool> insert(value_type
const&
value) {
381 return emplace(value);
384 template <
typename P>
387 std::pair<iterator, bool>>
389 return emplace(std::forward<P>(value));
394 template <
typename U1,
typename U2>
398 std::pair<iterator, bool>>
399 insert(std::pair<U1, U2>
const& value) {
400 return emplace(value);
404 template <
typename U1,
typename U2>
408 std::pair<iterator, bool>>
409 insert(std::pair<U1, U2>&& value) {
413 std::pair<iterator, bool> insert(value_type&& value) {
422 iterator insert(const_iterator , value_type
const& value) {
423 return insert(value).first;
426 template <
typename P>
428 insert(const_iterator , P&& value) {
429 return insert(std::forward<P>(value)).first;
432 iterator insert(const_iterator , value_type&& value) {
436 template <
class...
Args>
437 iterator emplace_hint(const_iterator ,
Args&&... args) {
438 return emplace(std::forward<Args>(args)...).first;
442 template <
class InputIt>
444 bulkInsert(InputIt first, InputIt last,
bool autoReserve) {
446 table_.reserveForInsert(std::distance(first, last));
448 while (first != last) {
454 template <
class InputIt>
455 void initialInsert(InputIt first, InputIt last, std::size_t initialCapacity) {
465 typename std::iterator_traits<InputIt>::iterator_category,
466 std::random_access_iterator_tag>::value &&
467 initialCapacity == 0;
468 bulkInsert(first, last, autoReserve);
472 template <
class InputIt>
473 void insert(InputIt first, InputIt last) {
479 typename std::iterator_traits<InputIt>::iterator_category,
480 std::random_access_iterator_tag>::value &&
482 bulkInsert(first, last, autoReserve);
485 void insert(std::initializer_list<value_type> ilist) {
486 insert(ilist.begin(), ilist.end());
489 template <
typename M>
490 std::pair<iterator, bool> insert_or_assign(key_type
const& key,
M&& obj) {
491 auto rv = try_emplace(key, std::forward<M>(obj));
493 rv.first->second = std::forward<M>(obj);
498 template <
typename M>
499 std::pair<iterator, bool> insert_or_assign(key_type&& key,
M&& obj) {
500 auto rv = try_emplace(
std::move(key), std::forward<M>(obj));
502 rv.first->second = std::forward<M>(obj);
507 template <
typename M>
509 insert_or_assign(const_iterator , key_type
const& key,
M&& obj) {
510 return insert_or_assign(key,
std::move(obj)).first;
513 template <
typename M>
514 iterator insert_or_assign(const_iterator , key_type&& key,
M&& obj) {
518 template <
typename K,
typename M>
519 EnableHeterogeneousInsert<K, std::pair<iterator, bool>> insert_or_assign(
522 auto rv = try_emplace(std::forward<K>(key), std::forward<M>(obj));
524 rv.first->second = std::forward<M>(obj);
530 std::pair<ItemIter, bool> emplaceItem() {
532 return table_.tryEmplaceValue(key_type{});
535 template <
typename U1,
typename U2>
536 std::pair<ItemIter, bool> emplaceItem(U1&&
x, U2&&
y) {
537 using K = KeyTypeForEmplace<key_type, hasher, key_equal, U1>;
538 K key(std::forward<U1>(
x));
544 return table_.tryEmplaceValue(
546 std::piecewise_construct,
547 std::forward_as_tuple(std::forward<K>(key)),
548 std::forward_as_tuple(std::forward<U2>(
y)));
551 template <
typename U1,
typename U2>
552 std::pair<ItemIter, bool> emplaceItem(std::pair<U1, U2>
const& p) {
553 return emplaceItem(p.first, p.second);
556 template <
typename U1,
typename U2>
557 std::pair<ItemIter, bool> emplaceItem(std::pair<U1, U2>&& p) {
561 template <
typename Arg1,
typename... Args2>
562 std::pair<ItemIter, bool> emplaceItem(
563 std::piecewise_construct_t,
564 std::tuple<Arg1>&& first_args,
565 std::tuple<Args2...>&& second_args) {
566 using K = KeyTypeForEmplace<key_type, hasher, key_equal, Arg1>;
567 K key(std::get<0>(
std::move(first_args)));
571 return table_.tryEmplaceValue(
573 std::piecewise_construct,
574 std::forward_as_tuple(std::forward<K>(key)),
575 std::tuple<Args2&&...>(
std::move(second_args)));
578 template <
typename... Args1,
typename... Args2>
579 std::enable_if_t<
sizeof...(Args1) != 1, std::pair<ItemIter, bool>>
581 std::piecewise_construct_t,
582 std::tuple<Args1...>&& first_args,
583 std::tuple<Args2...>&& second_args) {
584 auto key = make_from_tuple<key_type>(
585 std::tuple<Args1&&...>(
std::move(first_args)));
586 return table_.tryEmplaceValue(
588 std::piecewise_construct,
590 std::tuple<Args2&&...>(
std::move(second_args)));
594 template <
typename...
Args>
595 std::pair<iterator, bool> emplace(
Args&&... args) {
596 auto rv = emplaceItem(std::forward<Args>(args)...);
597 return std::make_pair(table_.makeIter(rv.first), rv.second);
600 template <
typename...
Args>
601 std::pair<iterator, bool> try_emplace(key_type
const& key,
Args&&... args) {
602 auto rv = table_.tryEmplaceValue(
604 std::piecewise_construct,
605 std::forward_as_tuple(key),
606 std::forward_as_tuple(std::forward<Args>(args)...));
607 return std::make_pair(table_.makeIter(rv.first), rv.second);
610 template <
typename...
Args>
611 std::pair<iterator, bool> try_emplace(key_type&& key,
Args&&... args) {
612 auto rv = table_.tryEmplaceValue(
614 std::piecewise_construct,
616 std::forward_as_tuple(std::forward<Args>(args)...));
617 return std::make_pair(table_.makeIter(rv.first), rv.second);
620 template <
typename...
Args>
622 try_emplace(const_iterator , key_type
const& key,
Args&&... args) {
623 auto rv = table_.tryEmplaceValue(
625 std::piecewise_construct,
626 std::forward_as_tuple(key),
627 std::forward_as_tuple(std::forward<Args>(args)...));
628 return table_.makeIter(rv.first);
631 template <
typename...
Args>
633 try_emplace(const_iterator , key_type&& key,
Args&&... args) {
634 auto rv = table_.tryEmplaceValue(
636 std::piecewise_construct,
638 std::forward_as_tuple(std::forward<Args>(args)...));
639 return table_.makeIter(rv.first);
642 template <
typename K,
typename...
Args>
643 EnableHeterogeneousInsert<K, std::pair<iterator, bool>> try_emplace(
646 auto rv = table_.tryEmplaceValue(
648 std::piecewise_construct,
649 std::forward_as_tuple(std::forward<K>(key)),
650 std::forward_as_tuple(std::forward<Args>(args)...));
651 return std::make_pair(table_.makeIter(rv.first), rv.second);
657 auto itemPos = table_.unwrapIter(pos);
658 table_.eraseIter(itemPos);
659 itemPos.advanceLikelyDead();
660 return table_.makeIter(itemPos);
665 iterator erase(iterator pos) {
666 auto itemPos = table_.unwrapIter(pos);
667 table_.eraseIter(itemPos);
668 itemPos.advanceLikelyDead();
669 return table_.makeIter(itemPos);
672 iterator erase(const_iterator first, const_iterator last) {
673 auto itemFirst = table_.unwrapIter(first);
674 auto itemLast = table_.unwrapIter(last);
675 while (itemFirst != itemLast) {
676 table_.eraseIter(itemFirst);
679 return table_.makeIter(itemFirst);
682 size_type erase(key_type
const& key) {
683 return table_.eraseKey(key);
686 template <
typename K>
687 EnableHeterogeneousErase<K, size_type> erase(K
const& key) {
688 return table_.eraseKey(key);
694 return at(*
this, key);
698 return at(*
this, key);
701 template <
typename K>
702 EnableHeterogeneousFind<K, mapped_type&> at(K
const& key) {
703 return at(*
this, key);
706 template <
typename K>
707 EnableHeterogeneousFind<K, mapped_type const&> at(K
const& key)
const {
708 return at(*
this, key);
711 mapped_type& operator[](key_type
const& key) {
712 return try_emplace(key).first->second;
715 mapped_type& operator[](key_type&& key) {
716 return try_emplace(
std::move(key)).first->second;
719 template <
typename K>
720 EnableHeterogeneousInsert<K, mapped_type&> operator[](K&& key) {
721 return try_emplace(std::forward<K>(key)).first->second;
725 return table_.find(key).atEnd() ? 0 : 1;
728 template <
typename K>
730 K
const& key)
const {
731 return table_.find(key).atEnd() ? 0 : 1;
748 F14HashToken prehash(key_type
const& key)
const {
749 return table_.prehash(key);
752 template <
typename K>
753 EnableHeterogeneousFind<K, F14HashToken> prehash(K
const& key)
const {
754 return table_.prehash(key);
758 return table_.makeIter(table_.find(key));
762 return table_.makeConstIter(table_.find(key));
766 find(F14HashToken
const& token, key_type
const& key) {
767 return table_.makeIter(table_.find(token, key));
771 find(F14HashToken
const& token, key_type
const& key)
const {
772 return table_.makeConstIter(table_.find(token, key));
775 template <
typename K>
777 return table_.makeIter(table_.find(key));
780 template <
typename K>
782 K
const& key)
const {
783 return table_.makeConstIter(table_.find(key));
786 template <
typename K>
788 F14HashToken
const& token,
790 return table_.makeIter(table_.find(token, key));
793 template <
typename K>
795 F14HashToken
const& token,
796 K
const& key)
const {
797 return table_.makeConstIter(table_.find(token, key));
800 std::pair<iterator, iterator> equal_range(key_type
const& key) {
801 return equal_range(*
this, key);
804 std::pair<const_iterator, const_iterator> equal_range(
805 key_type
const& key)
const {
806 return equal_range(*
this, key);
809 template <
typename K>
810 EnableHeterogeneousFind<K, std::pair<iterator, iterator>> equal_range(
812 return equal_range(*
this, key);
815 template <
typename K>
816 EnableHeterogeneousFind<K, std::pair<const_iterator, const_iterator>>
817 equal_range(K
const& key)
const {
818 return equal_range(*
this, key);
823 std::size_t bucket_count()
const noexcept {
824 return table_.bucket_count();
827 std::size_t max_bucket_count()
const noexcept {
828 return table_.max_bucket_count();
833 float load_factor()
const noexcept {
834 return table_.load_factor();
837 float max_load_factor()
const noexcept {
838 return table_.max_load_factor();
841 void max_load_factor(
float v) {
842 table_.max_load_factor(v);
845 void rehash(std::size_t bucketCapacity) {
852 void reserve(std::size_t capacity) {
853 table_.reserve(capacity);
858 hasher hash_function()
const {
859 return table_.hasher();
862 key_equal key_eq()
const {
863 return table_.keyEqual();
870 return table_.getAllocatedMemorySize();
882 template <
typename V>
884 return table_.visitAllocationClasses(visitor);
891 template <
typename V>
895 return table_.computeStats();
899 template <
typename Self,
typename K>
901 auto iter =
self.find(key);
902 if (iter ==
self.
end()) {
903 throw_exception<std::out_of_range>(
"at() did not find key");
908 template <
typename Self,
typename K>
909 static auto equal_range(Self&
self, K
const& key) {
910 auto first =
self.find(key);
912 if (last !=
self.
end()) {
915 return std::make_pair(first, last);
919 F14Table<Policy> table_;
922 template <
typename M>
923 bool mapsEqual(
M const& lhs,
M const&
rhs) {
924 if (lhs.size() != rhs.size()) {
927 for (
auto& kv : lhs) {
928 auto iter = rhs.find(kv.first);
929 if (iter == rhs.end()) {
933 typename M::key_equal,
934 std::equal_to<typename M::key_type>>::
value) {
936 if (!(kv.second == iter->second)) {
941 if (!(kv == *iter)) {
959 f14::detail::ValueContainerPolicy,
965 using Policy = f14::detail::MapPolicyWithDefaults<
966 f14::detail::ValueContainerPolicy,
975 using typename Super::value_type;
981 F14ValueMap& operator=(std::initializer_list<value_type> ilist) {
982 Super::operator=(ilist);
987 this->table_.swap(rhs.table_);
990 template <
typename V>
992 this->table_.visitContiguousItemRanges(visitor);
996 template <
typename K,
typename M,
typename H,
typename E,
typename A>
1000 return mapsEqual(lhs, rhs);
1003 template <
typename K,
typename M,
typename H,
typename E,
typename A>
1007 return !(lhs ==
rhs);
1018 f14::detail::NodeContainerPolicy,
1024 using Policy = f14::detail::MapPolicyWithDefaults<
1025 f14::detail::NodeContainerPolicy,
1034 using typename Super::value_type;
1040 F14NodeMap& operator=(std::initializer_list<value_type> ilist) {
1041 Super::operator=(ilist);
1046 this->table_.swap(rhs.table_);
1049 template <
typename V>
1051 this->table_.visitItems([&](
typename Policy::Item
ptr) {
1052 value_type
const*
b = std::addressof(*ptr);
1060 template <
typename K,
typename M,
typename H,
typename E,
typename A>
1064 return mapsEqual(lhs, rhs);
1067 template <
typename K,
typename M,
typename H,
typename E,
typename A>
1071 return !(lhs ==
rhs);
1082 f14::detail::VectorContainerPolicy,
1088 using Policy = f14::detail::MapPolicyWithDefaults<
1089 f14::detail::VectorContainerPolicy,
1097 template <
typename K,
typename T>
1098 using EnableHeterogeneousVectorErase = std::enable_if_t<
1099 f14::detail::EligibleForHeterogeneousFind<
1101 typename Policy::Hasher,
1102 typename Policy::KeyEqual,
1104 !std::is_same<typename Policy::Iter, remove_cvref_t<K>>
::value &&
1105 !std::is_same<typename Policy::ConstIter, remove_cvref_t<K>>
::value &&
1106 !std::is_same<typename Policy::ReverseIter, remove_cvref_t<K>>
:: 1108 !std::is_same<typename Policy::ConstReverseIter, remove_cvref_t<K>>
:: 1113 using typename Super::const_iterator;
1114 using typename Super::iterator;
1115 using typename Super::key_type;
1116 using typename Super::value_type;
1117 using reverse_iterator =
typename Policy::ReverseIter;
1118 using const_reverse_iterator =
typename Policy::ConstReverseIter;
1125 F14VectorMap& operator=(std::initializer_list<value_type> ilist) {
1126 Super::operator=(ilist);
1131 this->table_.swap(rhs.table_);
1156 return this->table_.linearBegin(this->
size());
1158 const_iterator
begin()
const {
1161 const_iterator
cbegin()
const {
1162 return this->table_.linearBegin(this->
size());
1166 return this->table_.linearEnd();
1168 const_iterator
end()
const {
1171 const_iterator
cend()
const {
1172 return this->table_.linearEnd();
1175 reverse_iterator rbegin() {
1176 return this->table_.values_;
1178 const_reverse_iterator rbegin()
const {
1181 const_reverse_iterator crbegin()
const {
1182 return this->table_.values_;
1185 reverse_iterator rend() {
1186 return this->table_.values_ + this->table_.size();
1188 const_reverse_iterator rend()
const {
1191 const_reverse_iterator crend()
const {
1192 return this->table_.values_ + this->table_.size();
1196 iterator iter(reverse_iterator riter) {
1197 return this->table_.iter(riter);
1199 const_iterator iter(const_reverse_iterator riter)
const {
1200 return this->table_.iter(riter);
1203 reverse_iterator riter(iterator it) {
1204 return this->table_.riter(it);
1206 const_reverse_iterator riter(const_iterator it)
const {
1207 return this->table_.riter(it);
1211 void eraseUnderlying(
typename Policy::ItemIter underlying) {
1212 Alloc&
a = this->table_.alloc();
1213 auto values = this->table_.values_;
1216 auto index = underlying.item();
1219 this->table_.eraseIter(underlying);
1223 auto tailIndex = this->
size();
1224 if (tailIndex != index) {
1225 auto tail = this->table_.find(f14::detail::VectorContainerIndexSearch{
1226 static_cast<uint32_t>(tailIndex)});
1227 tail.item() = index;
1228 auto p = std::addressof(
values[index]);
1230 this->table_.transfer(a, std::addressof(
values[tailIndex]), p, 1);
1234 template <
typename K>
1235 std::size_t eraseUnderlyingKey(K
const& key) {
1236 auto underlying = this->table_.find(key);
1237 if (underlying.atEnd()) {
1240 eraseUnderlying(underlying);
1247 auto index = this->table_.iterToIndex(pos);
1249 this->table_.find(f14::detail::VectorContainerIndexSearch{index});
1250 eraseUnderlying(underlying);
1251 return index == 0 ?
end() : this->table_.indexToIter(index - 1);
1257 const_iterator cpos{pos};
1261 iterator erase(const_iterator
first, const_iterator last) {
1262 while (first != last) {
1263 first = erase(first);
1265 auto index = this->table_.iterToIndex(first);
1266 return index == 0 ?
end() : this->table_.indexToIter(index - 1);
1273 std::size_t erase(key_type
const& key) {
1274 return eraseUnderlyingKey(key);
1277 template <
typename K>
1278 EnableHeterogeneousVectorErase<K, std::size_t> erase(K
const& key) {
1279 return eraseUnderlyingKey(key);
1282 template <
typename V>
1284 auto n = this->table_.size();
1286 value_type
const*
b = std::addressof(this->table_.values_[0]);
1292 template <
typename K,
typename M,
typename H,
typename E,
typename A>
1296 return mapsEqual(lhs, rhs);
1299 template <
typename K,
typename M,
typename H,
typename E,
typename A>
1303 return !(lhs ==
rhs);
1308 #endif // FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE 1318 class F14FastMap :
public std::conditional_t<
1319 sizeof(std::pair<Key const, Mapped>) < 24,
1320 F14ValueMap<Key, Mapped, Hasher, KeyEqual, Alloc>,
1321 F14VectorMap<Key, Mapped, Hasher, KeyEqual, Alloc>> {
1322 using Super = std::conditional_t<
1323 sizeof(std::pair<Key const, Mapped>) < 24,
1324 F14ValueMap<Key, Mapped, Hasher, KeyEqual, Alloc>,
1325 F14VectorMap<Key, Mapped, Hasher, KeyEqual, Alloc>>;
1328 using typename Super::value_type;
1330 F14FastMap() = default;
1334 F14FastMap& operator=(std::initializer_list<value_type> ilist) {
1335 Super::operator=(ilist);
1340 template <typename K, typename M, typename H, typename E, typename A>
1342 F14ValueMap<K, M, H, E, A>& lhs,
1343 F14ValueMap<K, M, H, E, A>& rhs) noexcept(noexcept(lhs.swap(rhs))) {
1347 template <typename K, typename M, typename H, typename E, typename A>
1349 F14NodeMap<K, M, H, E, A>& lhs,
1350 F14NodeMap<K, M, H, E, A>& rhs) noexcept(noexcept(lhs.swap(rhs))) {
1354 template <typename K, typename M, typename H, typename E, typename A>
1356 F14VectorMap<K, M, H, E, A>& lhs,
1357 F14VectorMap<K, M, H, E, A>& rhs) noexcept(noexcept(lhs.swap(rhs))) {
1361 template <typename K, typename M, typename H, typename E, typename A>
1363 F14FastMap<K, M, H, E, A>& lhs,
1364 F14FastMap<K, M, H, E, A>& rhs) noexcept(noexcept(lhs.swap(rhs))) {
#define FOLLY_ALWAYS_INLINE
bool operator!=(SwapTrackingAlloc< T1 > const &, SwapTrackingAlloc< T2 > const &)
constexpr detail::Map< Move > move
internal::KeyMatcher< M > Key(M inner_matcher)
auto begin(TestAdlIterable &instance)
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
—— Concurrent Priority Queue Implementation ——
requires E e noexcept(noexcept(s.error(std::move(e))))
FOLLY_PUSH_WARNING RHS rhs
void init(int *argc, char ***argv, bool removeFlags)
void visitContiguousRanges(V &&visitor) const
constexpr auto size(C const &c) -> decltype(c.size())
constexpr auto empty(C const &c) -> decltype(c.empty())
def Iter(n, format, sep='')
bool Value(const T &value, M matcher)
auto end(TestAdlIterable &instance)
std::enable_if< std::is_integral< Src >::value &&IsSomeString< Tgt >::value &&sizeof(Src)< 4 >::typetoAppend(Src value, Tgt *result){typedef typename std::conditional< std::is_signed< Src >::value, int64_t, uint64_t >::type Intermediate;toAppend< Tgt >static_cast< Intermediate >value), result);}template< class Src >typename std::enable_if< std::is_integral< Src >::value &&sizeof(Src)< 4 &&!std::is_same< Src, char >::value, size_t >::typeestimateSpaceNeeded(Src value){typedef typename std::conditional< std::is_signed< Src >::value, int64_t, uint64_t >::type Intermediate;return estimateSpaceNeeded(static_cast< Intermediate >value));}template< class Tgt, class Src >typename std::enable_if< std::is_enum< Src >::value &&IsSomeString< Tgt >::value >::typetoAppend(Src value, Tgt *result){toAppend(static_cast< typename std::underlying_type< Src >::type >value), result);}template< class Src >typename std::enable_if< std::is_enum< Src >::value, size_t >::typeestimateSpaceNeeded(Src value){return estimateSpaceNeeded(static_cast< typename std::underlying_type< Src >::type >value));}namespace detail{constexpr int kConvMaxDecimalInShortestLow=-6;constexpr int kConvMaxDecimalInShortestHigh=21;}template< class Tgt, class Src >typename std::enable_if< std::is_floating_point< Src >::value &&IsSomeString< Tgt >::value >::typetoAppend(Src value, Tgt *result, double_conversion::DoubleToStringConverter::DtoaMode mode, unsigned int numDigits){using namespace double_conversion;DoubleToStringConverter conv(DoubleToStringConverter::NO_FLAGS,"Infinity","NaN", 'E', detail::kConvMaxDecimalInShortestLow, detail::kConvMaxDecimalInShortestHigh, 6, 1);char buffer[256];StringBuilder builder(buffer, sizeof(buffer));switch(mode){case DoubleToStringConverter::SHORTEST:conv.ToShortest(value,&builder);break;case DoubleToStringConverter::SHORTEST_SINGLE:conv.ToShortestSingle(static_cast< float >value),&builder);break;case DoubleToStringConverter::FIXED:conv.ToFixed(value, int(numDigits),&builder);break;default:CHECK(mode==DoubleToStringConverter::PRECISION);conv.ToPrecision(value, int(numDigits),&builder);break;}const size_t length=size_t(builder.position());builder.Finalize();result->append(buffer, length);}template< class Tgt, class Src >typename std::enable_if< std::is_floating_point< Src >::value &&IsSomeString< Tgt >::value >::typetoAppend(Src value, Tgt *result){toAppend(value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0);}template< class Src >typename std::enable_if< std::is_floating_point< Src >::value, size_t >::typeestimateSpaceNeeded(Src value){constexpr int kMaxMantissaSpace=double_conversion::DoubleToStringConverter::kBase10MaximalLength+1;constexpr int kMaxExponentSpace=2+3;static const int kMaxPositiveSpace=std::max({kMaxMantissaSpace+kMaxExponentSpace, kMaxMantissaSpace-detail::kConvMaxDecimalInShortestLow, detail::kConvMaxDecimalInShortestHigh,});return size_t(kMaxPositiveSpace+(value< 0?1:0));}template< class Src >struct HasLengthEstimator:std::false_type{};template< class Src >constexpr typename std::enable_if< !std::is_fundamental< Src >::value &&!IsSomeString< Src >::value &&!std::is_convertible< Src, const char * >::value &&!std::is_convertible< Src, StringPiece >::value &&!std::is_enum< Src >::value &&!HasLengthEstimator< Src >::value, size_t >::typeestimateSpaceNeeded(const Src &){return sizeof(Src)+1;}namespace detail{template< class Tgt >typename std::enable_if< IsSomeString< Tgt >::value, size_t >::typeestimateSpaceToReserve(size_t sofar, Tgt *){return sofar;}template< class T, class...Ts >size_t estimateSpaceToReserve(size_t sofar, const T &v, const Ts &...vs){return estimateSpaceToReserve(sofar+estimateSpaceNeeded(v), vs...);}template< class...Ts >void reserveInTarget(const Ts &...vs){getLastElement(vs...) -> reserve(estimateSpaceToReserve(0, vs...))
static const char *const value
void visitAllocationClasses(V &&visitor) const
**Optimized Holders **The template hazptr_array< M > provides most of the functionality *of M hazptr_holder s but with faster construction destruction *for M
F14NodeMap & operator=(std::initializer_list< value_type > ilist)
F14ValueMap & operator=(std::initializer_list< value_type > ilist)
std::size_t getAllocatedMemorySize() const
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
std::unordered_map< Key, Mapped, Hasher, KeyEqual, Alloc > Super
void swap(SwapTrackingAlloc< T > &, SwapTrackingAlloc< T > &)
FOLLY_ALWAYS_INLINE void assume(bool cond)
F14VectorMap & operator=(std::initializer_list< value_type > ilist)
#define FOLLY_SAFE_DCHECK(expr, msg)
Iterator< typename Container::const_iterator > cbegin(const Container &c)
Iterator< typename Container::const_iterator > cend(const Container &c)
std::vector< int > values(1'000)
constexpr detail::First first
bool operator==(SwapTrackingAlloc< T1 > const &, SwapTrackingAlloc< T2 > const &)