78 FutureBindError(std::string msg, std::string loc): ExceptionMixin<FutureBindError>(std::move(msg), std::move(loc)) {}
89 Future(): pimpl_(
new Impl) {}
93 TLocker lock(pimpl_->mutex_);
94 return pimpl_->isBound_ || pimpl_->isBadAlloc_ || pimpl_->error_.get();
96 bool operator!()
const {
return !isBound(); }
97 explicit operator bool()
const {
return isBound(); }
103 pimpl_->condition_.wait();
111 const T& operator()()
const
114 TLocker lock(pimpl_->mutex_);
115 if (pimpl_->isBadAlloc_)
117 throw std::bad_alloc();
119 if (pimpl_->error_.get())
121 pimpl_->error_->throwSelf();
123 return *
reinterpret_cast<T*
>(pimpl_->value_);
126 void bind(
const T& value)
128 TLocker lock(pimpl_->mutex_);
129 if (pimpl_->isBound())
131 LASS_THROW_EX(FutureBindError,
"Future is already bound");
133 new (
reinterpret_cast<T*
>(pimpl_->value_)) T(value);
134 pimpl_->isBound_ =
true;
135 pimpl_->condition_.broadcast();
139 TLocker lock(pimpl_->mutex_);
143 void error(
const RemoteExceptionBase& error)
145 TLocker lock(pimpl_->mutex_);
148 pimpl_->error_ = error.clone();
150 catch (
const std::bad_alloc&)
152 pimpl_->isBadAlloc_ =
true;
154 pimpl_->condition_.broadcast();
156 template <
typename ExceptionType>
157 void error(
const ExceptionType& error)
159 TLocker lock(pimpl_->mutex_);
162 pimpl_->error_ =
new RemoteExceptionWrapper<ExceptionType>(error);
164 catch (
const std::bad_alloc&)
166 pimpl_->isBadAlloc_ =
true;
168 pimpl_->condition_.broadcast();
174 typedef util::Locker<TMutex> TLocker;
178 char value_[
sizeof(T)];
179 TRemoteExceptionBasePtr error_;
182 size_t referenceCount_;
183 volatile bool isBound_;
184 volatile bool isBadAlloc_;
186 Impl(): isBound_(
false) {}
195 reinterpret_cast<T*
>(value_)->~T();
202 typedef util::SharedPtr<Impl, util::ObjectStorage, TCounterPolicy> TImplPtr;