1 #pragma once 2 3 4 #include <type_traits> 5 #include <utility> 6 #include <memory> 7 #include <uv.h> 8 #include "resource.hpp" 9 10 11 namespace uvw { 12 13 14 template<typename T, typename U> 15 class Request: public Resource<T, U> { 16 protected: reserve(U * req)17 static auto reserve(U *req) { 18 auto ptr = static_cast<T*>(req->data)->shared_from_this(); 19 ptr->reset(); 20 return ptr; 21 } 22 23 template<typename E> defaultCallback(U * req,int status)24 static void defaultCallback(U *req, int status) { 25 auto ptr = reserve(req); 26 if(status) { ptr->publish(ErrorEvent{status}); } 27 else { ptr->publish(E{}); } 28 } 29 30 template<typename F, typename... Args> invoke(F && f,Args &&...args)31 auto invoke(F &&f, Args&&... args) 32 -> std::enable_if_t<not std::is_void<std::result_of_t<F(Args...)>>::value> { 33 auto err = std::forward<F>(f)(std::forward<Args>(args)...); 34 if(err) { Emitter<T>::publish(ErrorEvent{err}); } 35 else { this->leak(); } 36 } 37 38 template<typename F, typename... Args> invoke(F && f,Args &&...args)39 auto invoke(F &&f, Args&&... args) 40 -> std::enable_if_t<std::is_void<std::result_of_t<F(Args...)>>::value> { 41 std::forward<F>(f)(std::forward<Args>(args)...); 42 this->leak(); 43 } 44 45 public: 46 using Resource<T, U>::Resource; 47 48 /** 49 * @brief Cancels a pending request. 50 * 51 * This method fails if the request is executing or has finished 52 * executing.<br/> 53 * It can emit an ErrorEvent event in case of errors. 54 * 55 * See the official 56 * [documentation](http://docs.libuv.org/en/v1.x/request.html#c.uv_cancel) 57 * for further details. 58 * 59 * @return True in case of success, false otherwise. 60 */ cancel()61 bool cancel() { 62 return (0 == uv_cancel(this->template get<uv_req_t>())); 63 } 64 65 /** 66 * @brief Returns the size of the underlying request type. 67 * @return The size of the underlying request type. 68 */ size() const69 std::size_t size() const noexcept { 70 return uv_req_size(this->template get<uv_req_t>()->type); 71 } 72 }; 73 74 75 } 76