Created
September 17, 2022 17:35
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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