Commit 4eb1b242 authored by Nathan Bronson's avatar Nathan Bronson Committed by Facebook GitHub Bot

handle MSVC debug iterator tracking in F14 fallback

Summary:
MSVC's maintains an intrusive linked list of iterators for
debugging purposes in some build configurations, which means that
F14MapFallback's hacky conversion from unordered_map::local_iterator to
unordered_map::iterator doesn't work.  Fortunately, on that platform
local_iterator and iterator are the same type, so no hack is needed.

Reviewed By: Orvid

Differential Revision: D22776318

fbshipit-source-id: 80283c4c451afffe522e55e47cd94971126a6fa6
parent a055d929
......@@ -211,7 +211,7 @@ class F14BasicMap : public std::unordered_map<K, M, H, E, A> {
return std::make_pair(it, false);
}
auto rv = Super::emplace(std::forward<decltype(inner)>(inner)...);
FOLLY_SAFE_CHECK(
FOLLY_SAFE_DCHECK(
rv.second, "post-find emplace should always insert");
return rv;
} else {
......@@ -289,7 +289,6 @@ class F14BasicMap : public std::unordered_map<K, M, H, E, A> {
template <typename K2>
struct BottomKeyEqual {
[[noreturn]] bool operator()(K2 const&, K2 const&) const {
FOLLY_SAFE_CHECK(false, "bucket should not invoke key equality");
assume_unreachable();
}
};
......@@ -379,19 +378,33 @@ class F14BasicMap : public std::unordered_map<K, M, H, E, A> {
}
private:
template <typename Iter, typename LocalIter>
static std::
enable_if_t<std::is_constructible<Iter, LocalIter const&>::value, Iter>
fromLocal(LocalIter const& src, int = 0) {
return Iter(src);
}
template <typename Iter, typename LocalIter>
static std::
enable_if_t<!std::is_constructible<Iter, LocalIter const&>::value, Iter>
fromLocal(LocalIter const& src) {
Iter dst;
static_assert(sizeof(dst) <= sizeof(src), "");
std::memcpy(std::addressof(dst), std::addressof(src), sizeof(dst));
FOLLY_SAFE_CHECK(
std::addressof(*src) == std::addressof(*dst),
"ABI-assuming local_iterator to iterator conversion failed");
return dst;
}
template <typename Iter, typename Self, typename K2>
static Iter findImpl(Self& self, K2 const& key) {
auto optLocalIt = findLocal(self, key);
if (!optLocalIt) {
return self.end();
} else {
Iter it;
static_assert(sizeof(it) <= sizeof(*optLocalIt), "");
std::memcpy(&it, &*optLocalIt, sizeof(it));
FOLLY_SAFE_CHECK(
std::addressof(**optLocalIt) == std::addressof(*it),
"ABI-assuming local_iterator to iterator conversion failed");
return it;
return fromLocal<Iter>(*optLocalIt);
}
}
......
......@@ -116,7 +116,7 @@ class F14BasicSet
return std::make_pair(it, false);
}
auto rv = Super::emplace(std::forward<decltype(key)>(key));
FOLLY_SAFE_CHECK(
FOLLY_SAFE_DCHECK(
rv.second, "post-find emplace should always insert");
return rv;
} else {
......@@ -150,11 +150,30 @@ class F14BasicSet
template <typename K>
struct BottomKeyEqual {
[[noreturn]] bool operator()(K const&, K const&) const {
FOLLY_SAFE_CHECK(false, "bucket should not invoke key equality");
assume_unreachable();
}
};
template <typename Iter, typename LocalIter>
static std::
enable_if_t<std::is_constructible<Iter, LocalIter const&>::value, Iter>
fromLocal(LocalIter const& src, int = 0) {
return Iter(src);
}
template <typename Iter, typename LocalIter>
static std::
enable_if_t<!std::is_constructible<Iter, LocalIter const&>::value, Iter>
fromLocal(LocalIter const& src) {
Iter dst;
static_assert(sizeof(dst) <= sizeof(src), "");
std::memcpy(std::addressof(dst), std::addressof(src), sizeof(dst));
FOLLY_SAFE_CHECK(
std::addressof(*src) == std::addressof(*dst),
"ABI-assuming local_iterator to iterator conversion failed");
return dst;
}
template <typename Iter, typename Self, typename K>
static Iter findImpl(Self& self, K const& key) {
if (self.empty()) {
......@@ -171,13 +190,7 @@ class F14BasicSet
auto e = self.end(slot);
while (b != e) {
if (self.key_eq()(key, *b)) {
Iter it;
static_assert(sizeof(it) <= sizeof(b), "");
std::memcpy(&it, &b, sizeof(it));
FOLLY_SAFE_CHECK(
std::addressof(*b) == std::addressof(*it),
"ABI-assuming local_iterator to iterator conversion failed");
return it;
return fromLocal<Iter>(b);
}
++b;
}
......
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