File indexing completed on 2025-01-18 09:27:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef ABSL_CONTAINER_INTERNAL_COMMON_POLICY_TRAITS_H_
0016 #define ABSL_CONTAINER_INTERNAL_COMMON_POLICY_TRAITS_H_
0017
0018 #include <cstddef>
0019 #include <cstring>
0020 #include <memory>
0021 #include <new>
0022 #include <type_traits>
0023 #include <utility>
0024
0025 #include "absl/meta/type_traits.h"
0026
0027 namespace absl {
0028 ABSL_NAMESPACE_BEGIN
0029 namespace container_internal {
0030
0031
0032 template <class Policy, class = void>
0033 struct common_policy_traits {
0034
0035 using slot_type = typename Policy::slot_type;
0036 using reference = decltype(Policy::element(std::declval<slot_type*>()));
0037 using value_type = typename std::remove_reference<reference>::type;
0038
0039
0040
0041 template <class Alloc, class... Args>
0042 static void construct(Alloc* alloc, slot_type* slot, Args&&... args) {
0043 Policy::construct(alloc, slot, std::forward<Args>(args)...);
0044 }
0045
0046
0047
0048
0049 template <class Alloc>
0050 static auto destroy(Alloc* alloc, slot_type* slot) {
0051 return Policy::destroy(alloc, slot);
0052 }
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 template <class Alloc>
0066 static void transfer(Alloc* alloc, slot_type* new_slot, slot_type* old_slot) {
0067 transfer_impl(alloc, new_slot, old_slot, Rank2{});
0068 }
0069
0070
0071
0072
0073
0074 template <class P = Policy>
0075 static auto element(absl::remove_const_t<slot_type>* slot)
0076 -> decltype(P::element(slot)) {
0077 return P::element(slot);
0078 }
0079 template <class P = Policy>
0080 static auto element(const slot_type* slot) -> decltype(P::element(slot)) {
0081 return P::element(slot);
0082 }
0083
0084 static constexpr bool transfer_uses_memcpy() {
0085 return std::is_same<decltype(transfer_impl<std::allocator<char>>(
0086 nullptr, nullptr, nullptr, Rank2{})),
0087 std::true_type>::value;
0088 }
0089
0090
0091 template <class Alloc>
0092 static constexpr bool destroy_is_trivial() {
0093 return std::is_same<decltype(destroy<Alloc>(nullptr, nullptr)),
0094 std::true_type>::value;
0095 }
0096
0097 private:
0098
0099 struct Rank0 {};
0100 struct Rank1 : Rank0 {};
0101 struct Rank2 : Rank1 {};
0102
0103
0104
0105
0106 template <class Alloc, class P = Policy>
0107 static auto transfer_impl(Alloc* alloc, slot_type* new_slot,
0108 slot_type* old_slot,
0109 Rank2) -> decltype(P::transfer(alloc, new_slot,
0110 old_slot)) {
0111 return P::transfer(alloc, new_slot, old_slot);
0112 }
0113 #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
0114
0115
0116 template <class Alloc,
0117 typename = std::enable_if_t<absl::is_trivially_relocatable<
0118 std::conditional_t<false, Alloc, value_type>>::value>>
0119 static std::true_type transfer_impl(Alloc*, slot_type* new_slot,
0120 slot_type* old_slot, Rank1) {
0121
0122
0123 std::memcpy(
0124 static_cast<void*>(std::launder(
0125 const_cast<std::remove_const_t<value_type>*>(&element(new_slot)))),
0126 static_cast<const void*>(&element(old_slot)), sizeof(value_type));
0127 return {};
0128 }
0129 #endif
0130
0131 template <class Alloc>
0132 static void transfer_impl(Alloc* alloc, slot_type* new_slot,
0133 slot_type* old_slot, Rank0) {
0134 construct(alloc, new_slot, std::move(element(old_slot)));
0135 destroy(alloc, old_slot);
0136 }
0137 };
0138
0139 }
0140 ABSL_NAMESPACE_END
0141 }
0142
0143 #endif