Skip to content

Instantly share code, notes, and snippets.

@e2thenegpii
Created September 17, 2022 17:35
Show Gist options
  • Save e2thenegpii/611889c81a517a81995f986095b63420 to your computer and use it in GitHub Desktop.
Save e2thenegpii/611889c81a517a81995f986095b63420 to your computer and use it in GitHub Desktop.
Code invoke a generic com-esk object function and overload the return value in the case of a BSTR
#include <functional>
#include <memory>
#include <iostream>
#include <tuple>
static constexpr const char* strval = "The quick brown fox jumps over the lazy dog";
using BSTR = const char*;
struct foo1
{
int get_vall(long* v)
{
std::cout << "In get_vall" << std::endl;
*v = 5;
return 0;
}
int get_vals(const char** v)
{
std::cout << "In get_vals" << std::endl;
*v = strval;
return 0;
}
};
void cleaner(BSTR* ptr)
{
std::cout << "Cleaning " << *ptr << std::endl;
}
template <typename Obj, typename Arg> using comfetcher_f = int(Obj::*)(Arg*);
namespace detail
{
template <typename Obj, typename Arg>
struct com_fetcher_helper
{
std::tuple<int, Arg> operator()(comfetcher_f<Obj, Arg> funct, Obj& obj)
{
Arg arg;
if (int ret = std::invoke(funct, obj, &arg); ret != 0)
{
throw ret;
}
else
{
return {ret, arg};
}
}
};
template <typename Obj>
struct com_fetcher_helper<Obj, BSTR>
{
std::tuple<int, std::shared_ptr<BSTR>> operator()(comfetcher_f<Obj, BSTR> funct, Obj& obj)
{
BSTR arg = nullptr;
if (int ret = std::invoke(funct, obj, &arg); ret != 0)
{
throw ret;
}
else
{
return {ret, std::shared_ptr<BSTR>(&arg, cleaner) };
}
}
};
}
template <typename Obj, typename Arg>
auto com_fetcher(comfetcher_f<Obj, Arg> funct, Obj& obj)
{
return detail::com_fetcher_helper<Obj, Arg>()(std::forward<comfetcher_f<Obj, Arg>>(funct), std::forward<Obj&>(obj));
}
int main()
{
foo1 x;
auto [rval1, vall] = com_fetcher(&foo1::get_vall, x);
std::cout << "Value of foo1::get_vall=" << vall << std::endl;
auto [rval2, vals] = com_fetcher(&foo1::get_vals, x);
std::cout << "Value of foo2::get_vals=" << *vals << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment