//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.ComponentModel;

namespace CommonHelpers {

//**************************************************************************************************
partial class HUnsafeMemory {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static unsafe void* Clear<T>([HOut] void* pDestinationElements) where T: struct
{
   return (void*)HMemory.Clear<T>( (IntPtr)pDestinationElements );
}

public static unsafe void* Clear<T>([HOut] void* pDestinationElements,int? count) where T: struct
{
   return (void*)HMemory.Clear<T>( (IntPtr)pDestinationElements, count );
}

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

public static unsafe void* Copy<T>( [HIn] void* pSourceElements,
                                    [HOut] void* pDestinationElements,
                                    int count ) where T: struct
{
   return (void*)HMemory.Copy<T>( (IntPtr)pSourceElements, (IntPtr)pDestinationElements, count );
}

//==================================================================================================

public static unsafe T[] ToArray<T>([HIn] void* pSourceElements,int count) where T: struct
{
   HUnsafePtrArgChecking.VerifyNotNull( pSourceElements );
   if ( count < 0 )
      throw new ArgumentException(
         "Negative source element count for copy-to-array operation.",
         nameof( count ) );
   if ( count == 0 )
      return new T[0];
   return PAccessHlp.Impl.CopyBufferToArray<T>( pSourceElements, new T[ count ] );
}

//==================================================================================================

/// <exception cref="HOperationFailedException" />
public static unsafe void* Allocate<T>() where T: struct
{
   return (void*)HMemory.Allocate<T>();
}

/// <exception cref="HOperationFailedException" />
public static unsafe void* Allocate<T>(int capacity) where T: struct
{
   return (void*)HMemory.Allocate<T>( capacity );
}

/// <exception cref="HOperationFailedException" />
public static unsafe void* ReAllocate<T>( [HIn] void* pAllocatedBuffer,
                                          int newCapacity ) where T: struct
{
   return (void*)HMemory.ReAllocate<T>( (IntPtr)pAllocatedBuffer, newCapacity );
}

/// <exception cref="HOperationFailedException" />
public static unsafe void* ReAllocate<T>( [HIn] ref void* pAllocatedBuffer,
                                          int newCapacity ) where T: struct
{
   return pAllocatedBuffer = ReAllocate( pAllocatedBuffer, newCapacity );
}

/// <exception cref="HOperationFailedException" />
public static unsafe void* Duplicate<T>([HIn] void* pAllocatedBuffer) where T: struct
{
   return (void*)HMemory.Duplicate<T>( (IntPtr)pAllocatedBuffer );
}

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

/// <exception cref="HOperationFailedException" />
public static unsafe int GetAllocatedCapacity<T>(void* pAllocatedBuffer) where T: struct
{
   return HMemory.GetAllocatedCapacity<T>( (IntPtr)pAllocatedBuffer );
}

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

/// <exception cref="Win32Exception" />
public static unsafe bool Free<T>([HOptional] void* pAllocatedBuffer) where T: struct
{
   return HMemory.Free<T>( (IntPtr)pAllocatedBuffer );
}

/// <exception cref="Win32Exception" />
public static unsafe bool Free<T>( [HOptional][HInterlockedAccess]
                                   void** ppAllocatedBuffer ) where T: struct
{
   return Free( HUnsafePtr.InterlockedNullValueExchange( ppAllocatedBuffer ) );
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HUnsafeMemory
//**************************************************************************************************

} // CommonHelpers
