xbot/myirc/include/ref.hpp

47 lines
1.1 KiB
C++

#pragma once
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <memory>
template <typename> struct RefTraits {};
template <> struct RefTraits<EVP_PKEY> {
static constexpr void (*Free)(EVP_PKEY*) = EVP_PKEY_free;
static constexpr int (*UpRef)(EVP_PKEY*) = EVP_PKEY_up_ref;
};
template <> struct RefTraits<X509> {
static constexpr void (*Free)(X509*) = X509_free;
static constexpr int (*UpRef)(X509*) = X509_up_ref;
};
template <> struct RefTraits<EVP_PKEY_CTX> {
static constexpr void (*Free)(EVP_PKEY_CTX*) = EVP_PKEY_CTX_free;
};
template <typename T>
struct FnDeleter {
auto operator()(T *ptr) const -> void { RefTraits<T>::Free(ptr); }
};
template <typename T>
struct Ref : std::unique_ptr<T, FnDeleter<T>> {
using std::unique_ptr<T, FnDeleter<T>>::unique_ptr;
Ref(const Ref &ref) {
*this = ref;
}
Ref &operator=(const Ref &ref) {
if (ref) {
RefTraits<T>::UpRef(ref.get());
this->reset(ref.get());
}
return *this;
}
};
using EVP_PKEY_CTX_Ref = Ref<EVP_PKEY_CTX>;
using X509_Ref = Ref<X509>;
using EVP_PKEY_Ref = Ref<EVP_PKEY>;