4#ifndef WPI_MEMORY_ALLOCATOR_STORAGE_HPP_INCLUDED
5#define WPI_MEMORY_ALLOCATOR_STORAGE_HPP_INCLUDED
24 template <
class Alloc>
26 std::size_t alignment)
noexcept
32 template <
class Alloc>
34 std::size_t size, std::size_t alignment)
noexcept
40 template <
class Alloc>
42 std::size_t alignment)
noexcept
48 template <
class Alloc>
50 std::size_t size, std::size_t alignment)
noexcept
56 template <
class Alloc>
63 template <
class Alloc>
71 template <
class Alloc>
79 template <
class Alloc>
92 template <
class StoragePolicy,
class Mutex>
94 : WPI_EBO(StoragePolicy,
95 detail::mutex_storage<
96 detail::mutex_for<typename StoragePolicy::allocator_type, Mutex>>)
137 template <
class OtherPolicy>
178 std::lock_guard<actual_mutex>
lock(*
this);
185 std::lock_guard<actual_mutex>
lock(*
this);
192 std::lock_guard<actual_mutex>
lock(*
this);
198 std::size_t alignment)
noexcept
200 std::lock_guard<actual_mutex>
lock(*
this);
207 std::lock_guard<actual_mutex>
lock(*
this);
214 std::lock_guard<actual_mutex>
lock(*
this);
221 std::lock_guard<actual_mutex>
lock(*
this);
238 std::lock_guard<actual_mutex>
lock(*
this);
245 std::
size_t alignment) noexcept
248 std::lock_guard<actual_mutex>
lock(*
this);
257 std::lock_guard<actual_mutex>
lock(*
this);
264 std::
size_t alignment) noexcept
267 std::lock_guard<actual_mutex>
lock(*
this);
280 return storage_policy::get_allocator();
286 return storage_policy::get_allocator();
294 auto lock() noexcept -> WPI_IMPL_DEFINED(decltype(
detail::lock_allocator(
300 auto lock() const noexcept -> WPI_IMPL_DEFINED(decltype(
detail::lock_allocator(
314 return StoragePolicy::is_composable();
328 template <
class RawAllocator>
331 static_assert(!std::is_same<RawAllocator, any_allocator>::value,
332 "cannot type-erase in direct_storage");
385 template <
class RawAllocator>
391 template <
class RawAllocator>
403#if WPI_HOSTED_IMPLEMENTATION
404 template <
class RawAllocator,
class Mutex = std::mutex>
408 template <
class RawAllocator,
class Mutex>
413#if WPI_HOSTED_IMPLEMENTATION
416 template <
class RawAllocator>
428 template <
class Mutex,
class RawAllocator>
452 template <
class RawAllocator,
class Tag>
456 template <
class RawAllocator>
466 return alloc_ !=
nullptr;
476 RawAllocator* alloc_;
480 template <
class RawAllocator>
495 static RawAllocator alloc;
501 template <
class RawAllocator>
520 mutable RawAllocator alloc_;
532 template <
class RawAllocator>
544 template <
class RawAllocator>
547 : WPI_EBO(detail::reference_storage_impl<
548 typename allocator_traits<RawAllocator>::allocator_type,
549 decltype(detail::reference_type(
550 typename allocator_traits<RawAllocator>::is_stateful{},
551 is_shared_allocator<RawAllocator>{}))>)
557 RawAllocator>::is_stateful{},
590 explicit operator bool() const noexcept
592 return storage::is_valid();
599 return storage::get_allocator();
621 using is_stateful = std::true_type;
623 virtual ~base_allocator() =
default;
625 virtual void clone(
void* storage)
const noexcept = 0;
627 void* allocate_node(std::size_t size, std::size_t alignment)
629 return allocate_impl(1, size, alignment);
632 void* allocate_array(std::size_t count, std::size_t size, std::size_t alignment)
634 return allocate_impl(count, size, alignment);
637 void deallocate_node(
void* node, std::size_t size, std::size_t alignment)
noexcept
639 deallocate_impl(node, 1, size, alignment);
642 void deallocate_array(
void*
array, std::size_t count, std::size_t size,
643 std::size_t alignment)
noexcept
645 deallocate_impl(
array, count, size, alignment);
648 void* try_allocate_node(std::size_t size, std::size_t alignment)
noexcept
650 return try_allocate_impl(1, size, alignment);
653 void* try_allocate_array(std::size_t count, std::size_t size,
654 std::size_t alignment)
noexcept
656 return try_allocate_impl(count, size, alignment);
659 bool try_deallocate_node(
void* node, std::size_t size,
660 std::size_t alignment)
noexcept
662 return try_deallocate_impl(node, 1, size, alignment);
665 bool try_deallocate_array(
void*
array, std::size_t count, std::size_t size,
666 std::size_t alignment)
noexcept
668 return try_deallocate_impl(
array, count, size, alignment);
672 virtual void* allocate_impl(std::size_t count, std::size_t size,
673 std::size_t alignment) = 0;
674 virtual void deallocate_impl(
void*
ptr, std::size_t count, std::size_t size,
675 std::size_t alignment)
noexcept = 0;
677 virtual void* try_allocate_impl(std::size_t count, std::size_t size,
678 std::size_t alignment)
noexcept = 0;
680 virtual bool try_deallocate_impl(
void*
ptr, std::size_t count, std::size_t size,
681 std::size_t alignment)
noexcept = 0;
683 std::size_t max_node_size()
const
685 return max(query::node_size);
688 std::size_t max_array_size()
const
690 return max(query::array_size);
693 std::size_t max_alignment()
const
695 return max(query::alignment);
698 virtual bool is_composable()
const noexcept = 0;
708 virtual std::size_t max(query q)
const = 0;
717 template <
class RawAllocator>
720 static_assert(
sizeof(basic_allocator<RawAllocator>)
721 <=
sizeof(basic_allocator<default_instantiation>),
722 "requires all instantiations to have certain maximum size");
723 ::new (
static_cast<void*
>(&storage_)) basic_allocator<RawAllocator>(alloc);
729 template <
class RawAllocator>
731 const RawAllocator& alloc,
734 static_assert(
sizeof(basic_allocator<RawAllocator>)
735 <=
sizeof(basic_allocator<default_instantiation>),
736 "requires all instantiations to have certain maximum size");
737 ::new (
static_cast<void*
>(&storage_)) basic_allocator<RawAllocator>(alloc);
745 alloc.clone(&storage_);
761 other.get_allocator().clone(&storage_);
767 other.get_allocator().clone(&storage_);
778 auto mem =
static_cast<void*
>(&storage_);
779 return *
static_cast<base_allocator*
>(mem);
794 template <
class RawAllocator>
795 class basic_allocator
796 :
public base_allocator,
798 typename allocator_traits<RawAllocator>::allocator_type,
799 decltype(detail::reference_type(typename allocator_traits<
800 RawAllocator>::is_stateful{},
801 is_shared_allocator<RawAllocator>{}))>
808 RawAllocator>::is_stateful{},
809 is_shared_allocator<RawAllocator>{}))>;
813 basic_allocator(
const RawAllocator& alloc) noexcept : storage(alloc) {}
816 basic_allocator(RawAllocator& alloc) noexcept : storage(alloc) {}
819 typename traits::allocator_type&
get() const noexcept
821 return storage::get_allocator();
824 void clone(
void* storage)
const noexcept override
826 ::new (storage) basic_allocator(
get());
829 void* allocate_impl(std::size_t count, std::size_t size,
830 std::size_t alignment)
override
832 auto&& alloc =
get();
834 return traits::allocate_node(alloc, size, alignment);
836 return traits::allocate_array(alloc, count, size, alignment);
839 void deallocate_impl(
void*
ptr, std::size_t count, std::size_t size,
840 std::size_t alignment)
noexcept override
842 auto&& alloc =
get();
844 traits::deallocate_node(alloc,
ptr, size, alignment);
846 traits::deallocate_array(alloc,
ptr, count, size, alignment);
849 void* try_allocate_impl(std::size_t count, std::size_t size,
850 std::size_t alignment)
noexcept override
852 auto&& alloc =
get();
854 return detail::try_allocate_node(composable{}, alloc, size, alignment);
856 return detail::try_allocate_array(composable{}, alloc,
count, size,
860 bool try_deallocate_impl(
void*
ptr, std::size_t count, std::size_t size,
861 std::size_t alignment)
noexcept override
863 auto&& alloc =
get();
865 return detail::try_deallocate_node(composable{}, alloc,
ptr, size,
868 return detail::try_deallocate_array(composable{}, alloc,
ptr,
count, size,
872 bool is_composable() const noexcept
override
874 return composable::value;
877 std::size_t
max(query q)
const override
879 auto&& alloc =
get();
880 if (q == query::node_size)
881 return traits::max_node_size(alloc);
882 else if (q == query::array_size)
883 return traits::max_array_size(alloc);
884 return traits::max_alignment(alloc);
890 using default_instantiation = basic_allocator<base_allocator>;
891 alignas(default_instantiation)
mutable char storage_[
sizeof(default_instantiation)];
898 template <
class RawAllocator>
904 template <
class RawAllocator>
924 template <
class RawAllocator>
925 auto make_any_allocator_reference(RawAllocator&& allocator)
noexcept
The default specialization of the wpi::memory::allocator_traits.
constexpr T & get(wpi::array< T, N > &arr) noexcept
Definition array.h:66
This class is a wrapper around std::array that does compile time size checking.
Definition array.h:26
An alias template for allocator_storage using the direct_storage policy without a mutex.
Definition allocator_storage.hpp:387
auto make_allocator_adapter(RawAllocator &&allocator) noexcept -> allocator_adapter< typename std::decay< RawAllocator >::type >
Definition allocator_storage.hpp:392
An alias template for allocator_storage using the reference_storage policy.
Definition allocator_storage.hpp:900
auto make_allocator_reference(RawAllocator &&allocator) noexcept -> allocator_reference< typename std::decay< RawAllocator >::type >
Definition allocator_storage.hpp:905
A RawAllocator that stores another allocator.
Definition allocator_storage.hpp:97
void * allocate_node(std::size_t size, std::size_t alignment)
Definition allocator_storage.hpp:176
std::size_t max_node_size() const
Definition allocator_storage.hpp:205
typename StoragePolicy::allocator_type allocator_type
Definition allocator_storage.hpp:106
std::size_t max_alignment() const
Definition allocator_storage.hpp:219
allocator_storage(allocator_storage &&other) noexcept
Definition allocator_storage.hpp:149
std::size_t max_array_size() const
Definition allocator_storage.hpp:212
allocator_storage & operator=(allocator_storage &&other) noexcept
Definition allocator_storage.hpp:157
auto get_allocator() noexcept -> decltype(std::declval< storage_policy >().get_allocator())
Definition allocator_storage.hpp:277
void deallocate_array(void *ptr, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_storage.hpp:197
auto lock() noexcept -> implementation_defined
Definition allocator_storage.hpp:294
void * allocate_array(std::size_t count, std::size_t size, std::size_t alignment)
Definition allocator_storage.hpp:183
bool try_deallocate_node(void *ptr, std::size_t size, std::size_t alignment) noexcept
Definition allocator_storage.hpp:254
allocator_storage(const allocator_storage< OtherPolicy, Mutex > &other,)
Definition allocator_storage.hpp:138
void * try_allocate_array(std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_storage.hpp:244
allocator_storage()=default
auto get_allocator() const noexcept -> decltype(std::declval< const storage_policy >().get_allocator())
Definition allocator_storage.hpp:283
Mutex mutex
Definition allocator_storage.hpp:108
allocator_storage & operator=(const allocator_storage &)=default
allocator_storage(const allocator_storage &)=default
bool try_deallocate_array(void *ptr, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_storage.hpp:263
bool is_composable() const noexcept
Definition allocator_storage.hpp:312
typename traits::is_stateful is_stateful
Definition allocator_storage.hpp:109
allocator_storage(Alloc &&alloc,)
Definition allocator_storage.hpp:127
void deallocate_node(void *ptr, std::size_t size, std::size_t alignment) noexcept
Definition allocator_storage.hpp:190
auto lock() const noexcept -> implementation_defined
Definition allocator_storage.hpp:300
StoragePolicy storage_policy
Definition allocator_storage.hpp:107
void * try_allocate_node(std::size_t size, std::size_t alignment) noexcept
Definition allocator_storage.hpp:235
The default specialization of the allocator_traits for a RawAllocator.
Definition allocator_traits.hpp:292
static void deallocate_array(allocator_type &state, void *array, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:328
traits_detail::allocator_type< Allocator > allocator_type
Definition allocator_traits.hpp:294
static void * allocate_array(allocator_type &state, std::size_t count, std::size_t size, std::size_t alignment)
Definition allocator_traits.hpp:308
static std::size_t max_array_size(const allocator_type &state)
Definition allocator_traits.hpp:346
static std::size_t max_node_size(const allocator_type &state)
Definition allocator_traits.hpp:338
static std::size_t max_alignment(const allocator_type &state)
Definition allocator_traits.hpp:354
static void * allocate_node(allocator_type &state, std::size_t size, std::size_t alignment)
Definition allocator_traits.hpp:298
static void deallocate_node(allocator_type &state, void *node, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:318
decltype(traits_detail::is_stateful< Allocator >(traits_detail::full_concept{})) is_stateful
Definition allocator_traits.hpp:295
The default specialization of the composable_allocator_traits for a ComposableAllocator.
Definition allocator_traits.hpp:500
static void * try_allocate_node(allocator_type &state, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:504
static void * try_allocate_array(allocator_type &state, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:513
static bool try_deallocate_node(allocator_type &state, void *node, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:522
static bool try_deallocate_array(allocator_type &state, void *array, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:531
Definition threading.hpp:62
RawAllocator & get_allocator() const noexcept
Definition allocator_storage.hpp:514
bool is_valid() const noexcept
Definition allocator_storage.hpp:509
reference_storage_impl() noexcept=default
RawAllocator & get_allocator() const noexcept
Definition allocator_storage.hpp:469
reference_storage_impl() noexcept
Definition allocator_storage.hpp:460
reference_storage_impl(RawAllocator &allocator) noexcept
Definition allocator_storage.hpp:462
bool is_valid() const noexcept
Definition allocator_storage.hpp:464
bool is_valid() const noexcept
Definition allocator_storage.hpp:488
reference_storage_impl() noexcept=default
RawAllocator & get_allocator() const noexcept
Definition allocator_storage.hpp:493
Definition allocator_storage.hpp:453
A StoragePolicy that stores the allocator directly.
Definition allocator_storage.hpp:330
~direct_storage() noexcept=default
const allocator_type & get_allocator() const noexcept
Definition allocator_storage.hpp:366
allocator_type & get_allocator() noexcept
Definition allocator_storage.hpp:361
direct_storage & operator=(direct_storage &&other) noexcept
Definition allocator_storage.hpp:352
direct_storage(direct_storage &&other) noexcept
Definition allocator_storage.hpp:350
typename allocator_traits< RawAllocator >::allocator_type allocator_type
Definition allocator_storage.hpp:335
direct_storage(allocator_type &&allocator) noexcept
Definition allocator_storage.hpp:342
bool is_composable() const noexcept
Definition allocator_storage.hpp:375
Specialization of the class template reference_storage that is type-erased.
Definition allocator_storage.hpp:617
allocator_type & get_allocator() const noexcept
Definition allocator_storage.hpp:776
bool is_composable() const noexcept
Definition allocator_storage.hpp:788
reference_storage(const RawAllocator &alloc,) noexcept
It will not store anything, only creates the allocator as needed.
Definition allocator_storage.hpp:730
reference_storage(RawAllocator &alloc) noexcept
Definition allocator_storage.hpp:718
reference_storage(implementation_defined &alloc) noexcept
Definition allocator_storage.hpp:751
reference_storage(const reference_storage &other) noexcept
Definition allocator_storage.hpp:759
implementation_defined allocator_type
Definition allocator_storage.hpp:712
reference_storage(const implementation_defined &alloc) noexcept
Definition allocator_storage.hpp:743
reference_storage & operator=(const reference_storage &other) noexcept
Definition allocator_storage.hpp:764
~reference_storage() noexcept
Definition allocator_storage.hpp:783
A StoragePolicy that stores a reference to an allocator.
Definition allocator_storage.hpp:553
allocator_type & get_allocator() const noexcept
Definition allocator_storage.hpp:597
bool is_composable() const noexcept
Definition allocator_storage.hpp:605
~reference_storage() noexcept=default
typename allocator_traits< RawAllocator >::allocator_type allocator_type
Definition allocator_storage.hpp:561
reference_storage() noexcept=default
Default constructor.
reference_storage(allocator_type &alloc) noexcept
Definition allocator_storage.hpp:579
reference_storage & operator=(const reference_storage &) noexcept=default
reference_storage(const reference_storage &) noexcept=default
An alias template for allocator_storage using the direct_storage policy with a mutex.
Definition allocator_storage.hpp:410
auto make_thread_safe_allocator(RawAllocator &&allocator) -> thread_safe_allocator< typename std::decay< RawAllocator >::type, Mutex >
Definition allocator_storage.hpp:429
#define WPI_ALIAS_TEMPLATE(Name,...)
Definition config.hpp:73
detail namespace with internal helper functions
Definition input_adapters.h:32
constexpr auto count() -> int
Definition base.h:1028
constexpr common_t< T1, T2 > max(const T1 x, const T2 y) noexcept
Compile-time pairwise maximum function.
Definition max.hpp:41
Implement std::hash so that hash_code can be used in STL containers.
Definition PointerIntPair.h:280
typename std::conditional< is_thread_safe_allocator< RawAllocator >::value, no_mutex, Mutex >::type mutex_for
Definition threading.hpp:54
void * try_allocate_node(std::true_type, Alloc &alloc, std::size_t size, std::size_t alignment) noexcept
Definition allocator_storage.hpp:25
bool try_deallocate_node(std::true_type, Alloc &alloc, void *ptr, std::size_t size, std::size_t alignment) noexcept
Definition allocator_storage.hpp:41
locked_allocator< Alloc, Mutex > lock_allocator(Alloc &a, Mutex &m)
Definition threading.hpp:146
T && forward(typename std::remove_reference< T >::type &t) noexcept
Definition utility.hpp:31
reference_stateful reference_type(std::true_type stateful, std::false_type shared)
std::remove_reference< T >::type && move(T &&arg) noexcept
Definition utility.hpp:25
bool try_deallocate_array(std::true_type, Alloc &alloc, void *ptr, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_storage.hpp:49
void * try_allocate_array(std::true_type, Alloc &alloc, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_storage.hpp:33
Memory namespace.
Definition heap_allocator.hpp:20
Foonathan namespace.
Definition ntcore_cpp.h:26
Tag type that enables type-erasure in reference_storage.
Definition allocator_storage.hpp:322
Definition allocator_storage.hpp:444
Definition allocator_storage.hpp:438
Definition allocator_storage.hpp:441
Traits that check whether a type models concept ComposableAllocator.
Definition allocator_traits.hpp:596
Specifies whether or not a RawAllocator has shared semantics.
Definition allocator_storage.hpp:534
A dummy Mutex class that does not lock anything.
Definition threading.hpp:27
#define WPI_ENABLE_IF(Expr)
Definition utility.hpp:78
#define WPI_SFINAE(Expr)
Definition utility.hpp:85
#define WPI_REQUIRES(Expr)
Definition utility.hpp:70
#define WPI_MEMORY_UNREACHABLE(Msg)
Definition assert.hpp:48
#define WPI_MEMORY_ASSERT(Expr)
Definition assert.hpp:46