#ifndef PMEMOBJ_MAKE_PERSISTENT_HPP
#define PMEMOBJ_MAKE_PERSISTENT_HPP
#include "libpmemobj++/detail/check_persistent_ptr_array.hpp"
#include "libpmemobj++/detail/common.hpp"
#include "libpmemobj++/detail/life.hpp"
#include "libpmemobj++/detail/pexceptions.hpp"
#include "libpmemobj/tx_base.h"
#include <new>
#include <utility>
namespace pmem
{
namespace obj
{
template <typename T, typename... Args>
typename detail::pp_if_not_array<T>::type
make_persistent(Args &&... args)
{
if (pmemobj_tx_stage() != TX_STAGE_WORK)
throw transaction_scope_error(
"refusing to allocate "
"memory outside of transaction scope");
persistent_ptr<T> ptr =
pmemobj_tx_alloc(sizeof(T), detail::type_num<T>());
if (ptr == nullptr)
throw transaction_alloc_error("failed to allocate "
"persistent memory object");
try {
detail::create<T, Args...>(ptr.get(),
std::forward<Args>(args)...);
} catch (...) {
pmemobj_tx_free(*ptr.raw_ptr());
throw;
}
return ptr;
}
template <typename T>
void
delete_persistent(typename detail::pp_if_not_array<T>::type ptr)
{
if (pmemobj_tx_stage() != TX_STAGE_WORK)
throw transaction_scope_error(
"refusing to free "
"memory outside of transaction scope");
if (ptr == nullptr)
return;
detail::destroy<T>(*ptr);
if (pmemobj_tx_free(*ptr.raw_ptr()) != 0)
throw transaction_free_error("failed to delete "
"persistent memory object");
}
}
}
#endif