static_assert( __cplusplus > 2020'99 ); #pragma once #include #include #include #include #include namespace Alepha::Hydrogen::Memory ::detail:: ThreadSlab_m { inline namespace exports {} namespace exports::inline ThreadSlab { template< typename T > class Allocator; using String= std::basic_string< char, std::char_traits< char >, Allocator< char > >; template< typename T > using Vector= std::vector< T, Allocator< T > >; template< typename K, typename V, typename Compare= std::less< K > > using Map= std::map< K, V, Allocator< std::pair< const K, V > > >; } namespace shim { [[nodiscard]] void *allocate( std::size_t ); void deallocate( void * ) noexcept; Blob &slab(); } template< typename T > struct BlockFromSlab { std::byte raw[ sizeof( T ) ]; [[nodiscard]] static void * operator new [] ( const std::size_t sz ) { return shim::allocate( sz ); } static void operator delete [] ( void *const p ) noexcept { return shim::deallocate( p ); } }; template< typename T > class exports::Allocator { public: using value_type= T; using propagate_on_container_copy_assignment= std::true_type; using propagate_on_container_move_assignment= std::true_type; using propagate_on_container_swap= std::true_type; using is_always_equal= std::true_type; Allocator select_on_container_copy_construction() { auto rv= Allocator{}; } Allocator()= default; Allocator &operator= ( const Allocator &other )= default; Allocator( const Allocator &other )= default; Allocator( Allocator &&other ) : Allocator( std::as_const( other ) ) {} ~Allocator()= default; static Blob &slab() { return shim::slab(); } [[nodiscard]] T * allocate( const std::size_t amt ) { return reinterpret_cast< T * >( new BlockFromSlab< T >[ amt ] ); } void deallocate( T *const p, const std::size_t /* ignored */ ) noexcept { return BlockFromSlab< T >::operator delete [] ( p ); } friend constexpr bool operator == ( const Allocator &, const Allocator & ) noexcept { return true; } }; } namespace Alepha::Hydrogen::Memory::inline exports::inline ThreadSlab_m { using namespace detail::ThreadSlab_m::exports; }