Advertisement
Guest User

Untitled

a guest
Apr 30th, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.96 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <tuple>
  4. #include <utility>
  5. #include <cstddef>
  6.  
  7. namespace fn
  8. {
  9.  
  10.     namespace
  11.     {
  12.         template<size_t N>
  13.         using index = std::integral_constant<size_t, N>;
  14.  
  15.         const index<0> _1;
  16.         const index<1> _2;
  17.         const index<2> _3;
  18.         const index<3> _4;
  19.         const index<4> _5;
  20.         const index<5> _6;
  21.         const index<6> _7;
  22.         const index<7> _8;
  23.     }
  24.  
  25.     namespace details
  26.     {
  27.         template<size_t... Indices>
  28.         struct index_list
  29.         {
  30.             using next = index_list<Indices..., sizeof...(Indices)>;
  31.         };
  32.  
  33.         template<size_t N>
  34.         struct make_index_list_impl
  35.         {
  36.             using type = typename make_index_list_impl<N - 1>::type::next;
  37.         };
  38.  
  39.         template<>
  40.         struct make_index_list_impl<0>
  41.         {
  42.             using type = index_list<>;
  43.         };
  44.  
  45.         template<size_t N>
  46.         using make_index_list = typename make_index_list_impl<N>::type;
  47.  
  48.  
  49.         template<typename F, typename... BaseArgs>
  50.         class binder_t
  51.         {
  52.         private:
  53.             F func;
  54.             std::tuple<BaseArgs...> func_baseargs;
  55.             make_index_list<sizeof...(BaseArgs)> indices = make_index_list<sizeof...(BaseArgs)>();
  56.  
  57.         public:
  58.             binder_t(F&& func, BaseArgs&&... args)
  59.                 : func(std::move(func))
  60.                 , func_baseargs(std::move(args)...)
  61.             {}
  62.  
  63.             binder_t(const binder_t& other) = default;
  64.  
  65.             binder_t& operator=(binder_t other)
  66.             {
  67.                 swap(other);
  68.                 return *this;
  69.             }
  70.  
  71.             void swap(binder_t& other)
  72.             {
  73.                 std::swap(func, other.func);
  74.                 std::swap(func_baseargs, other.func_baseargs);
  75.             }
  76.  
  77.             //template<typename... FinalArgs, size_t... Indices>
  78.             //auto call_func(F& func, std::tuple<FinalArgs...> final_args, const index_list<Indices...>&) ->
  79.             //  decltype(func(std::get<Indices>(final_args)...))
  80.             //{
  81.             //  return func(std::get<Indices>(final_args)...);
  82.             //}
  83.  
  84.             template<typename... FinalArgs, typename... Args>
  85.             auto call_func(F& func, Args... args) ->
  86.                 decltype(func(args...))
  87.             {
  88.                 return func(args...);
  89.             }
  90.  
  91.             template<typename T, typename... Args>
  92.             std::tuple<T, Args...> make_tuple(const T& value, const std::tuple<Args...>& tuple) const
  93.             {
  94.                 return std::tuple_cat(std::make_tuple(value), tuple);
  95.             }
  96.  
  97.             template<typename... NewArgs>
  98.             std::tuple<> calc_full_args(const std::tuple<NewArgs...>&) const
  99.             {
  100.                 return std::make_tuple();
  101.             }
  102.  
  103.             template<typename... NewArgs, typename T, typename... R>
  104.             auto calc_full_args(const std::tuple<NewArgs...>& cur_args, const T& val, const R&... rest) ->
  105.                 decltype(make_tuple(val, calc_full_args(cur_args, rest...))) const
  106.             {
  107.                 return make_tuple(val, calc_full_args(cur_args, rest...));
  108.             }
  109.  
  110.             template<typename... NewArgs, size_t N, typename... R>
  111.             auto calc_full_args(const std::tuple<NewArgs...>& cur_args, index<N>, const R&... rest) ->
  112.                 decltype(make_tuple(std::get<N>(cur_args), calc_full_args(cur_args, rest...))) const
  113.             {
  114.                 return make_tuple(std::get<N>(cur_args), calc_full_args(cur_args, rest...));
  115.             }
  116.  
  117.             template<typename... NewArgs, size_t... Indices>
  118.             auto calc_full_args(const std::tuple<NewArgs...>& cur_args, index_list<Indices...>) ->
  119.                 decltype(calc_full_args(cur_args, std::get<Indices>(func_baseargs)...)) const
  120.             {
  121.                 return calc_full_args(cur_args, std::get<Indices>(func_baseargs)...);
  122.             }
  123.  
  124.             //template<typename... NewArgs>
  125.             //auto operator()(NewArgs... args) ->
  126.             //  decltype(call_func(func, calc_full_args(std::make_tuple(args...), indices), indices))
  127.             //{
  128.             //  return call_func(func, calc_full_args(std::make_tuple(args...), indices), indices);
  129.             //}        
  130.             template<typename... NewArgs>
  131.             auto operator()(NewArgs... args) ->
  132.                 decltype(0)
  133.             {
  134.                 calc_full_args(std::make_tuple(args...), indices);
  135.                 return 0;
  136.             }
  137.         };
  138.  
  139.     } // namespace details
  140.  
  141.     template<typename F, typename... Args>
  142.     details::binder_t<F, Args...> bind(F func, Args... args)
  143.     {
  144.         return details::binder_t<F, Args...>(std::move(func), std::move(args)...);
  145.     }
  146.  
  147.     // function implementation
  148.  
  149.     class bad_function_call : public std::exception
  150.     {};
  151.  
  152.     template<typename T>
  153.     class function;
  154.  
  155.     template<typename R, typename... Args>
  156.     class function<R(Args...)>
  157.     {
  158.     private:
  159.  
  160.         struct function_wrapper_base
  161.         {
  162.             virtual ~function_wrapper_base(){}
  163.             virtual function_wrapper_base* copy() = 0;
  164.             virtual R operator()(Args&&...) = 0;
  165.         };
  166.  
  167.         template<typename Functor>
  168.         struct function_wrapper : function_wrapper_base
  169.         {
  170.             function_wrapper(const Functor& func)
  171.                 : func(func)
  172.             {}
  173.  
  174.             function_wrapper(const function_wrapper&) = default;
  175.  
  176.             function_wrapper* copy() override
  177.             {
  178.                 return new function_wrapper(func);
  179.             }
  180.  
  181.             R operator()(Args&&...args) override
  182.             {
  183.                 return func(std::forward<Args>(args)...);
  184.             }
  185.  
  186.             Functor func;
  187.         };
  188.         function_wrapper_base* func_base;
  189.  
  190.     public:
  191.         function()
  192.             : func_base(nullptr)
  193.         {}
  194.  
  195.         template<typename Functor>
  196.         function(Functor func)
  197.             : func_base(new function_wrapper<Functor>(func))
  198.         {}
  199.  
  200.         function(nullptr_t)
  201.             : func_base(nullptr)
  202.         {}
  203.  
  204.         function(const function& other)
  205.             : func_base(other.copy())
  206.         {}
  207.  
  208.         function(function&& other)
  209.             : function()
  210.         {
  211.             swap(other);
  212.         }
  213.  
  214.         function_wrapper_base* copy() const
  215.         {
  216.             if (!func_base)
  217.                 return nullptr;
  218.             return func_base->copy();
  219.         }
  220.  
  221.         function& operator=(function other)
  222.         {
  223.             swap(other);
  224.             return *this;
  225.         }
  226.  
  227.         template<typename Functor>
  228.         function& operator=(const Functor& func)
  229.         {
  230.             function tmp(func);
  231.             swap(tmp);
  232.             return *this;
  233.         }
  234.  
  235.         void swap(function& other)
  236.         {
  237.             std::swap(func_base, other.func_base);
  238.         }
  239.  
  240.         bool is_empty() const
  241.         {
  242.             return func_base == nullptr;
  243.         }
  244.  
  245.         operator bool() const
  246.         {
  247.             return !is_empty();
  248.         }
  249.  
  250.         R operator()(Args&&... args) const
  251.         {
  252.             if (is_empty())
  253.                 throw bad_function_call();
  254.  
  255.             return (*func_base)(std::forward<Args>(args)...);
  256.         }
  257.  
  258.         ~function()
  259.         {
  260.             delete func_base;
  261.         }
  262.  
  263.     };
  264.  
  265.     template<typename R, typename... Args>
  266.     void swap(function<R(Args...)>& one, function<R(Args...)>& other)
  267.     {
  268.         one.swap(other);
  269.     }
  270.  
  271. } // namespace fn
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement