Advertisement
Savior

C++11: function-wrapper v2

Sep 28th, 2015
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.43 KB | None | 0 0
  1. #include <iostream>
  2. #include <memory>
  3. #include <stdexcept>
  4. using namespace std;
  5.  
  6. template <typename UnusedType>
  7. class OneTimer;
  8.  
  9. template <typename ReturnType, typename ... ArgumentTypes>
  10. class OneTimer <ReturnType (ArgumentTypes ...)>
  11. {
  12. public:
  13.  
  14.     typedef ReturnType signature_type (ArgumentTypes ...);
  15.  
  16.     // OneTimer() : mInvoker()  { }
  17.  
  18.  
  19.     template <typename FunctionT>
  20.  
  21.     OneTimer(FunctionT f)
  22.         : mInvoker(new free_function_holder<FunctionT>(f)), mUsable(true)
  23.     {
  24.     }
  25.  
  26.     template <typename FunctionType, typename ClassType>
  27.     OneTimer(FunctionType ClassType::* f)
  28.         : mInvoker(new member_function_holder<FunctionType, ArgumentTypes ...>(f)), mUsable(true)
  29.     {
  30.     }
  31.  
  32.  
  33.     OneTimer(const OneTimer & other)
  34.         : mInvoker(other.mInvoker->clone()), mUsable(other.mUsable)
  35.     {
  36.     }
  37.  
  38.     OneTimer & operator = (const OneTimer & other)
  39.     {
  40.         mInvoker = other.mInvoker->clone();
  41.         mUsable = other.mUsable;
  42.     }
  43.  
  44.     ReturnType operator ()(ArgumentTypes ... args)
  45.     {
  46.         if (mUsable) {
  47.             mUsable = false;
  48.             return mInvoker->invoke(args ...);
  49.         }
  50.         throw std::runtime_error("Poshel nahuy");
  51.     }
  52.  
  53.  
  54. private:
  55.  
  56.  
  57.     class function_holder_base
  58.     {
  59.     public:
  60.  
  61.         function_holder_base()
  62.         {
  63.         }
  64.  
  65.         virtual ~function_holder_base()
  66.         {
  67.         }
  68.  
  69.         virtual ReturnType invoke(ArgumentTypes ... args) = 0;
  70.  
  71.         virtual std::shared_ptr<function_holder_base> clone() = 0;
  72.  
  73.     private:
  74.         function_holder_base(const function_holder_base & );
  75.         void operator = (const function_holder_base &);
  76.     };
  77.  
  78.  
  79.     typedef std::shared_ptr<function_holder_base> invoker_t;
  80.  
  81.     template <typename FunctionT>
  82.     class free_function_holder : public function_holder_base
  83.     {
  84.     public:
  85.  
  86.         free_function_holder(FunctionT func)
  87.             : function_holder_base(),
  88.               mFunction(func)
  89.         {
  90.  
  91.         }
  92.  
  93.         virtual ReturnType invoke(ArgumentTypes ... args)
  94.         {
  95.             return mFunction(args ...);
  96.         }
  97.  
  98.  
  99.         virtual invoker_t clone()
  100.         {
  101.             return invoker_t(new free_function_holder(mFunction));
  102.         }
  103.  
  104.     private:
  105.         FunctionT mFunction;
  106.     };
  107.  
  108.  
  109.     template <typename FunctionType, typename ClassType, typename ... RestArgumentTypes>
  110.     class member_function_holder : public function_holder_base
  111.     {
  112.     public:
  113.  
  114.         typedef FunctionType ClassType::* member_function_signature_t;
  115.  
  116.         member_function_holder(member_function_signature_t f)
  117.             : mFunction(f)
  118.         {}
  119.  
  120.         virtual ReturnType invoke(ClassType obj, RestArgumentTypes ... restArgs)
  121.         {
  122.             return (obj.*mFunction)(restArgs ...);
  123.         }
  124.  
  125.         virtual invoker_t clone()
  126.         {
  127.             return invoker_t(new member_function_holder(mFunction));
  128.         }
  129.  
  130.     private:
  131.         member_function_signature_t mFunction;
  132.     };
  133.  
  134.     bool mUsable;
  135.     invoker_t mInvoker;
  136. };
  137.  
  138. int random() {
  139.     return 42;
  140. }
  141.  
  142. struct {
  143.     int i = 0;
  144.     int operator()() {return ++i; }
  145. } functor1;
  146.  
  147. class functor2 {
  148.     static int i;
  149. public:
  150.     static int get() { i += 3; return i; }
  151. };
  152. int functor2::i = 0;
  153.  
  154. class functor3 {
  155.     int i = 0;
  156. public:
  157.     int get() { i += 10; return i; }
  158. } ff;
  159.  
  160. int main() {
  161.     OneTimer<int()> a = random;                 // pointer to a generic function
  162. //  OneTimer<int()> a = []() { return 666; };       // lambda
  163. //  OneTimer<int()> a = functor1;               // functor
  164. //  OneTimer<int()> a = &functor2::get;         // pointer to a class function
  165. //  OneTimer<int()> a = std::bind(&functor3::get, &ff); // function of a specific class object
  166.     for (int i = 0; i < 10; ++i) {
  167.         try {
  168.             std::cout << a() << std::endl;
  169.         } catch(std::runtime_error &e) {
  170.             std::cerr << e.what() << std::endl;
  171.         }
  172.     }
  173.     return 0;
  174. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement