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

add pmr aliases

Summary:
Adds folly::pmr::* aliases for all of the F14 map and set types.
The only missing piece for full pmr support was to tolerate a deleted
operator= for allocators that are never actually assigned (based on the
propagate_... properties).

Reviewed By: yfeldblum

Differential Revision: D15572220

fbshipit-source-id: fd9687a73bf67e5e9c7962cc788fae658ccf7d36
parent d12df6e9
......@@ -19,6 +19,7 @@
#include <utility>
#include <folly/container/detail/F14Defaults.h>
#include <folly/memory/MemoryResource.h>
namespace folly {
template <
......@@ -53,4 +54,60 @@ template <
typename Alloc = f14::DefaultAlloc<std::pair<Key const, Mapped>>>
class F14FastMap;
#if FOLLY_HAS_MEMORY_RESOURCE
namespace pmr {
template <
typename Key,
typename Mapped,
typename Hasher = f14::DefaultHasher<Key>,
typename KeyEqual = f14::DefaultKeyEqual<Key>>
using F14NodeMap = folly::F14NodeMap<
Key,
Mapped,
Hasher,
KeyEqual,
folly::detail::std_pmr::polymorphic_allocator<
std::pair<Key const, Mapped>>>;
template <
typename Key,
typename Mapped,
typename Hasher = f14::DefaultHasher<Key>,
typename KeyEqual = f14::DefaultKeyEqual<Key>>
using F14ValueMap = folly::F14ValueMap<
Key,
Mapped,
Hasher,
KeyEqual,
folly::detail::std_pmr::polymorphic_allocator<
std::pair<Key const, Mapped>>>;
template <
typename Key,
typename Mapped,
typename Hasher = f14::DefaultHasher<Key>,
typename KeyEqual = f14::DefaultKeyEqual<Key>>
using F14VectorMap = folly::F14VectorMap<
Key,
Mapped,
Hasher,
KeyEqual,
folly::detail::std_pmr::polymorphic_allocator<
std::pair<Key const, Mapped>>>;
template <
typename Key,
typename Mapped,
typename Hasher = f14::DefaultHasher<Key>,
typename KeyEqual = f14::DefaultKeyEqual<Key>>
using F14FastMap = folly::F14FastMap<
Key,
Mapped,
Hasher,
KeyEqual,
folly::detail::std_pmr::polymorphic_allocator<
std::pair<Key const, Mapped>>>;
} // namespace pmr
#endif // FOLLY_HAS_MEMORY_RESOURCE
} // namespace folly
......@@ -19,7 +19,7 @@
/**
* F14NodeMap, F14ValueMap, and F14VectorMap
*
* F14FastMap conditionally inherits from F14ValueMap or F14VectorMap
* F14FastMap conditionally works like F14ValueMap or F14VectorMap
*
* See F14.md
*
......
......@@ -17,6 +17,7 @@
#pragma once
#include <folly/container/detail/F14Defaults.h>
#include <folly/memory/MemoryResource.h>
namespace folly {
template <
......@@ -47,4 +48,48 @@ template <
typename Alloc = f14::DefaultAlloc<Key>>
class F14FastSet;
#if FOLLY_HAS_MEMORY_RESOURCE
namespace pmr {
template <
typename Key,
typename Hasher = f14::DefaultHasher<Key>,
typename KeyEqual = f14::DefaultKeyEqual<Key>>
using F14NodeSet = folly::F14NodeSet<
Key,
Hasher,
KeyEqual,
folly::detail::std_pmr::polymorphic_allocator<Key>>;
template <
typename Key,
typename Hasher = f14::DefaultHasher<Key>,
typename KeyEqual = f14::DefaultKeyEqual<Key>>
using F14ValueSet = folly::F14ValueSet<
Key,
Hasher,
KeyEqual,
folly::detail::std_pmr::polymorphic_allocator<Key>>;
template <
typename Key,
typename Hasher = f14::DefaultHasher<Key>,
typename KeyEqual = f14::DefaultKeyEqual<Key>>
using F14VectorSet = folly::F14VectorSet<
Key,
Hasher,
KeyEqual,
folly::detail::std_pmr::polymorphic_allocator<Key>>;
template <
typename Key,
typename Hasher = f14::DefaultHasher<Key>,
typename KeyEqual = f14::DefaultKeyEqual<Key>>
using F14FastSet = folly::F14FastSet<
Key,
Hasher,
KeyEqual,
folly::detail::std_pmr::polymorphic_allocator<Key>>;
} // namespace pmr
#endif // FOLLY_HAS_MEMORY_RESOURCE
} // namespace folly
......@@ -19,7 +19,7 @@
/**
* F14NodeSet, F14ValueSet, and F14VectorSet
*
* F14FastSet conditionally inherits from F14ValueSet or F14VectorSet
* F14FastSet conditionally works like F14ValueSet or F14VectorSet
*
* See F14.md
*
......@@ -1245,4 +1245,5 @@ template <typename K, typename H, typename E, typename A, typename Pred>
void erase_if(F14FastSet<K, H, E, A>& c, Pred pred) {
f14::detail::erase_if_impl(c, pred);
}
} // namespace folly
......@@ -221,21 +221,40 @@ struct BasePolicy
KeyEqualHolder{std::move(rhs.keyEqual())},
AllocHolder{alloc} {}
private:
template <typename Src>
void maybeAssignAlloc(std::true_type, Src&& src) {
alloc() = std::forward<Src>(src);
}
template <typename Src>
void maybeAssignAlloc(std::false_type, Src&&) {}
template <typename A>
void maybeSwapAlloc(std::true_type, A& rhs) {
using std::swap;
swap(alloc(), rhs);
}
template <typename A>
void maybeSwapAlloc(std::false_type, A&) {}
public:
BasePolicy& operator=(BasePolicy const& rhs) {
hasher() = rhs.hasher();
keyEqual() = rhs.keyEqual();
if (AllocTraits::propagate_on_container_copy_assignment::value) {
alloc() = rhs.alloc();
}
maybeAssignAlloc(
typename AllocTraits::propagate_on_container_copy_assignment{},
rhs.alloc());
return *this;
}
BasePolicy& operator=(BasePolicy&& rhs) noexcept {
hasher() = std::move(rhs.hasher());
keyEqual() = std::move(rhs.keyEqual());
if (AllocTraits::propagate_on_container_move_assignment::value) {
alloc() = std::move(rhs.alloc());
}
maybeAssignAlloc(
typename AllocTraits::propagate_on_container_move_assignment{},
std::move(rhs.alloc()));
return *this;
}
......@@ -243,9 +262,8 @@ struct BasePolicy
using std::swap;
swap(hasher(), rhs.hasher());
swap(keyEqual(), rhs.keyEqual());
if (AllocTraits::propagate_on_container_swap::value) {
swap(alloc(), rhs.alloc());
}
maybeSwapAlloc(
typename AllocTraits::propagate_on_container_swap{}, rhs.alloc());
}
Hasher& hasher() {
......@@ -1360,7 +1378,7 @@ class VectorContainerPolicy : public BasePolicy<
&*outChunkAllocation + valuesOffset(chunkAllocSize))));
if (size > 0) {
Alloc& a{this->alloc()};
Alloc& a = this->alloc();
transfer(a, std::addressof(before[0]), std::addressof(after[0]), size);
}
......
......@@ -180,6 +180,16 @@ TEST(F14FastMap, visitContiguousRanges) {
runVisitContiguousRangesTest<folly::F14FastMap<int, int>>();
}
#if FOLLY_HAS_MEMORY_RESOURCE
TEST(F14Map, pmr_empty) {
folly::pmr::F14ValueMap<int, int> m1;
folly::pmr::F14NodeMap<int, int> m2;
folly::pmr::F14VectorMap<int, int> m3;
folly::pmr::F14FastMap<int, int> m4;
EXPECT_TRUE(m1.empty() && m2.empty() && m3.empty() && m4.empty());
}
#endif
///////////////////////////////////
#if FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
///////////////////////////////////
......@@ -674,6 +684,24 @@ TEST(F14FastMap, simple) {
runSimple<F14FastMap<std::string, std::string>>();
}
#if FOLLY_HAS_MEMORY_RESOURCE
TEST(F14ValueMap, pmr_simple) {
runSimple<pmr::F14ValueMap<std::string, std::string>>();
}
TEST(F14NodeMap, pmr_simple) {
runSimple<pmr::F14NodeMap<std::string, std::string>>();
}
TEST(F14VectorMap, pmr_simple) {
runSimple<pmr::F14VectorMap<std::string, std::string>>();
}
TEST(F14FastMap, pmr_simple) {
runSimple<pmr::F14FastMap<std::string, std::string>>();
}
#endif
TEST(F14VectorMap, reverse_iterator) {
using TMap = F14VectorMap<uint64_t, uint64_t>;
auto populate = [](TMap& h, uint64_t lo, uint64_t hi) {
......
......@@ -177,6 +177,16 @@ TEST(F14FastSet, visitContiguousRanges) {
runVisitContiguousRangesTest<folly::F14FastSet<int>>();
}
#if FOLLY_HAS_MEMORY_RESOURCE
TEST(F14Set, pmr_empty) {
folly::pmr::F14ValueSet<int> s1;
folly::pmr::F14NodeSet<int> s2;
folly::pmr::F14VectorSet<int> s3;
folly::pmr::F14FastSet<int> s4;
EXPECT_TRUE(s1.empty() && s2.empty() && s3.empty() && s4.empty());
}
#endif
///////////////////////////////////
#if FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
///////////////////////////////////
......@@ -561,11 +571,31 @@ TEST(F14VectorSet, simple) {
}
TEST(F14FastSet, simple) {
// F14FastSet inherits from a conditional typedef. Verify it compiles.
// F14FastSet internally uses a conditional typedef. Verify it compiles.
runRandom<F14FastSet<uint64_t>>();
runSimple<F14FastSet<std::string>>();
}
#if FOLLY_HAS_MEMORY_RESOURCE
TEST(F14ValueSet, pmr_simple) {
runSimple<pmr::F14ValueSet<std::string>>();
}
TEST(F14NodeSet, pmr_simple) {
runSimple<pmr::F14NodeSet<std::string>>();
}
TEST(F14VectorSet, pmr_simple) {
runSimple<pmr::F14VectorSet<std::string>>();
}
TEST(F14FastSet, pmr_simple) {
// F14FastSet internally uses a conditional typedef. Verify it compiles.
runRandom<pmr::F14FastSet<uint64_t>>();
runSimple<pmr::F14FastSet<std::string>>();
}
#endif
TEST(F14Set, ContainerSize) {
{
folly::F14ValueSet<int> set;
......
......@@ -28,7 +28,9 @@ namespace std_pmr = ::std::pmr;
} // namespace detail
} // namespace folly
#elif __has_include(<experimental/memory_resource>)
// Ignore experimental/memory_resource for libc++ so that all programs
// don't need to explicitly link the c++experimental lib
#elif !defined(_LIBCPP_VERSION) && __has_include(<experimental/memory_resource>)
#define FOLLY_HAS_MEMORY_RESOURCE 1
#include <experimental/memory_resource> // @manual
......
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