#include <utility>
#include "seal/c/memorymanager.h"
#include "seal/c/utilities.h"
#include "seal/memorymanager.h"
using namespace std;
using namespace seal;
using namespace seal::c;
namespace
{
template <class T>
HRESULT GenericCreateProfileCopy(T *original, MMProf **copyptr)
{
T *copy = new T(*original);
*copyptr = copy;
return S_OK;
}
HRESULT CreateProfileCopy(MMProf *profile, MMProf **copyptr)
{
IfNullRet(profile, E_POINTER);
IfNullRet(copyptr, E_POINTER);
MMProfGlobal *global = dynamic_cast<MMProfGlobal *>(profile);
if (nullptr != global)
{
return GenericCreateProfileCopy(global, copyptr);
}
MMProfFixed *fixed = dynamic_cast<MMProfFixed *>(profile);
if (nullptr != fixed)
{
return GenericCreateProfileCopy(fixed, copyptr);
}
MMProfNew *newprof = dynamic_cast<MMProfNew *>(profile);
if (nullptr != newprof)
{
return GenericCreateProfileCopy(newprof, copyptr);
}
MMProfThreadLocal *threadlocal = dynamic_cast<MMProfThreadLocal *>(profile);
if (nullptr != threadlocal)
{
return GenericCreateProfileCopy(threadlocal, copyptr);
}
return E_UNEXPECTED;
}
}
SEAL_C_FUNC MemoryManager_GetPool1(int prof_opt, bool clear_on_destruction, void **pool_handle)
{
IfNullRet(pool_handle, E_POINTER);
mm_prof_opt profile_opt = static_cast<mm_prof_opt>(prof_opt);
MemoryPoolHandle handle;
if (profile_opt == mm_prof_opt::mm_force_new)
{
handle = MemoryManager::GetPool(profile_opt, clear_on_destruction);
}
else
{
handle = MemoryManager::GetPool(profile_opt);
}
MemoryPoolHandle *handle_ptr = new MemoryPoolHandle(move(handle));
*pool_handle = handle_ptr;
return S_OK;
}
SEAL_C_FUNC MemoryManager_GetPool2(void **pool_handle)
{
IfNullRet(pool_handle, E_POINTER);
MemoryPoolHandle handle = MemoryManager::GetPool();
MemoryPoolHandle *handle_ptr = new MemoryPoolHandle(move(handle));
*pool_handle = handle_ptr;
return S_OK;
}
SEAL_C_FUNC MemoryManager_SwitchProfile(void *new_profile)
{
MMProf *profile = FromVoid<MMProf>(new_profile);
IfNullRet(profile, E_POINTER);
MMProf *new_mm_profile = nullptr;
IfFailRet(CreateProfileCopy(profile, &new_mm_profile));
MemoryManager::SwitchProfile(move(static_cast<MMProf *>(new_mm_profile)));
return S_OK;
}
SEAL_C_FUNC MMProf_CreateGlobal(void **profile)
{
IfNullRet(profile, E_POINTER);
MMProfGlobal *global = new MMProfGlobal();
*profile = global;
return S_OK;
}
SEAL_C_FUNC MMProf_CreateFixed(void *pool, void **profile)
{
MemoryPoolHandle *poolptr = FromVoid<MemoryPoolHandle>(pool);
IfNullRet(poolptr, E_POINTER);
IfNullRet(profile, E_POINTER);
MemoryPoolHandle myhandle(*poolptr);
MMProfFixed *fixed = new MMProfFixed(myhandle);
*profile = fixed;
return S_OK;
}
SEAL_C_FUNC MMProf_CreateNew(void **profile)
{
IfNullRet(profile, E_POINTER);
MMProfNew *newprof = new MMProfNew();
*profile = newprof;
return S_OK;
}
SEAL_C_FUNC MMProf_CreateThreadLocal(void **profile)
{
IfNullRet(profile, E_POINTER);
MMProfThreadLocal *threadlocal = new MMProfThreadLocal();
*profile = threadlocal;
return S_OK;
}
SEAL_C_FUNC MMProf_GetPool(void *thisptr, void **pool_handle)
{
MMProf *profile = FromVoid<MMProf>(thisptr);
IfNullRet(profile, E_POINTER);
IfNullRet(pool_handle, E_POINTER);
MemoryPoolHandle *handle_ptr = new MemoryPoolHandle(profile->get_pool(0));
*pool_handle = handle_ptr;
return S_OK;
}
SEAL_C_FUNC MMProf_Destroy(void *thisptr)
{
MMProf *profile = FromVoid<MMProf>(thisptr);
IfNullRet(profile, E_POINTER);
delete profile;
return S_OK;
}