[upstream_utils] Clean up and enable foonathan memory docs (#6990)

Group memory doxygen into one module.

Remove concept alias and add doxygen definitions for foonathan memory.

\concept was added as a doxygen command in 1.9.2 and is meant to be applied to concepts. Inserting them into standard comment paragraphs causes doxygen to interpret the following text as a concept name and add it to the documentation, as well as remove the text from the paragraph.
In the upstream repo, this alias links to markdown documentation, so it's not usable for us anyways.

That, plus adding the doxygen definitions/aliases from upstream cleans up most of the errors/weird output from doxygen for foonathan memory.
This commit is contained in:
Ryan Blue
2024-08-24 09:54:32 -04:00
committed by GitHub
parent 370e63ede6
commit 1fd1dc31b7
35 changed files with 3192 additions and 328 deletions

View File

@@ -290,10 +290,11 @@ TAB_SIZE = 4
# @} or use a double escape (\\{ and \\})
ALIASES = "effects=\par <i>Effects:</i>^^" \
"returns=\par <i>Returns:</i>^^" \
"notes=\par <i>Notes:</i>^^" \
"throws=\par <i>Throws:</i>^^" \
"requires=\par <i>Requires:</i>^^" \
"requiredbe=\par <i>Required Behavior:</i>^^" \
"concept{2}=<a href=\"md_doc_concepts.html#\1\">\2</a>" \
"defaultbe=\par <i>Default Behavior:</i>^^"
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
@@ -2443,7 +2444,18 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = __cplusplus "HAL_ENUM(name)=enum name : int32_t"
PREDEFINED = __cplusplus \
"HAL_ENUM(name)=enum name : int32_t" \
DOXYGEN \
WPI_NOEXCEPT:=noexcept \
WPI_SFINAE(x):= \
WPI_REQUIRES(x):= \
WPI_REQUIRES_RET(...):= \
WPI_ENABLE_IF(...):= \
WPI_CONSTEXPR:=constexpr \
WPI_CONSTEXPR_FNC:=constexpr \
WPI_IMPL_DEFINED(...):=implementation_defined \
WPI_EBO(...):=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@@ -2452,7 +2464,7 @@ PREDEFINED = __cplusplus "HAL_ENUM(name)=enum name : int32_t"
# definition found in the source code.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_AS_DEFINED =
EXPAND_AS_DEFINED = WPI_ALIAS_TEMPLATE
# If the SKIP_FUNCTION_MACROS tag is set to YES then Doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have

View File

@@ -144,9 +144,6 @@ doxygen {
exclude 'units/**'
}
//TODO: building memory docs causes search to break
exclude 'wpi/memory/**'
exclude '*.pb.h'
// Save space by excluding protobuf and eigen

View File

@@ -2799,4 +2799,4 @@ SOFTWARE.
left: var(--spacing-medium) !important;
right: auto;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -18,9 +18,9 @@ namespace wpi
{
namespace memory
{
/// A \concept{concept_rawallocator,RawAllocator} adapter that ensures a minimum alignment.
/// A RawAllocator adapter that ensures a minimum alignment.
/// It adjusts the alignment value so that it is always larger than the minimum and forwards to the specified allocator.
/// \ingroup adapter
/// \ingroup memory_adapter
template <class RawAllocator>
class aligned_allocator : WPI_EBO(allocator_traits<RawAllocator>::allocator_type)
{

View File

@@ -85,10 +85,10 @@ namespace wpi
}
} // namespace detail
/// A \concept{concept_rawallocator,RawAllocator} that stores another allocator.
/// The \concept{concept_storagepolicy,StoragePolicy} defines the allocator type being stored and how it is stored.
/// A RawAllocator that stores another allocator.
/// The StoragePolicy defines the allocator type being stored and how it is stored.
/// The \c Mutex controls synchronization of the access.
/// \ingroup storage
/// \ingroup memory_storage
template <class StoragePolicy, class Mutex>
class allocator_storage
: WPI_EBO(StoragePolicy,
@@ -317,14 +317,14 @@ namespace wpi
/// Tag type that enables type-erasure in \ref reference_storage.
/// It can be used everywhere a \ref allocator_reference is used internally.
/// \ingroup storage
/// \ingroup memory_storage
struct any_allocator
{
};
/// A \concept{concept_storagepolicy,StoragePolicy} that stores the allocator directly.
/// A StoragePolicy that stores the allocator directly.
/// It embeds the allocator inside it, i.e. moving the storage policy will move the allocator.
/// \ingroup storage
/// \ingroup memory_storage
template <class RawAllocator>
class direct_storage : WPI_EBO(allocator_traits<RawAllocator>::allocator_type)
{
@@ -379,9 +379,9 @@ namespace wpi
};
/// An alias template for \ref allocator_storage using the \ref direct_storage policy without a mutex.
/// It has the effect of giving any \concept{concept_rawallocator,RawAllocator} the interface with all member functions,
/// It has the effect of giving any RawAllocator the interface with all member functions,
/// avoiding the need to wrap it inside the \ref allocator_traits.
/// \ingroup storage
/// \ingroup memory_storage
template <class RawAllocator>
WPI_ALIAS_TEMPLATE(allocator_adapter,
allocator_storage<direct_storage<RawAllocator>, no_mutex>);
@@ -399,7 +399,7 @@ namespace wpi
/// It has a similar effect as \ref allocator_adapter but performs synchronization.
/// The \c Mutex will default to \c std::mutex if threading is supported,
/// otherwise there is no default.
/// \ingroup storage
/// \ingroup memory_storage
#if WPI_HOSTED_IMPLEMENTATION
template <class RawAllocator, class Mutex = std::mutex>
WPI_ALIAS_TEMPLATE(thread_safe_allocator,
@@ -521,26 +521,26 @@ namespace wpi
};
} // namespace detail
/// Specifies whether or not a \concept{concept_rawallocator,RawAllocator} has shared semantics.
/// Specifies whether or not a RawAllocator has shared semantics.
/// It is shared, if - like \ref allocator_reference - if multiple objects refer to the same internal allocator and if it can be copied.
/// This sharing is stateful, however, stateless allocators are not considered shared in the meaning of this traits. <br>
/// If a \c RawAllocator is shared, it will be directly embedded inside \ref reference_storage since it already provides \ref allocator_reference like semantics, so there is no need to add them manually,<br>
/// Specialize it for your own types, if they provide sharing semantics and can be copied.
/// They also must provide an `operator==` to check whether two allocators refer to the same shared one.
/// \note This makes no guarantees about the lifetime of the shared object, the sharing allocators can either own or refer to a shared object.
/// \ingroup storage
/// \ingroup memory_storage
template <class RawAllocator>
struct is_shared_allocator : std::false_type
{
};
/// A \concept{concept_storagepolicy,StoragePolicy} that stores a reference to an allocator.
/// A StoragePolicy that stores a reference to an allocator.
/// For stateful allocators it only stores a pointer to an allocator object and copying/moving only copies the pointer.
/// For stateless allocators it does not store anything, an allocator will be constructed as needed.
/// For allocators that are already shared (determined through \ref is_shared_allocator) it will store the allocator type directly.
/// \note It does not take ownership over the allocator in the stateful case, the user has to ensure that the allocator object stays valid.
/// In the other cases the lifetime does not matter.
/// \ingroup storage
/// \ingroup memory_storage
template <class RawAllocator>
class reference_storage
#ifndef DOXYGEN
@@ -611,7 +611,7 @@ namespace wpi
/// Specialization of the class template \ref reference_storage that is type-erased.
/// It is triggered by the tag type \ref any_allocator.
/// The specialization can store a reference to any allocator type.
/// \ingroup storage
/// \ingroup memory_storage
template <>
class reference_storage<any_allocator>
{
@@ -711,7 +711,7 @@ namespace wpi
public:
using allocator_type = WPI_IMPL_DEFINED(base_allocator);
/// \effects Creates it from a reference to any stateful \concept{concept_rawallocator,RawAllocator}.
/// \effects Creates it from a reference to any stateful RawAllocator.
/// It will store a pointer to this allocator object.
/// \note The user has to take care that the lifetime of the reference does not exceed the allocator lifetime.
template <class RawAllocator>
@@ -723,7 +723,7 @@ namespace wpi
::new (static_cast<void*>(&storage_)) basic_allocator<RawAllocator>(alloc);
}
// \effects Creates it from any stateless \concept{concept_rawallocator,RawAllocator}.
// \effects Creates it from any stateless RawAllocator.
/// It will not store anything, only creates the allocator as needed.
/// \requires The \c RawAllocator is stateless.
template <class RawAllocator>
@@ -771,7 +771,7 @@ namespace wpi
/// \returns A reference to the allocator.
/// The actual type is implementation-defined since it is the base class used in the type-erasure,
/// but it provides the full \concept{concept_rawallocator,RawAllocator} member functions.
/// but it provides the full RawAllocator member functions.
/// \note There is no way to access any custom member functions of the allocator type.
allocator_type& get_allocator() const noexcept
{
@@ -894,7 +894,7 @@ namespace wpi
/// An alias template for \ref allocator_storage using the \ref reference_storage policy.
/// It will store a reference to the given allocator type. The tag type \ref any_allocator enables type-erasure.
/// Wrap the allocator in a \ref thread_safe_allocator if you want thread safety.
/// \ingroup storage
/// \ingroup memory_storage
template <class RawAllocator>
WPI_ALIAS_TEMPLATE(allocator_reference,
allocator_storage<reference_storage<RawAllocator>, no_mutex>);
@@ -909,14 +909,14 @@ namespace wpi
}
/// An alias for the \ref reference_storage specialization using type-erasure.
/// \ingroup storage
/// \ingroup memory_storage
using any_reference_storage = reference_storage<any_allocator>;
/// An alias for \ref allocator_storage using the \ref any_reference_storage.
/// It will store a reference to any \concept{concept_rawallocator,RawAllocator}.
/// It will store a reference to any RawAllocator.
/// This is the same as passing the tag type \ref any_allocator to the alias \ref allocator_reference.
/// Wrap the allocator in a \ref thread_safe_allocator if you want thread safety.
/// \ingroup storage
/// \ingroup memory_storage
using any_allocator_reference = allocator_storage<any_reference_storage, no_mutex>;
/// \returns A new \ref any_allocator_reference object by forwarding the allocator to the constructor.

View File

@@ -50,11 +50,11 @@ namespace wpi
};
} // namespace detail
/// Traits class that checks whether or not a standard \c Allocator can be used as \concept{concept_rawallocator,RawAllocator}.
/// Traits class that checks whether or not a standard \c Allocator can be used as RawAllocator.
/// It checks the existence of a custom \c construct(), \c destroy() function, if provided,
/// it cannot be used since it would not be called.<br>
/// Specialize it for custom \c Allocator types to override this check.
/// \ingroup core
/// \ingroup memory_core
template <class Allocator>
struct allocator_is_raw_allocator
: WPI_EBO(detail::check_standard_allocator<Allocator>::valid)
@@ -62,7 +62,7 @@ namespace wpi
};
/// Specialization of \ref allocator_is_raw_allocator that allows \c std::allocator again.
/// \ingroup core
/// \ingroup memory_core
template <typename T>
struct allocator_is_raw_allocator<std::allocator<T>> : std::true_type
{
@@ -283,10 +283,10 @@ namespace wpi
}
} // namespace traits_detail
/// The default specialization of the allocator_traits for a \concept{concept_rawallocator,RawAllocator}.
/// The default specialization of the allocator_traits for a RawAllocator.
/// See the last link for the requirements on types that do not specialize this class and the interface documentation.
/// Any specialization must provide the same interface.
/// \ingroup core
/// \ingroup memory_core
template <class Allocator>
class allocator_traits
{
@@ -408,9 +408,9 @@ namespace wpi
};
} // namespace detail
/// Traits that check whether a type models concept \concept{concept_rawallocator,RawAllocator}.<br>
/// Traits that check whether a type models concept RawAllocator.<br>
/// It must either provide the necessary functions for the default traits specialization or has specialized it.
/// \ingroup core
/// \ingroup memory_core
template <typename T>
struct is_raw_allocator
: detail::is_raw_allocator<T,
@@ -491,10 +491,10 @@ namespace wpi
}
} // namespace traits_detail
/// The default specialization of the composable_allocator_traits for a \concept{concept_composableallocator,ComposableAllocator}.
/// The default specialization of the composable_allocator_traits for a ComposableAllocator.
/// See the last link for the requirements on types that do not specialize this class and the interface documentation.
/// Any specialization must provide the same interface.
/// \ingroup core
/// \ingroup memory_core
template <class Allocator>
class composable_allocator_traits
{
@@ -586,9 +586,9 @@ namespace wpi
};
} // namespace detail
/// Traits that check whether a type models concept \concept{concept_rawallocator,ComposableAllocator}.<br>
/// It must be a \concept{concept_rawallocator,RawAllocator} and either provide the necessary functions for the default traits specialization or has specialized it.
/// \ingroup core
/// Traits that check whether a type models concept ComposableAllocator.<br>
/// It must be a RawAllocator and either provide the necessary functions for the default traits specialization or has specialized it.
/// \ingroup memory_core
template <typename T>
struct is_composable_allocator
: detail::is_composable_allocator<T, decltype(detail::composable_alloc_uses_default_traits(

View File

@@ -83,54 +83,54 @@
// dummy definitions of config macros for doxygen
/// The major version number.
/// \ingroup core
/// \ingroup memory_core
#define WPI_MEMORY_VERSION_MAJOR 1
/// The minor version number.
/// \ingroup core
/// \ingroup memory_core
#define WPI_MEMORY_VERSION_MINOR 1
/// The total version number of the form \c Mmm.
/// \ingroup core
/// \ingroup memory_core
#define WPI_MEMORY_VERSION \
(WPI_MEMORY_VERSION_MAJOR * 100 + WPI_MEMORY_VERSION_MINOR)
/// Whether or not the allocation size will be checked,
/// i.e. the \ref wpi::memory::bad_allocation_size thrown.
/// \ingroup core
/// \ingroup memory_core
#define WPI_MEMORY_CHECK_ALLOCATION_SIZE 1
/// Whether or not internal assertions in the library are enabled.
/// \ingroup core
/// \ingroup memory_core
#define WPI_MEMORY_DEBUG_ASSERT 1
/// Whether or not allocated memory will be filled with special values.
/// \ingroup core
/// \ingroup memory_core
#define WPI_MEMORY_DEBUG_FILL 1
/// The size of the fence memory, it has no effect if \ref WPI_MEMORY_DEBUG_FILL is \c false.
/// \note For most allocators, the actual value doesn't matter and they use appropriate defaults to ensure alignment etc.
/// \ingroup core
/// \ingroup memory_core
#define WPI_MEMORY_DEBUG_FENCE 1
/// Whether or not leak checking is enabled.
/// \ingroup core
/// \ingroup memory_core
#define WPI_MEMORY_DEBUG_LEAK_CHECK 1
/// Whether or not the deallocation functions will check for pointers that were never allocated by an allocator.
/// \ingroup core
/// \ingroup memory_core
#define WPI_MEMORY_DEBUG_POINTER_CHECK 1
/// Whether or not the deallocation functions will check for double free errors.
/// This option makes no sense if \ref WPI_MEMORY_DEBUG_POINTER_CHECK is \c false.
/// \ingroup core
/// \ingroup memory_core
#define WPI_MEMORY_DEBUG_DOUBLE_DEALLOC_CHECK 1
/// Whether or not everything is in namespace <tt>wpi::memory</tt>.
/// If \c false, a namespace alias <tt>namespace memory = wpi::memory</tt> is automatically inserted into each header,
/// allowing to qualify everything with <tt>wpi::</tt>.
/// \note This option breaks in combination with using <tt>using namespace wpi;</tt>.
/// \ingroup core
/// \ingroup memory_core
#define WPI_MEMORY_NAMESPACE_PREFIX 1
/// The mode of the automatic \ref wpi::memory::temporary_stack creation.
@@ -140,7 +140,7 @@
/// requires managing it through the \ref wpi::memory::temporary_stack_initializer.
/// Set to `0` to disable the per-thread stack completely.
/// \ref wpi::memory::get_temporary_stack() will abort the program upon call.
/// \ingroup allocator
/// \ingroup memory_allocator
#define WPI_MEMORY_TEMPORARY_STACK_MODE 2
#endif

View File

@@ -5,7 +5,7 @@
#define WPI_MEMORY_CONTAINER_HPP_INCLUDED
/// \file
/// Aliasas for STL containers using a certain \concept{concept_rawallocator,RawAllocator}.
/// Aliasas for STL containers using a certain RawAllocator.
/// \note Only available on a hosted implementation.
#include "config.hpp"
@@ -36,11 +36,11 @@ namespace wpi
{
namespace memory
{
/// \ingroup adapter
/// \ingroup memory_adapter
/// @{
/// Alias template for an STL container that uses a certain
/// \concept{concept_rawallocator,RawAllocator}. It is just a shorthand for a passing in the \c
/// RawAllocator. It is just a shorthand for a passing in the \c
/// RawAllocator wrapped in a \ref wpi::memory::std_allocator.
template <typename T, class RawAllocator>
WPI_ALIAS_TEMPLATE(vector, std::vector<T, std_allocator<T, RawAllocator>>);
@@ -212,8 +212,8 @@ namespace wpi
/// @{
/// Convenience function to create a container adapter using a certain
/// \concept{concept_rawallocator,RawAllocator}. \returns An empty adapter with an
/// implementation container using a reference to a given allocator. \ingroup adapter
/// RawAllocator. \returns An empty adapter with an
/// implementation container using a reference to a given allocator. \ingroup memory_adapter
template <typename T, class RawAllocator, class Container = deque<T, RawAllocator>>
std::stack<T, Container> make_stack(RawAllocator& allocator)
{
@@ -271,7 +271,7 @@ namespace wpi
#endif
#else
/// \ingroup adapter
/// \ingroup memory_adapter
/// @{
/// Contains the node size of a node based STL container with a specific type.
@@ -355,7 +355,7 @@ namespace wpi
#if !defined(WPI_MEMORY_NO_NODE_SIZE)
/// The node size required by \ref allocate_shared.
/// \note This is similar to \ref shared_ptr_node_size but takes a
/// \concept{concept_rawallocator,RawAllocator} instead.
/// RawAllocator instead.
template <typename T, class RawAllocator>
struct allocate_shared_node_size : shared_ptr_node_size<T, std_allocator<T, RawAllocator>>
{

View File

@@ -18,7 +18,7 @@ namespace wpi
/// The magic values that are used for debug filling.
/// If \ref WPI_MEMORY_DEBUG_FILL is \c true, memory will be filled to help detect use-after-free or missing initialization errors.
/// These are the constants for the different types.
/// \ingroup core
/// \ingroup memory_core
enum class debug_magic : unsigned char
{
/// Marks internal memory used by the allocator - "allocated block".
@@ -47,19 +47,19 @@ namespace wpi
/// It must not throw any exceptions since it is called in the cleanup process.
/// \defaultbe On a hosted implementation it logs the leak to \c stderr and returns, continuing execution.
/// On a freestanding implementation it does nothing.
/// \ingroup core
/// \ingroup memory_core
using leak_handler = void (*)(const allocator_info& info, std::ptrdiff_t amount);
/// Exchanges the \ref leak_handler.
/// \effects Sets \c h as the new \ref leak_handler in an atomic operation.
/// A \c nullptr sets the default \ref leak_handler.
/// \returns The previous \ref leak_handler. This is never \c nullptr.
/// \ingroup core
/// \ingroup memory_core
leak_handler set_leak_handler(leak_handler h);
/// Returns the \ref leak_handler.
/// \returns The current \ref leak_handler. This is never \c nullptr.
/// \ingroup core
/// \ingroup memory_core
leak_handler get_leak_handler();
/// The type of the handler called when an invalid pointer is passed to a deallocation function.
@@ -69,19 +69,19 @@ namespace wpi
/// It must not throw any exceptions since it might be called in the cleanup process.
/// \defaultbe On a hosted implementation it logs the information to \c stderr and calls \c std::abort().
/// On a freestanding implementation it only calls \c std::abort().
/// \ingroup core
/// \ingroup memory_core
using invalid_pointer_handler = void (*)(const allocator_info& info, const void* ptr);
/// Exchanges the \ref invalid_pointer_handler.
/// \effects Sets \c h as the new \ref invalid_pointer_handler in an atomic operation.
/// A \c nullptr sets the default \ref invalid_pointer_handler.
/// \returns The previous \ref invalid_pointer_handler. This is never \c nullptr.
/// \ingroup core
/// \ingroup memory_core
invalid_pointer_handler set_invalid_pointer_handler(invalid_pointer_handler h);
/// Returns the \ref invalid_pointer_handler.
/// \returns The current \ref invalid_pointer_handler. This is never \c nullptr.
/// \ingroup core
/// \ingroup memory_core
invalid_pointer_handler get_invalid_pointer_handler();
/// The type of the handler called when a buffer under/overflow is detected.
@@ -92,7 +92,7 @@ namespace wpi
/// It must not throw any exceptions since it me be called in the cleanup process.
/// \defaultbe On a hosted implementation it logs the information to \c stderr and calls \c std::abort().
/// On a freestanding implementation it only calls \c std::abort().
/// \ingroup core
/// \ingroup memory_core
using buffer_overflow_handler = void (*)(const void* memory, std::size_t size,
const void* write_ptr);
@@ -100,12 +100,12 @@ namespace wpi
/// \effects Sets \c h as the new \ref buffer_overflow_handler in an atomic operation.
/// A \c nullptr sets the default \ref buffer_overflow_handler.
/// \returns The previous \ref buffer_overflow_handler. This is never \c nullptr.
/// \ingroup core
/// \ingroup memory_core
buffer_overflow_handler set_buffer_overflow_handler(buffer_overflow_handler h);
/// Returns the \ref buffer_overflow_handler.
/// \returns The current \ref buffer_overflow_handler. This is never \c nullptr.
/// \ingroup core
/// \ingroup memory_core
buffer_overflow_handler get_buffer_overflow_handler();
} // namespace memory
} // namespace wpi

View File

@@ -21,14 +21,14 @@ namespace wpi
{
namespace memory
{
/// The default \concept{concept_rawallocator,RawAllocator} that will be used as \concept{concept_blockallocator,BlockAllocator} in memory arenas.
/// The default RawAllocator that will be used as BlockAllocator in memory arenas.
/// Arena allocators like \ref memory_stack or \ref memory_pool allocate memory by subdividing a huge block.
/// They get a \concept{concept_blockallocator,BlockAllocator} that will be used for their internal allocation,
/// They get a BlockAllocator that will be used for their internal allocation,
/// this type is the default value.
/// \requiredbe Its type can be changed via the CMake option \c WPI_MEMORY_DEFAULT_ALLCOATOR,
/// but it must be one of the following: \ref heap_allocator, \ref new_allocator, \ref malloc_allocator, \ref static_allocator, \ref virtual_memory_allocator.
/// \defaultbe The default is \ref heap_allocator.
/// \ingroup allocator
/// \ingroup memory_allocator
using default_allocator = WPI_IMPL_DEFINED(WPI_MEMORY_IMPL_DEFAULT_ALLOCATOR);
} // namespace memory
} // namespace wpi

View File

@@ -5,7 +5,7 @@
#define WPI_MEMORY_DELETER_HPP_INCLUDED
/// \file
/// \c Deleter classes using a \concept{concept_rawallocator,RawAllocator}.
/// \c Deleter classes using a RawAllocator.
#include <type_traits>
@@ -17,10 +17,10 @@ namespace wpi
{
namespace memory
{
/// A deleter class that deallocates the memory through a specified \concept{concept_rawallocator,RawAllocator}.
/// A deleter class that deallocates the memory through a specified RawAllocator.
///
/// It deallocates memory for a specified type but does not call its destructors.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename Type, class RawAllocator>
class allocator_deallocator : WPI_EBO(allocator_reference<RawAllocator>)
{
@@ -63,7 +63,7 @@ namespace wpi
/// Specialization of \ref allocator_deallocator for array types.
/// Otherwise the same behavior.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename Type, class RawAllocator>
class allocator_deallocator<Type[], RawAllocator>
: WPI_EBO(allocator_reference<RawAllocator>)
@@ -116,10 +116,10 @@ namespace wpi
std::size_t size_;
};
/// A deleter class that deallocates the memory of a derived type through a specified \concept{concept_rawallocator,RawAllocator}.
/// A deleter class that deallocates the memory of a derived type through a specified RawAllocator.
///
/// It can only be created from a \ref allocator_deallocator and thus must only be used for smart pointers initialized by derived-to-base conversion of the pointer.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename BaseType, class RawAllocator>
class allocator_polymorphic_deallocator : WPI_EBO(allocator_reference<RawAllocator>)
{
@@ -159,7 +159,7 @@ namespace wpi
/// Similar to \ref allocator_deallocator but calls the destructors of the object.
/// Otherwise behaves the same.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename Type, class RawAllocator>
class allocator_deleter : WPI_EBO(allocator_reference<RawAllocator>)
{
@@ -203,7 +203,7 @@ namespace wpi
/// Specialization of \ref allocator_deleter for array types.
/// Otherwise the same behavior.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename Type, class RawAllocator>
class allocator_deleter<Type[], RawAllocator>
: WPI_EBO(allocator_reference<RawAllocator>)
@@ -260,7 +260,7 @@ namespace wpi
/// Similar to \ref allocator_polymorphic_deallocator but calls the destructors of the object.
/// Otherwise behaves the same.
/// \note It has a relatively high space overhead, so only use it if you have to.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename BaseType, class RawAllocator>
class allocator_polymorphic_deleter : WPI_EBO(allocator_reference<RawAllocator>)
{

View File

@@ -18,7 +18,7 @@ namespace wpi
{
/// Contains information about an allocator.
/// It can be used for logging in the various handler functions.
/// \ingroup core
/// \ingroup memory_core
struct allocator_info
{
/// The name of the allocator.
@@ -60,7 +60,7 @@ namespace wpi
/// It is derived from \c std::bad_alloc.
/// This can happen if a low level allocation function like \c std::malloc() runs out of memory.
/// Throwing can be prohibited by the handler function.
/// \ingroup core
/// \ingroup memory_core
class out_of_memory : public std::bad_alloc
{
public:
@@ -116,7 +116,7 @@ namespace wpi
/// thrown when a low-level allocator with a fixed size runs out of memory.
/// For example, thrown by \ref fixed_block_allocator or \ref static_allocator.<br>
/// It is derived from \ref out_of_memory but does not provide its own handler.
/// \ingroup core
/// \ingroup memory_core
class out_of_fixed_memory : public out_of_memory
{
public:
@@ -142,7 +142,7 @@ namespace wpi
/// since it always depends on fence memory, alignment buffer and the like.
/// \note A user should only \c catch for \c bad_allocation_size, not the derived classes.
/// \note Most checks will only be done if \ref WPI_MEMORY_CHECK_ALLOCATION_SIZE is \c true.
/// \ingroup core
/// \ingroup memory_core
class bad_allocation_size : public std::bad_alloc
{
public:
@@ -206,7 +206,7 @@ namespace wpi
/// The exception class thrown when the node size exceeds the supported maximum,
/// i.e. it is bigger than \c max_node_size().
/// It is derived from \ref bad_allocation_size but does not override the handler.
/// \ingroup core
/// \ingroup memory_core
class bad_node_size : public bad_allocation_size
{
public:
@@ -224,7 +224,7 @@ namespace wpi
/// The exception class thrown when the array size exceeds the supported maximum,
/// i.e. it is bigger than \c max_array_size().
/// It is derived from \ref bad_allocation_size but does not override the handler.
/// \ingroup core
/// \ingroup memory_core
class bad_array_size : public bad_allocation_size
{
public:
@@ -242,7 +242,7 @@ namespace wpi
/// The exception class thrown when the alignment exceeds the supported maximum,
/// i.e. it is bigger than \c max_alignment().
/// It is derived from \ref bad_allocation_size but does not override the handler.
/// \ingroup core
/// \ingroup memory_core
class bad_alignment : public bad_allocation_size
{
public:

View File

@@ -16,12 +16,12 @@ namespace wpi
{
namespace memory
{
/// A \concept{raw_allocator,RawAllocator} with a fallback.
/// A RawAllocator with a fallback.
/// Allocation first tries `Default`, if it fails,
/// it uses `Fallback`.
/// \requires `Default` must be a composable \concept{concept_rawallocator,RawAllocator},
/// `Fallback` must be a \concept{concept_rawallocator,RawAllocator}.
/// \ingroup adapter
/// \requires `Default` must be a composable RawAllocator,
/// `Fallback` must be a RawAllocator.
/// \ingroup memory_adapter
template <class Default, class Fallback>
class fallback_allocator
: WPI_EBO(detail::ebo_storage<0, typename allocator_traits<Default>::allocator_type>),

View File

@@ -28,7 +28,7 @@ namespace wpi
/// It shall return a \c nullptr if no memory is available.
/// It must be thread safe.
/// \defaultbe On a hosted implementation this function uses OS specific facilities, \c std::malloc is used as fallback.
/// \ingroup allocator
/// \ingroup memory_allocator
void* heap_alloc(std::size_t size) noexcept;
/// Deallocates heap memory.
@@ -39,7 +39,7 @@ namespace wpi
/// The pointer will not be zero.
/// It must be thread safe.
/// \defaultbe On a hosted implementation this function uses OS specific facilities, \c std::free is used as fallback.
/// \ingroup allocator
/// \ingroup memory_allocator
void heap_dealloc(void* ptr, std::size_t size) noexcept;
namespace detail
@@ -65,10 +65,10 @@ namespace wpi
heap_alloator_leak_checker)
} // namespace detail
/// A stateless \concept{concept_rawallocator,RawAllocator} that allocates memory from the heap.
/// A stateless RawAllocator that allocates memory from the heap.
/// It uses the two functions \ref heap_alloc and \ref heap_dealloc for the allocation,
/// which default to \c std::malloc and \c std::free.
/// \ingroup allocator
/// \ingroup memory_allocator
using heap_allocator =
WPI_IMPL_DEFINED(detail::lowlevel_allocator<detail::heap_allocator_impl>);

View File

@@ -24,7 +24,7 @@ namespace wpi
make_block_allocator_t<BlockOrRawAllocator, fixed_block_allocator>;
} // namespace detail
/// A stateful \concept{concept_rawallocator,RawAllocator} that is designed for allocations in a loop.
/// A stateful RawAllocator that is designed for allocations in a loop.
/// It uses `N` stacks for the allocation, one of them is always active.
/// Allocation uses the currently active stack.
/// Calling \ref iteration_allocator::next_iteration() at the end of the loop,
@@ -32,7 +32,7 @@ namespace wpi
/// effectively releasing all of its memory.
/// Any memory allocated will thus be usable for `N` iterations of the loop.
/// This type of allocator is a generalization of the double frame allocator.
/// \ingroup allocator
/// \ingroup memory_allocator
template <std::size_t N, class BlockOrRawAllocator = default_allocator>
class iteration_allocator
: WPI_EBO(detail::iteration_block_allocator<BlockOrRawAllocator>)
@@ -40,7 +40,7 @@ namespace wpi
public:
using allocator_type = detail::iteration_block_allocator<BlockOrRawAllocator>;
/// \effects Creates it with a given initial block size and and other constructor arguments for the \concept{concept_blockallocator,BlockAllocator}.
/// \effects Creates it with a given initial block size and and other constructor arguments for the BlockAllocator.
/// It will allocate the first (and only) block and evenly divide it on all the stacks it uses.
template <typename... Args>
explicit iteration_allocator(std::size_t block_size, Args&&... args)
@@ -89,7 +89,7 @@ namespace wpi
/// \effects Allocates a memory block of given size and alignment.
/// It simply moves the top marker of the currently active stack.
/// \returns A \concept{concept_node,node} with given size and alignment.
/// \returns A node with given size and alignment.
/// \throws \ref out_of_fixed_memory if the current stack does not have any memory left.
/// \requires \c size and \c alignment must be valid.
void* allocate(std::size_t size, std::size_t alignment)
@@ -106,7 +106,7 @@ namespace wpi
/// \effects Allocates a memory block of given size and alignment
/// similar to \ref allocate().
/// \returns A \concept{concept_node,node} with given size and alignment
/// \returns A node with given size and alignment
/// or `nullptr` if the current stack does not have any memory left.
void* try_allocate(std::size_t size, std::size_t alignment) noexcept
{
@@ -139,7 +139,7 @@ namespace wpi
return cur_;
}
/// \returns A reference to the \concept{concept_blockallocator,BlockAllocator} used for managing the memory.
/// \returns A reference to the BlockAllocator used for managing the memory.
/// \requires It is undefined behavior to move this allocator out into another object.
allocator_type& get_allocator() noexcept
{
@@ -187,7 +187,7 @@ namespace wpi
};
/// An alias for \ref iteration_allocator for two iterations.
/// \ingroup allocator
/// \ingroup memory_allocator
template <class BlockOrRawAllocator = default_allocator>
WPI_ALIAS_TEMPLATE(double_frame_allocator,
iteration_allocator<2, BlockOrRawAllocator>);
@@ -199,7 +199,7 @@ namespace wpi
/// Specialization of the \ref allocator_traits for \ref iteration_allocator.
/// \note It is not allowed to mix calls through the specialization and through the member functions,
/// i.e. \ref memory_stack::allocate() and this \c allocate_node().
/// \ingroup allocator
/// \ingroup memory_allocator
template <std::size_t N, class BlockAllocator>
class allocator_traits<iteration_allocator<N, BlockAllocator>>
{
@@ -256,7 +256,7 @@ namespace wpi
};
/// Specialization of the \ref composable_allocator_traits for \ref iteration_allocator classes.
/// \ingroup allocator
/// \ingroup memory_allocator
template <std::size_t N, class BlockAllocator>
class composable_allocator_traits<iteration_allocator<N, BlockAllocator>>
{

View File

@@ -97,7 +97,7 @@ namespace wpi
/// Tag type that can't be created.
///
/// It isued by \ref joint_ptr.
/// \ingroup allocator
/// \ingroup memory_allocator
class joint
{
joint(std::size_t cap) noexcept : capacity(cap) {}
@@ -113,7 +113,7 @@ namespace wpi
/// Tag type to make the joint size more explicit.
///
/// It is used by \ref joint_ptr.
/// \ingroup allocator
/// \ingroup memory_allocator
struct joint_size
{
std::size_t size;
@@ -125,7 +125,7 @@ namespace wpi
///
/// This will disable default copy/move operations
/// and inserts additional members for the joint memory management.
/// \ingroup allocator
/// \ingroup memory_allocator
template <typename T>
class joint_type
{
@@ -205,9 +205,9 @@ namespace wpi
/// make sure that you do not call their regular copy/move constructors,
/// but instead the version where you pass an allocator.
///
/// The memory block will be managed by the given \concept{concept_rawallocator,RawAllocator},
/// The memory block will be managed by the given RawAllocator,
/// it is stored in an \ref allocator_reference and not owned by the pointer directly.
/// \ingroup allocator
/// \ingroup memory_allocator
template <typename T, class RawAllocator>
class joint_ptr : WPI_EBO(allocator_reference<RawAllocator>)
{
@@ -220,7 +220,7 @@ namespace wpi
//=== constructors/destructor/assignment ===//
/// @{
/// \effects Creates it with a \concept{concept_rawallocator,RawAllocator}, but does not own a new object.
/// \effects Creates it with a RawAllocator, but does not own a new object.
explicit joint_ptr(allocator_type& alloc) noexcept
: allocator_reference<RawAllocator>(alloc), ptr_(nullptr)
{
@@ -235,7 +235,7 @@ namespace wpi
/// @{
/// \effects Reserves memory for the object and the additional size,
/// and creates the object by forwarding the arguments to its constructor.
/// The \concept{concept_rawallocator,RawAllocator} will be used for the allocation.
/// The RawAllocator will be used for the allocation.
template <typename... Args>
joint_ptr(allocator_type& alloc, joint_size additional_size, Args&&... args)
: joint_ptr(alloc)
@@ -450,7 +450,7 @@ namespace wpi
/// @{
/// \returns A new \ref joint_ptr as if created with the same arguments passed to the constructor.
/// \relatesalso joint_ptr
/// \ingroup allocator
/// \ingroup memory_allocator
template <typename T, class RawAllocator, typename... Args>
auto allocate_joint(RawAllocator& alloc, joint_size additional_size, Args&&... args)
-> joint_ptr<T, RawAllocator>
@@ -471,7 +471,7 @@ namespace wpi
/// @{
/// \returns A new \ref joint_ptr that points to a copy of `joint`.
/// It will allocate as much memory as needed and forward to the copy constructor.
/// \ingroup allocator
/// \ingroup memory_allocator
template <class RawAllocator, typename T>
auto clone_joint(RawAllocator& alloc, const joint_type<T>& joint)
-> joint_ptr<T, RawAllocator>
@@ -493,12 +493,12 @@ namespace wpi
}
/// @}
/// A \concept{concept_rawallocator,RawAllocator} that uses the additional joint memory for its allocation.
/// A RawAllocator that uses the additional joint memory for its allocation.
///
/// It is somewhat limited and allows only allocation once.
/// All joint allocators for an object share the joint memory and must not be used in multiple threads.
/// The memory it returns is owned by a \ref joint_ptr and will be destroyed through it.
/// \ingroup allocator
/// \ingroup memory_allocator
class joint_allocator
{
public:
@@ -567,7 +567,7 @@ namespace wpi
/// Specialization of \ref is_shared_allocator to mark \ref joint_allocator as shared.
/// This allows using it as \ref allocator_reference directly.
/// \ingroup allocator
/// \ingroup memory_allocator
template <>
struct is_shared_allocator<joint_allocator> : std::true_type
{
@@ -594,7 +594,7 @@ namespace wpi
/// \note This is required because the container constructor will end up copying/moving the allocator.
/// But this is not allowed as you need the allocator with the correct joined memory.
/// Copying can be customized (i.e. forbidden), but sadly not move, so keep that in mind.
/// \ingroup allocator
/// \ingroup memory_allocator
template <>
struct propagation_traits<joint_allocator>
{
@@ -624,7 +624,7 @@ namespace wpi
///
/// It has a dynamic, but fixed size,
/// it cannot grow after it has been created.
/// \ingroup allocator
/// \ingroup memory_allocator
template <typename T>
class joint_array
{

View File

@@ -54,9 +54,9 @@ namespace wpi
malloc_alloator_leak_checker)
} // namespace detail
/// A stateless \concept{concept_rawallocator,RawAllocator} that allocates memory using <tt>std::malloc()</tt>.
/// A stateless RawAllocator that allocates memory using <tt>std::malloc()</tt>.
/// It throws \ref out_of_memory when the allocation fails.
/// \ingroup allocator
/// \ingroup memory_allocator
using malloc_allocator =
WPI_IMPL_DEFINED(detail::lowlevel_allocator<detail::malloc_allocator_impl>);

View File

@@ -5,7 +5,7 @@
#define WPI_MEMORY_MEMORY_ARENA_HPP_INCLUDED
/// \file
/// Class \ref wpi::memory::memory_arena and related functionality regarding \concept{concept_blockallocator,BlockAllocators}.
/// Class \ref wpi::memory::memory_arena and related functionality regarding BlockAllocators.
#include <type_traits>
@@ -23,7 +23,7 @@ namespace wpi
{
/// A memory block.
/// It is defined by its starting address and size.
/// \ingroup core
/// \ingroup memory_core
struct memory_block
{
void* memory; ///< The address of the memory block (might be \c nullptr).
@@ -66,8 +66,8 @@ namespace wpi
std::false_type is_block_allocator_impl(short);
} // namespace detail
/// Traits that check whether a type models concept \concept{concept_blockallocator,BlockAllocator}.
/// \ingroup core
/// Traits that check whether a type models concept BlockAllocator.
/// \ingroup memory_core
template <typename T>
struct is_block_allocator : decltype(detail::is_block_allocator_impl<T>(0))
{
@@ -85,7 +85,7 @@ namespace wpi
/// This can be useful, e.g. if there will never be blocks available for deallocation.
/// The (tiny) overhead for the cache can then be disabled.
/// An example is \ref memory_pool.
/// \ingroup core
/// \ingroup memory_core
constexpr bool cached_arena = true;
constexpr bool uncached_arena = false;
/// @}
@@ -264,14 +264,14 @@ namespace wpi
/// A memory arena that manages huge memory blocks for a higher-level allocator.
/// Some allocators like \ref memory_stack work on huge memory blocks,
/// this class manages them fro those allocators.
/// It uses a \concept{concept_blockallocator,BlockAllocator} for the allocation of those blocks.
/// It uses a BlockAllocator for the allocation of those blocks.
/// The memory blocks in use are put onto a stack like structure, deallocation will pop from the top,
/// so it is only possible to deallocate the last allocated block of the arena.
/// By default, blocks are not really deallocated but stored in a cache.
/// This can be disabled with the second template parameter,
/// passing it \ref uncached_arena (or \c false) disables it,
/// \ref cached_arena (or \c true) enables it explicitly.
/// \ingroup core
/// \ingroup memory_core
template <class BlockAllocator, bool Cached /* = true */>
class memory_arena : WPI_EBO(BlockAllocator),
WPI_EBO(detail::memory_arena_cache<Cached>)
@@ -292,9 +292,9 @@ namespace wpi
return detail::memory_block_stack::implementation_offset() + byte_size;
}
/// \effects Creates it by giving it the size and other arguments for the \concept{concept_blockallocator,BlockAllocator}.
/// \effects Creates it by giving it the size and other arguments for the BlockAllocator.
/// It forwards these arguments to its constructor.
/// \requires \c block_size must be greater than \c min_block_size(0) and other requirements depending on the \concept{concept_blockallocator,BlockAllocator}.
/// \requires \c block_size must be greater than \c min_block_size(0) and other requirements depending on the BlockAllocator.
/// \throws Anything thrown by the constructor of the \c BlockAllocator.
template <typename... Args>
explicit memory_arena(std::size_t block_size, Args&&... args)
@@ -303,7 +303,7 @@ namespace wpi
WPI_MEMORY_ASSERT(block_size > min_block_size(0));
}
/// \effects Deallocates all memory blocks that where requested back to the \concept{concept_blockallocator,BlockAllocator}.
/// \effects Deallocates all memory blocks that where requested back to the BlockAllocator.
~memory_arena() noexcept
{
// clear cache
@@ -346,7 +346,7 @@ namespace wpi
/// It first uses a cache of previously deallocated blocks, if caching is enabled,
/// if it is empty, allocates a new one.
/// \returns The new \ref memory_block.
/// \throws Anything thrown by the \concept{concept_blockallocator,BlockAllocator} allocation function.
/// \throws Anything thrown by the BlockAllocator allocation function.
memory_block allocate_block()
{
if (!this->take_from_cache(used_))
@@ -411,7 +411,7 @@ namespace wpi
/// \returns The size of the next memory block,
/// i.e. of the next call to \ref allocate_block().
/// If there are blocks in the cache, returns size of the next one.
/// Otherwise forwards to the \concept{concept_blockallocator,BlockAllocator} and subtracts an implementation offset.
/// Otherwise forwards to the BlockAllocator and subtracts an implementation offset.
std::size_t next_block_size() const noexcept
{
return this->cache_empty() ?
@@ -420,7 +420,7 @@ namespace wpi
this->cached_block_size();
}
/// \returns A reference of the \concept{concept_blockallocator,BlockAllocator} object.
/// \returns A reference of the BlockAllocator object.
/// \requires It is undefined behavior to move this allocator out into another object.
allocator_type& get_allocator() noexcept
{
@@ -438,12 +438,12 @@ namespace wpi
extern template class memory_arena<virtual_block_allocator, false>;
#endif
/// A \concept{concept_blockallocator,BlockAllocator} that uses a given \concept{concept_rawallocator,RawAllocator} for allocating the blocks.
/// A BlockAllocator that uses a given RawAllocator for allocating the blocks.
/// It calls the \c allocate_array() function with a node of size \c 1 and maximum alignment on the used allocator for the block allocation.
/// The size of the next memory block will grow by a given factor after each allocation,
/// allowing an amortized constant allocation time in the higher level allocator.
/// The factor can be given as rational in the template parameter, default is \c 2.
/// \ingroup adapter
/// \ingroup memory_adapter
template <class RawAllocator = default_allocator, unsigned Num = 2, unsigned Den = 1>
class growing_block_allocator
: WPI_EBO(allocator_traits<RawAllocator>::allocator_type)
@@ -466,7 +466,7 @@ namespace wpi
/// \effects Allocates a new memory block and increases the block size for the next allocation.
/// \returns The new \ref memory_block.
/// \throws Anything thrown by the \c allocate_array() function of the \concept{concept_rawallocator,RawAllocator}.
/// \throws Anything thrown by the \c allocate_array() function of the RawAllocator.
memory_block allocate_block()
{
auto memory =
@@ -491,7 +491,7 @@ namespace wpi
return block_size_;
}
/// \returns A reference to the used \concept{concept_rawallocator,RawAllocator} object.
/// \returns A reference to the used RawAllocator object.
allocator_type& get_allocator() noexcept
{
return *this;
@@ -519,10 +519,10 @@ namespace wpi
extern template class memory_arena<growing_block_allocator<>, false>;
#endif
/// A \concept{concept_blockallocator,BlockAllocator} that allows only one block allocation.
/// A BlockAllocator that allows only one block allocation.
/// It can be used to prevent higher-level allocators from expanding.
/// The one block allocation is performed through the \c allocate_array() function of the given \concept{concept_rawallocator,RawAllocator}.
/// \ingroup adapter
/// The one block allocation is performed through the \c allocate_array() function of the given RawAllocator.
/// \ingroup memory_adapter
template <class RawAllocator = default_allocator>
class fixed_block_allocator : WPI_EBO(allocator_traits<RawAllocator>::allocator_type)
{
@@ -541,7 +541,7 @@ namespace wpi
/// \effects Allocates a new memory block or throws an exception if there was already one allocation.
/// \returns The new \ref memory_block.
/// \throws Anything thrown by the \c allocate_array() function of the \concept{concept_rawallocator,RawAllocator} or \ref out_of_memory if this is not the first call.
/// \throws Anything thrown by the \c allocate_array() function of the RawAllocator or \ref out_of_memory if this is not the first call.
memory_block allocate_block()
{
if (block_size_)
@@ -572,7 +572,7 @@ namespace wpi
return block_size_;
}
/// \returns A reference to the used \concept{concept_rawallocator,RawAllocator} object.
/// \returns A reference to the used RawAllocator object.
allocator_type& get_allocator() noexcept
{
return *this;
@@ -613,10 +613,10 @@ namespace wpi
}
} // namespace detail
/// Takes either a \concept{concept_blockallocator,BlockAllocator} or a \concept{concept_rawallocator,RawAllocator}.
/// In the first case simply aliases the type unchanged, in the second to \ref growing_block_allocator (or the template in `BlockAllocator`) with the \concept{concept_rawallocator,RawAllocator}.
/// Using this allows passing normal \concept{concept_rawallocator,RawAllocators} as \concept{concept_blockallocator,BlockAllocators}.
/// \ingroup core
/// Takes either a BlockAllocator or a RawAllocator.
/// In the first case simply aliases the type unchanged, in the second to \ref growing_block_allocator (or the template in `BlockAllocator`) with the RawAllocator.
/// Using this allows passing normal RawAllocators as BlockAllocators.
/// \ingroup memory_core
template <class BlockOrRawAllocator,
template <typename...> class BlockAllocator = detail::default_block_wrapper>
using make_block_allocator_t = WPI_IMPL_DEFINED(
@@ -625,10 +625,10 @@ namespace wpi
BlockAllocator<BlockOrRawAllocator>>::type);
/// @{
/// Helper function make a \concept{concept_blockallocator,BlockAllocator}.
/// \returns A \concept{concept_blockallocator,BlockAllocator} of the given type created with the given arguments.
/// Helper function make a BlockAllocator.
/// \returns A BlockAllocator of the given type created with the given arguments.
/// \requires Same requirements as the constructor.
/// \ingroup core
/// \ingroup memory_core
template <class BlockOrRawAllocator, typename... Args>
make_block_allocator_t<BlockOrRawAllocator> make_block_allocator(std::size_t block_size,
Args&&... args)
@@ -654,7 +654,7 @@ namespace wpi
{
/// Syntax sugar to express sizes with unit prefixes.
/// \returns The number of bytes `value` is in the given unit.
/// \ingroup core
/// \ingroup memory_core
/// @{
constexpr std::size_t operator"" _KiB(unsigned long long value) noexcept
{

View File

@@ -32,7 +32,7 @@ namespace wpi
};
} // namespace detail
/// A stateful \concept{concept_rawallocator,RawAllocator} that manages \concept{concept_node,nodes} of fixed size.
/// A stateful RawAllocator that manages nodes of fixed size.
/// It uses a \ref memory_arena with a given \c BlockOrRawAllocator defaulting to \ref growing_block_allocator,
/// subdivides them in small nodes of given size and puts them onto a free list.
/// Allocation and deallocation simply remove or add nodes from this list and are thus fast.
@@ -42,7 +42,7 @@ namespace wpi
/// for example in a node based container like \c std::list.
/// It is not so good for different allocation sizes and has some drawbacks for arrays
/// as described in \ref memory_pool_type.hpp.
/// \ingroup allocator
/// \ingroup memory_allocator
template <typename PoolType = node_pool, class BlockOrRawAllocator = default_allocator>
class memory_pool
: WPI_EBO(detail::default_leak_checker<detail::memory_pool_leak_handler>)
@@ -57,8 +57,8 @@ namespace wpi
static constexpr std::size_t min_node_size =
WPI_IMPL_DEFINED(free_list::min_element_size);
/// \returns The minimum block size required for certain number of \concept{concept_node,node}.
/// \requires \c node_size must be a valid \concept{concept_node,node size}
/// \returns The minimum block size required for certain number of node.
/// \requires \c node_size must be a valid node size
/// and \c number_of_nodes must be a non-zero value.
/// \note MSVC's implementation of \c std::list for example is never empty and always allocates proxy nodes.
/// To get enough memory for \c N elements of a list, \c number_of_nodes needs to include the proxy count in addition to \c N.
@@ -69,12 +69,12 @@ namespace wpi
+ free_list::min_block_size(node_size, number_of_nodes);
}
/// \effects Creates it by specifying the size each \concept{concept_node,node} will have,
/// the initial block size for the arena and other constructor arguments for the \concept{concept_blockallocator,BlockAllocator}.
/// \effects Creates it by specifying the size each node will have,
/// the initial block size for the arena and other constructor arguments for the BlockAllocator.
/// If the \c node_size is less than the \c min_node_size, the \c min_node_size will be the actual node size.
/// It will allocate an initial memory block with given size from the \concept{concept_blockallocator,BlockAllocator}
/// It will allocate an initial memory block with given size from the BlockAllocator
/// and puts it onto the free list.
/// \requires \c node_size must be a valid \concept{concept_node,node size}
/// \requires \c node_size must be a valid node size
/// and \c block_size must be at least \c min_block_size(node_size, 1).
template <typename... Args>
memory_pool(std::size_t node_size, std::size_t block_size, Args&&... args)
@@ -84,7 +84,7 @@ namespace wpi
}
/// \effects Destroys the \ref memory_pool by returning all memory blocks,
/// regardless of properly deallocated back to the \concept{concept_blockallocator,BlockAllocator}.
/// regardless of properly deallocated back to the BlockAllocator.
~memory_pool() noexcept {}
/// @{
@@ -108,12 +108,12 @@ namespace wpi
}
/// @}
/// \effects Allocates a single \concept{concept_node,node} by removing it from the free list.
/// \effects Allocates a single node by removing it from the free list.
/// If the free list is empty, a new memory block will be allocated from the arena and put onto it.
/// The new block size will be \ref next_capacity() big.
/// \returns A node of size \ref node_size() suitable aligned,
/// i.e. suitable for any type where <tt>sizeof(T) < node_size()</tt>.
/// \throws Anything thrown by the used \concept{concept_blockallocator,BlockAllocator}'s allocation function if a growth is needed.
/// \throws Anything thrown by the used BlockAllocator's allocation function if a growth is needed.
void* allocate_node()
{
if (free_list_.empty())
@@ -122,7 +122,7 @@ namespace wpi
return free_list_.allocate();
}
/// \effects Allocates a single \concept{concept_node,node} similar to \ref allocate_node().
/// \effects Allocates a single node similar to \ref allocate_node().
/// But if the free list is empty, a new block will *not* be allocated.
/// \returns A suitable aligned node of size \ref node_size() or `nullptr`.
void* try_allocate_node() noexcept
@@ -130,13 +130,13 @@ namespace wpi
return free_list_.empty() ? nullptr : free_list_.allocate();
}
/// \effects Allocates an \concept{concept_array,array} of nodes by searching for \c n continuous nodes on the list and removing them.
/// \effects Allocates an array of nodes by searching for \c n continuous nodes on the list and removing them.
/// Depending on the \c PoolType this can be a slow operation or not allowed at all.
/// This can sometimes lead to a growth, even if technically there is enough continuous memory on the free list.
/// \returns An array of \c n nodes of size \ref node_size() suitable aligned.
/// \throws Anything thrown by the used \concept{concept_blockallocator,BlockAllocator}'s allocation function if a growth is needed,
/// \throws Anything thrown by the used BlockAllocator's allocation function if a growth is needed,
/// or \ref bad_array_size if <tt>n * node_size()</tt> is too big.
/// \requires \c n must be valid \concept{concept_array,array count}.
/// \requires \c n must be valid array count.
void* allocate_array(std::size_t n)
{
detail::check_allocation_size<bad_array_size>(
@@ -145,7 +145,7 @@ namespace wpi
return allocate_array(n, node_size());
}
/// \effects Allocates an \concept{concept_array,array} of nodes similar to \ref allocate_array().
/// \effects Allocates an array of nodes similar to \ref allocate_array().
/// But it will never allocate a new memory block.
/// \returns An array of \c n nodes of size \ref node_size() suitable aligned
/// or `nullptr`.
@@ -154,7 +154,7 @@ namespace wpi
return try_allocate_array(n, node_size());
}
/// \effects Deallocates a single \concept{concept_node,node} by putting it back onto the free list.
/// \effects Deallocates a single node by putting it back onto the free list.
/// \requires \c ptr must be a result from a previous call to \ref allocate_node() on the same free list,
/// i.e. either this allocator object or a new object created by moving this to it.
void deallocate_node(void* ptr) noexcept
@@ -162,7 +162,7 @@ namespace wpi
free_list_.deallocate(ptr);
}
/// \effects Deallocates a single \concept{concept_node,node} but it does not be a result of a previous call to \ref allocate_node().
/// \effects Deallocates a single node but it does not be a result of a previous call to \ref allocate_node().
/// \returns `true` if the node could be deallocated, `false` otherwise.
/// \note Some free list implementations can deallocate any memory,
/// doesn't matter where it is coming from.
@@ -174,7 +174,7 @@ namespace wpi
return true;
}
/// \effects Deallocates an \concept{concept_array,array} by putting it back onto the free list.
/// \effects Deallocates an array by putting it back onto the free list.
/// \requires \c ptr must be a result from a previous call to \ref allocate_array() with the same \c n on the same free list,
/// i.e. either this allocator object or a new object created by moving this to it.
void deallocate_array(void* ptr, std::size_t n) noexcept
@@ -183,7 +183,7 @@ namespace wpi
free_list_.deallocate(ptr, n * node_size());
}
/// \effects Deallocates an \concept{concept_array,array} but it does not be a result of a previous call to \ref allocate_array().
/// \effects Deallocates an array but it does not be a result of a previous call to \ref allocate_array().
/// \returns `true` if the node could be deallocated, `false` otherwise.
/// \note Some free list implementations can deallocate any memory,
/// doesn't matter where it is coming from.
@@ -192,7 +192,7 @@ namespace wpi
return try_deallocate_array(ptr, n, node_size());
}
/// \returns The size of each \concept{concept_node,node} in the pool,
/// \returns The size of each node in the pool,
/// this is either the same value as in the constructor or \c min_node_size if the value was too small.
std::size_t node_size() const noexcept
{
@@ -215,7 +215,7 @@ namespace wpi
return free_list_.usable_size(arena_.next_block_size());
}
/// \returns A reference to the \concept{concept_blockallocator,BlockAllocator} used for managing the arena.
/// \returns A reference to the BlockAllocator used for managing the arena.
/// \requires It is undefined behavior to move this allocator out into another object.
allocator_type& get_allocator() noexcept
{
@@ -280,7 +280,7 @@ namespace wpi
/// Specialization of the \ref allocator_traits for \ref memory_pool classes.
/// \note It is not allowed to mix calls through the specialization and through the member functions,
/// i.e. \ref memory_pool::allocate_node() and this \c allocate_node().
/// \ingroup allocator
/// \ingroup memory_allocator
template <typename PoolType, class ImplRawAllocator>
class allocator_traits<memory_pool<PoolType, ImplRawAllocator>>
{
@@ -306,7 +306,7 @@ namespace wpi
/// \effects Forwards to \ref memory_pool::allocate_array()
/// with the number of nodes adjusted to be the minimum,
/// i.e. when the \c size is less than the \ref memory_pool::node_size().
/// \returns A \concept{concept_array,array} with specified properties.
/// \returns A array with specified properties.
/// \requires The \ref memory_pool has to support array allocations.
/// \throws Anything thrown by the pool allocation function.
static void* allocate_array(allocator_type& state, std::size_t count, std::size_t size,
@@ -360,7 +360,7 @@ namespace wpi
};
/// Specialization of the \ref composable_allocator_traits for \ref memory_pool classes.
/// \ingroup allocator
/// \ingroup memory_allocator
template <typename PoolType, class BlockOrRawAllocator>
class composable_allocator_traits<memory_pool<PoolType, BlockOrRawAllocator>>
{
@@ -382,7 +382,7 @@ namespace wpi
/// \effects Forwards to \ref memory_pool::try_allocate_array()
/// with the number of nodes adjusted to be the minimum,
/// if the \c size is less than the \ref memory_pool::node_size().
/// \returns A \concept{concept_array,array} with specified properties
/// \returns A array with specified properties
/// or `nullptr` if it was unable to allocate.
static void* try_allocate_array(allocator_type& state, std::size_t count,
std::size_t size, std::size_t alignment) noexcept

View File

@@ -34,7 +34,7 @@ namespace wpi
/// A \c BucketDistribution for \ref memory_pool_collection defining that there is a bucket, i.e. pool, for each size.
/// That means that for each possible size up to an upper bound there will be a seperate free list.
/// Allocating a node will not waste any memory.
/// \ingroup allocator
/// \ingroup memory_allocator
struct identity_buckets
{
using type = detail::identity_access_policy;
@@ -43,19 +43,19 @@ namespace wpi
/// A \c BucketDistribution for \ref memory_pool_collection defining that there is a bucket, i.e. pool, for each power of two.
/// That means for each power of two up to an upper bound there will be a separate free list.
/// Allocating a node will only waste half of the memory.
/// \ingroup allocator
/// \ingroup memory_allocator
struct log2_buckets
{
using type = detail::log2_access_policy;
};
/// A stateful \concept{concept_rawallocator,RawAllocator} that behaves as a collection of multiple \ref memory_pool objects.
/// A stateful RawAllocator that behaves as a collection of multiple \ref memory_pool objects.
/// It maintains a list of multiple free lists, whose types are controlled via the \c PoolType tags defined in \ref memory_pool_type.hpp,
/// each of a different size as defined in the \c BucketDistribution (\ref identity_buckets or \ref log2_buckets).
/// Allocating a node of given size will use the appropriate free list.<br>
/// This allocator is ideal for \concept{concept_node,node} allocations in any order but with a predefined set of sizes,
/// This allocator is ideal for node allocations in any order but with a predefined set of sizes,
/// not only one size like \ref memory_pool.
/// \ingroup allocator
/// \ingroup memory_allocator
template <class PoolType, class BucketDistribution,
class BlockOrRawAllocator = default_allocator>
class memory_pool_collection
@@ -72,10 +72,10 @@ namespace wpi
using bucket_distribution = BucketDistribution;
/// \effects Creates it by giving it the maximum node size it should be able to allocate,
/// the size of the initial memory block and other constructor arguments for the \concept{concept_blockallocator,BlockAllocator}.
/// the size of the initial memory block and other constructor arguments for the BlockAllocator.
/// The \c BucketDistribution controls how many free lists are created,
/// but unlike in \ref memory_pool all free lists are initially empty and the first memory block queued.
/// \requires \c block_size must be non-zero and \c max_node_size must be a valid \concept{concept_node,node} size and smaller than \c block_size divided by the number of pools.
/// \requires \c block_size must be non-zero and \c max_node_size must be a valid node size and smaller than \c block_size divided by the number of pools.
template <typename... Args>
memory_pool_collection(std::size_t max_node_size, std::size_t block_size,
Args&&... args)
@@ -87,7 +87,7 @@ namespace wpi
}
/// \effects Destroys the \ref memory_pool_collection by returning all memory blocks,
/// regardless of properly deallocated back to the \concept{concept_blockallocator,BlockAllocator}.
/// regardless of properly deallocated back to the BlockAllocator.
~memory_pool_collection() noexcept = default;
/// @{
@@ -113,16 +113,16 @@ namespace wpi
}
/// @}
/// \effects Allocates a \concept{concept_node,node} of given size.
/// \effects Allocates a node of given size.
/// It first finds the appropriate free list as defined in the \c BucketDistribution.
/// If it is empty, it will use an implementation defined amount of memory from the arena
/// and inserts it in it.
/// If the arena is empty too, it will request a new memory block from the \concept{concept_blockallocator,BlockAllocator}
/// If the arena is empty too, it will request a new memory block from the BlockAllocator
/// of size \ref next_capacity() and puts part of it onto this free list.
/// Then it removes a node from it.
/// \returns A \concept{concept_node,node} of given size suitable aligned,
/// \returns A node of given size suitable aligned,
/// i.e. suitable for any type where <tt>sizeof(T) < node_size</tt>.
/// \throws Anything thrown by the \concept{concept_blockallocator,BlockAllocator} if a growth is needed or a \ref bad_node_size exception if the node size is too big.
/// \throws Anything thrown by the BlockAllocator if a growth is needed or a \ref bad_node_size exception if the node size is too big.
void* allocate_node(std::size_t node_size)
{
detail::check_allocation_size<bad_node_size>(
@@ -139,10 +139,10 @@ namespace wpi
return mem;
}
/// \effects Allocates a \concept{concept_node,node} of given size.
/// \effects Allocates a node of given size.
/// It is similar to \ref allocate_node() but will return `nullptr` on any failure,
/// instead of growing the arnea and possibly throwing.
/// \returns A \concept{concept_node,node} of given size suitable aligned
/// \returns A node of given size suitable aligned
/// or `nullptr` in case of failure.
void* try_allocate_node(std::size_t node_size) noexcept
{
@@ -158,15 +158,15 @@ namespace wpi
return pool.allocate();
}
/// \effects Allocates an \concept{concept_array,array} of nodes by searching for \c n continuous nodes on the appropriate free list and removing them.
/// \effects Allocates an array of nodes by searching for \c n continuous nodes on the appropriate free list and removing them.
/// Depending on the \c PoolType this can be a slow operation or not allowed at all.
/// This can sometimes lead to a growth on the free list, even if technically there is enough continuous memory on the free list.
/// Otherwise has the same behavior as \ref allocate_node().
/// \returns An array of \c n nodes of size \c node_size suitable aligned.
/// \throws Anything thrown by the used \concept{concept_blockallocator,BlockAllocator}'s allocation function if a growth is needed,
/// \throws Anything thrown by the used BlockAllocator's allocation function if a growth is needed,
/// or a \ref bad_allocation_size exception.
/// \requires \c count must be valid \concept{concept_array,array count} and
/// \c node_size must be valid \concept{concept_node,node size}.
/// \requires \c count must be valid array count and
/// \c node_size must be valid node size.
void* allocate_array(std::size_t count, std::size_t node_size)
{
detail::check_allocation_size<bad_node_size>(
@@ -202,10 +202,10 @@ namespace wpi
return mem;
}
/// \effects Allocates a \concept{concept_array,array} of given size.
/// \effects Allocates a array of given size.
/// It is similar to \ref allocate_node() but will return `nullptr` on any failure,
/// instead of growing the arnea and possibly throwing.
/// \returns A \concept{concept_array,array} of given size suitable aligned
/// \returns A array of given size suitable aligned
/// or `nullptr` in case of failure.
void* try_allocate_array(std::size_t count, std::size_t node_size) noexcept
{
@@ -221,7 +221,7 @@ namespace wpi
return pool.allocate(count * node_size);
}
/// \effects Deallocates a \concept{concept_node,node} by putting it back onto the appropriate free list.
/// \effects Deallocates a node by putting it back onto the appropriate free list.
/// \requires \c ptr must be a result from a previous call to \ref allocate_node() with the same size on the same free list,
/// i.e. either this allocator object or a new object created by moving this to it.
void deallocate_node(void* ptr, std::size_t node_size) noexcept
@@ -229,7 +229,7 @@ namespace wpi
pools_.get(node_size).deallocate(ptr);
}
/// \effects Deallocates a \concept{concept_node,node} similar to \ref deallocate_node().
/// \effects Deallocates a node similar to \ref deallocate_node().
/// But it checks if it can deallocate this memory.
/// \returns `true` if the node could be deallocated,
/// `false` otherwise.
@@ -241,7 +241,7 @@ namespace wpi
return true;
}
/// \effects Deallocates an \concept{concept_array,array} by putting it back onto the free list.
/// \effects Deallocates an array by putting it back onto the free list.
/// \requires \c ptr must be a result from a previous call to \ref allocate_array() with the same sizes on the same free list,
/// i.e. either this allocator object or a new object created by moving this to it.
void deallocate_array(void* ptr, std::size_t count, std::size_t node_size) noexcept
@@ -249,7 +249,7 @@ namespace wpi
pools_.get(node_size).deallocate(ptr, count * node_size);
}
/// \effects Deallocates a \concept{concept_array,array} similar to \ref deallocate_array().
/// \effects Deallocates a array similar to \ref deallocate_array().
/// But it checks if it can deallocate this memory.
/// \returns `true` if the array could be deallocated,
/// `false` otherwise.
@@ -263,10 +263,10 @@ namespace wpi
/// \effects Inserts more memory on the free list for nodes of given size.
/// It will try to put \c capacity_left bytes from the arena onto the free list defined over the \c BucketDistribution,
/// if the arena is empty, a new memory block is requested from the \concept{concept_blockallocator,BlockAllocator}
/// if the arena is empty, a new memory block is requested from the BlockAllocator
/// and it will be used.
/// \throws Anything thrown by the \concept{concept_blockallocator,BlockAllocator} if a growth is needed.
/// \requires \c node_size must be valid \concept{concept_node,node size} less than or equal to \ref max_node_size(),
/// \throws Anything thrown by the BlockAllocator if a growth is needed.
/// \requires \c node_size must be valid node size less than or equal to \ref max_node_size(),
/// \c capacity_left must be less than \ref next_capacity().
void reserve(std::size_t node_size, std::size_t capacity)
{
@@ -294,7 +294,7 @@ namespace wpi
/// \returns The amount of memory available in the arena not inside the free lists.
/// This is the number of bytes that can be inserted into the free lists
/// without requesting more memory from the \concept{concept_blockallocator,BlockAllocator}.
/// without requesting more memory from the BlockAllocator.
/// \note Array allocations may lead to a growth even if the capacity is big enough.
std::size_t capacity_left() const noexcept
{
@@ -309,7 +309,7 @@ namespace wpi
return arena_.next_block_size();
}
/// \returns A reference to the \concept{concept_blockallocator,BlockAllocator} used for managing the arena.
/// \returns A reference to the BlockAllocator used for managing the arena.
/// \requires It is undefined behavior to move this allocator out into another object.
allocator_type& get_allocator() noexcept
{
@@ -398,7 +398,7 @@ namespace wpi
/// An alias for \ref memory_pool_collection using the \ref identity_buckets policy
/// and a \c PoolType defaulting to \ref node_pool.
/// \ingroup allocator
/// \ingroup memory_allocator
template <class PoolType = node_pool, class ImplAllocator = default_allocator>
WPI_ALIAS_TEMPLATE(bucket_allocator,
memory_pool_collection<PoolType, identity_buckets, ImplAllocator>);
@@ -409,7 +409,7 @@ namespace wpi
/// Specialization of the \ref allocator_traits for \ref memory_pool_collection classes.
/// \note It is not allowed to mix calls through the specialization and through the member functions,
/// i.e. \ref memory_pool_collection::allocate_node() and this \c allocate_node().
/// \ingroup allocator
/// \ingroup memory_allocator
template <class Pool, class BucketDist, class RawAllocator>
class allocator_traits<memory_pool_collection<Pool, BucketDist, RawAllocator>>
{
@@ -484,7 +484,7 @@ namespace wpi
};
/// Specialization of the \ref composable_allocator_traits for \ref memory_pool_collection classes.
/// \ingroup allocator
/// \ingroup memory_allocator
template <class Pool, class BucketDist, class RawAllocator>
class composable_allocator_traits<memory_pool_collection<Pool, BucketDist, RawAllocator>>
{

View File

@@ -20,7 +20,7 @@ namespace wpi
/// Tag type defining a memory pool optimized for nodes.
/// It does not support array allocations that great and may trigger a growth even if there is enough memory.
/// But it is the fastest pool type.
/// \ingroup allocator
/// \ingroup memory_allocator
struct node_pool : WPI_EBO(std::true_type)
{
using type = detail::node_free_memory_list;
@@ -31,7 +31,7 @@ namespace wpi
/// Array allocations are still pretty slow, if the array gets big enough it can get slower than \c new.
/// Node allocations are still fast, unless there is deallocation in random order.
/// \note Use this tag type only if you really need to have a memory pool!
/// \ingroup allocator
/// \ingroup memory_allocator
struct array_pool : WPI_EBO(std::true_type)
{
using type = detail::array_free_memory_list;
@@ -41,7 +41,7 @@ namespace wpi
/// The free list is intrusive and thus requires that each node has at least the size of a pointer.
/// This tag type does not have this requirement and thus allows zero-memory-overhead allocations of small nodes.
/// It is a little bit slower than \ref node_pool and does not support arrays.
/// \ingroup allocator
/// \ingroup memory_allocator
struct small_node_pool : WPI_EBO(std::false_type)
{
using type = detail::small_free_memory_list;

View File

@@ -87,11 +87,11 @@ namespace wpi
namespace memory
{
/// The \c memory_resource abstract base class used in the implementation.
/// \ingroup adapter
/// \ingroup memory_adapter
WPI_ALIAS_TEMPLATE(memory_resource, foonathan_memory_pmr::memory_resource);
/// Wraps a \concept{concept_rawallocator,RawAllocator} and makes it a \ref memory_resource.
/// \ingroup adapter
/// Wraps a RawAllocator and makes it a \ref memory_resource.
/// \ingroup memory_adapter
template <class RawAllocator>
class memory_resource_adapter
: public memory_resource,
@@ -124,7 +124,7 @@ namespace wpi
/// \effects Allocates raw memory with given size and alignment.
/// It forwards to \c allocate_node() or \c allocate_array() depending on the size.
/// \returns The new memory as returned by the \concept{concept_rawallocator,RawAllocator}.
/// \returns The new memory as returned by the RawAllocator.
/// \throws Anything thrown by the allocation function.
void* do_allocate(std::size_t bytes, std::size_t alignment) override
{
@@ -162,8 +162,8 @@ namespace wpi
}
};
/// Wraps a \ref memory_resource and makes it a \concept{concept_rawallocator,RawAllocator}.
/// \ingroup adapter
/// Wraps a \ref memory_resource and makes it a RawAllocator.
/// \ingroup memory_adapter
class memory_resource_allocator
{
public:
@@ -227,7 +227,7 @@ namespace wpi
/// Specialization of \ref is_shared_allocator to mark \ref memory_resource_allocator as shared.
/// This allows using it as \ref allocator_reference directly.
/// \ingroup adapter
/// \ingroup memory_adapter
template <>
struct is_shared_allocator<memory_resource_allocator> : std::true_type
{

View File

@@ -92,12 +92,12 @@ namespace wpi
};
} // namespace detail
/// A stateful \concept{concept_rawallocator,RawAllocator} that provides stack-like (LIFO) allocations.
/// A stateful RawAllocator that provides stack-like (LIFO) allocations.
/// It uses a \ref memory_arena with a given \c BlockOrRawAllocator defaulting to \ref growing_block_allocator to allocate huge blocks
/// and saves a marker to the current top.
/// Allocation simply moves this marker by the appropriate number of bytes and returns the pointer at the old marker position,
/// deallocation is not directly supported, only setting the marker to a previously queried position.
/// \ingroup allocator
/// \ingroup memory_allocator
template <class BlockOrRawAllocator = default_allocator>
class memory_stack
: WPI_EBO(detail::default_leak_checker<detail::memory_stack_leak_handler>)
@@ -116,7 +116,7 @@ namespace wpi
return detail::memory_block_stack::implementation_offset() + byte_size;
}
/// \effects Creates it with a given initial block size and and other constructor arguments for the \concept{concept_blockallocator,BlockAllocator}.
/// \effects Creates it with a given initial block size and and other constructor arguments for the BlockAllocator.
/// It will allocate the first block and sets the top to its beginning.
/// \requires \c block_size must be at least \c min_block_size(1).
template <typename... Args>
@@ -129,10 +129,10 @@ namespace wpi
/// \effects Allocates a memory block of given size and alignment.
/// It simply moves the top marker.
/// If there is not enough space on the current memory block,
/// a new one will be allocated by the \concept{concept_blockallocator,BlockAllocator} or taken from a cache
/// a new one will be allocated by the BlockAllocator or taken from a cache
/// and used for the allocation.
/// \returns A \concept{concept_node,node} with given size and alignment.
/// \throws Anything thrown by the \concept{concept_blockallocator,BlockAllocator} on growth
/// \returns A node with given size and alignment.
/// \throws Anything thrown by the BlockAllocator on growth
/// or \ref bad_allocation_size if \c size is too big.
/// \requires \c size and \c alignment must be valid.
void* allocate(std::size_t size, std::size_t alignment)
@@ -160,7 +160,7 @@ namespace wpi
/// \effects Allocates a memory block of given size and alignment,
/// similar to \ref allocate().
/// But it does not attempt a growth if the arena is empty.
/// \returns A \concept{concept_node,node} with given size and alignment
/// \returns A node with given size and alignment
/// or `nullptr` if there wasn't enough memory available.
void* try_allocate(std::size_t size, std::size_t alignment) noexcept
{
@@ -221,7 +221,7 @@ namespace wpi
}
}
/// \effects \ref unwind() does not actually do any deallocation of blocks on the \concept{concept_blockallocator,BlockAllocator},
/// \effects \ref unwind() does not actually do any deallocation of blocks on the BlockAllocator,
/// unused memory is stored in a cache for later reuse.
/// This function clears that cache.
void shrink_to_fit() noexcept
@@ -231,7 +231,7 @@ namespace wpi
/// \returns The amount of memory remaining in the current block.
/// This is the number of bytes that are available for allocation
/// before the cache or \concept{concept_blockallocator,BlockAllocator} needs to be used.
/// before the cache or BlockAllocator needs to be used.
std::size_t capacity_left() const noexcept
{
return std::size_t(block_end() - stack_.top());
@@ -246,7 +246,7 @@ namespace wpi
return arena_.next_block_size();
}
/// \returns A reference to the \concept{concept_blockallocator,BlockAllocator} used for managing the arena.
/// \returns A reference to the BlockAllocator used for managing the arena.
/// \requires It is undefined behavior to move this allocator out into another object.
allocator_type& get_allocator() noexcept
{
@@ -276,7 +276,7 @@ namespace wpi
/// A `Stack` is anything that provides a `marker`, a `top()` function returning a `marker`
/// and an `unwind()` function to unwind to a `marker`,
/// like a \ref wpi::memory::memory_stack
/// \ingroup allocator
/// \ingroup memory_allocator
template <class Stack = memory_stack<>>
class memory_stack_raii_unwind
{
@@ -379,7 +379,7 @@ namespace wpi
/// Specialization of the \ref allocator_traits for \ref memory_stack classes.
/// \note It is not allowed to mix calls through the specialization and through the member functions,
/// i.e. \ref memory_stack::allocate() and this \c allocate_node().
/// \ingroup allocator
/// \ingroup memory_allocator
template <class BlockAllocator>
class allocator_traits<memory_stack<BlockAllocator>>
{
@@ -441,7 +441,7 @@ namespace wpi
};
/// Specialization of the \ref composable_allocator_traits for \ref memory_stack classes.
/// \ingroup allocator
/// \ingroup memory_allocator
template <class BlockAllocator>
class composable_allocator_traits<memory_stack<BlockAllocator>>
{

View File

@@ -7,13 +7,18 @@
/// \file
/// Convenient namespace alias.
/// \defgroup core Core components
/// \defgroup memory Memory Allocator Library
/// @{
/// \defgroup allocator Allocator implementations
/// \defgroup memory_core Core components
/// \defgroup adapter Adapters and Wrappers
/// \defgroup memory_allocator Allocator implementations
/// \defgroup storage Allocator storage
/// \defgroup memory_adapter Adapters and Wrappers
/// \defgroup memory_storage Allocator storage
/// @}
/// \namespace wpi
/// Foonathan namespace.
@@ -32,5 +37,5 @@ namespace wpi
} // namespace wpi
namespace memory = wpi::memory;
///@}
#endif // WPI_MEMORY_NAMESPACE_ALIAS_HPP_INCLUDED

View File

@@ -37,10 +37,10 @@ namespace wpi
new_alloator_leak_checker)
} // namespace detail
/// A stateless \concept{concept_rawallocator,RawAllocator} that allocates memory using (nothrow) <tt>operator new</tt>.
/// A stateless RawAllocator that allocates memory using (nothrow) <tt>operator new</tt>.
/// If the operator returns \c nullptr, it behaves like \c new and loops calling \c std::new_handler,
/// but instead of throwing a \c std::bad_alloc exception, it throws \ref out_of_memory.
/// \ingroup allocator
/// \ingroup memory_allocator
using new_allocator =
WPI_IMPL_DEFINED(detail::lowlevel_allocator<detail::new_allocator_impl>);

View File

@@ -17,8 +17,8 @@ namespace wpi
{
namespace memory
{
/// A \concept{concept_segregatable,Segregatable} that allocates until a maximum size.
/// \ingroup adapter
/// A Segregatable that allocates until a maximum size.
/// \ingroup memory_adapter
template <class RawAllocator>
class threshold_segregatable : WPI_EBO(allocator_traits<RawAllocator>::allocator_type)
{
@@ -76,9 +76,9 @@ namespace wpi
std::forward<RawAllocator>(alloc));
}
/// A composable \concept{concept_rawallocator,RawAllocator} that will always fail.
/// A composable RawAllocator that will always fail.
/// This is useful for compositioning or as last resort in \ref binary_segregator.
/// \ingroup allocator
/// \ingroup memory_allocator
class null_allocator
{
public:
@@ -116,10 +116,10 @@ namespace wpi
}
};
/// A \concept{concept_rawallocator,RawAllocator} that either uses the \concept{concept_segregatable,Segregatable} or the other `RawAllocator`.
/// A RawAllocator that either uses the Segregatable or the other `RawAllocator`.
/// It is a faster alternative to \ref fallback_allocator that doesn't require a composable allocator
/// and decides about the allocator to use purely with the `Segregatable` based on size and alignment.
/// \ingroup adapter
/// \ingroup memory_adapter
template <class Segregatable, class RawAllocator>
class binary_segregator
: WPI_EBO(
@@ -133,8 +133,8 @@ namespace wpi
using segregatable_allocator_type = typename segregatable::allocator_type;
using fallback_allocator_type = typename allocator_traits<RawAllocator>::allocator_type;
/// \effects Creates it by giving the \concept{concept_segregatable,Segregatable}
/// and the \concept{concept_rawallocator,RawAllocator}.
/// \effects Creates it by giving the Segregatable
/// and the RawAllocator.
explicit binary_segregator(segregatable s,
fallback_allocator_type fallback = fallback_allocator_type())
: detail::ebo_storage<1, fallback_allocator_type>(detail::move(fallback)),
@@ -143,7 +143,7 @@ namespace wpi
}
/// @{
/// \effects Uses the \concept{concept_segregatable,Segregatable} to decide which allocator to use.
/// \effects Uses the Segregatable to decide which allocator to use.
/// Then forwards to the chosen allocator.
void* allocate_node(std::size_t size, std::size_t alignment)
{
@@ -223,7 +223,7 @@ namespace wpi
/// @{
/// \returns A reference to the fallback allocator.
/// It will be used if the \concept{concept_segregator,Segregator} doesn't want the alloction.
/// It will be used if the Segregator doesn't want the alloction.
fallback_allocator_type& get_fallback_allocator() noexcept
{
return detail::ebo_storage<1, fallback_allocator_type>::get();
@@ -366,16 +366,16 @@ namespace wpi
} // namespace detail
/// Creates multiple nested \ref binary_segregator.
/// If you pass one type, it must be a \concept{concept_segregatable,Segregatable}.
/// If you pass one type, it must be a Segregatable.
/// Then the result is a \ref binary_segregator with that `Segregatable` and \ref null_allocator as fallback.
/// If you pass two types, the first one must be a `Segregatable`,
/// the second one a \concept{concept_rawallocator,RawAllocator}.
/// the second one a RawAllocator.
/// Then the result is a simple \ref binary_segregator with those arguments.
/// If you pass more than one, the last one must be a `RawAllocator` all others `Segregatable`,
/// the result is `binary_segregator<Head, segregator<Tail...>>`.
/// \note It will result in an allocator that tries each `Segregatable` in the order specified
/// using the last parameter as final fallback.
/// \ingroup adapter
/// \ingroup memory_adapter
template <class... Allocators>
WPI_ALIAS_TEMPLATE(segregator,
typename detail::make_segregator_t<Allocators...>::type);
@@ -388,7 +388,7 @@ namespace wpi
return detail::make_segregator(std::forward<Args>(args)...);
}
/// The number of \concept{concept_segregatable,Segregatable} a \ref segregator has.
/// The number of Segregatable a \ref segregator has.
/// \relates segregator
template <class Segregator>
struct segregator_size
@@ -396,13 +396,13 @@ namespace wpi
static const std::size_t value = detail::fallback_type<Segregator>::size;
};
/// The type of the `I`th \concept{concept_segregatable,Segregatable}.
/// The type of the `I`th Segregatable.
/// \relates segregator
template <std::size_t I, class Segregator>
using segregatable_allocator_type = typename detail::segregatable_type<I, Segregator>::type;
/// @{
/// \returns The `I`th \concept{concept_segregatable,Segregatable}.
/// \returns The `I`th Segregatable.
/// \relates segregrator
template <std::size_t I, class Segregator, class Fallback>
auto get_segregatable_allocator(binary_segregator<Segregator, Fallback>& s)
@@ -419,13 +419,13 @@ namespace wpi
}
/// @}
/// The type of the final fallback \concept{concept_rawallocator,RawAllocator}.
/// The type of the final fallback RawAllocator.
/// \relates segregator
template <class Segregator>
using fallback_allocator_type = typename detail::fallback_type<Segregator>::type;
/// @{
/// \returns The final fallback \concept{concept_rawallocator,RawAllocator}.
/// \returns The final fallback RawAllocator.
/// \relates segregator
template <class Segregator, class Fallback>
auto get_fallback_allocator(binary_segregator<Segregator, Fallback>& s)

View File

@@ -5,7 +5,7 @@
#define WPI_MEMORY_SMART_PTR_HPP_INCLUDED
/// \file
/// \c std::make_unique() / \c std::make_shared() replacement allocating memory through a \concept{concept_rawallocator,RawAllocator}.
/// \c std::make_unique() / \c std::make_shared() replacement allocating memory through a RawAllocator.
/// \note Only available on a hosted implementation.
#include "config.hpp"
@@ -85,33 +85,33 @@ namespace wpi
}
} // namespace detail
/// A \c std::unique_ptr that deletes using a \concept{concept_rawallocator,RawAllocator}.
/// A \c std::unique_ptr that deletes using a RawAllocator.
///
/// It is an alias template using \ref allocator_deleter as \c Deleter class.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename T, class RawAllocator>
WPI_ALIAS_TEMPLATE(unique_ptr,
std::unique_ptr<T, allocator_deleter<T, RawAllocator>>);
/// A \c std::unique_ptr that deletes using a \concept{concept_rawallocator,RawAllocator} and allows polymorphic types.
/// A \c std::unique_ptr that deletes using a RawAllocator and allows polymorphic types.
///
/// It can only be created by converting a regular unique pointer to a pointer to a derived class,
/// and is meant to be used inside containers.
/// It is an alias template using \ref allocator_polymorphic_deleter as \c Deleter class.
/// \note It has a relatively high overhead, so only use it if you have to.
/// \ingroup adapter
/// \ingroup memory_adapter
template <class BaseType, class RawAllocator>
WPI_ALIAS_TEMPLATE(
unique_base_ptr,
std::unique_ptr<BaseType, allocator_polymorphic_deleter<BaseType, RawAllocator>>);
/// Creates a \c std::unique_ptr using a \concept{concept_rawallocator,RawAllocator} for the allocation.
/// Creates a \c std::unique_ptr using a RawAllocator for the allocation.
/// \effects Allocates memory for the given type using the allocator
/// and creates a new object inside it passing the given arguments to its constructor.
/// \returns A \c std::unique_ptr owning that memory.
/// \note If the allocator is stateful a reference to the \c RawAllocator will be stored inside the deleter,
/// the caller has to ensure that the object lives as long as the smart pointer.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename T, class RawAllocator, typename... Args>
auto allocate_unique(RawAllocator&& alloc, Args&&... args) -> WPI_REQUIRES_RET(
!std::is_array<T>::value,
@@ -122,14 +122,14 @@ namespace wpi
detail::forward<Args>(args)...);
}
/// Creates a \c std::unique_ptr using a type-erased \concept{concept_rawallocator,RawAllocator} for the allocation.
/// Creates a \c std::unique_ptr using a type-erased RawAllocator for the allocation.
/// It is the same as the other overload but stores the reference to the allocator type-erased inside the \c std::unique_ptr.
/// \effects Allocates memory for the given type using the allocator
/// and creates a new object inside it passing the given arguments to its constructor.
/// \returns A \c std::unique_ptr with a type-erased allocator reference owning that memory.
/// \note If the allocator is stateful a reference to the \c RawAllocator will be stored inside the deleter,
/// the caller has to ensure that the object lives as long as the smart pointer.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename T, class RawAllocator, typename... Args>
auto allocate_unique(any_allocator, RawAllocator&& alloc, Args&&... args)
-> WPI_REQUIRES_RET(!std::is_array<T>::value,
@@ -141,12 +141,12 @@ namespace wpi
detail::forward<Args>(args)...);
}
/// Creates a \c std::unique_ptr owning an array using a \concept{concept_rawallocator,RawAllocator} for the allocation.
/// Creates a \c std::unique_ptr owning an array using a RawAllocator for the allocation.
/// \effects Allocates memory for an array of given size and value initializes each element inside of it.
/// \returns A \c std::unique_ptr owning that array.
/// \note If the allocator is stateful a reference to the \c RawAllocator will be stored inside the deleter,
/// the caller has to ensure that the object lives as long as the smart pointer.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename T, class RawAllocator>
auto allocate_unique(RawAllocator&& alloc, std::size_t size) -> WPI_REQUIRES_RET(
std::is_array<T>::value,
@@ -158,13 +158,13 @@ namespace wpi
detail::forward<RawAllocator>(alloc)));
}
/// Creates a \c std::unique_ptr owning an array using a type-erased \concept{concept_rawallocator,RawAllocator} for the allocation.
/// Creates a \c std::unique_ptr owning an array using a type-erased RawAllocator for the allocation.
/// It is the same as the other overload but stores the reference to the allocator type-erased inside the \c std::unique_ptr.
/// \effects Allocates memory for an array of given size and value initializes each element inside of it.
/// \returns A \c std::unique_ptr with a type-erased allocator reference owning that array.
/// \note If the allocator is stateful a reference to the \c RawAllocator will be stored inside the deleter,
/// the caller has to ensure that the object lives as long as the smart pointer.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename T, class RawAllocator>
auto allocate_unique(any_allocator, RawAllocator&& alloc, std::size_t size)
-> WPI_REQUIRES_RET(std::is_array<T>::value,
@@ -177,13 +177,13 @@ namespace wpi
alloc)));
}
/// Creates a \c std::shared_ptr using a \concept{concept_rawallocator,RawAllocator} for the allocation.
/// Creates a \c std::shared_ptr using a RawAllocator for the allocation.
/// It is similar to \c std::allocate_shared but uses a \c RawAllocator (and thus also supports any \c Allocator).
/// \effects Calls \ref std_allocator::make_std_allocator to wrap the allocator and forwards to \c std::allocate_shared.
/// \returns A \c std::shared_ptr created using \c std::allocate_shared.
/// \note If the allocator is stateful a reference to the \c RawAllocator will be stored inside the shared pointer,
/// the caller has to ensure that the object lives as long as the smart pointer.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename T, class RawAllocator, typename... Args>
std::shared_ptr<T> allocate_shared(RawAllocator&& alloc, Args&&... args)
{

View File

@@ -27,7 +27,7 @@ namespace wpi
/// Its constructor will take a reference to it and use it for its allocation.
/// The storage type is simply a \c char array aligned for maximum alignment.
/// \note It is not allowed to access the memory of the storage.
/// \ingroup allocator
/// \ingroup memory_allocator
template <std::size_t Size>
struct static_allocator_storage
{
@@ -39,11 +39,11 @@ namespace wpi
struct allocator_info;
/// A stateful \concept{concept_rawallocator,RawAllocator} that uses a fixed sized storage for the allocations.
/// A stateful RawAllocator that uses a fixed sized storage for the allocations.
/// It works on a \ref static_allocator_storage and uses its memory for all allocations.
/// Deallocations are not supported, memory cannot be marked as freed.<br>
/// \note It is not allowed to share an \ref static_allocator_storage between multiple \ref static_allocator objects.
/// \ingroup allocator
/// \ingroup memory_allocator
class static_allocator
{
public:
@@ -60,13 +60,13 @@ namespace wpi
{
}
/// \effects A \concept{concept_rawallocator,RawAllocator} allocation function.
/// \effects A RawAllocator allocation function.
/// It uses the specified \ref static_allocator_storage.
/// \returns A pointer to a \concept{concept_node,node}, it will never be \c nullptr.
/// \returns A pointer to a node, it will never be \c nullptr.
/// \throws An exception of type \ref out_of_memory or whatever is thrown by its handler if the storage is exhausted.
void* allocate_node(std::size_t size, std::size_t alignment);
/// \effects A \concept{concept_rawallocator,RawAllocator} deallocation function.
/// \effects A RawAllocator deallocation function.
/// It does nothing, deallocation is not supported by this allocator.
void deallocate_node(void*, std::size_t, std::size_t) noexcept {}
@@ -96,11 +96,11 @@ namespace wpi
struct memory_block;
/// A \concept{concept_blockallocator,BlockAllocator} that allocates the blocks from a fixed size storage.
/// A BlockAllocator that allocates the blocks from a fixed size storage.
/// It works on a \ref static_allocator_storage and uses it for all allocations,
/// deallocations are only allowed in reversed order which is guaranteed by \ref memory_arena.
/// \note It is not allowed to share an \ref static_allocator_storage between multiple \ref static_allocator objects.
/// \ingroup allocator
/// \ingroup memory_allocator
class static_block_allocator
{
public:

View File

@@ -43,8 +43,8 @@ namespace wpi
auto propagate_on_container_copy_assignment(min_concept) -> std::true_type;
} // namespace traits_detail
/// Controls the propagation of a \ref std_allocator for a certain \concept{concept_rawallocator,RawAllocator}.
/// \ingroup adapter
/// Controls the propagation of a \ref std_allocator for a certain RawAllocator.
/// \ingroup memory_adapter
template <class RawAllocator>
struct propagation_traits
{
@@ -67,9 +67,9 @@ namespace wpi
}
};
/// Wraps a \concept{concept_rawallocator,RawAllocator} and makes it a "normal" \c Allocator.
/// Wraps a RawAllocator and makes it a "normal" \c Allocator.
/// It allows using a \c RawAllocator anywhere a \c Allocator is required.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename T, class RawAllocator>
class std_allocator :
#if defined _MSC_VER && defined __clang__
@@ -186,7 +186,7 @@ namespace wpi
}
//=== allocation/deallocation ===//
/// \effects Allocates memory using the underlying \concept{concept_rawallocator,RawAllocator}.
/// \effects Allocates memory using the underlying RawAllocator.
/// If \c n is \c 1, it will call <tt>allocate_node(sizeof(T), alignof(T))</tt>,
/// otherwise <tt>allocate_array(n, sizeof(T), alignof(T))</tt>.
/// \returns A pointer to a memory block suitable for \c n objects of type \c T.
@@ -196,7 +196,7 @@ namespace wpi
return static_cast<pointer>(allocate_impl(is_any{}, n));
}
/// \effects Deallcoates memory using the underlying \concept{concept_rawallocator,RawAllocator}.
/// \effects Deallcoates memory using the underlying RawAllocator.
/// It will forward to the deallocation function in the same way as in \ref allocate().
/// \requires The pointer must come from a previous call to \ref allocate() with the same \c n on this object or any copy of it.
void deallocate(pointer p, size_type n) noexcept
@@ -341,10 +341,10 @@ namespace wpi
return {detail::forward<RawAllocator>(allocator)};
}
/// An alias template for \ref std_allocator using a type-erased \concept{concept_rawallocator,RawAllocator}.
/// An alias template for \ref std_allocator using a type-erased RawAllocator.
/// This is the same as using a \ref std_allocator with the tag type \ref any_allocator.
/// The implementation is optimized to call fewer virtual functions.
/// \ingroup adapter
/// \ingroup memory_adapter
template <typename T>
WPI_ALIAS_TEMPLATE(any_std_allocator, std_allocator<T, any_allocator>);

View File

@@ -91,7 +91,7 @@ namespace wpi
/// A wrapper around the \ref memory_stack that is used by the \ref temporary_allocator.
/// There should be at least one per-thread.
/// \ingroup allocator
/// \ingroup memory_allocator
class temporary_stack : WPI_EBO(detail::temporary_stack_list_node)
{
public:
@@ -209,13 +209,13 @@ namespace wpi
temporary_stack& get_temporary_stack(
std::size_t initial_size = temporary_stack_initializer::default_stack_size);
/// A stateful \concept{concept_rawallocator,RawAllocator} that handles temporary allocations.
/// A stateful RawAllocator that handles temporary allocations.
/// It works similar to \c alloca() but uses a seperate \ref memory_stack for the allocations,
/// instead of the actual program stack.
/// This avoids the stack overflow error and is portable,
/// with a similar speed.
/// All allocations done in the scope of the allocator object are automatically freed when the object is destroyed.
/// \ingroup allocator
/// \ingroup memory_allocator
class temporary_allocator
{
public:
@@ -267,7 +267,7 @@ namespace wpi
/// Specialization of the \ref allocator_traits for \ref temporary_allocator classes.
/// \note It is not allowed to mix calls through the specialization and through the member functions,
/// i.e. \ref temporary_allocator::allocate() and this \c allocate_node().
/// \ingroup allocator
/// \ingroup memory_allocator
template <>
class allocator_traits<temporary_allocator>
{

View File

@@ -22,7 +22,7 @@ namespace wpi
{
/// A dummy \c Mutex class that does not lock anything.
/// It is a valid \c Mutex and can be used to disable locking anywhere a \c Mutex is requested.
/// \ingroup core
/// \ingroup memory_core
struct no_mutex
{
void lock() noexcept {}
@@ -35,11 +35,11 @@ namespace wpi
void unlock() noexcept {}
};
/// Specifies whether or not a \concept{concept_rawallocator,RawAllocator} is thread safe as-is.
/// Specifies whether or not a RawAllocator is thread safe as-is.
/// This allows to use \ref no_mutex as an optimization.
/// Note that stateless allocators are implictly thread-safe.
/// Specialize it only for your own stateful allocators.
/// \ingroup core
/// \ingroup memory_core
template <class RawAllocator>
struct is_thread_safe_allocator
: std::integral_constant<bool, !allocator_traits<RawAllocator>::is_stateful::value>

View File

@@ -69,12 +69,12 @@ namespace wpi
};
} // namespace detail
/// A \concept{concept_blockallocator,BlockAllocator} adapter that tracks another allocator using a \concept{concept_tracker,tracker}.
/// It wraps another \concept{concept_blockallocator,BlockAllocator} and calls the tracker function before forwarding to it.
/// The class can then be used anywhere a \concept{concept_blockallocator,BlockAllocator} is required and the memory usage will be tracked.<br>
/// A BlockAllocator adapter that tracks another allocator using a tracker.
/// It wraps another BlockAllocator and calls the tracker function before forwarding to it.
/// The class can then be used anywhere a BlockAllocator is required and the memory usage will be tracked.<br>
/// It will only call the <tt>on_allocator_growth()</tt> and <tt>on_allocator_shrinking()</tt> tracking functions,
/// since a \concept{concept_blockallocator,BlockAllocator} is normally used inside higher allocators only.
/// \ingroup adapter
/// since a BlockAllocator is normally used inside higher allocators only.
/// \ingroup memory_adapter
template <class Tracker, class BlockOrRawAllocator>
class tracked_block_allocator
: WPI_EBO(Tracker, make_block_allocator_t<BlockOrRawAllocator>)
@@ -84,7 +84,7 @@ namespace wpi
using tracker = Tracker;
/// @{
/// \effects Creates it by giving it a \concept{concept_tracker,tracker} and the tracked \concept{concept_rawallocator,RawAllocator}.
/// \effects Creates it by giving it a tracker and the tracked RawAllocator.
/// It will embed both objects.
explicit tracked_block_allocator(tracker t = {}) noexcept : tracker(detail::move(t)) {}
@@ -154,18 +154,18 @@ namespace wpi
/// Similar to \ref tracked_block_allocator, but shares the tracker with the higher level allocator.
/// This allows tracking both (de-)allocations and growth with one tracker.
/// \note Due to implementation reasons, it cannot track growth and shrinking in the constructor/destructor of the higher level allocator.
/// \ingroup adapter
/// \ingroup memory_adapter
template <class Tracker, class BlockOrRawAllocator>
using deeply_tracked_block_allocator = WPI_IMPL_DEFINED(
detail::deeply_tracked_block_allocator<Tracker,
make_block_allocator_t<BlockOrRawAllocator>>);
/// A \concept{concept_rawallocator,RawAllocator} adapter that tracks another allocator using a \concept{concept_tracker,tracker}.
/// It wraps another \concept{concept_rawallocator,RawAllocator} and calls the tracker function before forwarding to it.
/// The class can then be used anywhere a \concept{concept_rawallocator,RawAllocator} is required and the memory usage will be tracked.<br>
/// If the \concept{concept_rawallocator,RawAllocator} uses \ref deeply_tracked_block_allocator as \concept{concept_blockallocator,BlockAllocator},
/// A RawAllocator adapter that tracks another allocator using a tracker.
/// It wraps another RawAllocator and calls the tracker function before forwarding to it.
/// The class can then be used anywhere a RawAllocator is required and the memory usage will be tracked.<br>
/// If the RawAllocator uses \ref deeply_tracked_block_allocator as BlockAllocator,
/// it will also track growth and shrinking of the allocator.
/// \ingroup adapter
/// \ingroup memory_adapter
template <class Tracker, class RawAllocator>
class tracked_allocator
: WPI_EBO(Tracker, allocator_traits<RawAllocator>::allocator_type)
@@ -181,7 +181,7 @@ namespace wpi
|| !std::is_empty<Tracker>::value>;
/// @{
/// \effects Creates it by giving it a \concept{concept_tracker,tracker} and the tracked \concept{concept_rawallocator,RawAllocator}.
/// \effects Creates it by giving it a tracker and the tracked RawAllocator.
/// It will embed both objects.
/// \note This will never call the <tt>Tracker::on_allocator_growth()</tt> function.
explicit tracked_allocator(tracker t = {}) noexcept
@@ -350,7 +350,7 @@ namespace wpi
/// @}
};
/// \effects Takes a \concept{concept_rawallocator,RawAllocator} and wraps it with a \concept{concept_tracker,tracker}.
/// \effects Takes a RawAllocator and wraps it with a tracker.
/// \returns A \ref tracked_allocator with the corresponding parameters forwarded to the constructor.
/// \relates tracked_allocator
template <class Tracker, class RawAllocator>
@@ -403,16 +403,16 @@ namespace wpi
RawAllocator, deeply_tracked_block_allocator_for<Tracker, RawAllocator>>::type;
} // namespace detail
/// A \ref tracked_allocator that has rebound any \concept{concept_blockallocator,BlockAllocator} to the corresponding \ref deeply_tracked_block_allocator.
/// A \ref tracked_allocator that has rebound any BlockAllocator to the corresponding \ref deeply_tracked_block_allocator.
/// This makes it a deeply tracked allocator.<br>
/// It replaces each template argument of the given \concept{concept_rawallocator,RawAllocator} for which \ref is_block_allocator or \ref is_raw_allocator is \c true with a \ref deeply_tracked_block_allocator.
/// \ingroup adapter
/// It replaces each template argument of the given RawAllocator for which \ref is_block_allocator or \ref is_raw_allocator is \c true with a \ref deeply_tracked_block_allocator.
/// \ingroup memory_adapter
template <class Tracker, class RawAllocator>
WPI_ALIAS_TEMPLATE(
deeply_tracked_allocator,
tracked_allocator<Tracker, detail::rebound_allocator<Tracker, RawAllocator>>);
/// \effects Takes a \concept{concept_rawallocator,RawAllocator} and deeply wraps it with a \concept{concept_tracker,tracker}.
/// \effects Takes a RawAllocator and deeply wraps it with a tracker.
/// \returns A \ref deeply_tracked_allocator with the corresponding parameters forwarded to the constructor.
/// \relates deeply_tracked_allocator
template <class RawAllocator, class Tracker, typename... Args>

View File

@@ -36,14 +36,14 @@ namespace wpi
/// The page size of the virtual memory.
/// All virtual memory allocations must be multiple of this size.
/// It is usually 4KiB.
/// \ingroup allocator
/// \ingroup memory_allocator
/// \deprecated use \ref get_virtual_memory_page_size instead.
extern const std::size_t virtual_memory_page_size;
/// \returns the page size of the virtual memory.
/// All virtual memory allocations must be multiple of this size.
/// It is usually 4KiB.
/// \ingroup allocator
/// \ingroup memory_allocator
std::size_t get_virtual_memory_page_size() noexcept;
/// Reserves virtual memory.
@@ -52,33 +52,33 @@ namespace wpi
/// \returns The address of the first reserved page,
/// or \c nullptr in case of error.
/// \note The memory may not be used, it must first be commited.
/// \ingroup allocator
/// \ingroup memory_allocator
void* virtual_memory_reserve(std::size_t no_pages) noexcept;
/// Releases reserved virtual memory.
/// \effects Returns previously reserved pages to the system.
/// \requires \c pages must come from a previous call to \ref virtual_memory_reserve with the same \c calc_no_pages,
/// it must not be \c nullptr.
/// \ingroup allocator
/// \ingroup memory_allocator
void virtual_memory_release(void* pages, std::size_t no_pages) noexcept;
/// Commits reserved virtual memory.
/// \effects Marks \c calc_no_pages pages starting at the given address available for use.
/// \returns The beginning of the committed area, i.e. \c memory, or \c nullptr in case of error.
/// \requires The memory must be previously reserved.
/// \ingroup allocator
/// \ingroup memory_allocator
void* virtual_memory_commit(void* memory, std::size_t no_pages) noexcept;
/// Decommits commited virtual memory.
/// \effects Puts commited memory back in the reserved state.
/// \requires \c memory must come from a previous call to \ref virtual_memory_commit with the same \c calc_no_pages
/// it must not be \c nullptr.
/// \ingroup allocator
/// \ingroup memory_allocator
void virtual_memory_decommit(void* memory, std::size_t no_pages) noexcept;
/// A stateless \concept{concept_rawallocator,RawAllocator} that allocates memory using the virtual memory allocation functions.
/// A stateless RawAllocator that allocates memory using the virtual memory allocation functions.
/// It does not prereserve any memory and will always reserve and commit combined.
/// \ingroup allocator
/// \ingroup memory_allocator
class virtual_memory_allocator
: WPI_EBO(detail::global_leak_checker<detail::virtual_memory_allocator_leak_handler>)
{
@@ -94,17 +94,17 @@ namespace wpi
return *this;
}
/// \effects A \concept{concept_rawallocator,RawAllocator} allocation function.
/// \effects A RawAllocator allocation function.
/// It uses \ref virtual_memory_reserve followed by \ref virtual_memory_commit for the allocation.
/// The number of pages allocated will be the minimum to hold \c size continuous bytes,
/// i.e. \c size will be rounded up to the next multiple.
/// If debug fences are activated, one additional page before and after the memory will be allocated.
/// \returns A pointer to a \concept{concept_node,node}, it will never be \c nullptr.
/// \returns A pointer to a node, it will never be \c nullptr.
/// It will always be aligned on a fence boundary, regardless of the alignment parameter.
/// \throws An exception of type \ref out_of_memory or whatever is thrown by its handler if the allocation fails.
void* allocate_node(std::size_t size, std::size_t alignment);
/// \effects A \concept{concept_rawallocator,RawAllocator} deallocation function.
/// \effects A RawAllocator deallocation function.
/// It calls \ref virtual_memory_decommit followed by \ref virtual_memory_release for the deallocation.
void deallocate_node(void* node, std::size_t size, std::size_t alignment) noexcept;
@@ -122,10 +122,10 @@ namespace wpi
struct memory_block;
struct allocator_info;
/// A \concept{concept_blockallocator,BlockAllocator} that reserves virtual memory and commits it part by part.
/// A BlockAllocator that reserves virtual memory and commits it part by part.
/// It is similar to \ref memory_stack but does not support growing and uses virtual memory,
/// also meant for big blocks not small allocations.
/// \ingroup allocator
/// \ingroup memory_allocator
class virtual_block_allocator
{
public: