//**************************************************************************************************
//
// MEMORY MANIPULATION ROUTINES:
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// RuntimeForStatic base library | C+- (SysRoutine) | Author: Sergei Y.Kitáev
#pragma once
#include "include_restrictions.h"
namespace RuntimeForStatic {

//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//
// "$Memory" STATIC CLASS:
//
//==================================================================================================
class $Memory
{
$STATIC_CLASS( $Memory )
public:
   static PVOID Allocate($AM, SIZE_T size $not_zero ) $fatal_error_on_failure;
   static PVOID Allocate($AM, SIZE_T size $not_zero, int count $not_zero ) $fatal_error_on_failure;
   static PVOID CleanAlloc($AM, SIZE_T size $not_zero ) $fatal_error_on_failure;
   static PVOID CleanAlloc($AM, SIZE_T size $not_zero, int count $not_zero )
                                $fatal_error_on_failure;
   static PVOID ReAllocate($AM, PVOID memoryBlock, SIZE_T newSize ) $fatal_error_on_failure;
   static PVOID ReAllocate($AM, PVOID memoryBlock, SIZE_T size, int newCount $not_zero )
                                $fatal_error_on_failure;

   static PVOID Allocate($A,$M, SIZE_T size $not_zero ) $fatal_error_on_failure;
   static PVOID Allocate($A,$M, SIZE_T size $not_zero, int count $not_zero )
                                $fatal_error_on_failure;
   static PVOID CleanAlloc($A,$M, SIZE_T size $not_zero ) $fatal_error_on_failure;
   static PVOID CleanAlloc($A,$M, SIZE_T size $not_zero, int count $not_zero )
                                  $fatal_error_on_failure;
   static PVOID ReAllocate($A,$M, PVOID memoryBlock, SIZE_T newSize ) $fatal_error_on_failure;
   static PVOID ReAllocate($A,$M, PVOID memoryBlock, SIZE_T size, int newCount $not_zero )
                                  $fatal_error_on_failure;

   static void Free( PVOID memoryBlock $optional );
   static void Free( PVOID memoryBlock $optional,
                     $MemFreeRoutine specialFreeRoutine $optional );
   static void Free( const std::initializer_list<PVOID>& memoryBlockPointers $optionals );
   static void Free( const std::initializer_list<PVOID>& memoryBlockPointers $optionals,
                     $MemFreeRoutine specialFreeRoutine $optional );

   static void FreeByPtr($A, PVOID volatile* pPointer $p_optional );
   static void FreeByPtr($A, PVOID volatile* pPointer $p_optional,
                             $MemFreeRoutine specialFreeRoutine $optional );
   static void FreeByPointers($A, const std::initializer_list<PVOID volatile*>& ptrPointers
                                                                                $p_optional_list );
   static void FreeByPointers($A, const std::initializer_list<PVOID volatile*>& ptrPointers
                                                                                $p_optional_list,
                                  $MemFreeRoutine specialFreeRoutine $optional );
public:
   static PVOID AllocateNS($AM, SIZE_T size $not_zero ) $null_on_failure $last_error;
   static PVOID AllocateNS($AM, SIZE_T size $not_zero, int count $not_zero )
                                $null_on_failure $last_error;
   static PVOID CleanAllocNS($AM, SIZE_T size $not_zero ) $null_on_failure $last_error;
   static PVOID CleanAllocNS($AM, SIZE_T size $not_zero, int count $not_zero )
                                  $null_on_failure $last_error;
   static PVOID ReAllocateNS($AM, PVOID memoryBlock, SIZE_T newSize ) $null_on_failure $last_error;
   static PVOID ReAllocateNS($AM, PVOID memoryBlock, SIZE_T size, int newCount $not_zero )
                                  $null_on_failure $last_error;

   static PVOID AllocateNS($A,$M, SIZE_T size $not_zero ) $null_on_failure $last_error;
   static PVOID AllocateNS($A,$M, SIZE_T size $not_zero, int count $not_zero )
                                  $null_on_failure $last_error;
   static PVOID CleanAllocNS($A,$M, SIZE_T size $not_zero ) $null_on_failure $last_error;
   static PVOID CleanAllocNS($A,$M, SIZE_T size $not_zero, int count $not_zero )
                                    $null_on_failure $last_error;
   static PVOID ReAllocateNS($A,$M, PVOID memoryBlock, SIZE_T newSize )
                                    $null_on_failure $last_error;
   static PVOID ReAllocateNS($A,$M, PVOID memoryBlock, SIZE_T size, int newCount $not_zero )
                                    $null_on_failure $last_error;
public:
   static SIZE_T Size($A, PVOID memoryBlock ) $fatal_error_on_failure;

   static PVOID TwiceEnlarge($AM, PVOID memoryBlock ) $fatal_error_on_failure;
   static PVOID TwiceEnlargeNS($AM, PVOID memoryBlock ) $null_on_failure $last_error;

   static PVOID TwiceEnlarge($A,$M, PVOID memoryBlock ) $fatal_error_on_failure;
   static PVOID TwiceEnlargeNS($A,$M, PVOID memoryBlock ) $null_on_failure $last_error;
public:
   static void SysLocalFree($A,PVOID memoryBlock $optional) $fatal_error_on_failure;
public:
   static PVOID Clear($A,PVOID memoryBlock,SIZE_T size $not_zero) $ret_target;
   static PVOID Copy($A,$PCVoid source,PVOID target,SIZE_T size $not_zero) $ret_target;
public:
   static int VerifyAllocationSize($A,SIZE_T size $not_zero) $fatal_error_on_failure;
   static void Fail_AllocationSizeExcess( $CI_REF ) $not_returns;
   static void Fail_IncorrectPointerForBlockSizeRequest( $CI_REF ) $not_returns;
   static PCWSTR AllocationSizeExcess_MessageFmt() $static_pointer $not_null;
   static PCWSTR IncorrectPointerForBlockSizeRequest_Message() $static_pointer $not_null;
   static PCWSTR SizeTooLargeForTwiceEnlarge_Message() $static_pointer $not_null;
}; // $Memory
//==================================================================================================

} // RuntimeForStatic
