Coverage Report

Created: 2025-08-25 06:55

/src/abseil-cpp/absl/container/internal/common_policy_traits.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2022 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
#ifndef ABSL_CONTAINER_INTERNAL_COMMON_POLICY_TRAITS_H_
16
#define ABSL_CONTAINER_INTERNAL_COMMON_POLICY_TRAITS_H_
17
18
#include <cstddef>
19
#include <cstring>
20
#include <memory>
21
#include <new>
22
#include <type_traits>
23
#include <utility>
24
25
#include "absl/meta/type_traits.h"
26
27
namespace absl {
28
ABSL_NAMESPACE_BEGIN
29
namespace container_internal {
30
31
template <class Policy, class = void>
32
struct policy_trait_element_is_owner : std::false_type {};
33
34
template <class Policy>
35
struct policy_trait_element_is_owner<
36
    Policy,
37
    std::enable_if_t<!std::is_void<typename Policy::element_is_owner>::value>>
38
    : Policy::element_is_owner {};
39
40
// Defines how slots are initialized/destroyed/moved.
41
template <class Policy, class = void>
42
struct common_policy_traits {
43
  // The actual object stored in the container.
44
  using slot_type = typename Policy::slot_type;
45
  using reference = decltype(Policy::element(std::declval<slot_type*>()));
46
  using value_type = typename std::remove_reference<reference>::type;
47
48
  // PRECONDITION: `slot` is UNINITIALIZED
49
  // POSTCONDITION: `slot` is INITIALIZED
50
  template <class Alloc, class... Args>
51
16
  static void construct(Alloc* alloc, slot_type* slot, Args&&... args) {
52
16
    Policy::construct(alloc, slot, std::forward<Args>(args)...);
53
16
  }
void absl::container_internal::common_policy_traits<absl::container_internal::FlatHashMapPolicy<std::__1::basic_string_view<char, std::__1::char_traits<char> >, absl::CommandLineFlag*>, void>::construct<std::__1::allocator<std::__1::pair<std::__1::basic_string_view<char, std::__1::char_traits<char> > const, absl::CommandLineFlag*> >, std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string_view<char, std::__1::char_traits<char> > const&&>, std::__1::tuple<absl::CommandLineFlag*&&> >(std::__1::allocator<std::__1::pair<std::__1::basic_string_view<char, std::__1::char_traits<char> > const, absl::CommandLineFlag*> >*, absl::container_internal::map_slot_type<std::__1::basic_string_view<char, std::__1::char_traits<char> >, absl::CommandLineFlag*>*, std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string_view<char, std::__1::char_traits<char> > const&&>&&, std::__1::tuple<absl::CommandLineFlag*&&>&&)
Line
Count
Source
51
16
  static void construct(Alloc* alloc, slot_type* slot, Args&&... args) {
52
16
    Policy::construct(alloc, slot, std::forward<Args>(args)...);
53
16
  }
Unexecuted instantiation: void absl::container_internal::common_policy_traits<absl::container_internal::FlatHashMapPolicy<std::__1::basic_string_view<char, std::__1::char_traits<char> >, absl::CommandLineFlag*>, void>::construct<std::__1::allocator<std::__1::pair<std::__1::basic_string_view<char, std::__1::char_traits<char> > const, absl::CommandLineFlag*> >, std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string_view<char, std::__1::char_traits<char> >&&>, std::__1::tuple<absl::CommandLineFlag*&&> >(std::__1::allocator<std::__1::pair<std::__1::basic_string_view<char, std::__1::char_traits<char> > const, absl::CommandLineFlag*> >*, absl::container_internal::map_slot_type<std::__1::basic_string_view<char, std::__1::char_traits<char> >, absl::CommandLineFlag*>*, std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string_view<char, std::__1::char_traits<char> >&&>&&, std::__1::tuple<absl::CommandLineFlag*&&>&&)
54
55
  // PRECONDITION: `slot` is INITIALIZED
56
  // POSTCONDITION: `slot` is UNINITIALIZED
57
  // Returns std::true_type in case destroy is trivial.
58
  template <class Alloc>
59
0
  static auto destroy(Alloc* alloc, slot_type* slot) {
60
0
    return Policy::destroy(alloc, slot);
61
0
  }
62
63
  // Transfers the `old_slot` to `new_slot`. Any memory allocated by the
64
  // allocator inside `old_slot` to `new_slot` can be transferred.
65
  //
66
  // OPTIONAL: defaults to:
67
  //
68
  //     clone(new_slot, std::move(*old_slot));
69
  //     destroy(old_slot);
70
  //
71
  // PRECONDITION: `new_slot` is UNINITIALIZED and `old_slot` is INITIALIZED
72
  // POSTCONDITION: `new_slot` is INITIALIZED and `old_slot` is
73
  //                UNINITIALIZED
74
  template <class Alloc>
75
0
  static void transfer(Alloc* alloc, slot_type* new_slot, slot_type* old_slot) {
76
0
    transfer_impl(alloc, new_slot, old_slot, Rank2{});
77
0
  }
78
79
  // PRECONDITION: `slot` is INITIALIZED
80
  // POSTCONDITION: `slot` is INITIALIZED
81
  // Note: we use remove_const_t so that the two overloads have different args
82
  // in the case of sets with explicitly const value_types.
83
  template <class P = Policy>
84
  static auto element(absl::remove_const_t<slot_type>* slot)
85
30
      -> decltype(P::element(slot)) {
86
30
    return P::element(slot);
87
30
  }
88
  template <class P = Policy>
89
  static auto element(const slot_type* slot) -> decltype(P::element(slot)) {
90
    return P::element(slot);
91
  }
92
93
0
  static constexpr bool transfer_uses_memcpy() {
94
0
    return std::is_same<decltype(transfer_impl<std::allocator<char>>(
95
0
                            nullptr, nullptr, nullptr, Rank2{})),
96
0
                        std::true_type>::value;
97
0
  }
98
99
  // Returns true if destroy is trivial and can be omitted.
100
  template <class Alloc>
101
0
  static constexpr bool destroy_is_trivial() {
102
0
    return std::is_same<decltype(destroy<Alloc>(nullptr, nullptr)),
103
0
                        std::true_type>::value;
104
0
  }
105
106
 private:
107
  // Use go/ranked-overloads for dispatching.
108
  struct Rank0 {};
109
  struct Rank1 : Rank0 {};
110
  struct Rank2 : Rank1 {};
111
112
  // Use auto -> decltype as an enabler.
113
  // P::transfer returns std::true_type if transfer uses memcpy (e.g. in
114
  // node_slot_policy).
115
  template <class Alloc, class P = Policy>
116
  static auto transfer_impl(Alloc* alloc, slot_type* new_slot,
117
                            slot_type* old_slot,
118
                            Rank2) -> decltype(P::transfer(alloc, new_slot,
119
0
                                                           old_slot)) {
120
0
    return P::transfer(alloc, new_slot, old_slot);
121
0
  }
122
123
  // This overload returns true_type for the trait below.
124
  // The conditional_t is to make the enabler type dependent.
125
  template <class Alloc,
126
            typename = std::enable_if_t<absl::is_trivially_relocatable<
127
                std::conditional_t<false, Alloc, value_type>>::value>>
128
  static std::true_type transfer_impl(Alloc*, slot_type* new_slot,
129
                                      slot_type* old_slot, Rank1) {
130
    // TODO(b/247130232): remove casts after fixing warnings.
131
    // TODO(b/251814870): remove casts after fixing warnings.
132
    std::memcpy(
133
        static_cast<void*>(std::launder(
134
            const_cast<std::remove_const_t<value_type>*>(&element(new_slot)))),
135
        static_cast<const void*>(&element(old_slot)), sizeof(value_type));
136
    return {};
137
  }
138
139
  template <class Alloc>
140
  static void transfer_impl(Alloc* alloc, slot_type* new_slot,
141
                            slot_type* old_slot, Rank0) {
142
    construct(alloc, new_slot, std::move(element(old_slot)));
143
    destroy(alloc, old_slot);
144
  }
145
};
146
147
}  // namespace container_internal
148
ABSL_NAMESPACE_END
149
}  // namespace absl
150
151
#endif  // ABSL_CONTAINER_INTERNAL_COMMON_POLICY_TRAITS_H_