Skip to content

Instantly share code, notes, and snippets.

@marty1885
Created June 29, 2021 12:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marty1885/62b49260be6c1582d8cd632c986f57a8 to your computer and use it in GitHub Desktop.
Save marty1885/62b49260be6c1582d8cd632c986f57a8 to your computer and use it in GitHub Desktop.
#include <cstddef>
#include <functional>
#include <memory>
#include <utility>
#include <stdexcept>
#include <iostream>
template <typename>
struct shared_function{};
/**
* @brief A shared function object that performs shallow copy by default
* @note The operator std::function<...> is intentionally omited so it gets wrapped when passed into a std::function. Allowing the shallow copy capablity to propergate
*/
template <typename R, typename... Args>
struct shared_function<R(Args...)>
{
using function_type = std::function<R(Args...)>;
using result_type = R;
shared_function() = default;
shared_function(const function_type& f) : fptr_(std::make_shared<function_type>(f)) {}
shared_function(function_type&& f) : fptr_(std::make_shared<function_type>(std::move(f))) {}
shared_function(const shared_function<R(Args...)>& other)
{
fptr_ = other.fptr_;
}
shared_function(shared_function<R(Args...)>&& other)
{
fptr_ = std::move(other.fptr_);
}
R operator() (Args... args)
{
if(!bool(*this))
throw std::bad_function_call();
return (*fptr_)((std::forward<Args>(args))...);
}
size_t use_count() const
{
return fptr_->use_count();
}
void reset()
{
fptr_.reset();
}
void swap(shared_function<R(Args...)>& other) const
{
std::swap(fptr_, other.fptr_);
}
operator bool() const
{
return (fptr_ != nullptr) && bool(*fptr_);
}
protected:
std::shared_ptr<function_type> fptr_;
};
template <typename R, typename... Args>
bool operator== (const shared_function<R(Args...)>& func, std::nullptr_t ptr)
{
return !bool(func);
}
template <typename R, typename... Args>
bool operator== (std::nullptr_t ptr, const shared_function<R(Args...)>& func)
{
return !bool(func);
}
int main()
{
static_assert(sizeof(shared_function<void(int)>) <= 16, "Static functoin should fit in small function allocation");
shared_function<void(int)> func([](int n) {std::cout << n << '\n';});
std::function<void(int)> f(func);
f(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment