Line data Source code
1 :
2 : /* Copyright (c) 2013-2014, Stefan.Eilemann@epfl.ch
3 : *
4 : * This library is free software; you can redistribute it and/or modify it under
5 : * the terms of the GNU Lesser General Public License version 2.1 as published
6 : * by the Free Software Foundation.
7 : *
8 : * This library is distributed in the hope that it will be useful, but WITHOUT
9 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 : * details.
12 : *
13 : * You should have received a copy of the GNU Lesser General Public License
14 : * along with this library; if not, write to the Free Software Foundation, Inc.,
15 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 : */
17 :
18 : #ifndef LUNCHBOX_FUTURE_H
19 : #define LUNCHBOX_FUTURE_H
20 :
21 : #include <lunchbox/refPtr.h> // used inline
22 : #include <lunchbox/referenced.h> // base class
23 :
24 : #include <stdexcept>
25 :
26 : namespace lunchbox
27 : {
28 :
29 0 : class FutureTimeout : public std::runtime_error
30 : {
31 : public:
32 0 : FutureTimeout() : std::runtime_error("") {}
33 : };
34 :
35 : /** Base class to implement the wait method fulfilling the future. */
36 : template< class T >
37 3 : class FutureImpl : public Referenced, public boost::noncopyable
38 : {
39 : public:
40 : /** Destruct the future. */
41 3 : virtual ~FutureImpl(){}
42 :
43 : /**
44 : * Wait for the promise to be fullfilled.
45 : *
46 : * May be called multiple times.
47 : * @param timeout optional timeout in milliseconds. If the future is
48 : * not ready when the timer goes off a timeout exception
49 : * is thrown.
50 : */
51 : virtual T wait( const uint32_t timeout = LB_TIMEOUT_INDEFINITE ) = 0;
52 :
53 : /**
54 : * @return true if the future has been fulfilled, false if it is pending.
55 : */
56 : virtual bool isReady() const = 0;
57 : };
58 :
59 : /** A future represents a asynchronous operation. Do not subclass. */
60 : template< class T > class Future
61 : {
62 : private:
63 : typedef void (Future< T >::*bool_t)() const;
64 : void bool_true() const {}
65 :
66 : public:
67 : typedef RefPtr< FutureImpl< T > > Impl; //!< The wait implementation
68 :
69 : /** Construct a new future. */
70 2 : explicit Future( Impl impl ) : impl_( impl ){}
71 :
72 : /** Destruct the future. */
73 2 : ~Future(){}
74 :
75 : /**
76 : * Wait for the promise to be fullfilled.
77 : *
78 : * @param timeout_ optional timeout in milliseconds. If the future is
79 : * not ready when the timer goes off a timeout exception
80 : * is thrown.
81 : */
82 5 : T wait( const uint32_t timeout_ = LB_TIMEOUT_INDEFINITE )
83 : {
84 5 : return impl_->wait( timeout_ );
85 : }
86 :
87 : /**
88 : * @return true if the future has been fulfilled, false if it is pending.
89 : */
90 : bool isReady() const { return impl_->isReady(); }
91 :
92 : /** @name Blocking comparison operators. */
93 : //@{
94 : /** @return a bool conversion of the result. */
95 : operator bool_t() { return wait() ? &Future< T >::bool_true : 0; }
96 :
97 : /** @return true if the result does convert to false. */
98 : bool operator ! () { return !wait(); }
99 :
100 : /** @return true if the result is equal to the given value. */
101 : bool operator == ( const T& rhs ) { return wait() == rhs; }
102 :
103 : /** @return true if the result is not equal to the rhs. */
104 : bool operator != ( const T& rhs ) { return wait() != rhs; }
105 :
106 : /** @return true if the result is smaller than the rhs. */
107 : bool operator < ( const T& rhs ) { return wait() < rhs; }
108 :
109 : /** @return true if the result is bigger than the rhs. */
110 : bool operator > ( const T& rhs ) { return wait() > rhs; }
111 :
112 : /** @return true if the result is smaller or equal. */
113 : bool operator <= ( const T& rhs ) { return wait() <= rhs; }
114 :
115 : /** @return true if the result is bigger or equal. */
116 : bool operator >= ( const T& rhs ) { return wait() >= rhs; }
117 : //@}
118 :
119 : protected:
120 : Impl impl_;
121 : };
122 :
123 : /** Future template specialization for void */
124 : template<> class Future< void >
125 : {
126 : private:
127 : typedef void (Future< void >::*bool_t)() const;
128 : void bool_true() const {}
129 :
130 : public:
131 : typedef RefPtr< FutureImpl< void > > Impl; //!< The wait implementation
132 :
133 : /** Construct a new future. */
134 1 : explicit Future( Impl impl ) : impl_( impl ){}
135 :
136 : /** Destruct the future. */
137 1 : ~Future(){}
138 :
139 : /**
140 : * Wait for the promise to be fullfilled.
141 : *
142 : * @param timeout_ optional timeout in milliseconds. If the future is
143 : * not ready when the timer goes off a timeout exception
144 : * is thrown.
145 : */
146 1 : void wait( const uint32_t timeout_ = LB_TIMEOUT_INDEFINITE )
147 : {
148 1 : impl_->wait( timeout_ );
149 1 : }
150 :
151 : /**
152 : * @return true if the future has been fulfilled, false if it is pending.
153 : */
154 : bool isReady() const { return impl_->isReady(); }
155 :
156 : protected:
157 : Impl impl_;
158 : };
159 :
160 : }
161 : #endif //LUNCHBOX_FUTURE_H
|