15 #ifndef ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_ 16 #define ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_ 18 #ifdef ADDRESS_SANITIZER 19 #include <sanitizer/asan_interface.h> 22 #ifdef MEMORY_SANITIZER 23 #include <sanitizer/msan_interface.h> 30 #include <type_traits> 37 namespace container_internal {
46 template <
size_t Alignment,
class Alloc>
48 static_assert(Alignment > 0,
"");
49 assert(n &&
"n must be positive");
50 struct alignas(Alignment) M {};
54 void* p = AT::allocate(mem_alloc, (n +
sizeof(M) - 1) /
sizeof(M));
55 assert(reinterpret_cast<uintptr_t>(p) % Alignment == 0 &&
56 "allocator does not respect alignment");
62 template <
size_t Alignment,
class Alloc>
64 static_assert(Alignment > 0,
"");
65 assert(n &&
"n must be positive");
66 struct alignas(Alignment) M {};
70 AT::deallocate(mem_alloc, static_cast<M*>(p),
71 (n +
sizeof(M) - 1) /
sizeof(M));
74 namespace memory_internal {
78 template <
class Alloc,
class T,
class Tuple,
size_t... I>
82 *alloc, ptr, std::get<I>(std::forward<Tuple>(t))...);
85 template <
class T,
class F>
87 template <
class... Args>
88 decltype(std::declval<F>()(std::declval<T>())) operator()(
89 Args&&... args)
const {
90 return std::forward<F>(f)(T(std::forward<Args>(args)...));
95 template <
class T,
class Tuple,
size_t... Is,
class F>
99 std::get<Is>(std::forward<Tuple>(t))...);
102 template <
class T,
size_t... Is>
104 -> decltype(std::forward_as_tuple(std::get<Is>(std::forward<T>(t))...)) {
105 return std::forward_as_tuple(std::get<Is>(std::forward<T>(t))...);
114 std::tuple_size<
typename std::decay<T>::type>::
value>())) {
118 std::tuple_size<
typename std::decay<T>::type>::
value>());
121 template <
class F,
class K,
class V>
122 decltype(std::declval<F>()(std::declval<const K&>(), std::piecewise_construct,
123 std::declval<std::tuple<K>>(), std::declval<V>()))
125 const auto& key = std::get<0>(p.first);
126 return std::forward<F>(f)(key, std::piecewise_construct,
std::move(p.first),
134 template <
class Alloc,
class T,
class Tuple>
137 alloc, ptr, std::forward<Tuple>(t),
139 std::tuple_size<
typename std::decay<Tuple>::type>::
value>());
144 template <
class T,
class Tuple,
class F>
147 return memory_internal::WithConstructedImpl<T>(
148 std::forward<Tuple>(t),
150 std::tuple_size<
typename std::decay<Tuple>::type>::
value>(),
165 inline std::pair<std::tuple<>, std::tuple<>>
PairArgs() {
return {}; }
166 template <
class F,
class S>
167 std::pair<std::tuple<F&&>, std::tuple<S&&>>
PairArgs(F&& f, S&& s) {
168 return {std::piecewise_construct, std::forward_as_tuple(std::forward<F>(f)),
169 std::forward_as_tuple(std::forward<S>(s))};
171 template <
class F,
class S>
172 std::pair<std::tuple<const F&>, std::tuple<const S&>>
PairArgs(
173 const std::pair<F, S>& p) {
176 template <
class F,
class S>
177 std::pair<std::tuple<F&&>, std::tuple<S&&>>
PairArgs(std::pair<F, S>&& p) {
178 return PairArgs(std::forward<F>(p.first), std::forward<S>(p.second));
180 template <
class F,
class S>
181 auto PairArgs(std::piecewise_construct_t, F&& f, S&& s)
189 template <
class F,
class... Args>
192 std::forward<F>(f),
PairArgs(std::forward<Args>(args)...))) {
194 std::forward<F>(f),
PairArgs(std::forward<Args>(args)...));
198 template <
class F,
class Arg>
199 decltype(std::declval<F>()(std::declval<const Arg&>(), std::declval<Arg>()))
201 const auto& key =
arg;
202 return std::forward<F>(f)(key, std::forward<Arg>(arg));
207 #ifdef ADDRESS_SANITIZER 208 ASAN_POISON_MEMORY_REGION(m, s);
210 #ifdef MEMORY_SANITIZER 218 #ifdef ADDRESS_SANITIZER 219 ASAN_UNPOISON_MEMORY_REGION(m, s);
221 #ifdef MEMORY_SANITIZER 222 __msan_unpoison(m, s);
228 template <
typename T>
233 template <
typename T>
238 namespace memory_internal {
246 template <
class Pair,
class = std::true_type>
248 static constexpr
size_t kFirst = -1;
249 static constexpr
size_t kSecond = -1;
252 template <
class Pair>
253 struct OffsetOf<Pair, typename
std::is_standard_layout<Pair>::type> {
254 static constexpr
size_t kFirst = offsetof(Pair, first);
255 static constexpr
size_t kSecond = offsetof(Pair, second);
258 template <
class K,
class V>
269 return std::is_standard_layout<P>() &&
sizeof(P) ==
sizeof(
Pair) &&
270 alignof(P) ==
alignof(
Pair) &&
280 static constexpr
bool value = std::is_standard_layout<K>() &&
281 std::is_standard_layout<Pair>() &&
283 LayoutCompatible<std::pair<K, V>>() &&
284 LayoutCompatible<std::pair<const K, V>>();
313 template <
class K,
class V>
325 template <
class K,
class V>
352 template <
class Allocator,
class... Args>
357 std::forward<Args>(args)...);
360 std::forward<Args>(args)...);
365 template <
class Allocator>
377 template <
class Allocator>
386 template <
class Allocator>
400 template <
class Allocator>
416 template <
class Allocator>
427 template <
class Allocator>
430 for (
slot_type *src = first, *dest = result; src != last; ++src, ++dest)
431 move(alloc, src, dest);
438 #endif // ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_
void * Allocate(Alloc *alloc, size_t n)
void ConstructFromTuple(Alloc *alloc, T *ptr, Tuple &&t)
static constexpr bool LayoutCompatible()
static void move(Allocator *alloc, slot_type *src, slot_type *dest)
decltype(std::declval< F >()(std::declval< const Arg & >(), std::declval< Arg >())) DecomposeValue(F &&f, Arg &&arg)
static void destroy(Alloc &a, T *p)
void ConstructFromTupleImpl(Alloc *alloc, T *ptr, Tuple &&t, absl::index_sequence< I... >)
std::pair< const K, V > value_type
std::pair< const K, V > value_type
std::pair< K, V > mutable_value_type
static const value_type & element(const slot_type *slot)
make_integer_sequence< size_t, N > make_index_sequence
static std::function< void(void *, Slot *)> destroy
static void construct(Allocator *alloc, slot_type *slot, slot_type *other)
static void destroy(Allocator *alloc, slot_type *slot)
void SanitizerUnpoisonMemoryRegion(const void *m, size_t s)
std::pair< std::tuple<>, std::tuple<> > PairArgs()
std::pair< std::string, std::string > pair
std::pair< K, V > mutable_value_type
void swap(absl::InlinedVector< T, N, A > &a, absl::InlinedVector< T, N, A > &b) noexcept(noexcept(a.swap(b)))
auto DecomposePair(F &&f, Args &&...args) -> decltype(memory_internal::DecomposePairImpl(std::forward< F >(f), PairArgs(std::forward< Args >(args)...)))
static void construct(Allocator *alloc, slot_type *slot, Args &&...args)
static void move(Allocator *alloc, slot_type *first, slot_type *last, slot_type *result)
void SanitizerPoisonMemoryRegion(const void *m, size_t s)
static const K & key(const slot_type *slot)
void Deallocate(Alloc *alloc, void *p, size_t n)
static value_type & element(slot_type *slot)
void SanitizerPoisonObject(const T *object)
auto TupleRefImpl(T &&t, absl::index_sequence< Is... >) -> decltype(std::forward_as_tuple(std::get< Is >(std::forward< T >(t))...))
static void swap(Allocator *alloc, slot_type *a, slot_type *b)
decltype(std::declval< F >()(std::declval< T >())) WithConstructed(Tuple &&t, F &&f)
auto TupleRef(T &&t) -> decltype(TupleRefImpl(std::forward< T >(t), absl::make_index_sequence< std::tuple_size< typename std::decay< T >::type >::value >()))
void SanitizerUnpoisonObject(const T *object)
mutable_value_type mutable_value
std::allocator< int > alloc
static void transfer(Allocator *alloc, slot_type *new_slot, slot_type *old_slot)
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
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)
static void emplace(slot_type *slot)
static void construct(Alloc &a, T *p, Args &&...args)
decltype(std::declval< F >()(std::declval< T >())) WithConstructedImpl(Tuple &&t, absl::index_sequence< Is... >, F &&f)