// -*- C++ -*- (c) 2015 Jiří Weiser // (c) 2016 Jan Mrázek #include #include #include #include "sys/divm.h" #ifndef _DIOS_MEMORY_H_ #define _DIOS_MEMORY_H_ #if __cplusplus >= 201103L #define NOTHROW noexcept #else #define NOTHROW throw() #endif namespace __dios { struct AllocatorBase { using pointer = void *; using const_pointer = const void *; using size_type = std::size_t; using difference_type = std::ptrdiff_t; AllocatorBase() {} AllocatorBase( const AllocatorBase & ) {}; template< typename U > AllocatorBase( const std::allocator< U > & ) {} pointer allocate( size_type n, __attribute__((unused)) const_pointer hint = nullptr ) { #ifdef __divine__ return static_cast< pointer >( __vm_obj_make( n ) ); #else return std::allocator< char >().allocate( n, hint ); #endif } void deallocate( pointer p, __attribute__((unused)) size_type n ) { #ifdef __divine__ __vm_obj_free( p ); #else char *_p = static_cast< char * >( p ); std::allocator< char >().deallocate( _p, n ); #endif } size_type max_size() const { #ifdef __divine__ return std::numeric_limits< std::int32_t >::max(); #else return std::numeric_limits< size_type >::max(); #endif } template< typename U, typename... Args > void construct( U *p, Args &&... args ) { ::new( p ) U( std::forward< Args >( args )... ); } template< typename U > void destroy( U *p ) { p->~U(); } }; template< typename T > struct Allocator : AllocatorBase { // STL compatibility typedefs using value_type = T; using pointer = T *; using const_pointer = const T *; using reference = T &; using const_reference = const T &; // using propagate_on_container_move_assignment = std::true_type; // C++14 // using is_always_equal = std::true_type; // C++17 Allocator() {} Allocator( const Allocator & ) {}; template< typename U > Allocator( const Allocator< U > & ) {} template< typename U > Allocator( const std::allocator< U > & ) {} template< typename U > struct rebind { using other = Allocator< U >; }; pointer address( reference x ) const { return &x; } const_pointer address( const_reference x ) const { return &x; } pointer allocate( size_type n, const_pointer hint = nullptr ) { return static_cast< pointer >( AllocatorBase::allocate( n * sizeof( value_type ), hint ) ); } void deallocate( pointer p, size_type n ) { AllocatorBase::deallocate( p, n * sizeof( value_type ) ); } }; using AllocatorPure = Allocator< char >; template< typename T1, typename T2 > bool operator==( const Allocator< T1 > &, const Allocator< T2 > & ) { return true; } template< typename T1, typename T2 > bool operator!=( const Allocator< T1 > &, const Allocator< T2 > & ) { return false; } struct nofail_t {}; extern nofail_t nofail; } // namespace __dios void *operator new( std::size_t count, const __dios::nofail_t & ) NOTHROW; void *operator new[]( std::size_t count, const __dios::nofail_t & ) NOTHROW; #endif // _DIOS_MEMORY_H_