Advertisement
Guest User

Untitled

a guest
Jan 17th, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.11 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <tuple>
  4. #include <mutex>
  5. #include <utility>
  6. #include <functional>
  7. #include <boost/asio.hpp>
  8.  
  9. namespace stdex{
  10. // ************************************************************************** //
  11. // ************** data::index_sequence ************** //
  12. // ************************************************************************** //
  13.  
  14. template <std::size_t... Ns>
  15. struct index_sequence {};
  16.  
  17. template<typename IS1, typename IS2>
  18. struct merge_index_sequence;
  19.  
  20. template <std::size_t... Ns1, std::size_t... Ns2>
  21. struct merge_index_sequence<index_sequence<Ns1...>, index_sequence<Ns2...>> {
  22. typedef index_sequence<Ns1..., Ns2...> type;
  23. };
  24.  
  25. template <std::size_t B, std::size_t E, typename Enabler = void>
  26. struct make_index_sequence {
  27. typedef typename merge_index_sequence<typename make_index_sequence<B,(B+E)/2>::type,
  28. typename make_index_sequence<(B+E)/2,E>::type>::type type;
  29. };
  30.  
  31. template <std::size_t B, std::size_t E>
  32. struct make_index_sequence<B,E,typename std::enable_if<E==B+1,void>::type> {
  33. typedef index_sequence<B> type;
  34. };
  35.  
  36. template <typename... T>
  37. using index_sequence_for = typename make_index_sequence<0, sizeof...(T)>::type;
  38.  
  39. }
  40.  
  41.  
  42. template<typename TimerType, typename... T>
  43. class smart_timer
  44. {
  45. public:
  46. explicit smart_timer(boost::asio::io_service& io)
  47. : io(io)
  48. , m_timer(io)
  49. {}
  50.  
  51. template<typename... TT>
  52. void expires_from_now(TT... arg)
  53. {
  54. m_timer.expires_from_now(arg...);
  55. }
  56.  
  57.  
  58. //The helper method.
  59. template<std::size_t... Is>
  60. void call_handler_with_tuple(boost::system::error_code ec, const std::tuple<T...>& tuple, stdex::index_sequence<Is...>)
  61. {
  62. m_handler(ec, std::get<Is>(tuple)...);
  63. }
  64.  
  65. void m_handler_with_values(boost::system::error_code ec)
  66. {
  67. call_handler_with_tuple(ec, tuple_, stdex::index_sequence_for<T...>());
  68. }
  69.  
  70. template<typename Handler>
  71. void async_wait(BOOST_ASIO_MOVE_ARG(Handler) handler)
  72. {
  73. std::unique_lock<std::mutex> l(m);
  74.  
  75. if (no_wait)
  76. {
  77. no_wait = false;
  78. io.post([this](){
  79. m_handler_with_values(boost::asio::error::make_error_code(boost::asio::error::interrupted));
  80. });
  81. return;
  82. }
  83.  
  84. m_handler = handler;
  85. handler_set = true;
  86. m_timer.async_wait(std::bind(&smart_timer::handle_timer, this, std::placeholders::_1));
  87. }
  88.  
  89. void wake_up(T... arg)
  90. {
  91. std::unique_lock<std::mutex> l(m);
  92. if (handler_set)
  93. {
  94. handler_set = false;
  95.  
  96. io.post([this](){
  97. m_handler_with_values(boost::asio::error::make_error_code(boost::asio::error::interrupted));
  98. });
  99.  
  100. boost::system::error_code ignore;
  101. m_timer.cancel(ignore);
  102. }
  103. else
  104. no_wait = true;
  105. }
  106.  
  107. private:
  108. void handle_timer(boost::system::error_code ec)
  109. {
  110. std::unique_lock<std::mutex> l(m);
  111. if (ec == boost::asio::error::operation_aborted)
  112. {
  113. // check for wake_up parameter.
  114. return;
  115. }
  116. handler_set = false;
  117.  
  118. m_handler_with_values(boost::asio::error::make_error_code(boost::asio::error::interrupted));
  119. }
  120.  
  121. private:
  122. boost::asio::io_service& io;
  123. TimerType m_timer;
  124. bool handler_set = false;
  125. bool no_wait = false;
  126. std::function<void(boost::system::error_code ec, T...)> m_handler;
  127. std::mutex m;
  128.  
  129. std::tuple<T...> tuple_;
  130. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement