#include <exception>
#include <cstdatomic>
-#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
- && defined(_GLIBCXX_ATOMIC_BUILTINS_4)
-
namespace std
{
/**
inline error_condition make_error_condition(future_errc __errc)
{ return error_condition(static_cast<int>(__errc), *future_category); }
- /// Exception type thrown by futures.
+ /**
+ * @brief Exception type thrown by futures.
+ * @ingroup exceptions
+ */
class future_error : public logic_error
{
+ error_code _M_code;
+
public:
explicit future_error(future_errc __ec)
: logic_error("std::future_error"), _M_code(make_error_code(__ec))
{ }
- const error_code& code() const throw() { return _M_code; }
+ virtual ~future_error() throw();
- const char* what() const throw() { return _M_code.message().c_str(); }
+ virtual const char*
+ what() const throw();
- private:
- error_code _M_code;
+ const error_code&
+ code() const throw() { return _M_code; }
};
// Forward declarations.
template<typename _Result>
class promise;
+#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
+ && defined(_GLIBCXX_ATOMIC_BUILTINS_4)
+
// Holds the result of a future
struct _Future_result_base
{
{
lock_guard<mutex> __lock(_M_mutex);
if (_M_ready())
- throw future_error(future_errc::promise_already_satisfied);
+ __throw_future_error(int(future_errc::promise_already_satisfied));
_M_result.swap(__res);
}
_M_cond.notify_all();
_M_set_retrieved_flag()
{
if (_M_retrieved.test_and_set())
- throw future_error(future_errc::future_already_retrieved);
+ __throw_future_error(int(future_errc::future_already_retrieved));
}
private:
if (static_cast<bool>(this->_M_state))
this->_M_state->_M_set_retrieved_flag();
else
- throw future_error(future_errc::future_already_retrieved);
+ __throw_future_error(int(future_errc::future_already_retrieved));
}
// copy construction from a shared_future
unique_future(const _State_ptr& __state) : _Base_type(__state) { }
};
- /// primary template for unique_future
+ /// primary template for shared_future
template<typename _Result>
class shared_future : public _Future_impl<_Result>
{
unique_future<_Result>
get_future()
{
- try
+ __try
{
return _M_promise.get_future();
}
- catch (const future_error& __e)
+ __catch (const future_error& __e)
{
+#ifdef __EXCEPTIONS
if (__e.code() == future_errc::future_already_retrieved)
- throw std::bad_function_call();
- throw;
+ throw std::bad_function_call();
+ throw;
+#endif
}
}
operator()(_ArgTypes... __args)
{
if (!static_cast<bool>(_M_task) || _M_promise._M_satisfied())
- throw std::bad_function_call();
- try
+ {
+#ifdef __EXCEPTIONS
+ throw std::bad_function_call();
+#else
+ __builtin_abort();
+#endif
+ }
+
+ __try
{
_Run_task<_Result, _ArgTypes...>::_S_run(_M_promise, _M_task,
std::forward<_ArgTypes>(__args)...);
}
- catch (...)
+ __catch (...)
{
_M_promise.set_exception(current_exception());
}
promise<_Result> _M_promise;
};
- // @} group futures
-}
-
#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
// && _GLIBCXX_ATOMIC_BUILTINS_4
+ // @} group futures
+}
+
#endif // __GXX_EXPERIMENTAL_CXX0X__
#endif // _GLIBCXX_FUTURE