/**
 * @file Alloc.h
 * @author apio (cloudapio.eu)
 * @brief Fallible version of new.
 *
 * @copyright Copyright (c) 2022-2023, the Luna authors.
 *
 */

#pragma once
#include <luna/Heap.h>
#include <luna/PlacementNew.h>
#include <luna/Result.h>

/**
 * @brief Allocate a value on the heap and initialize it.
 *
 * When this value is no longer used, you must call delete to destroy it.
 *
 * @tparam T The type of the value.
 * @tparam Args The types of arguments to pass to the value's constructor.
 * @param args The arguments to pass to the value's constructor.
 * @return Result<T*> An error, or a pointer to the new value.
 */
template <typename T, class... Args> [[nodiscard]] Result<T*> make(Args... args)
{
    T* const result = (T*)TRY(malloc_impl(sizeof(T), false, false));
    new (result) T(args...);
    return result;
}