Export of internal Abseil changes
-- 0f6565955231dc74ebad62ef32a18c457afa2dc7 by Abseil Team <absl-team@google.com>: Document guarantee that we do not move from rvalue arguments if no insertion happens with absl::raw_hash_map::try_emplace, as done with std::unordered_map::try_emplace. PiperOrigin-RevId: 264430409 -- 292e6b9e08fa689e8400d7f2db94cbcab29d5889 by CJ Johnson <johnsoncj@google.com>: Removes use of aligned_storage in FixedArray and InlinedVector in favor of aligned char buffers. PiperOrigin-RevId: 264385559 -- aa0b19ad11ae5702022feee0e2e6434cfb28c9e9 by Derek Mauro <dmauro@google.com>: Make the unit tests for absl::any, absl::optional, and absl::variant no-ops when these types are just aliases for the corresponding std:: types. We have no way to fix standard library implementation bugs, so don't bother working around them. Also disable the corresponding exception-safety tests as well when exceptions are not enabled. Fixes https://github.com/abseil/abseil-cpp/pull/360 PiperOrigin-RevId: 264382050 -- 65896a911f36481b89b4712c83b91c90a76b64e8 by Abseil Team <absl-team@google.com>: Improve documentation on erase PiperOrigin-RevId: 264381266 GitOrigin-RevId: 0f6565955231dc74ebad62ef32a18c457afa2dc7 Change-Id: I74b9bd2ddf84526014104f17e87de70bd3fe65fa
This commit is contained in:
parent
0e7afdcbd2
commit
f0afae0d49
20 changed files with 140 additions and 30 deletions
|
|
@ -19,6 +19,7 @@
|
|||
#define ABSL_CONTAINER_INTERNAL_HASH_GENERATOR_TESTING_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iosfwd>
|
||||
#include <random>
|
||||
|
|
@ -27,6 +28,7 @@
|
|||
#include <utility>
|
||||
|
||||
#include "absl/container/internal/hash_policy_testing.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
|
|
@ -129,6 +131,13 @@ struct Generator<std::tuple<Ts...>> {
|
|||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct Generator<std::unique_ptr<T>> {
|
||||
std::unique_ptr<T> operator()() const {
|
||||
return absl::make_unique<T>(Generator<T>()());
|
||||
}
|
||||
};
|
||||
|
||||
template <class U>
|
||||
struct Generator<U, absl::void_t<decltype(std::declval<U&>().key()),
|
||||
decltype(std::declval<U&>().value())>>
|
||||
|
|
|
|||
|
|
@ -445,9 +445,7 @@ class Storage {
|
|||
};
|
||||
|
||||
struct Inlined {
|
||||
using InlinedDataElement =
|
||||
absl::aligned_storage_t<sizeof(value_type), alignof(value_type)>;
|
||||
InlinedDataElement inlined_data[N];
|
||||
alignas(value_type) char inlined_data[sizeof(value_type[N])];
|
||||
};
|
||||
|
||||
union Data {
|
||||
|
|
|
|||
|
|
@ -109,6 +109,9 @@ class raw_hash_map : public raw_hash_set<Policy, Hash, Eq, Alloc> {
|
|||
return insert_or_assign(k, v).first;
|
||||
}
|
||||
|
||||
// All `try_emplace()` overloads make the same guarantees regarding rvalue
|
||||
// arguments as `std::unordered_map::try_emplace()`, namely that these
|
||||
// functions will not move from rvalue arguments if insertions do not happen.
|
||||
template <class K = key_type, class... Args,
|
||||
typename std::enable_if<
|
||||
!std::is_convertible<K, const_iterator>::value, int>::type = 0,
|
||||
|
|
|
|||
|
|
@ -1133,15 +1133,16 @@ class raw_hash_set {
|
|||
}
|
||||
|
||||
// Erases the element pointed to by `it`. Unlike `std::unordered_set::erase`,
|
||||
// this method returns void to reduce algorithmic complexity to O(1). In
|
||||
// order to erase while iterating across a map, use the following idiom (which
|
||||
// also works for standard containers):
|
||||
// this method returns void to reduce algorithmic complexity to O(1). The
|
||||
// iterator is invalidated, so any increment should be done before calling
|
||||
// erase. In order to erase while iterating across a map, use the following
|
||||
// idiom (which also works for standard containers):
|
||||
//
|
||||
// for (auto it = m.begin(), end = m.end(); it != end;) {
|
||||
// // `erase()` will invalidate `it`, so advance `it` first.
|
||||
// auto copy_it = it++;
|
||||
// if (<pred>) {
|
||||
// m.erase(it++);
|
||||
// } else {
|
||||
// ++it;
|
||||
// m.erase(copy_it);
|
||||
// }
|
||||
// }
|
||||
void erase(const_iterator cit) { erase(cit.inner_); }
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
#ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MODIFIERS_TEST_H_
|
||||
#define ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MODIFIERS_TEST_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/container/internal/hash_generator_testing.h"
|
||||
|
|
@ -267,6 +269,45 @@ REGISTER_TYPED_TEST_CASE_P(ModifiersTest, Clear, Insert, InsertHint,
|
|||
Emplace, EmplaceHint, TryEmplace, TryEmplaceHint,
|
||||
Erase, EraseRange, EraseKey, Swap);
|
||||
|
||||
template <typename Type>
|
||||
struct is_unique_ptr : std::false_type {};
|
||||
|
||||
template <typename Type>
|
||||
struct is_unique_ptr<std::unique_ptr<Type>> : std::true_type {};
|
||||
|
||||
template <class UnordMap>
|
||||
class UniquePtrModifiersTest : public ::testing::Test {
|
||||
protected:
|
||||
UniquePtrModifiersTest() {
|
||||
static_assert(is_unique_ptr<typename UnordMap::mapped_type>::value,
|
||||
"UniquePtrModifiersTyest may only be called with a "
|
||||
"std::unique_ptr value type.");
|
||||
}
|
||||
};
|
||||
|
||||
TYPED_TEST_SUITE_P(UniquePtrModifiersTest);
|
||||
|
||||
// Test that we do not move from rvalue arguments if an insertion does not
|
||||
// happen.
|
||||
TYPED_TEST_P(UniquePtrModifiersTest, TryEmplace) {
|
||||
#ifdef UNORDERED_MAP_CXX17
|
||||
using T = hash_internal::GeneratedType<TypeParam>;
|
||||
using V = typename TypeParam::mapped_type;
|
||||
T val = hash_internal::Generator<T>()();
|
||||
TypeParam m;
|
||||
auto p = m.try_emplace(val.first, std::move(val.second));
|
||||
EXPECT_TRUE(p.second);
|
||||
// A moved from std::unique_ptr is guaranteed to be nullptr.
|
||||
EXPECT_EQ(val.second, nullptr);
|
||||
T val2 = {val.first, hash_internal::Generator<V>()()};
|
||||
p = m.try_emplace(val2.first, std::move(val2.second));
|
||||
EXPECT_FALSE(p.second);
|
||||
EXPECT_NE(val2.second, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_SUITE_P(UniquePtrModifiersTest, TryEmplace);
|
||||
|
||||
} // namespace container_internal
|
||||
} // namespace absl
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "absl/container/internal/unordered_map_constructor_test.h"
|
||||
|
|
@ -35,6 +36,13 @@ INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedMap, LookupTest, MapTypes);
|
|||
INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedMap, MembersTest, MapTypes);
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedMap, ModifiersTest, MapTypes);
|
||||
|
||||
using UniquePtrMapTypes = ::testing::Types<std::unordered_map<
|
||||
int, std::unique_ptr<int>, StatefulTestingHash, StatefulTestingEqual,
|
||||
Alloc<std::pair<const int, std::unique_ptr<int>>>>>;
|
||||
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedMap, UniquePtrModifiersTest,
|
||||
UniquePtrMapTypes);
|
||||
|
||||
} // namespace
|
||||
} // namespace container_internal
|
||||
} // namespace absl
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue