Skip to content

Instantly share code, notes, and snippets.

@DrkWithT
Created January 31, 2025 18:36
Show Gist options
  • Save DrkWithT/ade725f028219d6998f8010774f860c9 to your computer and use it in GitHub Desktop.
Save DrkWithT/ade725f028219d6998f8010774f860c9 to your computer and use it in GitHub Desktop.
Example function wrapper for educational purposes
#include <memory>
#include <iostream>
enum class MyStorageKind {
static_ptr, // pointer to non-member function
dud_ptr
};
template <typename Result, typename... Args>
class MyFunc {
private:
struct IStorage {
using stored_fn = Result(Args...);
using stored_p = stored_fn*;
virtual ~IStorage() = default;
virtual MyStorageKind getKind() const noexcept = 0;
virtual stored_p getPtr() const noexcept = 0;
};
template <MyStorageKind K, typename ResP, typename... ArgP>
struct Invocable {};
template <typename ResP, typename... ArgP>
struct Invocable <MyStorageKind::static_ptr, ResP, ArgP...> : public IStorage {
using func_type = ResP(ArgP...);
func_type* m_ptr;
Invocable() = delete;
Invocable(func_type* ptr) noexcept
: m_ptr {ptr} {}
[[nodiscard]] MyStorageKind getKind() const noexcept override {
return MyStorageKind::static_ptr;
}
[[nodiscard]] func_type* getPtr() const noexcept override {
return m_ptr;
}
};
std::unique_ptr<IStorage> m_fn_store;
bool m_has_addr;
public:
using func_type_2 = Result(Args...);
MyFunc() = delete;
MyFunc(func_type_2* ptr)
: m_fn_store {std::make_unique<Invocable<MyStorageKind::static_ptr, Result, Args...>>(ptr)}, m_has_addr {ptr != nullptr} {}
/// TODO: add copy, move operations
[[nodiscard]] Result operator()(Args... args) const {
if (m_has_addr) {
return m_fn_store->getPtr()(args...);
}
return Result {};
}
};
int avgThree(int a, int b, int c) {
return (a + b + c) / 3;
}
int main() {
MyFunc avg {avgThree};
std::cout << avg(15, 5, 35);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment