Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio> // for printf
- #include <memory> // for std::unique_ptr, std::make_unique
- #include <utility> // for std::swap, std::move, std::forward
- // function design patterns:
- // 1) External Polymorphism
- // 2) Bridge (or PIMPL)
- // 3) Prototype
- // 4) Type Erasure
- template <class Fn>
- class function;
- template <class R, class... Args>
- class function<R(Args...)> {
- public:
- template <class F>
- function(F&& f) : pimpl_(std::make_unique<Model<F>>(std::forward<F>(f))) {}
- R operator()(Args... args) const {
- return pimpl_->invoke(std::forward<Args>(args)...);
- }
- ~function() = default;
- function(function&&) = default;
- function& operator=(function&&) = default;
- function(const function& other) : pimpl_(other.pimpl_->clone()) {}
- function& operator=(const function& other) {
- function tmp(other);
- std::swap(pimpl_, tmp.pimpl_);
- return *this;
- }
- private:
- class Concept {
- public:
- virtual ~Concept() = default;
- virtual std::unique_ptr<Concept> clone() const = 0;
- virtual R invoke(Args...) const = 0;
- };
- template <typename F>
- class Model final : public Concept {
- public:
- explicit Model(F f) : fn_(std::move(f)) {}
- std::unique_ptr<Concept> clone() const final {
- return std::make_unique<Model>(fn_);
- }
- R invoke(Args... args) const final {
- return fn_(std::forward<Args>(args)...);
- }
- private:
- F fn_;
- };
- std::unique_ptr<Concept> pimpl_;
- };
- void test() { printf("hello\n"); }
- int main() {
- function<void()> f{test};
- f();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement