Current section
Files
Jump to
Current section
Files
c_src/egit_utils.hpp
#pragma once
#include <tuple>
#include <string>
#include <memory>
#include <type_traits>
#include <erl_nif.h>
#include "egit_atoms.hpp"
/*
#define SMART_PTR(var, deleter) \
std::unique_ptr<std::remove_pointer<decltype(var)>::type, void(*)(decltype(var))> p ## var(var, deleter)
*/
template <typename T>
struct SmartPtr {
using type = T;
typedef void(*Deleter)(T*);
explicit SmartPtr(Deleter del, T* p = nullptr) : m_ptr(p), m_del(del) {
assert(m_del);
}
~SmartPtr() {
if (m_ptr) { m_del(m_ptr); m_ptr = nullptr; }
}
T** operator&() { return &m_ptr; }
T const* operator->() const { return m_ptr; }
//T* operator->() { return m_ptr; }
bool operator!() const { return m_ptr == nullptr; }
// Cast operator
operator const T*() const { return (const T*)m_ptr; }
operator T*() const { return m_ptr; }
operator bool() const { return m_ptr != nullptr; }
T const* get() const { return m_ptr; }
T* get() { return m_ptr; }
template <typename U>
U cast() { return reinterpret_cast<U>(m_ptr); }
private:
T* m_ptr;
Deleter m_del;
};
template <typename T>
struct ScopeCleanup {
ScopeCleanup(T fun) : m_fun(fun) {}
~ScopeCleanup() { m_fun(); }
private:
T m_fun;
};
inline std::string oid_to_str(git_oid const& oid)
{
auto out = std::string(GIT_OID_SHA1_HEXSIZE, '\0');
git_oid_tostr(out.data(), out.size()+1, &oid);
return out;
}
inline std::string oid_to_str(git_oid const* oid) { return oid_to_str(*oid); }
inline std::tuple<ERL_NIF_TERM, unsigned char*>
make_binary(ErlNifEnv* env, size_t size)
{
ERL_NIF_TERM term;
auto p = enif_make_new_binary(env, size, &term);
return std::make_tuple(term, p);
}
inline ERL_NIF_TERM make_binary(ErlNifEnv* env, std::string_view const& str)
{
auto [term, p] = make_binary(env, str.length());
memcpy(p, str.data(), str.length());
return term;
}
inline ERL_NIF_TERM fmt_git_error(ErlNifEnv* env, std::string const& pfx)
{
char buf[256];
const char* delim = "";
const char* err = "";
if (git_error_last())
err = git_error_last()->message;
if (git_error_last() && !pfx.empty())
delim = ": ";
snprintf(buf, sizeof(buf), "%s%s%s", pfx.c_str(), delim, err);
return make_binary(env, buf);
}
inline ERL_NIF_TERM raise_git_error(ErlNifEnv* env, std::string const& pfx)
{
return enif_raise_exception(env, fmt_git_error(env, pfx));
}
inline ERL_NIF_TERM make_git_error(ErlNifEnv* env, std::string const& pfx)
{
return enif_make_tuple2(env, ATOM_ERROR, fmt_git_error(env, pfx));
}
inline ERL_NIF_TERM make_error(ErlNifEnv* env, std::string_view const& err)
{
return enif_make_tuple2(env, ATOM_ERROR, make_binary(env, err));
}
inline ERL_NIF_TERM make_error(ErlNifEnv* env, ERL_NIF_TERM err)
{
return enif_make_tuple2(env, ATOM_ERROR, err);
}