1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
10
11 #ifndef BOOST_COMPUTE_ASYNC_FUTURE_HPP
12 #define BOOST_COMPUTE_ASYNC_FUTURE_HPP
13
14 #include <boost/compute/event.hpp>
15
16 namespace boost {
17 namespace compute {
18
19 /// \class future
20 /// \brief Holds the result of an asynchronous computation.
21 ///
22 /// \see event, wait_list
23 template<class T>
24 class future
25 {
26 public:
future()27 future()
28 : m_event(0)
29 {
30 }
31
future(const T & result,const event & event)32 future(const T &result, const event &event)
33 : m_result(result),
34 m_event(event)
35 {
36 }
37
future(const future<T> & other)38 future(const future<T> &other)
39 : m_result(other.m_result),
40 m_event(other.m_event)
41 {
42 }
43
operator =(const future<T> & other)44 future& operator=(const future<T> &other)
45 {
46 if(this != &other){
47 m_result = other.m_result;
48 m_event = other.m_event;
49 }
50
51 return *this;
52 }
53
~future()54 ~future()
55 {
56 }
57
58 /// Returns the result of the computation. This will block until
59 /// the result is ready.
get()60 T get()
61 {
62 wait();
63
64 return m_result;
65 }
66
67 /// Returns \c true if the future is valid.
valid() const68 bool valid() const
69 {
70 return m_event != 0;
71 }
72
73 /// Blocks until the computation is complete.
wait() const74 void wait() const
75 {
76 m_event.wait();
77 }
78
79 /// Returns the underlying event object.
get_event() const80 event get_event() const
81 {
82 return m_event;
83 }
84
85 #if defined(BOOST_COMPUTE_CL_VERSION_1_1) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
86 /// Invokes a generic callback function once the future is ready.
87 ///
88 /// The function specified by callback must be invokable with zero arguments.
89 ///
90 /// \see_opencl_ref{clSetEventCallback}
91 /// \opencl_version_warning{1,1}
92 template<class Function>
then(Function callback)93 future& then(Function callback)
94 {
95 m_event.set_callback(callback);
96 return *this;
97 }
98 #endif // BOOST_COMPUTE_CL_VERSION_1_1
99
100 private:
101 T m_result;
102 event m_event;
103 };
104
105 /// \internal_
106 template<>
107 class future<void>
108 {
109 public:
future()110 future()
111 : m_event(0)
112 {
113 }
114
115 template<class T>
future(const future<T> & other)116 future(const future<T> &other)
117 : m_event(other.get_event())
118 {
119 }
120
future(const event & event)121 explicit future(const event &event)
122 : m_event(event)
123 {
124 }
125
126 template<class T>
operator =(const future<T> & other)127 future<void> &operator=(const future<T> &other)
128 {
129 m_event = other.get_event();
130
131 return *this;
132 }
133
operator =(const future<void> & other)134 future<void> &operator=(const future<void> &other)
135 {
136 if(this != &other){
137 m_event = other.m_event;
138 }
139
140 return *this;
141 }
142
~future()143 ~future()
144 {
145 }
146
get()147 void get()
148 {
149 wait();
150 }
151
valid() const152 bool valid() const
153 {
154 return m_event != 0;
155 }
156
wait() const157 void wait() const
158 {
159 m_event.wait();
160 }
161
get_event() const162 event get_event() const
163 {
164 return m_event;
165 }
166
167 #if defined(BOOST_COMPUTE_CL_VERSION_1_1) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
168 /// Invokes a generic callback function once the future is ready.
169 ///
170 /// The function specified by callback must be invokable with zero arguments.
171 ///
172 /// \see_opencl_ref{clSetEventCallback}
173 /// \opencl_version_warning{1,1}
174 template<class Function>
then(Function callback)175 future<void> &then(Function callback)
176 {
177 m_event.set_callback(callback);
178 return *this;
179 }
180 #endif // BOOST_COMPUTE_CL_VERSION_1_1
181
182 private:
183 event m_event;
184 };
185
186 /// \internal_
187 template<class Result>
make_future(const Result & result,const event & event)188 inline future<Result> make_future(const Result &result, const event &event)
189 {
190 return future<Result>(result, event);
191 }
192
193 } // end compute namespace
194 } // end boost namespace
195
196 #endif // BOOST_COMPUTE_ASYNC_FUTURE_HPP
197