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