Advertisement
fsb4000

c++ function

Jan 30th, 2022
1,204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.68 KB | None | 0 0
  1. #include <cstdio>   // for printf
  2. #include <memory>   // for std::unique_ptr, std::make_unique
  3. #include <utility>  // for std::swap, std::move, std::forward
  4.  
  5. // function design patterns:
  6. // 1) External Polymorphism
  7. // 2) Bridge (or PIMPL)
  8. // 3) Prototype
  9. // 4) Type Erasure
  10.  
  11. template <class Fn>
  12. class function;
  13.  
  14. template <class R, class... Args>
  15. class function<R(Args...)> {
  16.    public:
  17.     template <class F>
  18.     function(F&& f) : pimpl_(std::make_unique<Model<F>>(std::forward<F>(f))) {}
  19.  
  20.     R operator()(Args... args) const {
  21.         return pimpl_->invoke(std::forward<Args>(args)...);
  22.     }
  23.  
  24.     ~function() = default;
  25.     function(function&&) = default;
  26.     function& operator=(function&&) = default;
  27.  
  28.     function(const function& other) : pimpl_(other.pimpl_->clone()) {}
  29.  
  30.     function& operator=(const function& other) {
  31.         function tmp(other);
  32.         std::swap(pimpl_, tmp.pimpl_);
  33.         return *this;
  34.     }
  35.  
  36.    private:
  37.     class Concept {
  38.        public:
  39.         virtual ~Concept() = default;
  40.         virtual std::unique_ptr<Concept> clone() const = 0;
  41.         virtual R invoke(Args...) const = 0;
  42.     };
  43.  
  44.     template <typename F>
  45.     class Model final : public Concept {
  46.        public:
  47.         explicit Model(F f) : fn_(std::move(f)) {}
  48.  
  49.         std::unique_ptr<Concept> clone() const final {
  50.             return std::make_unique<Model>(fn_);
  51.         }
  52.  
  53.         R invoke(Args... args) const final {
  54.             return fn_(std::forward<Args>(args)...);
  55.         }
  56.  
  57.        private:
  58.         F fn_;
  59.     };
  60.     std::unique_ptr<Concept> pimpl_;
  61. };
  62.  
  63. void test() { printf("hello\n"); }
  64.  
  65. int main() {
  66.     function<void()> f{test};
  67.     f();
  68. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement