57 lines
1.4 KiB
C++
57 lines
1.4 KiB
C++
#pragma once
|
|
|
|
#include <openssl/evp.h>
|
|
#include <openssl/x509.h>
|
|
|
|
#include <memory>
|
|
|
|
// Specializations must Free to release a reference
|
|
// Specializations can implement UpRef to increase a reference count on copy
|
|
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;
|
|
// this type does not implement UpRef
|
|
};
|
|
|
|
template <typename T>
|
|
struct RefDeleter {
|
|
auto operator()(T *ptr) const -> void { RefTraits<T>::Free(ptr); }
|
|
};
|
|
|
|
template <typename T>
|
|
struct Ref : std::unique_ptr<T, RefDeleter<T>>
|
|
{
|
|
using base = std::unique_ptr<T, RefDeleter<T>>;
|
|
|
|
/// Owns nothing
|
|
Ref() noexcept = default;
|
|
|
|
/// Takes ownership of the pointer
|
|
explicit Ref(T *x) noexcept : base{x} {}
|
|
|
|
Ref(Ref &&ref) noexcept = default;
|
|
Ref(const Ref &ref) noexcept {
|
|
*this = ref;
|
|
}
|
|
|
|
Ref &operator=(Ref&&) noexcept = default;
|
|
Ref &operator=(const Ref &ref) noexcept {
|
|
if (ref) {
|
|
RefTraits<T>::UpRef(ref.get());
|
|
}
|
|
this->reset(ref.get());
|
|
return *this;
|
|
}
|
|
};
|