From d27a9dbaf4f8c60c59bf321735bf8fa1e2476d40 Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Fri, 24 Jun 2016 11:23:42 -0700 Subject: [PATCH] Fix uses of std::nextafter on Android Summary: On Android, std::nextafter isn't implemented. However, the C functions and compiler builtins are still provided. This change adds a portability abstraction as folly::nextafter. Reviewed By: mzlee, yfeldblum Differential Revision: D3478081 fbshipit-source-id: 54fec1ca8bdec24ba45d51e07020259fdbae61b4 --- folly/Conv.h | 5 +-- folly/Makefile.am | 1 + folly/portability/Math.h | 71 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 folly/portability/Math.h diff --git a/folly/Conv.h b/folly/Conv.h index 08628a0e..8c03e28f 100644 --- a/folly/Conv.h +++ b/folly/Conv.h @@ -41,6 +41,7 @@ #include #include #include +#include #define FOLLY_RANGE_CHECK_STRINGIZE(x) #x #define FOLLY_RANGE_CHECK_STRINGIZE2(x) FOLLY_RANGE_CHECK_STRINGIZE(x) @@ -1172,7 +1173,7 @@ checkConversion(const Src& value) { if (value > tgtMaxAsSrc) { return false; } - const Src mmax = std::nextafter(tgtMaxAsSrc, Src()); + const Src mmax = folly::nextafter(tgtMaxAsSrc, Src()); if (static_cast(value - mmax) > std::numeric_limits::max() - static_cast(mmax)) { return false; @@ -1181,7 +1182,7 @@ checkConversion(const Src& value) { if (value < tgtMinAsSrc) { return false; } - const Src mmin = std::nextafter(tgtMinAsSrc, Src()); + const Src mmin = folly::nextafter(tgtMinAsSrc, Src()); if (static_cast(value - mmin) < std::numeric_limits::min() - static_cast(mmin)) { return false; diff --git a/folly/Makefile.am b/folly/Makefile.am index 08ce2f23..212c0a17 100644 --- a/folly/Makefile.am +++ b/folly/Makefile.am @@ -257,6 +257,7 @@ nobase_follyinclude_HEADERS = \ portability/IOVec.h \ portability/Libgen.h \ portability/Malloc.h \ + portability/Math.h \ portability/Memory.h \ portability/PThread.h \ portability/Sockets.h \ diff --git a/folly/portability/Math.h b/folly/portability/Math.h new file mode 100644 index 00000000..c9bdd51f --- /dev/null +++ b/folly/portability/Math.h @@ -0,0 +1,71 @@ +/* + * Copyright 2016 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace folly { + +#ifndef __ANDROID__ + +/** + * Most platforms hopefully provide std::nextafter. + */ + +/* using override */ using std::nextafter; + +#else // !__ANDROID__ + +/** + * On Android, std::nextafter isn't implemented. However, the C functions and + * compiler builtins are still provided. Using the GCC builtin is actually + * slightly faster, as they're constexpr and the use cases within folly are in + * constexpr context. + */ + +#if defined(__GNUC__) && !defined(__clang__) + +constexpr float nextafter(float x, float y) { + return __builtin_nextafterf(x, y); +} + +constexpr double nextafter(double x, double y) { + return __builtin_nextafter(x, y); +} + +constexpr long double nextafter(long double x, long double y) { + return __builtin_nextafterl(x, y); +} + +#else // __GNUC__ + +inline float nextafter(float x, float y) { + return ::nextafterf(x, y); +} + +inline double nextafter(double x, double y) { + return ::nextafter(x, y); +} + +inline long double nextafter(long double x, long double y) { + return ::nextafterl(x, y); +} + +#endif // __GNUC__ + +#endif // __ANDROID__ +} -- 2.34.1