Advertisement
GeneralGDA

ScopeGuardEx - try #2

Oct 22nd, 2014
506
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.24 KB | None | 0 0
  1. class Access
  2. {
  3. public:
  4.     virtual ~Access() = 0 {}
  5.     virtual void foo() = 0;
  6. };
  7.  
  8. class Interface
  9. {
  10. public:
  11.     virtual ~Interface() = 0 {}
  12.     virtual Access& open() = 0;
  13. };
  14.  
  15. class ScopeGuard final
  16. {
  17. public:
  18.     explicit ScopeGuard(std::function<void()> onExit)
  19.         : onExit_(onExit)
  20.         , ready_(true)
  21.     {
  22.     }
  23.     ScopeGuard(ScopeGuard&& other)
  24.         : onExit_(other.onExit_)
  25.         , ready_(true)
  26.     {
  27.         other.ready_ = false;
  28.     }
  29.     virtual ~ScopeGuard()
  30.     {
  31.         if (ready_)
  32.         {
  33.             onExit_();
  34.             ready_ = false;
  35.         }
  36.     }
  37. private:
  38.     ScopeGuard();
  39.     ScopeGuard(ScopeGuard& other);
  40.     ScopeGuard& operator=(ScopeGuard&& other);
  41.     ScopeGuard& operator=(const ScopeGuard& other);
  42.  
  43.     bool ready_;
  44.     std::function<void()> onExit_;
  45. };
  46.  
  47. class Widget final : public Interface
  48. {
  49. private:
  50.     class Opener final : public Access
  51.     {
  52.     public:
  53.         explicit Opener(Widget& host)
  54.             : guard_([&host] { host.end();})
  55.             , host_(host)
  56.         {}
  57.         Opener(Opener&& other)
  58.             : guard_(std::move(other.guard_))
  59.             , host_(other.host_)
  60.         {}
  61.         virtual void foo()
  62.         {
  63.             host_.foo();
  64.         }
  65.     private:
  66.         ScopeGuard guard_;
  67.         Widget& host_;
  68.     };
  69.  
  70.     class Giver final
  71.     {
  72.     public:
  73.         explicit Giver(Widget& host)
  74.             : guard_([&host] { host.end();})
  75.             , host_(host)
  76.         {
  77.         }
  78.         Giver(Giver&& other)
  79.             : guard_(std::move(other.guard_))
  80.             , host_(other.host_)
  81.         {
  82.         }
  83.         void zig()
  84.         {
  85.             host_.zig();
  86.         }
  87.         void zag()
  88.         {
  89.             host_.zag();
  90.         }
  91.     private:
  92.         ScopeGuard guard_;
  93.         Widget& host_;
  94.     };
  95.  
  96.     void close()
  97.     {
  98.         std::cout << "close" << std::endl;
  99.     }
  100.        
  101.     void end()
  102.     {
  103.         std::cout << "end" << std::endl;
  104.     }
  105.  
  106.     void zig()
  107.     {
  108.         std::cout << "zig" << std::endl;
  109.     }
  110.  
  111.     void zag()
  112.     {
  113.         std::cout << "zag" << std::endl;
  114.     }
  115.  
  116.     void foo()
  117.     {
  118.         std::cout << "foo" << std::endl;
  119.     }
  120.  
  121.     Opener opener_;
  122.  
  123. public:
  124.     Widget()
  125.         : opener_(*this)
  126.     {
  127.     }
  128.     virtual Access& open() override
  129.     {
  130.         std::cout << "open" << std::endl;
  131.         return opener_;
  132.  
  133.     }
  134.     Giver begin()
  135.     {
  136.         std::cout << "begin" << std::endl;
  137.         return Giver(*this);
  138.     }
  139. };
  140.  
  141. int _tmain(int, _TCHAR*)
  142. {
  143.     {
  144.         Widget widget;
  145.  
  146.         auto giver = widget.begin();
  147.         auto& opener = widget.open();
  148.  
  149.         giver.zig();
  150.         giver.zag();
  151.  
  152.         opener.foo();
  153.  
  154.         std::cout << "hell, yeah!" << std::endl;
  155.     }
  156.  
  157.     return 0;
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement