proxygen
Memory.h
Go to the documentation of this file.
1 /*
2  * Copyright 2013-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cassert>
20 #include <cerrno>
21 #include <cstddef>
22 #include <cstdlib>
23 #include <exception>
24 #include <limits>
25 #include <memory>
26 #include <stdexcept>
27 #include <type_traits>
28 #include <utility>
29 
30 #include <folly/ConstexprMath.h>
31 #include <folly/Likely.h>
32 #include <folly/Traits.h>
34 #include <folly/lang/Align.h>
35 #include <folly/lang/Exception.h>
38 
39 namespace folly {
40 
43 inline void* allocateBytes(size_t n) {
44  return ::operator new(n);
45 }
46 
47 inline void deallocateBytes(void* p, size_t n) {
48 #if __cpp_sized_deallocation
49  return ::operator delete(p, n);
50 #else
51  (void)n;
52  return ::operator delete(p);
53 #endif
54 }
55 
56 #if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 || \
57  (defined(__ANDROID__) && (__ANDROID_API__ > 16)) || \
58  (defined(__APPLE__) && \
59  (__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_6 || \
60  __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_0))
61 
62 inline void* aligned_malloc(size_t size, size_t align) {
63  // use posix_memalign, but mimic the behaviour of memalign
64  void* ptr = nullptr;
65  int rc = posix_memalign(&ptr, align, size);
66  return rc == 0 ? (errno = 0, ptr) : (errno = rc, nullptr);
67 }
68 
69 inline void aligned_free(void* aligned_ptr) {
70  free(aligned_ptr);
71 }
72 
73 #elif defined(_WIN32)
74 
75 inline void* aligned_malloc(size_t size, size_t align) {
76  return _aligned_malloc(size, align);
77 }
78 
79 inline void aligned_free(void* aligned_ptr) {
80  _aligned_free(aligned_ptr);
81 }
82 
83 #else
84 
85 inline void* aligned_malloc(size_t size, size_t align) {
86  return memalign(align, size);
87 }
88 
89 inline void aligned_free(void* aligned_ptr) {
90  free(aligned_ptr);
91 }
92 
93 #endif
94 
95 namespace detail {
96 template <typename Alloc, size_t kAlign, bool kAllocate>
97 void rawOverAlignedImpl(Alloc const& alloc, size_t n, void*& raw) {
98  static_assert((kAlign & (kAlign - 1)) == 0, "Align must be a power of 2");
99 
100  using AllocTraits = std::allocator_traits<Alloc>;
101  using T = typename AllocTraits::value_type;
102 
103  constexpr bool kCanBypass = std::is_same<Alloc, std::allocator<T>>::value;
104 
105  // BaseType is a type that gives us as much alignment as we need if
106  // we can get it naturally, otherwise it is aligned as max_align_t.
107  // kBaseAlign is both the alignment and size of this type.
108  constexpr size_t kBaseAlign = constexpr_min(kAlign, alignof(max_align_t));
109  using BaseType = std::aligned_storage_t<kBaseAlign, kBaseAlign>;
110  using BaseAllocTraits =
111  typename AllocTraits::template rebind_traits<BaseType>;
112  using BaseAlloc = typename BaseAllocTraits::allocator_type;
113  static_assert(
114  sizeof(BaseType) == kBaseAlign && alignof(BaseType) == kBaseAlign, "");
115 
116 #if __cpp_sized_deallocation
117  if (kCanBypass && kAlign == kBaseAlign) {
118  // until std::allocator uses sized deallocation, it is worth the
119  // effort to bypass it when we are able
120  if (kAllocate) {
121  raw = ::operator new(n * sizeof(T));
122  } else {
123  ::operator delete(raw, n * sizeof(T));
124  }
125  return;
126  }
127 #endif
128 
129  if (kCanBypass && kAlign > kBaseAlign) {
130  // allocating as BaseType isn't sufficient to get alignment, but
131  // since we can bypass Alloc we can use something like posix_memalign
132  if (kAllocate) {
133  raw = aligned_malloc(n * sizeof(T), kAlign);
134  } else {
135  aligned_free(raw);
136  }
137  return;
138  }
139 
140  // we're not allowed to bypass Alloc, or we don't want to
141  BaseAlloc a(alloc);
142 
143  // allocation size is counted in sizeof(BaseType)
144  size_t quanta = (n * sizeof(T) + kBaseAlign - 1) / sizeof(BaseType);
145  if (kAlign <= kBaseAlign) {
146  // rebinding Alloc to BaseType is sufficient to get us the alignment
147  // we want, happy path
148  if (kAllocate) {
149  raw = static_cast<void*>(
150  std::addressof(*BaseAllocTraits::allocate(a, quanta)));
151  } else {
152  BaseAllocTraits::deallocate(
153  a,
154  std::pointer_traits<typename BaseAllocTraits::pointer>::pointer_to(
155  *static_cast<BaseType*>(raw)),
156  quanta);
157  }
158  return;
159  }
160 
161  // Overaligned and custom allocator, our only option is to
162  // overallocate and store a delta to the actual allocation just
163  // before the returned ptr.
164  //
165  // If we give ourselves kAlign extra bytes, then since
166  // sizeof(BaseType) divides kAlign we can meet alignment while
167  // getting a prefix of one BaseType. If we happen to get a
168  // kAlign-aligned block, then we can return a pointer to underlying
169  // + kAlign, otherwise there will be at least kBaseAlign bytes in
170  // the unused prefix of the first kAlign-aligned block.
171  if (kAllocate) {
172  char* base = reinterpret_cast<char*>(std::addressof(
173  *BaseAllocTraits::allocate(a, quanta + kAlign / sizeof(BaseType))));
174  size_t byteDelta =
175  kAlign - (reinterpret_cast<uintptr_t>(base) & (kAlign - 1));
176  raw = static_cast<void*>(base + byteDelta);
177  static_cast<size_t*>(raw)[-1] = byteDelta;
178  } else {
179  size_t byteDelta = static_cast<size_t*>(raw)[-1];
180  char* base = static_cast<char*>(raw) - byteDelta;
181  BaseAllocTraits::deallocate(
182  a,
183  std::pointer_traits<typename BaseAllocTraits::pointer>::pointer_to(
184  *reinterpret_cast<BaseType*>(base)),
185  quanta + kAlign / sizeof(BaseType));
186  }
187 }
188 } // namespace detail
189 
190 // Works like std::allocator_traits<Alloc>::allocate, but handles
191 // over-aligned types. Feel free to manually specify any power of two as
192 // the Align template arg. Must be matched with deallocateOverAligned.
193 // allocationBytesForOverAligned will give you the number of bytes that
194 // this function actually requests.
195 template <
196  typename Alloc,
197  size_t kAlign = alignof(typename std::allocator_traits<Alloc>::value_type)>
198 typename std::allocator_traits<Alloc>::pointer allocateOverAligned(
199  Alloc const& alloc,
200  size_t n) {
201  void* raw = nullptr;
202  detail::rawOverAlignedImpl<Alloc, kAlign, true>(alloc, n, raw);
203  return std::pointer_traits<typename std::allocator_traits<Alloc>::pointer>::
204  pointer_to(
205  *static_cast<typename std::allocator_traits<Alloc>::value_type*>(
206  raw));
207 }
208 
209 template <
210  typename Alloc,
211  size_t kAlign = alignof(typename std::allocator_traits<Alloc>::value_type)>
213  Alloc const& alloc,
214  typename std::allocator_traits<Alloc>::pointer ptr,
215  size_t n) {
216  void* raw = static_cast<void*>(std::addressof(*ptr));
217  detail::rawOverAlignedImpl<Alloc, kAlign, false>(alloc, n, raw);
218 }
219 
220 template <
221  typename Alloc,
222  size_t kAlign = alignof(typename std::allocator_traits<Alloc>::value_type)>
224  static_assert((kAlign & (kAlign - 1)) == 0, "Align must be a power of 2");
225 
226  using AllocTraits = std::allocator_traits<Alloc>;
227  using T = typename AllocTraits::value_type;
228 
229  constexpr size_t kBaseAlign = constexpr_min(kAlign, alignof(max_align_t));
230 
231  if (kAlign > kBaseAlign && std::is_same<Alloc, std::allocator<T>>::value) {
232  return n * sizeof(T);
233  } else {
234  size_t quanta = (n * sizeof(T) + kBaseAlign - 1) / kBaseAlign;
235  if (kAlign > kBaseAlign) {
236  quanta += kAlign / kBaseAlign;
237  }
238  return quanta * kBaseAlign;
239  }
240 }
241 
250 #if __cplusplus >= 201402L || __cpp_lib_make_unique >= 201304L || \
251  (__ANDROID__ && __cplusplus >= 201300L) || _MSC_VER >= 1900
252 
253 /* using override */ using std::make_unique;
254 
255 #else
256 
257 template <typename T, typename... Args>
258 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
259 make_unique(Args&&... args) {
260  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
261 }
262 
263 // Allows 'make_unique<T[]>(10)'. (N3690 s20.9.1.4 p3-4)
264 template <typename T>
265 typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
266 make_unique(const size_t n) {
267  return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
268 }
269 
270 // Disallows 'make_unique<T[10]>()'. (N3690 s20.9.1.4 p5)
271 template <typename T, typename... Args>
272 typename std::enable_if<std::extent<T>::value != 0, std::unique_ptr<T>>::type
273 make_unique(Args&&...) = delete;
274 
275 #endif
276 
297 template <typename T, void (*f)(T*)>
299  void operator()(T* t) const {
300  f(t);
301  }
302 };
303 
322 template <typename T, typename D>
323 std::shared_ptr<T> to_shared_ptr(std::unique_ptr<T, D>&& ptr) {
324  return std::shared_ptr<T>(std::move(ptr));
325 }
326 
345 template <typename T>
346 std::weak_ptr<T> to_weak_ptr(const std::shared_ptr<T>& ptr) {
347  return std::weak_ptr<T>(ptr);
348 }
349 
350 namespace detail {
351 template <typename T>
353  using type = T;
354 };
355 template <>
356 struct lift_void_to_char<void> {
357  using type = char;
358 };
359 } // namespace detail
360 
367 template <typename T>
369  private:
371 
372  public:
373  using value_type = T;
374 
375  T* allocate(size_t count) {
376  using lifted = typename detail::lift_void_to_char<T>::type;
377  auto const p = std::malloc(sizeof(lifted) * count);
378  if (!p) {
379  throw_exception<std::bad_alloc>();
380  }
381  return static_cast<T*>(p);
382  }
383  void deallocate(T* p, size_t /* count */) {
384  std::free(p);
385  }
386 
387  friend bool operator==(Self const&, Self const&) noexcept {
388  return true;
389  }
390  friend bool operator!=(Self const&, Self const&) noexcept {
391  return false;
392  }
393 };
394 
396  private:
398  std::size_t align_;
399 
400  public:
401  explicit DefaultAlign(std::size_t align) noexcept : align_(align) {
402  assert(!(align_ < sizeof(void*)) && bool("bad align: too small"));
403  assert(!(align_ & (align_ - 1)) && bool("bad align: not power-of-two"));
404  }
405  std::size_t operator()() const noexcept {
406  return align_;
407  }
408 
409  friend bool operator==(Self const& a, Self const& b) noexcept {
410  return a.align_ == b.align_;
411  }
412  friend bool operator!=(Self const& a, Self const& b) noexcept {
413  return a.align_ != b.align_;
414  }
415 };
416 
417 template <std::size_t Align>
418 class FixedAlign {
419  private:
420  static_assert(!(Align < sizeof(void*)), "bad align: too small");
421  static_assert(!(Align & (Align - 1)), "bad align: not power-of-two");
423 
424  public:
425  constexpr std::size_t operator()() const noexcept {
426  return Align;
427  }
428 
429  friend bool operator==(Self const&, Self const&) noexcept {
430  return true;
431  }
432  friend bool operator!=(Self const&, Self const&) noexcept {
433  return false;
434  }
435 };
436 
452 template <typename T, typename Align = DefaultAlign>
453 class AlignedSysAllocator : private Align {
454  private:
456 
457  template <typename, typename>
458  friend class AlignedSysAllocator;
459 
460  constexpr Align const& align() const {
461  return *this;
462  }
463 
464  public:
467 
468  using value_type = T;
469 
473 
474  using Align::Align;
475 
476  // TODO: remove this ctor, which is required only by gcc49
477  template <
478  typename S = Align,
480  constexpr AlignedSysAllocator() noexcept(noexcept(Align())) : Align() {}
481 
482  template <typename U>
483  constexpr explicit AlignedSysAllocator(
485  : Align(other.align()) {}
486 
487  T* allocate(size_t count) {
488  using lifted = typename detail::lift_void_to_char<T>::type;
489  auto const p = aligned_malloc(sizeof(lifted) * count, align()());
490  if (!p) {
491  if (FOLLY_UNLIKELY(errno != ENOMEM)) {
492  std::terminate();
493  }
494  throw_exception<std::bad_alloc>();
495  }
496  return static_cast<T*>(p);
497  }
498  void deallocate(T* p, size_t /* count */) {
499  aligned_free(p);
500  }
501 
502  friend bool operator==(Self const& a, Self const& b) noexcept {
503  return a.align() == b.align();
504  }
505  friend bool operator!=(Self const& a, Self const& b) noexcept {
506  return a.align() != b.align();
507  }
508 };
509 
521 template <typename T, class Inner>
523  private:
525 
526  template <typename U, typename UAlloc>
527  friend class CxxAllocatorAdaptor;
528 
529  std::reference_wrapper<Inner> ref_;
530 
531  public:
532  using value_type = T;
533 
537 
538  explicit CxxAllocatorAdaptor(Inner& ref) : ref_(ref) {}
539 
540  template <typename U>
542  : ref_(other.ref_) {}
543 
544  T* allocate(std::size_t n) {
545  using lifted = typename detail::lift_void_to_char<T>::type;
546  return static_cast<T*>(ref_.get().allocate(sizeof(lifted) * n));
547  }
548  void deallocate(T* p, std::size_t n) {
549  using lifted = typename detail::lift_void_to_char<T>::type;
550  ref_.get().deallocate(p, sizeof(lifted) * n);
551  }
552 
553  friend bool operator==(Self const& a, Self const& b) noexcept {
554  return std::addressof(a.ref_.get()) == std::addressof(b.ref_.get());
555  }
556  friend bool operator!=(Self const& a, Self const& b) noexcept {
557  return std::addressof(a.ref_.get()) != std::addressof(b.ref_.get());
558  }
559 };
560 
561 /*
562  * allocator_delete
563  *
564  * A deleter which automatically works with a given allocator.
565  *
566  * Derives from the allocator to take advantage of the empty base
567  * optimization when possible.
568  */
569 template <typename Alloc>
570 class allocator_delete : private std::remove_reference<Alloc>::type {
571  private:
573  using allocator_traits = std::allocator_traits<allocator_type>;
574  using value_type = typename allocator_traits::value_type;
575  using pointer = typename allocator_traits::pointer;
576 
577  public:
578  allocator_delete() = default;
579  allocator_delete(allocator_delete const&) = default;
580  allocator_delete(allocator_delete&&) = default;
581  allocator_delete& operator=(allocator_delete const&) = default;
582  allocator_delete& operator=(allocator_delete&&) = default;
583 
584  explicit allocator_delete(const allocator_type& alloc)
585  : allocator_type(alloc) {}
586 
588  : allocator_type(std::move(alloc)) {}
589 
590  template <typename U>
592  : allocator_type(other.get_allocator()) {}
593 
594  allocator_type const& get_allocator() const {
595  return *this;
596  }
597 
598  void operator()(pointer p) const {
599  auto alloc = get_allocator();
600  allocator_traits::destroy(alloc, p);
601  allocator_traits::deallocate(alloc, p, 1);
602  }
603 };
604 
608 template <typename T, typename Alloc, typename... Args>
609 std::unique_ptr<T, allocator_delete<Alloc>> allocate_unique(
610  Alloc const& alloc,
611  Args&&... args) {
612  using traits = std::allocator_traits<Alloc>;
613  struct DeferCondDeallocate {
614  bool& cond;
615  Alloc& copy;
616  T* p;
617  ~DeferCondDeallocate() {
618  if (FOLLY_UNLIKELY(!cond)) {
619  traits::deallocate(copy, p, 1);
620  }
621  }
622  };
623  auto copy = alloc;
624  auto const p = traits::allocate(copy, 1);
625  {
626  bool constructed = false;
627  DeferCondDeallocate handler{constructed, copy, p};
628  traits::construct(copy, p, static_cast<Args&&>(args)...);
629  constructed = true;
630  }
631  return {p, allocator_delete<Alloc>(std::move(copy))};
632 }
633 
635  void operator()(void* ptr) {
636  std::free(ptr);
637  }
638 };
639 using SysBufferUniquePtr = std::unique_ptr<void, SysBufferDeleter>;
640 
641 inline SysBufferUniquePtr allocate_sys_buffer(std::size_t size) {
642  auto p = std::malloc(size);
643  if (!p) {
644  throw_exception<std::bad_alloc>();
645  }
646  return {p, {}};
647 }
648 
659 template <typename Alloc>
661 
662 template <typename T, class Alloc>
664  : AllocatorHasTrivialDeallocate<Alloc> {};
665 
666 namespace detail {
667 // note that construct and destroy here are methods, not short names for
668 // the constructor and destructor
669 FOLLY_CREATE_MEMBER_INVOKE_TRAITS(AllocatorConstruct_, construct);
670 FOLLY_CREATE_MEMBER_INVOKE_TRAITS(AllocatorDestroy_, destroy);
671 
672 template <typename Void, typename Alloc, typename... Args>
674  : AllocatorConstruct_::template is_invocable<Alloc, Args...> {};
675 
676 template <typename Alloc, typename... Args>
678  void_t<typename Alloc::folly_has_default_object_construct>,
679  Alloc,
680  Args...> : Negation<typename Alloc::folly_has_default_object_construct> {};
681 
682 template <typename Void, typename Alloc, typename... Args>
684  : AllocatorDestroy_::template is_invocable<Alloc, Args...> {};
685 
686 template <typename Alloc, typename... Args>
688  void_t<typename Alloc::folly_has_default_object_destroy>,
689  Alloc,
690  Args...> : Negation<typename Alloc::folly_has_default_object_destroy> {};
691 } // namespace detail
692 
709 template <typename Alloc, typename T, typename... Args>
711  : Negation<
712  detail::AllocatorCustomizesConstruct_<void, Alloc, T*, Args...>> {};
713 
714 template <typename Value, typename T, typename... Args>
715 struct AllocatorHasDefaultObjectConstruct<std::allocator<Value>, T, Args...>
716  : std::true_type {};
717 
733 template <typename Alloc, typename T>
735  : Negation<detail::AllocatorCustomizesDestroy_<void, Alloc, T*>> {};
736 
737 template <typename Value, typename T>
738 struct AllocatorHasDefaultObjectDestroy<std::allocator<Value>, T>
739  : std::true_type {};
740 
741 } // namespace folly
std::true_type propagate_on_container_copy_assignment
Definition: Memory.h:534
void * ptr
typename allocator_traits::pointer pointer
Definition: Memory.h:575
T * allocate(size_t count)
Definition: Memory.h:375
constexpr std::size_t operator()() const noexcept
Definition: Memory.h:425
std::size_t operator()() const noexcept
Definition: Memory.h:405
auto f
friend bool operator==(Self const &, Self const &) noexcept
Definition: Memory.h:429
void deallocate(T *p, size_t)
Definition: Memory.h:383
char b
void deallocate(T *p, std::size_t n)
Definition: Memory.h:548
constexpr AlignedSysAllocator(AlignedSysAllocator< U, Align > const &other) noexcept
Definition: Memory.h:483
PskType type
allocator_type const & get_allocator() const
Definition: Memory.h:594
typename std::remove_reference< Alloc >::type allocator_type
Definition: Memory.h:572
constexpr T constexpr_min(T a)
Definition: ConstexprMath.h:79
std::true_type propagate_on_container_copy_assignment
Definition: Memory.h:470
void aligned_free(void *aligned_ptr)
Definition: Memory.h:89
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
friend bool operator!=(Self const &, Self const &) noexcept
Definition: Memory.h:390
STL namespace.
#define FOLLY_UNLIKELY(x)
Definition: Likely.h:36
folly::std T
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
friend bool operator==(Self const &a, Self const &b) noexcept
Definition: Memory.h:553
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
std::reference_wrapper< Inner > ref_
Definition: Memory.h:529
requires E e noexcept(noexcept(s.error(std::move(e))))
std::unique_ptr< T, allocator_delete< Alloc > > allocate_unique(Alloc const &alloc, Args &&...args)
Definition: Memory.h:609
void operator()(T *t) const
Definition: Memory.h:299
bool_constant< true > true_type
Definition: gtest-port.h:2210
allocator_delete(const allocator_delete< U > &other)
Definition: Memory.h:591
static void destroy()
std::true_type propagate_on_container_move_assignment
Definition: Memory.h:535
CxxAllocatorAdaptor(CxxAllocatorAdaptor< U, Inner > const &other)
Definition: Memory.h:541
void handler(int, siginfo_t *, void *)
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
DefaultAlign(std::size_t align) noexcept
Definition: Memory.h:401
std::weak_ptr< T > to_weak_ptr(const std::shared_ptr< T > &ptr)
Definition: Memory.h:346
FOLLY_CREATE_MEMBER_INVOKE_TRAITS(AllocatorConstruct_, construct)
friend bool operator==(Self const &a, Self const &b) noexcept
Definition: Memory.h:502
std::true_type propagate_on_container_swap
Definition: Memory.h:472
void * aligned_malloc(size_t size, size_t align)
Definition: Memory.h:85
bool Value(const T &value, M matcher)
friend bool operator==(Self const &, Self const &) noexcept
Definition: Memory.h:387
typename T::type _t
Definition: Traits.h:171
std::allocator_traits< Alloc >::pointer allocateOverAligned(Alloc const &alloc, size_t n)
Definition: Memory.h:198
friend bool operator!=(Self const &a, Self const &b) noexcept
Definition: Memory.h:505
type_t< void, Ts... > void_t
Definition: Traits.h:302
std::size_t align_
Definition: Memory.h:398
char a
void operator()(pointer p) const
Definition: Memory.h:598
void * allocateBytes(size_t n)
Definition: Memory.h:43
allocator_delete(const allocator_type &alloc)
Definition: Memory.h:584
size_t allocationBytesForOverAligned(size_t n)
Definition: Memory.h:223
static const char *const value
Definition: Conv.cpp:50
void free()
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&...args)
Definition: Memory.h:259
friend bool operator!=(Self const &a, Self const &b) noexcept
Definition: Memory.h:412
friend bool operator!=(Self const &a, Self const &b) noexcept
Definition: Memory.h:556
int * count
std::true_type propagate_on_container_swap
Definition: Memory.h:536
std::allocator_traits< allocator_type > allocator_traits
Definition: Memory.h:573
friend bool operator!=(Self const &, Self const &) noexcept
Definition: Memory.h:432
T * allocate(std::size_t n)
Definition: Memory.h:544
friend bool operator==(Self const &a, Self const &b) noexcept
Definition: Memory.h:409
void operator()(void *ptr)
Definition: Memory.h:635
void deallocate(T *p, size_t)
Definition: Memory.h:498
const
Definition: upload.py:398
SysBufferUniquePtr allocate_sys_buffer(std::size_t size)
Definition: Memory.h:641
constexpr AlignedSysAllocator() noexcept(noexcept(Align()))
Definition: Memory.h:480
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
bool_constant< false > false_type
Definition: gtest-port.h:2209
typename allocator_traits::value_type value_type
Definition: Memory.h:574
std::true_type propagate_on_container_move_assignment
Definition: Memory.h:471
CxxAllocatorAdaptor(Inner &ref)
Definition: Memory.h:538
void rawOverAlignedImpl(Alloc const &alloc, size_t n, void *&raw)
Definition: Memory.h:97
std::unique_ptr< void, SysBufferDeleter > SysBufferUniquePtr
Definition: Memory.h:639
constexpr Align const & align() const
Definition: Memory.h:460
T * allocate(size_t count)
Definition: Memory.h:487
void deallocateOverAligned(Alloc const &alloc, typename std::allocator_traits< Alloc >::pointer ptr, size_t n)
Definition: Memory.h:212
void deallocateBytes(void *p, size_t n)
Definition: Memory.h:47
std::enable_if< std::extent< T >::value!=0, std::unique_ptr< T > >::type make_unique(Args &&...)=delete
std::shared_ptr< T > to_shared_ptr(std::unique_ptr< T, D > &&ptr)
Definition: Memory.h:323
allocator_delete(allocator_type &&alloc)
Definition: Memory.h:587