X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FTraits.h;h=caeb852c3b6f3d85949398331b3a00be9a5bb9e2;hb=bc857f03fc85a34e84ae8fcdf2d910259940f711;hp=d3002dce5a07bd90a3171fb0136c132843c4d1f3;hpb=378a3bbc7ec5298f92f8c43083c2b0f7836348a6;p=folly.git diff --git a/folly/Traits.h b/folly/Traits.h index d3002dce..caeb852c 100644 --- a/folly/Traits.h +++ b/folly/Traits.h @@ -1,5 +1,5 @@ /* - * Copyright 2013 Facebook, Inc. + * Copyright 2015 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,9 +20,22 @@ #define FOLLY_BASE_TRAITS_H_ #include +#include #include - +#include + +#include + +// libc++ doesn't provide this header, nor does msvc +#ifdef FOLLY_HAVE_BITS_CXXCONFIG_H +// This file appears in two locations: inside fbcode and in the +// libstdc++ source code (when embedding fbstring as std::string). +// To aid in this schizophrenic use, two macros are defined in +// c++config.h: +// _LIBSTDCXX_FBSTRING - Set inside libstdc++. This is useful to +// gate use inside fbcode v. libstdc++ #include +#endif #include #include @@ -222,13 +235,15 @@ template struct IsZeroInitializable * although that is not guaranteed by the standard. */ -namespace std { +FOLLY_NAMESPACE_STD_BEGIN template struct pair; #ifndef _GLIBCXX_USE_FB +FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN template class basic_string; +FOLLY_GLIBCXX_NAMESPACE_CXX11_END #else template class basic_string; @@ -237,8 +252,10 @@ template class vector; template class deque; +FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN template class list; +FOLLY_GLIBCXX_NAMESPACE_CXX11_END template class set; template @@ -246,7 +263,7 @@ template template class shared_ptr; -} +FOLLY_NAMESPACE_STD_END namespace boost { @@ -278,9 +295,13 @@ struct IsOneOf { }; /* - * Complementary type traits to check for a negative value. + * Complementary type traits for integral comparisons. + * + * For instance, `if(x < 0)` yields an error in clang for unsigned types + * when -Werror is used due to -Wtautological-compare * - * if(x < 0) yields an error in clang for unsigned types when -Werror is used + * + * @author: Marcelo Juchem */ namespace detail { @@ -292,24 +313,76 @@ struct is_negative_impl { template struct is_negative_impl { - constexpr static bool check(T x) { return false; } + constexpr static bool check(T) { return false; } }; +// folly::to integral specializations can end up generating code +// inside what are really static ifs (not executed because of the templated +// types) that violate -Wsign-compare so suppress them in order to not prevent +// all calling code from using it. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-compare" + +template +bool less_than_impl(LHS const lhs) { + return + rhs > std::numeric_limits::max() ? true : + rhs <= std::numeric_limits::min() ? false : + lhs < rhs; +} + +#pragma GCC diagnostic pop + +template +bool greater_than_impl(LHS const lhs) { + return + rhs > std::numeric_limits::max() ? false : + rhs < std::numeric_limits::min() ? true : + lhs > rhs; +} + } // namespace detail { +// same as `x < 0` template constexpr bool is_negative(T x) { return folly::detail::is_negative_impl::value>::check(x); } +// same as `x <= 0` +template +constexpr bool is_non_positive(T x) { return !x || folly::is_negative(x); } + +// same as `x > 0` +template +constexpr bool is_positive(T x) { return !is_non_positive(x); } + +// same as `x >= 0` +template +constexpr bool is_non_negative(T x) { + return !x || is_positive(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(LHS const lhs) { + return detail::greater_than_impl< + RHS, rhs, typename std::remove_reference::type + >(lhs); +} + } // namespace folly FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(std::basic_string); FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::vector); FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::list); FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::deque); -FOLLY_ASSUME_FBVECTOR_COMPATIBLE_4(std::map); -FOLLY_ASSUME_FBVECTOR_COMPATIBLE_3(std::set); FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::unique_ptr); FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::shared_ptr); FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::function); @@ -317,6 +390,16 @@ FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::function); // Boost FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(boost::shared_ptr); +#define FOLLY_CREATE_HAS_MEMBER_TYPE_TRAITS(classname, type_name) \ + template \ + struct classname { \ + template \ + constexpr static bool test(typename C::type_name*) { return true; } \ + template \ + constexpr static bool test(...) { return false; } \ + constexpr static bool value = test(nullptr); \ + } + #define FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL(classname, func_name, cv_qual) \ template \ class classname { \ @@ -377,12 +460,16 @@ 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; \ FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL(classname, func_name, ); \ FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL(classname, func_name, const); \ - FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL(classname, func_name, volatile); \ - FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL(classname, func_name, volatile const) + FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL( \ + classname, func_name, /* nolint */ volatile); \ + FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL( \ + classname, func_name, /* nolint */ volatile const) #endif //FOLLY_BASE_TRAITS_H_