Go to the documentation of this file.
15 #ifndef ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_
16 #define ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_
23 #include <type_traits>
26 #include "absl/base/config.h"
27 #include "absl/memory/memory.h"
28 #include "absl/meta/type_traits.h"
29 #include "absl/utility/utility.h"
31 #ifdef ABSL_HAVE_ADDRESS_SANITIZER
32 #include <sanitizer/asan_interface.h>
35 #ifdef ABSL_HAVE_MEMORY_SANITIZER
36 #include <sanitizer/msan_interface.h>
41 namespace container_internal {
43 template <
size_t Alignment>
53 template <
size_t Alignment,
class Alloc>
55 static_assert(Alignment > 0,
"");
56 assert(
n &&
"n must be positive");
64 void* p = AT::allocate(my_mem_alloc, (
n +
sizeof(M) - 1) /
sizeof(M));
65 assert(
reinterpret_cast<uintptr_t>(p) % Alignment == 0 &&
66 "allocator does not respect alignment");
72 template <
size_t Alignment,
class Alloc>
74 static_assert(Alignment > 0,
"");
75 assert(
n &&
"n must be positive");
83 AT::deallocate(my_mem_alloc,
static_cast<M*
>(p),
84 (
n +
sizeof(M) - 1) /
sizeof(M));
87 namespace memory_internal {
91 template <
class Alloc,
class T,
class Tuple,
size_t...
I>
95 *
alloc,
ptr, std::get<I>(std::forward<Tuple>(t))...);
98 template <
class T,
class F>
100 template <
class...
Args>
101 decltype(std::declval<F>()(std::declval<T>())) operator()(
103 return std::forward<F>(f)(
T(std::forward<Args>(
args)...));
108 template <
class T,
class Tuple,
size_t... Is,
class F>
112 std::get<Is>(std::forward<Tuple>(t))...);
115 template <
class T,
size_t... Is>
117 -> decltype(std::forward_as_tuple(std::get<Is>(std::forward<T>(t))...)) {
118 return std::forward_as_tuple(std::get<Is>(std::forward<T>(t))...);
134 template <
class F,
class K,
class V>
135 decltype(std::declval<F>()(std::declval<const K&>(), std::piecewise_construct,
136 std::declval<std::tuple<K>>(), std::declval<V>()))
138 const auto&
key = std::get<0>(p.first);
139 return std::forward<F>(f)(
key, std::piecewise_construct,
std::move(p.first),
147 template <
class Alloc,
class T,
class Tuple>
157 template <
class T,
class Tuple,
class F>
160 return memory_internal::WithConstructedImpl<T>(
161 std::forward<Tuple>(t),
178 inline std::pair<std::tuple<>, std::tuple<>>
PairArgs() {
return {}; }
179 template <
class F,
class S>
180 std::pair<std::tuple<F&&>, std::tuple<S&&>>
PairArgs(F&& f,
S&& s) {
181 return {std::piecewise_construct, std::forward_as_tuple(std::forward<F>(f)),
182 std::forward_as_tuple(std::forward<S>(
s))};
184 template <
class F,
class S>
185 std::pair<std::tuple<const F&>, std::tuple<const S&>>
PairArgs(
186 const std::pair<F, S>& p) {
189 template <
class F,
class S>
190 std::pair<std::tuple<F&&>, std::tuple<S&&>>
PairArgs(std::pair<F, S>&& p) {
191 return PairArgs(std::forward<F>(p.first), std::forward<S>(p.second));
193 template <
class F,
class S>
202 template <
class F,
class...
Args>
205 std::forward<F>(f),
PairArgs(std::forward<Args>(
args)...))) {
207 std::forward<F>(f),
PairArgs(std::forward<Args>(
args)...));
211 template <
class F,
class Arg>
212 decltype(std::declval<F>()(std::declval<const Arg&>(), std::declval<Arg>()))
215 return std::forward<F>(f)(
key, std::forward<Arg>(
arg));
220 #ifdef ABSL_HAVE_ADDRESS_SANITIZER
221 ASAN_POISON_MEMORY_REGION(
m,
s);
223 #ifdef ABSL_HAVE_MEMORY_SANITIZER
231 #ifdef ABSL_HAVE_ADDRESS_SANITIZER
232 ASAN_UNPOISON_MEMORY_REGION(
m,
s);
234 #ifdef ABSL_HAVE_MEMORY_SANITIZER
235 __msan_unpoison(
m,
s);
241 template <
typename T>
246 template <
typename T>
251 namespace memory_internal {
259 template <
class Pair,
class = std::true_type>
261 static constexpr
size_t kFirst =
static_cast<size_t>(-1);
262 static constexpr
size_t kSecond =
static_cast<size_t>(-1);
265 template <
class Pair>
271 template <
class K,
class V>
282 return std::is_standard_layout<P>() &&
sizeof(
P) ==
sizeof(
Pair) &&
283 alignof(
P) ==
alignof(
Pair) &&
293 static constexpr
bool value = std::is_standard_layout<K>() &&
294 std::is_standard_layout<Pair>() &&
296 LayoutCompatible<std::pair<K, V>>() &&
297 LayoutCompatible<std::pair<const K, V>>();
326 template <
class K,
class V>
339 template <
class K,
class V>
364 #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
365 static K& mutable_key(slot_type* slot) {
369 : *std::launder(
const_cast<K*
>(
370 std::addressof(slot->value.first)));
372 #else // !(defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606)
380 template <
class Allocator,
class...
Args>
385 std::forward<Args>(
args)...);
388 std::forward<Args>(
args)...);
393 template <
class Allocator>
406 template <
class Allocator>
414 template <
class Allocator>
423 template <
class Allocator>
442 #endif // ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_
static void destroy(Allocator *alloc, slot_type *slot)
static void construct(Allocator *alloc, slot_type *slot, slot_type *other)
decltype(std::declval< F >()(std::declval< const Arg & >(), std::declval< Arg >())) DecomposeValue(F &&f, Arg &&arg)
std::pair< const K, V > value_type
auto DecomposePair(F &&f, Args &&... args) -> decltype(memory_internal::DecomposePairImpl(std::forward< F >(f), PairArgs(std::forward< Args >(args)...)))
void ConstructFromTuple(Alloc *alloc, T *ptr, Tuple &&t)
#define ABSL_NAMESPACE_END
Arg(64) -> Arg(128) ->Arg(256) ->Arg(512) ->Arg(1024) ->Arg(1536) ->Arg(2048) ->Arg(3072) ->Arg(4096) ->Arg(5120) ->Arg(6144) ->Arg(7168)
static void construct(Alloc &a, T *p, Args &&... args)
std::pair< const K, V > value_type
#define T(upbtypeconst, upbtype, ctype, default_value)
typename std::remove_const< T >::type remove_const_t
#define ABSL_NAMESPACE_BEGIN
std::pair< std::tuple<>, std::tuple<> > PairArgs()
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
void Deallocate(Alloc *alloc, void *p, size_t n)
make_integer_sequence< size_t, N > make_index_sequence
void SanitizerUnpoisonMemoryRegion(const void *m, size_t s)
static constexpr bool LayoutCompatible()
absl::remove_const_t< K > key
static const K & mutable_key(slot_type *slot)
static void emplace(slot_type *slot)
static void construct(Allocator *alloc, slot_type *slot, const slot_type *other)
static void transfer(Allocator *alloc, slot_type *new_slot, slot_type *old_slot)
void * Alloc(FlagOpFn op)
static value_type & element(slot_type *slot)
_W64 unsigned int uintptr_t
internal::PairMatcher< FirstMatcher, SecondMatcher > Pair(FirstMatcher first_matcher, SecondMatcher second_matcher)
mutable_value_type mutable_value
void SanitizerPoisonMemoryRegion(const void *m, size_t s)
auto TupleRefImpl(T &&t, absl::index_sequence< Is... >) -> decltype(std::forward_as_tuple(std::get< Is >(std::forward< T >(t))...))
auto TupleRef(T &&t) -> decltype(TupleRefImpl(std::forward< T >(t), absl::make_index_sequence< std::tuple_size< typename std::decay< T >::type >::value >()))
decltype(std::declval< F >()(std::declval< T >())) WithConstructed(Tuple &&t, F &&f)
std::pair< absl::remove_const_t< K >, absl::remove_const_t< V > > mutable_value_type
decltype(std::declval< F >()(std::declval< const K & >(), std::piecewise_construct, std::declval< std::tuple< K >>(), std::declval< V >())) DecomposePairImpl(F &&f, std::pair< std::tuple< K >, V > p)
decltype(std::declval< F >()(std::declval< T >())) WithConstructedImpl(Tuple &&t, absl::index_sequence< Is... >, F &&f)
void SanitizerPoisonObject(const T *object)
static const K & key(const slot_type *slot)
void * Allocate(Alloc *alloc, size_t n)
void ConstructFromTupleImpl(Alloc *alloc, T *ptr, Tuple &&t, absl::index_sequence< I... >)
static void destroy(Alloc &a, T *p)
std::function< Poll< absl::StatusOr< T > >()> P
static void construct(Allocator *alloc, slot_type *slot, Args &&... args)
std::pair< std::string, std::string > pair
static const value_type & element(const slot_type *slot)
std::pair< K, V > mutable_value_type
void SanitizerUnpoisonObject(const T *object)
std::allocator< int > alloc
static std::function< void(void *, Slot *)> destroy
grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:01