On 28.11.2016 11:59, Christopher J. Pisz wrote:
> On 11/28/2016 2:37 AM, Paavo Helde wrote:
>
> Memory Management is not equivalent to C++ std::allocator from what I am
> finding, and I have not found any that actually use post C++11 allocator
> requirements, that works, beyond simply adding a logging features and
> the like.
If you are interested in how exactly a memory manager works in low level
then I am pretty sure they are just working with bytes of memory, no
object type involved.
For a C++-compliant memory allocator, see e.g.
"
https://www.threadingbuildingblocks.org/tutorial-intel-tbb-scalable-memory-allocator"
Their C++-compliant allocator is just a wrapper around C-style interface
using untyped memory blocks: scalable_malloc() and scalable_free(). One
can use these directly as well. Here you have low-level implementation
which does not care about types, and the high-level C++-compliant
allocator template which works for any type (see the rebind member).
Quote from TBB scalable_allocator.h:
//! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5
/** The members are ordered the same way they are in section 20.4.1
of the ISO C++ standard.
@ingroup memory_allocation */
template<typename T>
class scalable_allocator {
public:
typedef typename internal::allocator_type<T>::value_type value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
template<class U> struct rebind {
typedef scalable_allocator<U> other;
};
scalable_allocator() throw() {}
scalable_allocator( const scalable_allocator& ) throw() {}
template<typename U> scalable_allocator(const
scalable_allocator<U>&) throw() {}
pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}
//! Allocate space for n objects.
pointer allocate( size_type n, const void* /*hint*/ =0 ) {
return static_cast<pointer>( scalable_malloc( n *
sizeof(value_type) ) );
}
//! Free previously allocated block of memory
void deallocate( pointer p, size_type ) {
scalable_free( p );
}
//! Largest value for which method allocate might succeed.
size_type max_size() const throw() {
size_type absolutemax = static_cast<size_type>(-1) / sizeof
(value_type);
return (absolutemax > 0 ? absolutemax : 1);
}
#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
template<typename U, typename... Args>
void construct(U *p, Args&&... args)
{ ::new((void *)p) U(std::forward<Args>(args)...); }
#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
#if __TBB_CPP11_RVALUE_REF_PRESENT
void construct( pointer p, value_type&& value ) { ::new((void*)(p))
value_type( std::move( value ) ); }
#endif
void construct( pointer p, const value_type& value )
{::new((void*)(p)) value_type(value);}
#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
void destroy( pointer p ) {p->~value_type();}
};