summaryrefslogtreecommitdiff
path: root/absl/container/internal
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2019-01-09 09:55:36 -0800
committerGravatar Shaindel Schwartz <shaindel@google.com>2019-01-09 13:09:28 -0500
commit018b4db1d73ec8238e6dc4b17fd9e1fd7468d0ed (patch)
tree061373b7238a57c6765f147bbb96cefa5c83230b /absl/container/internal
parent9449ae94397f2fd683851348e25ed8c93f75b3b9 (diff)
Export of internal Abseil changes.
-- fd86c60bac6c41f1629ce1ab7dc1c8edff398a59 by Alex Strelnikov <strel@google.com>: Import PR: https://github.com/abseil/abseil-cpp/pull/243 Fix Windows ARM64 intrinsic use. PiperOrigin-RevId: 228535649 -- a0ca663f606a3b31493683e405be2b1cff450894 by CJ Johnson <johnsoncj@google.com>: Fixes issue of mixed signedness comparison PiperOrigin-RevId: 228535623 -- d71aaa1705d7303b43fe02088fe07b153e647796 by Shaindel Schwartz <shaindel@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 228534365 -- c1b49d361aa880198e071f93997724bddbcd4760 by Samuel Benzaquen <sbenza@google.com>: Internal cleanup PiperOrigin-RevId: 228406627 -- 0c4b1c2bed107698e209055b3431771d7a1bdba1 by Dave Walker <dawalker@google.com>: Add comments about the purpose of container_internal::slot_type. PiperOrigin-RevId: 228264537 -- 060aa6077d2f3a0a129149e0644d19f2f521b241 by Abseil Team <absl-team@google.com>: #include <cmath> in hashtablez_sampler.cc Expected to fix the android build. PiperOrigin-RevId: 228222550 GitOrigin-RevId: fd86c60bac6c41f1629ce1ab7dc1c8edff398a59 Change-Id: I26339fd4548c1a81b037cb52c26910d1bd850ea8
Diffstat (limited to 'absl/container/internal')
-rw-r--r--absl/container/internal/common.h48
-rw-r--r--absl/container/internal/container_memory.h27
-rw-r--r--absl/container/internal/hashtablez_sampler.cc1
-rw-r--r--absl/container/internal/raw_hash_map.h4
-rw-r--r--absl/container/internal/raw_hash_set.h29
5 files changed, 77 insertions, 32 deletions
diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h
new file mode 100644
index 00000000..a6dc9103
--- /dev/null
+++ b/absl/container/internal/common.h
@@ -0,0 +1,48 @@
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_CONTAINER_INTERNAL_CONTAINER_H_
+#define ABSL_CONTAINER_INTERNAL_CONTAINER_H_
+
+#include <type_traits>
+
+#include "absl/meta/type_traits.h"
+
+namespace absl {
+namespace container_internal {
+
+template <class, class = void>
+struct IsTransparent : std::false_type {};
+template <class T>
+struct IsTransparent<T, absl::void_t<typename T::is_transparent>>
+ : std::true_type {};
+
+template <bool is_transparent>
+struct KeyArg {
+ // Transparent. Forward `K`.
+ template <typename K, typename key_type>
+ using type = K;
+};
+
+template <>
+struct KeyArg<false> {
+ // Not transparent. Always use `key_type`.
+ template <typename K, typename key_type>
+ using type = key_type;
+};
+
+} // namespace container_internal
+} // namespace absl
+
+#endif // ABSL_CONTAINER_INTERNAL_CONTAINER_H_
diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h
index 56c5d2df..35b691ce 100644
--- a/absl/container/internal/container_memory.h
+++ b/absl/container/internal/container_memory.h
@@ -286,11 +286,30 @@ struct IsLayoutCompatible {
} // namespace memory_internal
-// If kMutableKeys is false, only the value member is accessed.
+// The internal storage type for key-value containers like flat_hash_map.
//
-// If kMutableKeys is true, key is accessed through all slots while value and
-// mutable_value are accessed only via INITIALIZED slots. Slots are created and
-// destroyed via mutable_value so that the key can be moved later.
+// It is convenient for the value_type of a flat_hash_map<K, V> to be
+// pair<const K, V>; the "const K" prevents accidental modification of the key
+// when dealing with the reference returned from find() and similar methods.
+// However, this creates other problems; we want to be able to emplace(K, V)
+// efficiently with move operations, and similarly be able to move a
+// pair<K, V> in insert().
+//
+// The solution is this union, which aliases the const and non-const versions
+// of the pair. This also allows flat_hash_map<const K, V> to work, even though
+// that has the same efficiency issues with move in emplace() and insert() -
+// but people do it anyway.
+//
+// If kMutableKeys is false, only the value member can be accessed.
+//
+// If kMutableKeys is true, key can be accessed through all slots while value
+// and mutable_value must be accessed only via INITIALIZED slots. Slots are
+// created and destroyed via mutable_value so that the key can be moved later.
+//
+// Accessing one of the union fields while the other is active is safe as
+// long as they are layout-compatible, which is guaranteed by the definition of
+// kMutableKeys. For C++11, the relevant section of the standard is
+// https://timsong-cpp.github.io/cppwp/n3337/class.mem#19 (9.2.19)
template <class K, class V>
union slot_type {
private:
diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc
index e588f24c..1ba95645 100644
--- a/absl/container/internal/hashtablez_sampler.cc
+++ b/absl/container/internal/hashtablez_sampler.cc
@@ -16,6 +16,7 @@
#include <atomic>
#include <cassert>
+#include <cmath>
#include <functional>
#include <limits>
diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h
index 05270ef3..e0f5c07c 100644
--- a/absl/container/internal/raw_hash_map.h
+++ b/absl/container/internal/raw_hash_map.h
@@ -39,8 +39,8 @@ class raw_hash_map : public raw_hash_set<Policy, Hash, Eq, Alloc> {
using MappedConstReference = decltype(P::value(
std::addressof(std::declval<typename raw_hash_map::const_reference>())));
- using KeyArgImpl = container_internal::KeyArg<IsTransparent<Eq>::value &&
- IsTransparent<Hash>::value>;
+ using KeyArgImpl =
+ KeyArg<IsTransparent<Eq>::value && IsTransparent<Hash>::value>;
public:
using key_type = typename Policy::key_type;
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 8cdea4ec..8f2350a7 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -105,6 +105,7 @@
#include "absl/base/internal/bits.h"
#include "absl/base/internal/endian.h"
#include "absl/base/port.h"
+#include "absl/container/internal/common.h"
#include "absl/container/internal/compressed_tuple.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/hash_policy_traits.h"
@@ -165,12 +166,6 @@ struct IsDecomposable<
std::declval<Ts>()...))>,
Policy, Hash, Eq, Ts...> : std::true_type {};
-template <class, class = void>
-struct IsTransparent : std::false_type {};
-template <class T>
-struct IsTransparent<T, absl::void_t<typename T::is_transparent>>
- : std::true_type {};
-
// TODO(alkis): Switch to std::is_nothrow_swappable when gcc/clang supports it.
template <class T>
constexpr bool IsNoThrowSwappable() {
@@ -605,24 +600,6 @@ struct insert_return_type {
NodeType node;
};
-// Helper trait to allow or disallow arbitrary keys when the hash and
-// eq functions are transparent.
-// It is very important that the inner template is an alias and that the type it
-// produces is not a dependent type. Otherwise, type deduction would fail.
-template <bool is_transparent>
-struct KeyArg {
- // Transparent. Forward `K`.
- template <typename K, typename key_type>
- using type = K;
-};
-
-template <>
-struct KeyArg<false> {
- // Not transparent. Always use `key_type`.
- template <typename K, typename key_type>
- using type = key_type;
-};
-
// Policy: a policy defines how to perform different operations on
// the slots of the hashtable (see hash_policy_traits.h for the full interface
// of policy).
@@ -643,8 +620,8 @@ struct KeyArg<false> {
template <class Policy, class Hash, class Eq, class Alloc>
class raw_hash_set {
using PolicyTraits = hash_policy_traits<Policy>;
- using KeyArgImpl = container_internal::KeyArg<IsTransparent<Eq>::value &&
- IsTransparent<Hash>::value>;
+ using KeyArgImpl =
+ KeyArg<IsTransparent<Eq>::value && IsTransparent<Hash>::value>;
public:
using init_type = typename PolicyTraits::init_type;