X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FTraits.h;h=16aab8d6ef1e9011b195e44f35d04e69b00144cc;hb=422c78beb630d6d5518ba357d3f8ae7d792d6415;hp=ebdb84d1e28ac0ac2856fac14bdb3da18391795e;hpb=622fe822372560c525bd8029d6e68d06d81d24d6;p=folly.git diff --git a/folly/Traits.h b/folly/Traits.h index ebdb84d1..16aab8d6 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 { @@ -277,39 +294,15 @@ struct IsOneOf { enum { value = std::is_same::value || IsOneOf::value }; }; -/** - * A traits class to check for incomplete types. - * - * Example: - * - * struct FullyDeclared {}; // complete type - * struct ForwardDeclared; // incomplete type - * - * is_complete::value // evaluates to true - * is_complete::value // evaluates to true - * is_complete::value // evaluates to false +/* + * Complementary type traits for integral comparisons. * - * struct ForwardDeclared {}; // declared, at last + * For instance, `if(x < 0)` yields an error in clang for unsigned types + * when -Werror is used due to -Wtautological-compare * - * is_complete::value // now it evaluates to true * * @author: Marcelo Juchem */ -template -class is_complete { - template struct sfinae {}; - template - constexpr static bool test(sfinae*) { return true; } - template constexpr static bool test(...) { return false; } -public: - constexpr static bool value = test(nullptr); -}; - -/* - * Complementary type traits to check for a negative/non-positive value. - * - * `if(x < 0)` yields an error in clang for unsigned types when -Werror is used - */ namespace detail { @@ -320,9 +313,34 @@ 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` @@ -335,14 +353,43 @@ constexpr bool is_negative(T x) { 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); +} + +/** + * Like std::piecewise_construct, a tag type & instance used for in-place + * construction of non-movable contained types, e.g. by Synchronized. + */ +struct construct_in_place_t {}; +constexpr construct_in_place_t construct_in_place{}; + } // 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); @@ -350,6 +397,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 { \ @@ -410,12 +467,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_