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

template<typename T>static T* Clear($A,T* pElement) $ret_target;
template<typename T>static T* Clear($A,T* pElements,int count $positive) $ret_target;

template<typename T>static T* ClearIfNotNull(T* pElement $optional ) $ret_target;
template<typename T>static T* ClearIfNotNull(T* pElements $optional,
                                                int count $positive ) $ret_target;

template<typename T>static T* Copy($A, const T* pSourceElement, T* pTargetElement ) $ret_target;
template<typename T>static T* Copy($A, const T* pSourceElements, T* pTargetElements,
                                       int count $positive ) $ret_target;

//--------------------------------------------------------------------------------------------------

template<typename T>static T* Allocate($M) $fatal_error_on_failure;
template<typename T>static T* Allocate($AM, int count $positive ) $fatal_error_on_failure;
template<typename T>static T* CleanAlloc($M) $fatal_error_on_failure;
template<typename T>static T* CleanAlloc($AM, int count $positive ) $fatal_error_on_failure;
template<typename T>static T* ReAllocate($AM, T* pElements,
                                              int newCount $positive ) $fatal_error_on_failure;

template<typename T>static T* Allocate($A,$M, int count $positive ) $fatal_error_on_failure;
template<typename T>static T* CleanAlloc($A,$M, int count $positive ) $fatal_error_on_failure;
template<typename T>static T* ReAllocate($A,$M, T* pElements,
                                                int newCount $positive ) $fatal_error_on_failure;

template<typename T>static T* Free( T*& pElements $optional ) $ret_null;
template<typename T>static T* Free( const std::initializer_list<T*&>& listOfPointers $optionals )
                                    $ret_null;

template<typename T>static T* FreeByPtr( T* volatile* ppElements $optional ) $ret_null;
template<typename T>static T* FreeByPointers( const std::initializer_list<T* volatile*>&
                                              listOfPtrPointers $optionals ) $ret_null;

//-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

template<typename T>static T* AllocateNS($M) $null_on_failure $last_error;
template<typename T>static T* AllocateNS($AM, int count $positive ) $null_on_failure $last_error;
template<typename T>static T* CleanAllocNS($M) $null_on_failure $last_error;
template<typename T>static T* CleanAllocNS($AM, int count $positive ) $null_on_failure $last_error;
template<typename T>static T* ReAllocateNS($AM, T* pElements,
                                                int newCount $positive ) $null_on_failure
                                                                         $last_error;

template<typename T>static T* AllocateNS($A,$M, int count $positive ) $null_on_failure $last_error;
template<typename T>static T* CleanAllocNS($A,$M, int count $positive )
                                                  $null_on_failure $last_error;
template<typename T>static T* ReAllocateNS($A,$M, T* pElements,
                                                  int newCount $positive ) $null_on_failure
                                                                           $last_error;

//--------------------------------------------------------------------------------------------------

template<typename T>static T* TwiceEnlarge($AM, T* pElements ) $fatal_error_on_failure;
template<typename T>static T* TwiceEnlargeNS($AM, T* pElements ) $null_on_failure
                                                                 $last_error;

template<typename T>static T* TwiceEnlarge($A,$M, T* pElements ) $fatal_error_on_failure;
template<typename T>static T* TwiceEnlargeNS($A,$M, T* pElements ) $null_on_failure
                                                                   $last_error;

//--------------------------------------------------------------------------------------------------
}; // $memory
//==================================================================================================
} // RuntimeForStatic
