Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(common): support libc++ >= 18.1 #14151

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions google/cloud/internal/future_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,50 @@
// limitations under the License.

#include "google/cloud/internal/future_impl.h"
#include "google/cloud/internal/port_platform.h"
#include "google/cloud/terminate_handler.h"
#include <stdexcept>

// This function is only needed if exceptions are enabled.
#ifdef GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
// TODO(#14152): Remove libC++ hack
// The `std::future_error::future_error(std::future_errc)` constructor is not
alevenberg marked this conversation as resolved.
Show resolved Hide resolved
// guaranteed to exist until C++17. Fortunately, stdlibc++, MSVC are forgiving,
// and libc++ is forgiving until version 18.1.
#if GOOGLE_CLOUD_CPP_CPP_VERSION >= 201703L || _LIBCPP_VERSION < 180100

namespace {
std::future_error MakeFutureErrorImpl(std::future_errc ec) {
return std::future_error(ec);
}
} // namespace

#else
// We can probably tolerate this terrible hack (which depends on UB) until we
// require C++17.
namespace {
struct OhTheHorrors {};
} // namespace

namespace std {
template <>
class promise<OhTheHorrors> {
public:
static auto MakeFutureError(std::future_errc ec) {
return std::future_error(std::make_error_code(ec));
}
};
} // namespace std

namespace {
std::future_error MakeFutureErrorImpl(std::future_errc ec) {
return std::promise<OhTheHorrors>::MakeFutureError(ec);
}
} // namespace

#endif
#endif // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS

namespace google {
namespace cloud {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
Expand All @@ -24,7 +65,7 @@ namespace internal {
[[noreturn]] void ThrowFutureError(std::future_errc ec, char const* msg) {
#ifdef GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
(void)msg; // disable unused argument warning.
throw std::future_error(ec);
throw MakeFutureErrorImpl(ec);
#else
std::string full_msg = "future_error[";
full_msg += std::make_error_code(ec).message();
Expand All @@ -46,7 +87,7 @@ namespace internal {

std::exception_ptr MakeFutureError(std::future_errc ec) {
#ifdef GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS
return std::make_exception_ptr(std::future_error(ec));
return std::make_exception_ptr(MakeFutureErrorImpl(ec));
#else
(void)ec;
// We cannot create a valid `std::exception_ptr` in this case. It does not
Expand Down