19 #include <unordered_map> 26 template <
template <
typename,
typename,
typename,
typename>
class TSet>
44 testCustomSwap<folly::F14ValueSet>();
45 testCustomSwap<folly::F14NodeSet>();
46 testCustomSwap<folly::F14VectorSet>();
47 testCustomSwap<folly::F14FastSet>();
52 template <
typename,
typename,
typename,
typename>
class TSet,
54 void runAllocatedMemorySizeTest() {
68 if (preciseAllocInfo) {
75 for (
size_t i = 0;
i < 1000; ++
i) {
76 s.insert(folly::to<K>(
i));
77 s.erase(folly::to<K>(
i / 10 + 2));
78 if (preciseAllocInfo) {
81 EXPECT_GE(s.getAllocatedMemorySize(),
sizeof(K) * s.size());
83 std::size_t
count = 0;
84 s.visitAllocationClasses([&](std::size_t, std::size_t)
mutable {});
85 s.visitAllocationClasses([&](std::size_t bytes, std::size_t n) {
89 if (preciseAllocInfo) {
108 template <
typename K>
109 void runAllocatedMemorySizeTests() {
110 runAllocatedMemorySizeTest<folly::F14ValueSet, K>();
111 runAllocatedMemorySizeTest<folly::F14NodeSet, K>();
112 runAllocatedMemorySizeTest<folly::F14VectorSet, K>();
113 runAllocatedMemorySizeTest<folly::F14FastSet, K>();
117 TEST(F14Set, getAllocatedMemorySize) {
118 runAllocatedMemorySizeTests<bool>();
119 runAllocatedMemorySizeTests<int>();
120 runAllocatedMemorySizeTests<long>();
121 runAllocatedMemorySizeTests<double>();
122 runAllocatedMemorySizeTests<std::string>();
123 runAllocatedMemorySizeTests<folly::fbstring>();
126 template <
typename S>
130 for (
int i = 0;
i < n; ++
i) {
135 std::unordered_map<uintptr_t, bool> visited;
136 for (
auto& entry :
set) {
137 visited[
reinterpret_cast<uintptr_t
>(&entry)] =
false;
140 set.visitContiguousRanges([&](
auto b,
auto e) {
141 for (
auto i =
b;
i != e; ++
i) {
142 auto iter = visited.find(reinterpret_cast<uintptr_t>(
i));
150 for (
auto& e : visited) {
155 template <
typename S>
157 runVisitContiguousRangesTest<S>(0);
158 runVisitContiguousRangesTest<S>(5);
159 runVisitContiguousRangesTest<S>(1000);
162 TEST(F14ValueSet, visitContiguousRanges) {
163 runVisitContiguousRangesTest<folly::F14ValueSet<int>>();
166 TEST(F14NodeSet, visitContiguousRanges) {
167 runVisitContiguousRangesTest<folly::F14NodeSet<int>>();
170 TEST(F14VectorSet, visitContiguousRanges) {
171 runVisitContiguousRangesTest<folly::F14VectorSet<int>>();
174 TEST(F14FastSet, visitContiguousRanges) {
175 runVisitContiguousRangesTest<folly::F14FastSet<int>>();
179 #if FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE 185 #include <unordered_set> 189 using namespace folly;
191 using namespace folly::string_piece_literals;
199 template <
typename T>
210 h.erase(h.find(
s(
"abc")));
245 EXPECT_EQ(*h2.find(to<std::string>(i * i * i)), to<std::string>(i * i *
i));
246 EXPECT_TRUE(h2.find(to<std::string>(i * i * i + 2)) == h2.end());
258 T h8({
s(
"abc"),
s(
"def")});
259 T h9({
s(
"abd"),
s(
"def")});
275 auto k = to<std::string>(
i *
i *
i);
283 h8.emplace(
s(
"abc"));
287 h9 = {
s(
"abc"),
s(
"def")};
291 auto expectH8 = [&](
T& ref) {
EXPECT_EQ(&ref, &h8); };
306 template <
typename T>
310 for (
unsigned i = 0;
i < n; ++
i) {
311 h.insert(to<std::string>(
i));
318 template <
typename T>
320 using R = std::unordered_set<uint64_t>;
322 std::mt19937_64 gen(0);
323 std::uniform_int_distribution<> pctDist(0, 100);
324 std::uniform_int_distribution<uint64_t> bitsBitsDist(1, 6);
330 for (std::size_t reps = 0; reps < 100000; ++reps) {
332 auto discardBits = (
uint64_t{1} << bitsBitsDist(gen)) - 2;
333 auto k = gen() >> discardBits;
334 auto pct = pctDist(gen);
339 auto t = t0.insert(
k);
340 auto r = r0.insert(
k);
343 }
else if (pct < 25) {
345 auto t = t0.emplace(
k);
346 auto r = r0.emplace(
k);
349 }
else if (pct < 30) {
351 t0.insert(t1.begin(), t1.end());
352 r0.insert(r1.begin(), r1.end());
353 }
else if (pct < 40) {
355 auto t = t0.erase(
k);
356 auto r = r0.erase(
k);
358 }
else if (pct < 47) {
376 }
else if (pct < 50) {
387 t = t0.erase(firstt, lastt);
393 r = r0.erase(firstr, lastr);
398 }
else if (pct < 58) {
403 if (
t != t0.end() && r != r0.end()) {
407 }
else if (pct < 60) {
409 auto t = t0.equal_range(
k);
410 auto r = r0.equal_range(
k);
411 EXPECT_EQ((
t.first ==
t.second), (r.first == r.second));
412 if (
t.first !=
t.second && r.first != r.second) {
419 }
else if (pct < 65) {
430 }
else if (pct < 69) {
435 }
else if (pct < 70) {
439 }
else if (pct < 72) {
445 }
else if (pct < 74) {
447 std::size_t capacity =
k & 0xffff;
449 new (&t0)
T(capacity);
451 new (&r0) R(capacity);
452 }
else if (pct < 80) {
455 new (&t0)
T(r1.begin(), r1.end());
457 new (&r0) R(r1.begin(), r1.end());
458 }
else if (pct < 82) {
460 auto k2 = gen() >> discardBits;
462 new (&t0)
T({
k,
k, k2});
464 new (&r0) R({
k,
k, k2});
465 }
else if (pct < 88) {
471 }
else if (pct < 90) {
477 }
else if (pct < 94) {
481 }
else if (pct < 96) {
485 }
else if (pct < 98) {
488 }
else if (pct < 99) {
493 }
else if (pct < 100) {
495 auto scale = std::uniform_int_distribution<>(0, 8)(gen);
496 auto delta = std::uniform_int_distribution<>(-2, 2)(gen);
497 std::ptrdiff_t target = (t0.size() * scale) / 4 + delta;
499 t0.reserve(static_cast<std::size_t>(target));
500 r0.reserve(static_cast<std::size_t>(target));
507 runSimple<F14ValueSet<std::string>>();
511 runSimple<F14NodeSet<std::string>>();
515 runSimple<F14VectorSet<std::string>>();
520 runRandom<F14FastSet<uint64_t>>();
521 runSimple<F14FastSet<std::string>>();
524 TEST(F14Set, ContainerSize) {
528 EXPECT_EQ(
sizeof(
set), 4 *
sizeof(
void*));
531 EXPECT_EQ(
set.getAllocatedMemorySize(), 32);
534 EXPECT_EQ(
set.getAllocatedMemorySize(), 24);
540 EXPECT_EQ(
sizeof(
set), 4 *
sizeof(
void*));
543 EXPECT_EQ(
set.getAllocatedMemorySize(), 36);
546 EXPECT_EQ(
set.getAllocatedMemorySize(), 20 + 2 *
sizeof(
void*));
552 EXPECT_EQ(
sizeof(
set), 8 + 2 *
sizeof(
void*));
553 EXPECT_EQ(
set.getAllocatedMemorySize(), 32);
558 using TSet = F14VectorSet<uint64_t>;
560 for (
auto i = lo;
i < hi; ++
i) {
565 auto loIt = h.find(lo);
568 for (
auto rit = h.riter(loIt); rit != h.rend(); ++rit) {
570 TSet::const_iterator it = h.iter(rit);
581 while (newSize < 10
'000) { 582 populate(h, prevSize, newSize); 583 verify(h, 0, newSize); 584 verify(h, newSize / 2, newSize); 587 verify(h2, 0, newSize); 590 verify(h, 0, newSize); 596 TEST(F14ValueSet, rehash) { 597 runRehash<F14ValueSet<std::string>>(); 600 TEST(F14NodeSet, rehash) { 601 runRehash<F14NodeSet<std::string>>(); 604 TEST(F14VectorSet, rehash) { 605 runRehash<F14VectorSet<std::string>>(); 608 TEST(F14ValueSet, random) { 609 runRandom<F14ValueSet<uint64_t>>(); 612 TEST(F14NodeSet, random) { 613 runRandom<F14NodeSet<uint64_t>>(); 616 TEST(F14VectorSet, random) { 617 runRandom<F14VectorSet<uint64_t>>(); 620 TEST(F14ValueSet, grow_stats) { 621 F14ValueSet<uint64_t> h; 622 for (unsigned i = 1; i <= 3072; ++i) { 625 // F14ValueSet just before rehash 626 F14TableStats::compute(h); 628 // F14ValueSet just after rehash 629 F14TableStats::compute(h); 632 TEST(F14ValueSet, steady_state_stats) { 633 // 10k keys, 14% probability of insert, 90% chance of erase, so the 634 // table should converge to 1400 size without triggering the rehash 635 // that would occur at 1536. 636 F14ValueSet<uint64_t> h; 638 std::uniform_int_distribution<> dist(0, 10000); 639 for (std::size_t i = 0; i < 100000; ++i) { 640 auto key = dist(gen); 641 if (dist(gen) < 1400) { 646 if (((i + 1) % 10000) == 0) { 647 auto stats = F14TableStats::compute(h); 648 // Verify that average miss probe length is bounded despite continued 649 // erase + reuse. p99 of the average across 10M random steps is 4.69, 651 EXPECT_LT(f14::expectedProbe(stats.missProbeLengthHisto), 10.0); 654 // F14ValueSet at steady state 655 F14TableStats::compute(h); 658 // S should be a set of Tracked<0>. F should take a set 659 // and a key_type const& or key_type&& and cause it to be inserted 660 template <typename S, typename F> 661 void runInsertCases(std::string const& /* name */, F const& insertFunc) { 662 static_assert(std::is_same<typename S::value_type, Tracked<0>>::value, ""); 664 typename S::value_type k{0}; 668 // fresh key, value_type const& -> 670 EXPECT_EQ(Tracked<0>::counts.dist(Counts{1, 0, 0, 0}), 0); 673 typename S::value_type k{0}; 676 insertFunc(s, std::move(k)); 677 // fresh key, value_type&& -> 679 EXPECT_EQ(Tracked<0>::counts.dist(Counts{0, 1, 0, 0}), 0); 684 template <typename M, typename P> 685 void operator()(M& m, P&& p) const { 686 m.insert(std::forward<P>(p)); 691 template <typename M, typename P> 692 void operator()(M& m, P&& p) const { 693 m.emplace(std::forward<P>(p)); 697 template <typename S> 698 void runInsertAndEmplace() { 700 typename S::value_type k1{0}; 701 typename S::value_type k2{0}; 704 EXPECT_TRUE(s.insert(k1).second); 705 // copy is expected on successful insert 706 EXPECT_EQ(Tracked<0>::counts.dist(Counts{1, 0, 0, 0}), 0); 709 EXPECT_FALSE(s.insert(k2).second); 710 // no copies or moves on failing insert 711 EXPECT_EQ(Tracked<0>::counts.dist(Counts{0, 0, 0, 0}), 0); 714 typename S::value_type k1{0}; 715 typename S::value_type k2{0}; 718 EXPECT_TRUE(s.insert(std::move(k1)).second); 719 // move is expected on successful insert 720 EXPECT_EQ(Tracked<0>::counts.dist(Counts{0, 1, 0, 0}), 0); 723 EXPECT_FALSE(s.insert(std::move(k2)).second); 724 // no copies or moves on failing insert 725 EXPECT_EQ(Tracked<0>::counts.dist(Counts{0, 0, 0, 0}), 0); 728 typename S::value_type k1{0}; 729 typename S::value_type k2{0}; 733 EXPECT_TRUE(s.emplace(k1).second); 734 // copy is expected on successful emplace 735 EXPECT_EQ(Tracked<0>::counts.dist(Counts{1, 0, 0, 0}), 0); 738 EXPECT_FALSE(s.emplace(k2).second); 739 // no copies or moves on failing emplace with value_type 740 EXPECT_EQ(Tracked<0>::counts.dist(Counts{0, 0, 0, 0}), 0); 743 EXPECT_FALSE(s.emplace(k3).second); 744 // copy convert expected for failing emplace with wrong type 745 EXPECT_EQ(Tracked<0>::counts.dist(Counts{0, 0, 1, 0}), 0); 749 EXPECT_TRUE(s.emplace(k3).second); 750 // copy convert + move expected for successful emplace with wrong type 751 EXPECT_EQ(Tracked<0>::counts.dist(Counts{0, 1, 1, 0}), 0); 754 typename S::value_type k1{0}; 755 typename S::value_type k2{0}; 759 EXPECT_TRUE(s.emplace(std::move(k1)).second); 760 // move is expected on successful emplace 761 EXPECT_EQ(Tracked<0>::counts.dist(Counts{0, 1, 0, 0}), 0); 764 EXPECT_FALSE(s.emplace(std::move(k2)).second); 765 // no copies or moves on failing emplace with value_type 766 EXPECT_EQ(Tracked<0>::counts.dist(Counts{0, 0, 0, 0}), 0); 769 EXPECT_FALSE(s.emplace(std::move(k3)).second); 770 // move convert expected for failing emplace with wrong type 771 EXPECT_EQ(Tracked<0>::counts.dist(Counts{0, 0, 0, 1}), 0); 775 EXPECT_TRUE(s.emplace(std::move(k3)).second); 776 // move convert + move expected for successful emplace with wrong type 777 EXPECT_EQ(Tracked<0>::counts.dist(Counts{0, 1, 0, 1}), 0); 780 // Calling the default pair constructor via emplace is valid, but not 781 // very useful in real life. Verify that it works. 783 typename S::value_type k; 784 EXPECT_EQ(s.count(k), 0); 786 EXPECT_EQ(s.count(k), 1); 788 EXPECT_EQ(s.count(k), 1); 791 TEST(F14ValueSet, destructuring) { 792 runInsertAndEmplace<F14ValueSet<Tracked<0>>>(); 795 TEST(F14NodeSet, destructuring) { 796 runInsertAndEmplace<F14NodeSet<Tracked<0>>>(); 799 TEST(F14VectorSet, destructuring) { 800 runInsertAndEmplace<F14VectorSet<Tracked<0>>>(); 803 TEST(F14ValueSet, maxSize) { 806 s.max_size(), std::numeric_limits<std::size_t>::max() / sizeof(int)); 809 TEST(F14NodeSet, maxSize) { 812 s.max_size(), std::numeric_limits<std::size_t>::max() / sizeof(int)); 815 TEST(F14VectorSet, maxSize) { 820 std::size_t{std::numeric_limits<uint32_t>::max()}, 821 std::numeric_limits<std::size_t>::max() / sizeof(int))); 824 template <typename S> 825 void runMoveOnlyTest() { 830 EXPECT_TRUE(t0.empty()); 832 EXPECT_TRUE(t2.empty()); 834 EXPECT_EQ(t2.size(), 2); 837 TEST(F14ValueSet, moveOnly) { 838 runMoveOnlyTest<F14ValueSet<f14::MoveOnlyTestInt>>(); 841 TEST(F14NodeSet, moveOnly) { 842 runMoveOnlyTest<F14NodeSet<f14::MoveOnlyTestInt>>(); 845 TEST(F14VectorSet, moveOnly) { 846 runMoveOnlyTest<F14VectorSet<f14::MoveOnlyTestInt>>(); 849 TEST(F14FastSet, moveOnly) { 850 runMoveOnlyTest<F14FastSet<f14::MoveOnlyTestInt>>(); 853 template <typename S> 854 void runEraseIntoTest() { 858 auto insertIntoT0 = [&t0](auto&& value) { 859 EXPECT_FALSE(value.destroyed); 860 t0.emplace(std::move(value)); 862 auto insertIntoT0Mut = [&](typename S::value_type&& value) mutable { 863 insertIntoT0(std::move(value)); 868 t1.eraseInto(t1.begin(), insertIntoT0); 869 EXPECT_TRUE(t1.empty()); 870 EXPECT_EQ(t0.size(), 2); 871 EXPECT_TRUE(t0.find(10) != t0.end()); 872 EXPECT_TRUE(t0.find(20) != t0.end()); 877 t1.eraseInto(t1.begin(), t1.end(), insertIntoT0Mut); 878 EXPECT_TRUE(t1.empty()); 879 EXPECT_EQ(t0.size(), 4); 880 EXPECT_TRUE(t0.find(30) != t0.end()); 881 EXPECT_TRUE(t0.find(40) != t0.end()); 884 size_t erased = t1.eraseInto(*t1.find(50), insertIntoT0); 885 EXPECT_EQ(erased, 1); 886 EXPECT_TRUE(t1.empty()); 887 EXPECT_EQ(t0.size(), 5); 888 EXPECT_TRUE(t0.find(50) != t0.end()); 890 typename S::value_type key{60}; 891 erased = t1.eraseInto(key, insertIntoT0Mut); 892 EXPECT_EQ(erased, 0); 893 EXPECT_EQ(t0.size(), 5); 896 TEST(F14ValueSet, eraseInto) { 897 runEraseIntoTest<F14ValueSet<f14::MoveOnlyTestInt>>(); 900 TEST(F14NodeSet, eraseInto) { 901 runEraseIntoTest<F14NodeSet<f14::MoveOnlyTestInt>>(); 904 TEST(F14VectorSet, eraseInto) { 905 runEraseIntoTest<F14VectorSet<f14::MoveOnlyTestInt>>(); 908 TEST(F14FastSet, eraseInto) { 909 runEraseIntoTest<F14FastSet<f14::MoveOnlyTestInt>>(); 912 TEST(F14ValueSet, heterogeneous) { 913 // note: std::string is implicitly convertible to but not from StringPiece 914 using Hasher = folly::transparent<folly::hasher<folly::StringPiece>>; 915 using KeyEqual = folly::transparent<std::equal_to<folly::StringPiece>>; 917 constexpr auto hello = "hello"_sp; 918 constexpr auto buddy = "buddy"_sp; 919 constexpr auto world = "world"_sp; 921 F14ValueSet<std::string, Hasher, KeyEqual> set; 925 auto checks = [hello, buddy](auto& ref) { 927 EXPECT_EQ(0, ref.count(buddy)); 928 EXPECT_EQ(1, ref.count(hello)); 931 EXPECT_TRUE(ref.end() == ref.find(buddy)); 932 EXPECT_EQ(hello, *ref.find(hello)); 935 EXPECT_TRUE(ref.end() == ref.find(ref.prehash(buddy), buddy)); 936 EXPECT_EQ(hello, *ref.find(ref.prehash(hello), hello)); 939 EXPECT_TRUE(std::make_pair(ref.end(), ref.end()) == ref.equal_range(buddy)); 941 std::make_pair(ref.find(hello), ++ref.find(hello)) == 942 ref.equal_range(hello)); 946 checks(folly::as_const(set)); 949 template <typename S> 950 void runStatefulFunctorTest() { 951 bool ranHasher = false; 952 bool ranEqual = false; 953 bool ranAlloc = false; 954 bool ranDealloc = false; 956 auto hasher = [&](int x) { 960 auto equal = [&](int x, int y) { 964 auto alloc = [&](std::size_t n) { 966 return std::malloc(n); 968 auto dealloc = [&](void* p, std::size_t) { 974 S set(0, hasher, equal, {alloc, dealloc}); 977 EXPECT_EQ(set.size(), 1); 980 S set3(std::move(set)); 983 set2 = std::move(set3); 985 EXPECT_TRUE(ranHasher); 986 EXPECT_TRUE(ranEqual); 987 EXPECT_TRUE(ranAlloc); 988 EXPECT_TRUE(ranDealloc); 991 TEST(F14ValueSet, statefulFunctors) { 992 runStatefulFunctorTest<F14ValueSet< 996 GenericAlloc<int>>>(); 999 TEST(F14NodeSet, statefulFunctors) { 1000 runStatefulFunctorTest<F14NodeSet< 1004 GenericAlloc<int>>>(); 1007 TEST(F14VectorSet, statefulFunctors) { 1008 runStatefulFunctorTest<F14VectorSet< 1012 GenericAlloc<int>>>(); 1015 TEST(F14FastSet, statefulFunctors) { 1016 runStatefulFunctorTest<F14FastSet< 1020 GenericAlloc<int>>>(); 1023 template <typename S> 1024 void runHeterogeneousInsertTest() { 1028 EXPECT_EQ(set.count(10), 0); 1029 EXPECT_EQ(Tracked<1>::counts.dist(Counts{0, 0, 0, 0}), 0) 1030 << Tracked<1>::counts; 1034 EXPECT_EQ(Tracked<1>::counts.dist(Counts{0, 0, 0, 1}), 0) 1035 << Tracked<1>::counts; 1039 std::vector<int> v({10}); 1042 set.insert(v.begin(), v.end()); 1044 std::make_move_iterator(v.begin()), std::make_move_iterator(v.end())); 1047 EXPECT_EQ(Tracked<1>::counts.dist(Counts{0, 0, 0, 0}), 0) 1048 << Tracked<1>::counts; 1052 EXPECT_EQ(set.size(), 1); 1053 EXPECT_EQ(Tracked<1>::counts.dist(Counts{0, 0, 0, 0}), 0) 1054 << Tracked<1>::counts; 1058 EXPECT_EQ(set.size(), 0); 1059 EXPECT_EQ(Tracked<1>::counts.dist(Counts{0, 0, 0, 0}), 0) 1060 << Tracked<1>::counts; 1064 set.eraseInto(10, [](auto&&) {}); 1065 EXPECT_EQ(Tracked<1>::counts.dist(Counts{0, 0, 0, 0}), 0) 1066 << Tracked<1>::counts; 1069 template <typename S> 1070 void runHeterogeneousInsertStringTest() { 1072 StringPiece k{"foo"}; 1073 std::vector<StringPiece> v{k}; 1077 set.insert(StringPiece{"foo"}); 1078 set.insert(v.begin(), v.end()); 1080 std::make_move_iterator(v.begin()), std::make_move_iterator(v.end())); 1085 set.emplace(StringPiece("foo")); 1089 set.erase(StringPiece{"foo"}); 1090 EXPECT_TRUE(set.empty()); 1093 TEST(F14ValueSet, heterogeneousInsert) { 1094 runHeterogeneousInsertTest<F14ValueSet< 1096 TransparentTrackedHash<1>, 1097 TransparentTrackedEqual<1>>>(); 1098 runHeterogeneousInsertStringTest<F14ValueSet< 1100 transparent<hasher<StringPiece>>, 1101 transparent<DefaultKeyEqual<StringPiece>>>>(); 1102 runHeterogeneousInsertStringTest<F14ValueSet<std::string>>(); 1105 TEST(F14NodeSet, heterogeneousInsert) { 1106 runHeterogeneousInsertTest<F14NodeSet< 1108 TransparentTrackedHash<1>, 1109 TransparentTrackedEqual<1>>>(); 1110 runHeterogeneousInsertStringTest<F14NodeSet< 1112 transparent<hasher<StringPiece>>, 1113 transparent<DefaultKeyEqual<StringPiece>>>>(); 1114 runHeterogeneousInsertStringTest<F14NodeSet<std::string>>(); 1117 TEST(F14VectorSet, heterogeneousInsert) { 1118 runHeterogeneousInsertTest<F14VectorSet< 1120 TransparentTrackedHash<1>, 1121 TransparentTrackedEqual<1>>>(); 1122 runHeterogeneousInsertStringTest<F14VectorSet< 1124 transparent<hasher<StringPiece>>, 1125 transparent<DefaultKeyEqual<StringPiece>>>>(); 1126 runHeterogeneousInsertStringTest<F14VectorSet<std::string>>(); 1129 TEST(F14FastSet, heterogeneousInsert) { 1130 runHeterogeneousInsertTest<F14FastSet< 1132 TransparentTrackedHash<1>, 1133 TransparentTrackedEqual<1>>>(); 1134 runHeterogeneousInsertStringTest<F14FastSet< 1136 transparent<hasher<StringPiece>>, 1137 transparent<DefaultKeyEqual<StringPiece>>>>(); 1138 runHeterogeneousInsertStringTest<F14FastSet<std::string>>(); 1142 struct CharArrayHasher { 1143 template <std::size_t N> 1144 std::size_t operator()(std::array<char, N> const& value) const { 1145 return folly::Hash{}( 1146 StringPiece{value.data(), &value.data()[value.size()]}); 1151 template <typename, typename, typename, typename> class S, 1153 struct RunAllValueSizeTests { 1154 void operator()() const { 1155 using Key = std::array<char, N>; 1156 static_assert(sizeof(Key) == N, ""); 1157 S<Key, CharArrayHasher, std::equal_to<Key>, std::allocator<Key>> set; 1159 for (int i = 0; i < 100; ++i) { 1160 Key key{{static_cast<char>(i)}}; 1163 while (!set.empty()) { 1164 set.erase(set.begin()); 1167 RunAllValueSizeTests<S, N - 1>{}(); 1171 template <template <typename, typename, typename, typename> class S> 1172 struct RunAllValueSizeTests<S, 0> { 1173 void operator()() const {} 1177 TEST(F14ValueSet, valueSize) { 1178 RunAllValueSizeTests<F14ValueSet, 32>{}(); 1182 #endif // FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
void populate(Vector &v, const pair< int, int > &ss)
#define EXPECT_EQ(val1, val2)
constexpr detail::Map< Move > move
—— Concurrent Priority Queue Implementation ——
#define EXPECT_GE(val1, val2)
static F14TableStats compute(T const &m)
thread_local size_t testAllocatedBlockCount
constexpr auto size(C const &c) -> decltype(c.size())
static constexpr F14IntrinsicsMode getF14IntrinsicsMode()
std::uniform_int_distribution< milliseconds::rep > dist
thread_local size_t testAllocatedMemorySize
#define EXPECT_TRUE(condition)
#define EXPECT_NE(val1, val2)
void runVisitContiguousRangesTest(int n)
void swap(SwapTrackingAlloc< T > &, SwapTrackingAlloc< T > &)
#define EXPECT_FALSE(condition)
#define ASSERT_TRUE(condition)
TEST(SequencedExecutor, CPUThreadPoolExecutor)
#define EXPECT_GT(val1, val2)