node_slot_policy.h 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. #ifndef ABSL_CONTAINER_INTERNAL_NODE_SLOT_POLICY_H_
  33. #define ABSL_CONTAINER_INTERNAL_NODE_SLOT_POLICY_H_
  34. #include <cassert>
  35. #include <cstddef>
  36. #include <memory>
  37. #include <type_traits>
  38. #include <utility>
  39. #include "absl/base/config.h"
  40. namespace absl {
  41. ABSL_NAMESPACE_BEGIN
  42. namespace container_internal {
  43. template <class Reference, class Policy>
  44. struct node_slot_policy {
  45. static_assert(std::is_lvalue_reference<Reference>::value, "");
  46. using slot_type = typename std::remove_cv<
  47. typename std::remove_reference<Reference>::type>::type*;
  48. template <class Alloc, class... Args>
  49. static void construct(Alloc* alloc, slot_type* slot, Args&&... args) {
  50. *slot = Policy::new_element(alloc, std::forward<Args>(args)...);
  51. }
  52. template <class Alloc>
  53. static void destroy(Alloc* alloc, slot_type* slot) {
  54. Policy::delete_element(alloc, *slot);
  55. }
  56. // Returns true_type to indicate that transfer can use memcpy.
  57. template <class Alloc>
  58. static std::true_type transfer(Alloc*, slot_type* new_slot,
  59. slot_type* old_slot) {
  60. *new_slot = *old_slot;
  61. return {};
  62. }
  63. static size_t space_used(const slot_type* slot) {
  64. if (slot == nullptr) return Policy::element_space_used(nullptr);
  65. return Policy::element_space_used(*slot);
  66. }
  67. static Reference element(slot_type* slot) { return **slot; }
  68. template <class T, class P = Policy>
  69. static auto value(T* elem) -> decltype(P::value(elem)) {
  70. return P::value(elem);
  71. }
  72. template <class... Ts, class P = Policy>
  73. static auto apply(Ts&&... ts) -> decltype(P::apply(std::forward<Ts>(ts)...)) {
  74. return P::apply(std::forward<Ts>(ts)...);
  75. }
  76. };
  77. } // namespace container_internal
  78. ABSL_NAMESPACE_END
  79. } // namespace absl
  80. #endif // ABSL_CONTAINER_INTERNAL_NODE_SLOT_POLICY_H_