Line data Source code
1 :
2 : /* Copyright (c) 2013-2015, 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 : #include <boost/noncopyable.hpp> // base class
24 : #include <stdexcept>
25 :
26 : namespace lunchbox
27 : {
28 :
29 1 : class FutureTimeout : public std::runtime_error
30 : {
31 : public:
32 1 : FutureTimeout() : std::runtime_error("") {}
33 : };
34 :
35 : /** Base class to implement the wait method fulfilling the future. */
36 : template< class T >
37 2000007 : class FutureImpl : public Referenced, public boost::noncopyable
38 : {
39 : public:
40 : /** Destruct the future. */
41 2000007 : 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 1000000 : 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 2000004 : explicit Future( Impl impl ) : impl_( impl ){}
71 :
72 : /** Destruct the future. */
73 3000004 : ~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 2 : 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 2 : 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 : typedef Future< bool > f_bool_t; //!< A boolean future
124 :
125 : /** Future template specialization for void */
126 : template<> class Future< void >
127 : {
128 : private:
129 : typedef void (Future< void >::*bool_t)() const;
130 : void bool_true() const {}
131 :
132 : public:
133 : typedef RefPtr< FutureImpl< void > > Impl; //!< The wait implementation
134 :
135 : /** Construct a new future. */
136 3 : explicit Future( Impl impl ) : impl_( impl ){}
137 :
138 : /** Destruct the future. */
139 3 : ~Future(){}
140 :
141 : /**
142 : * Wait for the promise to be fullfilled.
143 : *
144 : * @param timeout_ optional timeout in milliseconds. If the future is
145 : * not ready when the timer goes off a timeout exception
146 : * is thrown.
147 : */
148 4 : void wait( const uint32_t timeout_ = LB_TIMEOUT_INDEFINITE )
149 : {
150 4 : impl_->wait( timeout_ );
151 2 : }
152 :
153 : /**
154 : * @return true if the future has been fulfilled, false if it is pending.
155 : */
156 1 : bool isReady() const { return impl_->isReady(); }
157 :
158 : protected:
159 : Impl impl_;
160 : };
161 : }
162 : #endif //LUNCHBOX_FUTURE_H
|