fork(6) download
  1. #include <iostream>
  2.  
  3. struct mutex {
  4. void acquire() { std::cout << "Mutex acquired.\n"; }
  5. void release() { std::cout << "Mutex released.\n"; }
  6. };
  7.  
  8. template <typename T>
  9. struct locker_box {
  10. struct cookie {
  11. cookie() : b(nullptr) {}
  12. cookie(locker_box& b) : b(&b) {}
  13.  
  14. T& operator*() {
  15. return b->t;
  16. }
  17. T* operator->() {
  18. return b->t;
  19. }
  20. cookie& operator++() {
  21. b = nullptr;
  22. return *this;
  23. }
  24. cookie operator++(int) {
  25. cookie copy(*this);
  26. operator++();
  27. return copy;
  28. }
  29. bool operator==(cookie const& c) {
  30. return b == c.b;
  31. }
  32. bool operator!=(cookie const& c) {
  33. return b != c.b;
  34. }
  35. private:
  36. locker_box* b;
  37. };
  38. struct open_box {
  39. open_box(locker_box& b) : b(b) { b.m.acquire(); }
  40. ~open_box() { b.m.release(); }
  41. cookie begin() { return cookie(b); }
  42. cookie end() { return cookie(); }
  43. private:
  44. locker_box& b;
  45. };
  46.  
  47. open_box open() {
  48. return open_box(*this);
  49. }
  50.  
  51. private:
  52. friend class open_box;
  53. friend class cookie;
  54. mutex m;
  55. T t;
  56. };
  57.  
  58. struct not_suitable_for_this_audience {};
  59.  
  60. struct racy {
  61. void do_racy_stuff() { std::cout << "Being racy...\n"; }
  62. void do_more_racy_stuff() { std::cout << "Being even more racy...\n"; }
  63. void do_really_raunchy_stuff() { throw not_suitable_for_this_audience(); }
  64. };
  65.  
  66. int main() {
  67. locker_box<racy> box;
  68. try {
  69. for(auto& x : box.open()) {
  70. x.do_racy_stuff();
  71. x.do_more_racy_stuff();
  72. x.do_really_raunchy_stuff();
  73. }
  74. } catch(not_suitable_for_this_audience const&) {
  75. std::cout << "Ooops..."
  76. }
  77. }
  78.  
  79. // This prints:
  80. // Mutex acquired.
  81. // Being racy...
  82. // Being even more racy...
  83. // Mutex released.
  84. // Ooops...
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty