daily pastebin goal
68%
SHARE
TWEET

Untitled

a guest Jan 20th, 2019 69 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #ifndef FUNCTION_FUNCTION_H
  2. #define FUNCTION_FUNCTION_H
  3.  
  4. #include <utility>
  5. #include <variant>
  6. #include <memory>
  7.  
  8. static const size_t B_SIZE = 64;
  9.  
  10.  
  11. template <typename T>
  12. class function;
  13.  
  14. template <typename Ret, typename ...Args>
  15. class function<Ret (Args...)> {
  16. public:
  17.     Ret operator()(Args...args) const {
  18.         if (!is_small)
  19.             return holder->invoke(std::forward<Args>(args)...);
  20.         return ((function_holder_base *)buf)->invoke(std::forward<Args>(args)...);
  21.     }
  22.  
  23.     function() noexcept : holder(nullptr), is_small(false) {}
  24.  
  25.     function(std::nullptr_t) noexcept : holder(nullptr), is_small(false) {}
  26.  
  27.     function(const function &other) {
  28.         function_holder_base *c = (function_holder_base *) other.buf;
  29.         is_small = other.is_small;
  30.         if (other.is_small)
  31.             c->create_small_copy(buf);
  32.         else
  33.             holder = other.holder->copy();
  34.  
  35.     }
  36.  
  37.     function(function &&other) noexcept : holder(nullptr){
  38.         std::swap(buf, other.buf);
  39.         std::swap(is_small, other.is_small);
  40.         other.is_small = false;
  41.     }
  42.  
  43.     function& operator=(const function& other) {
  44.         function tmp(other);
  45.         swap(tmp);
  46.         return *this;
  47.     }
  48.  
  49.     function &operator=(function &&other) noexcept {
  50.         auto tmp(std::forward<function>(other));
  51.         swap(tmp);
  52.         return *this;
  53.     }
  54.  
  55.     void swap(function& other) noexcept {
  56.         std::swap(buf, other.buf);
  57.         std::swap(is_small, other.is_small);
  58.     }
  59.  
  60.     explicit operator bool() const noexcept {
  61.         if (is_small)
  62.             return true;
  63.         return static_cast<bool>(holder);
  64.     }
  65.  
  66.  
  67.     template<typename T>
  68.     function(T t) {
  69.         if constexpr (sizeof(function_holder<T>(t)) <= B_SIZE){
  70.             is_small = true;
  71.             new(buf) function_holder<T>(std::move(t));
  72.         }
  73.         else{
  74.             is_small = false;
  75.             new(buf) std::unique_ptr<function_holder < T>>(std::make_unique<function_holder<T>>(std::move(t)));
  76.         }
  77.     }
  78.  
  79.     ~function() {
  80.         if (is_small) {
  81.             ((function_holder_base*)buf)->~function_holder_base();
  82.         } else {
  83.             holder.reset();
  84.         }
  85.     }
  86.  
  87.  
  88.  
  89.     class function_holder_base {
  90.     public:
  91.         function_holder_base() {};
  92.         virtual ~function_holder_base() {};
  93.         virtual Ret invoke(Args...) = 0;
  94.         virtual std::unique_ptr<function_holder_base> copy() const = 0;
  95.         virtual void create_small_copy(void *adr) = 0;
  96.  
  97.     };
  98.  
  99.     template <typename Func>
  100.     class function_holder : public function_holder_base {
  101.     public:
  102.         function_holder(const Func& func) : f(func) {}
  103.  
  104.         ~function_holder() override = default;
  105.  
  106.         Ret invoke(Args...args){
  107.             return f(std::forward<Args>(args)...);
  108.         }
  109.  
  110.         void create_small_copy(void *adr){
  111.             new (adr) function_holder<Func>(f);
  112.  
  113.         }
  114.  
  115.         std::unique_ptr<function_holder_base> copy() const override {
  116.             return std::make_unique<function_holder<Func>>(f);
  117.         }
  118.  
  119.         Func f;
  120.  
  121.     };
  122.  
  123. private:
  124.     union {
  125.         std::unique_ptr<function_holder_base> holder;
  126.         char buf[B_SIZE];
  127.     };
  128.     bool is_small;
  129. };
  130.  
  131. #endif /
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top