27 #include <type_traits> 44 return ::operator
new(n);
48 #if __cpp_sized_deallocation 49 return ::operator
delete(p, n);
52 return ::operator
delete(p);
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)) 65 int rc = posix_memalign(&ptr, align, size);
66 return rc == 0 ? (errno = 0,
ptr) : (errno = rc,
nullptr);
76 return _aligned_malloc(size, align);
80 _aligned_free(aligned_ptr);
86 return memalign(align, size);
96 template <
typename Alloc,
size_t kAlign,
bool kAllocate>
98 static_assert((kAlign & (kAlign - 1)) == 0,
"Align must be a power of 2");
100 using AllocTraits = std::allocator_traits<Alloc>;
101 using T =
typename AllocTraits::value_type;
103 constexpr
bool kCanBypass = std::is_same<Alloc, std::allocator<T>>
::value;
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;
114 sizeof(BaseType) == kBaseAlign &&
alignof(BaseType) == kBaseAlign,
"");
116 #if __cpp_sized_deallocation 117 if (kCanBypass && kAlign == kBaseAlign) {
121 raw = ::operator
new(n *
sizeof(
T));
123 ::operator
delete(raw, n *
sizeof(
T));
129 if (kCanBypass && kAlign > kBaseAlign) {
144 size_t quanta = (n *
sizeof(
T) + kBaseAlign - 1) /
sizeof(BaseType);
145 if (kAlign <= kBaseAlign) {
149 raw =
static_cast<void*
>(
150 std::addressof(*BaseAllocTraits::allocate(a, quanta)));
152 BaseAllocTraits::deallocate(
154 std::pointer_traits<typename BaseAllocTraits::pointer>::pointer_to(
155 *static_cast<BaseType*>(raw)),
172 char* base =
reinterpret_cast<char*
>(std::addressof(
173 *BaseAllocTraits::allocate(a, quanta + kAlign /
sizeof(BaseType))));
175 kAlign - (
reinterpret_cast<uintptr_t
>(base) & (kAlign - 1));
176 raw =
static_cast<void*
>(base + byteDelta);
177 static_cast<size_t*
>(raw)[-1] = byteDelta;
179 size_t byteDelta =
static_cast<size_t*
>(raw)[-1];
180 char* base =
static_cast<char*
>(raw) - byteDelta;
181 BaseAllocTraits::deallocate(
183 std::pointer_traits<typename BaseAllocTraits::pointer>::pointer_to(
184 *reinterpret_cast<BaseType*>(base)),
185 quanta + kAlign /
sizeof(BaseType));
197 size_t kAlign =
alignof(
typename std::allocator_traits<Alloc>::value_type)>
202 detail::rawOverAlignedImpl<Alloc, kAlign, true>(alloc, n, raw);
203 return std::pointer_traits<typename std::allocator_traits<Alloc>::pointer>::
205 *
static_cast<typename std::allocator_traits<Alloc>::value_type*
>(
211 size_t kAlign =
alignof(
typename std::allocator_traits<Alloc>::value_type)>
214 typename std::allocator_traits<Alloc>::pointer
ptr,
216 void* raw =
static_cast<void*
>(std::addressof(*ptr));
217 detail::rawOverAlignedImpl<Alloc, kAlign, false>(alloc, n, raw);
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");
226 using AllocTraits = std::allocator_traits<Alloc>;
227 using T =
typename AllocTraits::value_type;
231 if (kAlign > kBaseAlign && std::is_same<Alloc, std::allocator<T>>::
value) {
232 return n *
sizeof(
T);
234 size_t quanta = (n *
sizeof(
T) + kBaseAlign - 1) / kBaseAlign;
235 if (kAlign > kBaseAlign) {
236 quanta += kAlign / kBaseAlign;
238 return quanta * kBaseAlign;
250 #if __cplusplus >= 201402L || __cpp_lib_make_unique >= 201304L || \ 251 (__ANDROID__ && __cplusplus >= 201300L) || _MSC_VER >= 1900 257 template <
typename T,
typename...
Args>
260 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
264 template <
typename T>
271 template <
typename T,
typename...
Args>
297 template <
typename T,
void (*f)(T*)>
322 template <
typename T,
typename D>
324 return std::shared_ptr<T>(
std::move(ptr));
345 template <
typename T>
347 return std::weak_ptr<T>(
ptr);
351 template <
typename T>
367 template <
typename T>
377 auto const p = std::malloc(
sizeof(lifted) * count);
379 throw_exception<std::bad_alloc>();
381 return static_cast<T*
>(p);
402 assert(!(align_ <
sizeof(
void*)) &&
bool(
"bad align: too small"));
403 assert(!(align_ & (align_ - 1)) &&
bool(
"bad align: not power-of-two"));
410 return a.align_ ==
b.align_;
413 return a.align_ !=
b.align_;
417 template <std::
size_t Align>
420 static_assert(!(Align <
sizeof(
void*)),
"bad align: too small");
421 static_assert(!(Align & (Align - 1)),
"bad align: not power-of-two");
452 template <
typename T,
typename Align = DefaultAlign>
457 template <
typename,
typename>
460 constexpr Align
const&
align()
const {
482 template <
typename U>
485 : Align(other.align()) {}
494 throw_exception<std::bad_alloc>();
496 return static_cast<T*
>(p);
503 return a.align() ==
b.align();
506 return a.align() !=
b.align();
521 template <
typename T,
class Inner>
526 template <
typename U,
typename UAlloc>
529 std::reference_wrapper<Inner>
ref_;
540 template <
typename U>
542 : ref_(other.ref_) {}
546 return static_cast<T*
>(ref_.get().allocate(
sizeof(lifted) * n));
550 ref_.get().deallocate(p,
sizeof(lifted) * n);
554 return std::addressof(
a.ref_.get()) == std::addressof(
b.ref_.get());
557 return std::addressof(
a.ref_.get()) != std::addressof(
b.ref_.get());
569 template <
typename Alloc>
575 using pointer =
typename allocator_traits::pointer;
590 template <
typename U>
599 auto alloc = get_allocator();
601 allocator_traits::deallocate(alloc, p, 1);
608 template <
typename T,
typename Alloc,
typename...
Args>
612 using traits = std::allocator_traits<Alloc>;
613 struct DeferCondDeallocate {
617 ~DeferCondDeallocate() {
619 traits::deallocate(copy, p, 1);
624 auto const p = traits::allocate(
copy, 1);
626 bool constructed =
false;
628 traits::construct(
copy, p, static_cast<Args&&>(args)...);
642 auto p = std::malloc(size);
644 throw_exception<std::bad_alloc>();
659 template <
typename Alloc>
662 template <
typename T,
class Alloc>
672 template <
typename Void,
typename Alloc,
typename...
Args>
674 : AllocatorConstruct_::template
is_invocable<Alloc, Args...> {};
676 template <
typename Alloc,
typename...
Args>
678 void_t<typename Alloc::folly_has_default_object_construct>,
680 Args...> :
Negation<typename Alloc::folly_has_default_object_construct> {};
682 template <
typename Void,
typename Alloc,
typename...
Args>
684 : AllocatorDestroy_::template
is_invocable<Alloc, Args...> {};
686 template <
typename Alloc,
typename...
Args>
688 void_t<typename Alloc::folly_has_default_object_destroy>,
690 Args...> :
Negation<typename Alloc::folly_has_default_object_destroy> {};
709 template <
typename Alloc,
typename T,
typename...
Args>
712 detail::AllocatorCustomizesConstruct_<void, Alloc, T*, Args...>> {};
714 template <
typename Value,
typename T,
typename...
Args>
733 template <
typename Alloc,
typename T>
735 :
Negation<detail::AllocatorCustomizesDestroy_<void, Alloc, T*>> {};
737 template <
typename Value,
typename T>
std::true_type propagate_on_container_copy_assignment
typename allocator_traits::pointer pointer
T * allocate(size_t count)
constexpr std::size_t operator()() const noexcept
std::size_t operator()() const noexcept
friend bool operator==(Self const &, Self const &) noexcept
void deallocate(T *p, size_t)
void deallocate(T *p, std::size_t n)
constexpr AlignedSysAllocator(AlignedSysAllocator< U, Align > const &other) noexcept
allocator_type const & get_allocator() const
typename std::remove_reference< Alloc >::type allocator_type
constexpr T constexpr_min(T a)
std::true_type propagate_on_container_copy_assignment
void aligned_free(void *aligned_ptr)
constexpr detail::Map< Move > move
friend bool operator!=(Self const &, Self const &) noexcept
#define FOLLY_UNLIKELY(x)
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
friend bool operator==(Self const &a, Self const &b) noexcept
—— Concurrent Priority Queue Implementation ——
std::reference_wrapper< Inner > ref_
requires E e noexcept(noexcept(s.error(std::move(e))))
std::unique_ptr< T, allocator_delete< Alloc > > allocate_unique(Alloc const &alloc, Args &&...args)
void operator()(T *t) const
bool_constant< true > true_type
allocator_delete(const allocator_delete< U > &other)
std::true_type propagate_on_container_move_assignment
CxxAllocatorAdaptor(CxxAllocatorAdaptor< U, Inner > const &other)
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))))
constexpr auto size(C const &c) -> decltype(c.size())
DefaultAlign(std::size_t align) noexcept
std::weak_ptr< T > to_weak_ptr(const std::shared_ptr< T > &ptr)
FOLLY_CREATE_MEMBER_INVOKE_TRAITS(AllocatorConstruct_, construct)
friend bool operator==(Self const &a, Self const &b) noexcept
std::true_type propagate_on_container_swap
void * aligned_malloc(size_t size, size_t align)
bool Value(const T &value, M matcher)
friend bool operator==(Self const &, Self const &) noexcept
std::allocator_traits< Alloc >::pointer allocateOverAligned(Alloc const &alloc, size_t n)
friend bool operator!=(Self const &a, Self const &b) noexcept
type_t< void, Ts... > void_t
void operator()(pointer p) const
void * allocateBytes(size_t n)
allocator_delete(const allocator_type &alloc)
size_t allocationBytesForOverAligned(size_t n)
static const char *const value
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&...args)
friend bool operator!=(Self const &a, Self const &b) noexcept
friend bool operator!=(Self const &a, Self const &b) noexcept
std::true_type propagate_on_container_swap
std::allocator_traits< allocator_type > allocator_traits
friend bool operator!=(Self const &, Self const &) noexcept
T * allocate(std::size_t n)
friend bool operator==(Self const &a, Self const &b) noexcept
void operator()(void *ptr)
void deallocate(T *p, size_t)
SysBufferUniquePtr allocate_sys_buffer(std::size_t size)
constexpr AlignedSysAllocator() noexcept(noexcept(Align()))
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
bool_constant< false > false_type
typename allocator_traits::value_type value_type
std::true_type propagate_on_container_move_assignment
CxxAllocatorAdaptor(Inner &ref)
void rawOverAlignedImpl(Alloc const &alloc, size_t n, void *&raw)
std::unique_ptr< void, SysBufferDeleter > SysBufferUniquePtr
constexpr Align const & align() const
T * allocate(size_t count)
void deallocateOverAligned(Alloc const &alloc, typename std::allocator_traits< Alloc >::pointer ptr, size_t n)
void deallocateBytes(void *p, size_t n)
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)
allocator_delete(allocator_type &&alloc)