1 // Copyright 2018 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // Adapts a policy for nodes. 16 // 17 // The node policy should model: 18 // 19 // struct Policy { 20 // // Returns a new node allocated and constructed using the allocator, using 21 // // the specified arguments. 22 // template <class Alloc, class... Args> 23 // value_type* new_element(Alloc* alloc, Args&&... args) const; 24 // 25 // // Destroys and deallocates node using the allocator. 26 // template <class Alloc> 27 // void delete_element(Alloc* alloc, value_type* node) const; 28 // }; 29 // 30 // It may also optionally define `value()` and `apply()`. For documentation on 31 // these, see hash_policy_traits.h. 32 33 #ifndef ABSL_CONTAINER_INTERNAL_NODE_HASH_POLICY_H_ 34 #define ABSL_CONTAINER_INTERNAL_NODE_HASH_POLICY_H_ 35 36 #include <cassert> 37 #include <cstddef> 38 #include <memory> 39 #include <type_traits> 40 #include <utility> 41 42 #include "absl/base/config.h" 43 44 namespace absl { 45 ABSL_NAMESPACE_BEGIN 46 namespace container_internal { 47 48 template <class Reference, class Policy> 49 struct node_hash_policy { 50 static_assert(std::is_lvalue_reference<Reference>::value, ""); 51 52 using slot_type = typename std::remove_cv< 53 typename std::remove_reference<Reference>::type>::type*; 54 55 template <class Alloc, class... Args> constructnode_hash_policy56 static void construct(Alloc* alloc, slot_type* slot, Args&&... args) { 57 *slot = Policy::new_element(alloc, std::forward<Args>(args)...); 58 } 59 60 template <class Alloc> destroynode_hash_policy61 static void destroy(Alloc* alloc, slot_type* slot) { 62 Policy::delete_element(alloc, *slot); 63 } 64 65 template <class Alloc> transfernode_hash_policy66 static void transfer(Alloc*, slot_type* new_slot, slot_type* old_slot) { 67 *new_slot = *old_slot; 68 } 69 space_usednode_hash_policy70 static size_t space_used(const slot_type* slot) { 71 if (slot == nullptr) return Policy::element_space_used(nullptr); 72 return Policy::element_space_used(*slot); 73 } 74 elementnode_hash_policy75 static Reference element(slot_type* slot) { return **slot; } 76 77 template <class T, class P = Policy> 78 static auto value(T* elem) -> decltype(P::value(elem)) { 79 return P::value(elem); 80 } 81 82 template <class... Ts, class P = Policy> 83 static auto apply(Ts&&... ts) -> decltype(P::apply(std::forward<Ts>(ts)...)) { 84 return P::apply(std::forward<Ts>(ts)...); 85 } 86 }; 87 88 } // namespace container_internal 89 ABSL_NAMESPACE_END 90 } // namespace absl 91 92 #endif // ABSL_CONTAINER_INTERNAL_NODE_HASH_POLICY_H_ 93