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