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