X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FTraits.h;h=16aab8d6ef1e9011b195e44f35d04e69b00144cc;hb=140c62d25d930cdbdacaa337d254a2471875a4be;hp=4d6deeb5628799cc4a61d0964411588586ba8589;hpb=708be4fcfe5c4c985b879cf8a3b1a36c6c9c6626;p=folly.git diff --git a/folly/Traits.h b/folly/Traits.h index 4d6deeb5..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. @@ -22,11 +22,12 @@ #include #include #include +#include -#include "folly/Portability.h" +#include -// libc++ doesn't provide this header -#if !FOLLY_USE_LIBCPP +// 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 @@ -239,8 +240,10 @@ 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; @@ -249,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 @@ -289,34 +294,6 @@ 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 - * - * struct ForwardDeclared {}; // declared, at last - * - * 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 for integral comparisons. * @@ -336,69 +313,32 @@ struct is_negative_impl { template struct is_negative_impl { - constexpr static bool check(T x) { return false; } + constexpr static bool check(T) { 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; -} +// 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( - typename std::enable_if< - (rhs > std::numeric_limits::max()), - LHS - >::type const -) { - return true; +bool less_than_impl(LHS const lhs) { + return + rhs > std::numeric_limits::max() ? true : + rhs <= std::numeric_limits::min() ? false : + lhs < rhs; } -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< - (rhs <= std::numeric_limits::max() - && rhs >= std::numeric_limits::min()), - LHS - >::type const lhs -) { - return lhs > rhs; -} - -template -bool greater_than_impl( - typename std::enable_if< - (rhs > std::numeric_limits::max()), - LHS - >::type const -) { - return false; -} +#pragma GCC diagnostic pop template -bool greater_than_impl( - typename std::enable_if< - (rhs < std::numeric_limits::min()), - LHS - >::type const -) { - return true; +bool greater_than_impl(LHS const lhs) { + return + rhs > std::numeric_limits::max() ? false : + rhs < std::numeric_limits::min() ? true : + lhs > rhs; } } // namespace detail { @@ -437,6 +377,13 @@ bool greater_than(LHS const lhs) { >(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); @@ -450,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 { \ @@ -517,7 +474,9 @@ FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(boost::shared_ptr); 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_