makiolo

move and perfect forwarding test

Jan 25th, 2017
120
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <string>
  3. #include <functional>
  4.  
  5. struct custom
  6. {  
  7.     custom(const std::string& str = "bar")
  8.         : _str(str)
  9.     {
  10.         std::cout << "constructor default custom" << std::endl;
  11.     }
  12.    
  13.     custom(const custom& other)
  14.         : _str(other._str)
  15.     {
  16.         std::cout << "constructor copy custom" << std::endl;
  17.     }
  18.  
  19.     custom(custom&& other)
  20.         : _str(std::move(other._str))
  21.     {
  22.         std::cout << "constructor move custom" << std::endl;
  23.     }
  24.  
  25.     ~custom() {
  26.         std::cout << "destructor custom" << std::endl;    
  27.     }
  28.    
  29.     void swap(custom& other)
  30.     {
  31.         std::cout << "swap custom" << std::endl;
  32.         using std::swap;
  33.         std::swap(_str, other._str);
  34.     }
  35.  
  36.     custom& operator=(const custom& other)
  37.     {
  38.         std::cout << "operator copy custom" << std::endl;
  39.         custom(other).swap(*this);
  40.         return *this;
  41.     }
  42.  
  43.     custom& operator=(custom&& other)
  44.     {
  45.         std::cout << "operator move custom" << std::endl;
  46.         custom(std::move(other)).swap(*this);
  47.         return *this;
  48.     }
  49.    
  50.     std::string str() const {return _str;}
  51.    
  52. public:
  53.     std::string _str;
  54. };
  55.  
  56. template <int...>
  57. struct int_sequence
  58. {
  59. };
  60.  
  61. template <int N, int... Is>
  62. struct make_int_sequence : make_int_sequence<N - 1, N - 1, Is...>
  63. {
  64. };
  65.  
  66. template <int... Is>
  67. struct make_int_sequence<0, Is...> : int_sequence<Is...>
  68. {
  69. };
  70.  
  71. template <int>
  72. struct placeholder_template
  73. {
  74. };
  75.  
  76. namespace std
  77. {
  78. template <int N>
  79. struct is_placeholder<placeholder_template<N>> : integral_constant<int, N + 1>
  80. {
  81. };
  82. }
  83.  
  84. template <typename... Args>
  85. class method
  86. {
  87. public:
  88.     using return_type = void;
  89.     using function = std::function<return_type(const Args&...)>;
  90.  
  91.     template <typename FUNCTION>
  92.     method(FUNCTION&& m)
  93.         : _method(std::forward<FUNCTION>(m))
  94.     {
  95.     }
  96.  
  97.     template <typename T, typename ... PARMS>
  98.     method(T* obj, return_type (T::*ptr_func)(PARMS...))
  99.         : method(obj, ptr_func, make_int_sequence<sizeof...(PARMS)>{})
  100.     {
  101.     }
  102.  
  103.     template <typename T, typename ... PARMS, int... Is>
  104.     method(T* obj, return_type (T::*ptr_func)(PARMS...), int_sequence<Is...>)
  105.         : method(std::bind(ptr_func, obj, placeholder_template<Is>{}...))
  106.     {
  107.     }
  108.  
  109.     method(const method& other) = delete;
  110.     method& operator=(const method& other) = delete;
  111.     ~method() { ; }
  112.  
  113.     template <typename ... PARMS>
  114.     return_type operator()(PARMS&&... data) const
  115.     {
  116.         _method(std::forward<PARMS>(data)...);
  117.     }
  118.  
  119. protected:
  120.     function _method;
  121. };
  122.  
  123. method<custom> m( [](const custom& parm){std::cout << "parm lambda: " << parm.str() << "." << std::endl;} );
  124.  
  125. struct my_method
  126. {
  127.     void call(const custom& parm)
  128.     {
  129.         std::cout << "parm functor: " << parm.str() << "." << std::endl;
  130.     }
  131. };
  132. my_method mm;
  133. method<custom> m2(&mm, &my_method::call);
  134.  
  135. template <typename T>
  136. void pr(T&& parm)
  137. {
  138.     // lambda currified
  139.     m(std::forward<T>(parm));
  140.     // functor
  141.     m2(std::forward<T>(parm));
  142. }
  143.  
  144. template <typename T, typename ... Args>
  145. void pr(T&& parm, Args&&... data)
  146. {
  147.     pr(std::forward<T>(parm));
  148.     pr(std::forward<Args>(data)...);
  149. }
  150.  
  151. template <typename ... Args>
  152. struct bar
  153. {
  154.     template <typename ... PARMS>
  155.     void call(PARMS&&... data) const
  156.     {
  157.         pr(std::forward<PARMS>(data)...);
  158.         std::cout << std::endl;
  159.     }
  160. };
  161.  
  162. template <typename ... Args>
  163. struct foo
  164. {
  165.     template <typename ... PARMS>
  166.     void call(PARMS&&... data) const
  167.     {
  168.         b.call(std::forward<PARMS>(data)...);
  169.     }
  170.    
  171.     bar<Args...> b;
  172. };
  173.  
  174. int main()
  175. {
  176.     foo<custom, custom, custom> f;
  177.     custom a("a");
  178.     custom b("b");
  179.     custom c("c");
  180.     f.call(a, b, c);
  181.     std::cout << "---------------" << std::endl;
  182.     foo<custom, custom, custom> f2;
  183.     f2.call(custom(), custom(), custom());
  184. }
RAW Paste Data