Commit c3ffff44 authored by Nathan Bronson's avatar Nathan Bronson Committed by Facebook Github Bot

more tests for F14 - stateful functors

Summary:
This diff adds recurring tests of F14's ability to use stateful
functors with no default constructor.

This is a test-only diff.

Reviewed By: yfeldblum

Differential Revision: D8170593

fbshipit-source-id: 6ce8c7751ce32ed69b60c6884b5deb7e6378a5d1
parent 299a38f8
......@@ -1168,6 +1168,84 @@ TEST(F14ValueMap, heterogeneous) {
checks(folly::as_const(map));
}
template <typename M>
void runStatefulFunctorTest() {
bool ranHasher = false;
bool ranEqual = false;
bool ranAlloc = false;
bool ranDealloc = false;
auto hasher = [&](int x) {
ranHasher = true;
return x;
};
auto equal = [&](int x, int y) {
ranEqual = true;
return x == y;
};
auto alloc = [&](std::size_t n) {
ranAlloc = true;
return std::malloc(n);
};
auto dealloc = [&](void* p, std::size_t) {
ranDealloc = true;
std::free(p);
};
{
M map(0, hasher, equal, {alloc, dealloc});
map[10]++;
map[10]++;
EXPECT_EQ(map[10], 2);
M map2(map);
M map3(std::move(map));
map = map2;
map2.clear();
map2 = std::move(map3);
}
EXPECT_TRUE(ranHasher);
EXPECT_TRUE(ranEqual);
EXPECT_TRUE(ranAlloc);
EXPECT_TRUE(ranDealloc);
}
TEST(F14ValueMap, statefulFunctors) {
runStatefulFunctorTest<F14ValueMap<
int,
int,
GenericHasher<int>,
GenericEqual<int>,
GenericAlloc<std::pair<int const, int>>>>();
}
TEST(F14NodeMap, statefulFunctors) {
runStatefulFunctorTest<F14NodeMap<
int,
int,
GenericHasher<int>,
GenericEqual<int>,
GenericAlloc<std::pair<int const, int>>>>();
}
TEST(F14VectorMap, statefulFunctors) {
runStatefulFunctorTest<F14VectorMap<
int,
int,
GenericHasher<int>,
GenericEqual<int>,
GenericAlloc<std::pair<int const, int>>>>();
}
TEST(F14FastMap, statefulFunctors) {
runStatefulFunctorTest<F14FastMap<
int,
int,
GenericHasher<int>,
GenericEqual<int>,
GenericAlloc<std::pair<int const, int>>>>();
}
///////////////////////////////////
#endif // FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
///////////////////////////////////
......@@ -814,6 +814,80 @@ TEST(F14ValueSet, heterogeneous) {
checks(folly::as_const(set));
}
template <typename S>
void runStatefulFunctorTest() {
bool ranHasher = false;
bool ranEqual = false;
bool ranAlloc = false;
bool ranDealloc = false;
auto hasher = [&](int x) {
ranHasher = true;
return x;
};
auto equal = [&](int x, int y) {
ranEqual = true;
return x == y;
};
auto alloc = [&](std::size_t n) {
ranAlloc = true;
return std::malloc(n);
};
auto dealloc = [&](void* p, std::size_t) {
ranDealloc = true;
std::free(p);
};
{
S set(0, hasher, equal, {alloc, dealloc});
set.insert(10);
set.insert(10);
EXPECT_EQ(set.size(), 1);
S set2(set);
S set3(std::move(set));
set = set2;
set2.clear();
set2 = std::move(set3);
}
EXPECT_TRUE(ranHasher);
EXPECT_TRUE(ranEqual);
EXPECT_TRUE(ranAlloc);
EXPECT_TRUE(ranDealloc);
}
TEST(F14ValueSet, statefulFunctors) {
runStatefulFunctorTest<F14ValueSet<
int,
GenericHasher<int>,
GenericEqual<int>,
GenericAlloc<int>>>();
}
TEST(F14NodeSet, statefulFunctors) {
runStatefulFunctorTest<F14NodeSet<
int,
GenericHasher<int>,
GenericEqual<int>,
GenericAlloc<int>>>();
}
TEST(F14VectorSet, statefulFunctors) {
runStatefulFunctorTest<F14VectorSet<
int,
GenericHasher<int>,
GenericEqual<int>,
GenericAlloc<int>>>();
}
TEST(F14FastSet, statefulFunctors) {
runStatefulFunctorTest<F14FastSet<
int,
GenericHasher<int>,
GenericEqual<int>,
GenericAlloc<int>>>();
}
///////////////////////////////////
#endif // FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
///////////////////////////////////
......@@ -18,10 +18,12 @@
#include <cstddef>
#include <limits>
#include <memory>
#include <ostream>
#include <vector>
#include <folly/Demangle.h>
#include <folly/Function.h>
#include <folly/container/detail/F14Policy.h>
#include <folly/container/detail/F14Table.h>
......@@ -427,6 +429,117 @@ std::ostream& operator<<(std::ostream& xo, F14TableStats const& stats) {
return xo;
}
template <class T>
class GenericAlloc {
public:
using value_type = T;
using pointer = T*;
using const_pointer = T const*;
using reference = T&;
using const_reference = T const&;
using size_type = std::size_t;
using propagate_on_container_swap = std::true_type;
using propagate_on_container_copy_assignment = std::true_type;
using propagate_on_container_move_assignment = std::true_type;
using AllocBytesFunc = folly::Function<void*(std::size_t)>;
using DeallocBytesFunc = folly::Function<void(void*, std::size_t)>;
GenericAlloc() = delete;
template <typename A, typename D>
GenericAlloc(A&& alloc, D&& dealloc)
: alloc_{std::make_shared<AllocBytesFunc>(std::forward<A>(alloc))},
dealloc_{std::make_shared<DeallocBytesFunc>(std::forward<D>(dealloc))} {
}
template <class U>
GenericAlloc(GenericAlloc<U> const& other) noexcept
: alloc_{other.alloc_}, dealloc_{other.dealloc_} {}
template <class U>
GenericAlloc& operator=(GenericAlloc<U> const& other) noexcept {
alloc_ = other.alloc_;
dealloc_ = other.dealloc_;
return *this;
}
template <class U>
GenericAlloc(GenericAlloc<U>&& other) noexcept
: alloc_(std::move(other.alloc_)), dealloc_(std::move(other.dealloc_)) {}
template <class U>
GenericAlloc& operator=(GenericAlloc<U>&& other) noexcept {
alloc_ = std::move(other.alloc_);
dealloc_ = std::move(other.dealloc_);
return *this;
}
T* allocate(size_t n) {
return static_cast<T*>((*alloc_)(n * sizeof(T)));
}
void deallocate(T* p, size_t n) {
(*dealloc_)(static_cast<void*>(p), n * sizeof(T));
}
template <typename U>
bool operator==(GenericAlloc<U> const& rhs) const {
return alloc_ == rhs.alloc_;
}
template <typename U>
bool operator!=(GenericAlloc<U> const& rhs) const {
return !(*this == rhs);
}
private:
std::shared_ptr<AllocBytesFunc> alloc_;
std::shared_ptr<DeallocBytesFunc> dealloc_;
template <class U>
friend class GenericAlloc;
};
template <typename T>
class GenericEqual {
public:
using EqualFunc = folly::Function<bool(T const&, T const&)>;
GenericEqual() = delete;
template <typename E>
GenericEqual(E&& equal)
: equal_{std::make_shared<EqualFunc>(std::forward<E>(equal))} {}
bool operator()(T const& lhs, T const& rhs) const {
return (*equal_)(lhs, rhs);
}
private:
std::shared_ptr<EqualFunc> equal_;
};
template <typename T>
class GenericHasher {
public:
using HasherFunc = folly::Function<std::size_t(T const&)>;
GenericHasher() = delete;
template <typename H>
GenericHasher(H&& hasher)
: hasher_{std::make_shared<HasherFunc>(std::forward<H>(hasher))} {}
std::size_t operator()(T const& val) const {
return (*hasher_)(val);
}
private:
std::shared_ptr<HasherFunc> hasher_;
};
} // namespace f14
} // namespace folly
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment