From 005a6c1f172f4508a9e00b413175750061174724 Mon Sep 17 00:00:00 2001 From: Marcelo Juchem Date: Sat, 30 Mar 2013 00:13:31 -0700 Subject: [PATCH] Fixing clang compatibility issues Test Plan: all folly unit tests Reviewed By: andrewjcg@fb.com FB internal diff: D757374 --- folly/Conv.h | 12 ++++--- folly/Format-inl.h | 6 ++-- folly/Traits.h | 87 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 97 insertions(+), 8 deletions(-) diff --git a/folly/Conv.h b/folly/Conv.h index 4ccacf22..c8360a6d 100644 --- a/folly/Conv.h +++ b/folly/Conv.h @@ -64,13 +64,17 @@ typename std::enable_if< to(const Src & value) { /* static */ if (std::numeric_limits::max() < std::numeric_limits::max()) { - FOLLY_RANGE_CHECK(value <= std::numeric_limits::max(), - "Overflow"); + FOLLY_RANGE_CHECK( + (!greater_than::max()>(value)), + "Overflow" + ); } /* static */ if (std::is_signed::value && (!std::is_signed::value || sizeof(Src) > sizeof(Tgt))) { - FOLLY_RANGE_CHECK(value >= std::numeric_limits::min(), - "Negative overflow"); + FOLLY_RANGE_CHECK( + (!less_than::min()>(value)), + "Negative overflow" + ); } return static_cast(value); } diff --git a/folly/Format-inl.h b/folly/Format-inl.h index c8c90418..70672d47 100644 --- a/folly/Format-inl.h +++ b/folly/Format-inl.h @@ -18,6 +18,8 @@ #error This file may only be included from Format.h. #endif +#include "folly/Traits.h" + namespace folly { namespace detail { @@ -45,7 +47,7 @@ size_t uintToHex(char* buffer, size_t bufLen, Uint v, const char (&repr)[256][2]) { // 'v >>= 7, v >>= 1' is no more than a work around to get rid of shift size // warning when Uint = uint8_t (it's false as v >= 256 implies sizeof(v) > 1). - for (; v >= 256; v >>= 7, v >>= 1) { + for (; !less_than(v); v >>= 7, v >>= 1) { auto b = v & 0xff; bufLen -= 2; buffer[bufLen] = repr[b][0]; @@ -89,7 +91,7 @@ size_t uintToOctal(char* buffer, size_t bufLen, Uint v) { auto& repr = formatOctal; // 'v >>= 7, v >>= 2' is no more than a work around to get rid of shift size // warning when Uint = uint8_t (it's false as v >= 512 implies sizeof(v) > 1). - for (; v >= 512; v >>= 7, v >>= 2) { + for (; !less_than(v); v >>= 7, v >>= 2) { auto b = v & 0x1ff; bufLen -= 3; buffer[bufLen] = repr[b][0]; diff --git a/folly/Traits.h b/folly/Traits.h index ebdb84d1..db8bd33a 100644 --- a/folly/Traits.h +++ b/folly/Traits.h @@ -20,6 +20,7 @@ #define FOLLY_BASE_TRAITS_H_ #include +#include #include #include @@ -306,9 +307,13 @@ public: }; /* - * Complementary type traits to check for a negative/non-positive value. + * Complementary type traits for integral comparisons. * - * `if(x < 0)` yields an error in clang for unsigned types when -Werror is used + * For instance, `if(x < 0)` yields an error in clang for unsigned types + * when -Werror is used due to -Wtautological-compare + * + * + * @author: Marcelo Juchem */ namespace detail { @@ -323,6 +328,68 @@ struct is_negative_impl { constexpr static bool check(T x) { return false; } }; +template +bool less_than_impl( + typename std::enable_if< + (rhs <= std::numeric_limits::max() + && rhs >= std::numeric_limits::min()), + LHS + >::type const lhs +) { + return lhs < rhs; +} + +template +bool less_than_impl( + typename std::enable_if< + (rhs > std::numeric_limits::max()), + LHS + >::type const +) { + return true; +} + +template +bool less_than_impl( + typename std::enable_if< + (rhs < std::numeric_limits::min()), + LHS + >::type const +) { + return false; +} + +template +bool greater_than_impl( + typename std::enable_if< + (lhs <= std::numeric_limits::max() + && lhs >= std::numeric_limits::min()), + RHS + >::type const rhs +) { + return lhs < rhs; +} + +template +bool greater_than_impl( + typename std::enable_if< + (lhs > std::numeric_limits::max()), + RHS + >::type const +) { + return false; +} + +template +bool greater_than_impl( + typename std::enable_if< + (lhs < std::numeric_limits::min()), + RHS + >::type const +) { + return true; +} + } // namespace detail { // same as `x < 0` @@ -335,6 +402,20 @@ constexpr bool is_negative(T x) { template constexpr bool is_non_positive(T x) { return !x || folly::is_negative(x); } +template +bool less_than(LHS const lhs) { + return detail::less_than_impl< + RHS, rhs, typename std::remove_reference::type + >(lhs); +} + +template +bool greater_than(RHS const rhs) { + return detail::greater_than_impl< + LHS, lhs, typename std::remove_reference::type + >(rhs); +} + } // namespace folly FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(std::basic_string); @@ -410,6 +491,8 @@ FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(boost::shared_ptr); * cout << "Does class Bar have a member double test(const string&, long)? " * << boolalpha << has_test_traits::value; * } + * + * @author: Marcelo Juchem */ #define FOLLY_CREATE_HAS_MEMBER_FN_TRAITS(classname, func_name) \ template class classname; \ -- 2.34.1