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 <boost/noncopyable.hpp> // base class
22 : #include <lunchbox/refPtr.h> // used inline
23 : #include <lunchbox/referenced.h> // base class
24 : #include <stdexcept>
25 :
26 : namespace lunchbox
27 : {
28 1 : class FutureTimeout : public std::runtime_error
29 : {
30 : public:
31 1 : FutureTimeout()
32 1 : : std::runtime_error("")
33 : {
34 1 : }
35 : };
36 :
37 : /** Base class to implement the wait method fulfilling the future. */
38 : template <class T>
39 2000007 : class FutureImpl : public Referenced, public boost::noncopyable
40 : {
41 : public:
42 : /** Destruct the future. */
43 2000007 : virtual ~FutureImpl() {}
44 : /**
45 : * Wait for the promise to be fullfilled.
46 : *
47 : * May be called multiple times.
48 : * @param timeout optional timeout in milliseconds. If the future is
49 : * not ready when the timer goes off a timeout exception
50 : * is thrown.
51 : */
52 : virtual T wait(const uint32_t timeout = LB_TIMEOUT_INDEFINITE) = 0;
53 :
54 : /**
55 : * @return true if the future has been fulfilled, false if it is pending.
56 : */
57 : virtual bool isReady() const = 0;
58 : };
59 :
60 : /** A future represents a asynchronous operation. Do not subclass. */
61 : template <class T>
62 1000000 : class Future
63 : {
64 : private:
65 : typedef void (Future<T>::*bool_t)() const;
66 : void bool_true() const {}
67 : public:
68 : typedef RefPtr<FutureImpl<T> > Impl; //!< The wait implementation
69 :
70 : /** Construct a new future. */
71 2000004 : explicit Future(Impl impl)
72 2000004 : : impl_(impl)
73 : {
74 2000004 : }
75 :
76 : /** Destruct the future. */
77 3000004 : ~Future() {}
78 : /**
79 : * Wait for the promise to be fullfilled.
80 : *
81 : * @param timeout_ optional timeout in milliseconds. If the future is
82 : * not ready when the timer goes off a timeout exception
83 : * is thrown.
84 : */
85 5 : T wait(const uint32_t timeout_ = LB_TIMEOUT_INDEFINITE)
86 : {
87 5 : return impl_->wait(timeout_);
88 : }
89 :
90 : /**
91 : * @return true if the future has been fulfilled, false if it is pending.
92 : */
93 2 : bool isReady() const { return impl_->isReady(); }
94 : /** @name Blocking comparison operators. */
95 : //@{
96 : /** @return a bool conversion of the result. */
97 : operator bool_t() { return wait() ? &Future<T>::bool_true : 0; }
98 : /** @return true if the result does convert to false. */
99 : bool operator!() { return !wait(); }
100 : /** @return true if the result is equal to the given value. */
101 2 : bool operator==(const T& rhs) { return wait() == rhs; }
102 : /** @return true if the result is not equal to the rhs. */
103 : bool operator!=(const T& rhs) { return wait() != rhs; }
104 : /** @return true if the result is smaller than the rhs. */
105 : bool operator<(const T& rhs) { return wait() < rhs; }
106 : /** @return true if the result is bigger than the rhs. */
107 : bool operator>(const T& rhs) { return wait() > rhs; }
108 : /** @return true if the result is smaller or equal. */
109 : bool operator<=(const T& rhs) { return wait() <= rhs; }
110 : /** @return true if the result is bigger or equal. */
111 : bool operator>=(const T& rhs) { return wait() >= rhs; }
112 : //@}
113 :
114 : protected:
115 : Impl impl_;
116 : };
117 :
118 : typedef Future<bool> f_bool_t; //!< A boolean future
119 :
120 : /** Future template specialization for void */
121 : template <>
122 : class Future<void>
123 : {
124 : private:
125 : typedef void (Future<void>::*bool_t)() const;
126 : void bool_true() const {}
127 : public:
128 : typedef RefPtr<FutureImpl<void> > Impl; //!< The wait implementation
129 :
130 : /** Construct a new future. */
131 3 : explicit Future(Impl impl)
132 3 : : impl_(impl)
133 : {
134 3 : }
135 :
136 : /** Destruct the future. */
137 3 : ~Future() {}
138 : /**
139 : * Wait for the promise to be fullfilled.
140 : *
141 : * @param timeout_ optional timeout in milliseconds. If the future is
142 : * not ready when the timer goes off a timeout exception
143 : * is thrown.
144 : */
145 4 : void wait(const uint32_t timeout_ = LB_TIMEOUT_INDEFINITE)
146 : {
147 4 : impl_->wait(timeout_);
148 2 : }
149 :
150 : /**
151 : * @return true if the future has been fulfilled, false if it is pending.
152 : */
153 1 : bool isReady() const { return impl_->isReady(); }
154 : protected:
155 : Impl impl_;
156 : };
157 : }
158 : #endif // LUNCHBOX_FUTURE_H
|