diff options
author | Abseil Team <absl-team@google.com> | 2019-08-05T18·32-0700 |
---|---|---|
committer | vslashg <gfalcon@google.com> | 2019-08-05T19·42-0400 |
commit | c5c4db4f5191fe5e76cbf68dcc71fb28702f7d2b (patch) | |
tree | a5f5c13c9a239ac01d0f7b5280e71d1b2a641307 /absl/base | |
parent | 14550beb3b7b97195e483fb74b5efb906395c31e (diff) |
Export of internal Abseil changes
-- f8fe0f483378c7520d8f8bdfabe4b20de4d96c7e by Andy Soffer <asoffer@google.com>: Ensure that Invoke can support C++17 in the sense that noexcept is part of the type. PiperOrigin-RevId: 261730155 -- bf796ab71653a80498f9374bc8c5111d065c64ba by Abseil Team <absl-team@google.com>: Fix typo in static_assert message for copy/move constructible by replacing "by" with "be". PiperOrigin-RevId: 261713992 -- 8c7c17c40d03a322f304a2fd73ed34462dbf265a by Andy Soffer <asoffer@google.com>: Add absl::is_function drop-in replacement for std::is_function. Some standard libraries incorrectly implement std::is_function in a few corner cases. In particular, libstdc++ functions marked noexcept. The trick being used here is that function types decay to pointers. After excluding cases like is_class, etc, we can distinguish function types by testing for this decay. Many thanks to ericwf@ for essentially writing this CL. PiperOrigin-RevId: 261705008 -- c5adf42d0a132c2525d17a719329eab2ffe0aa94 by Abseil Team <absl-team@google.com>: Add microbenchmark for StrSplit that uses delimiter ByAnyChar. PiperOrigin-RevId: 261424010 -- 66a342f9381ec56be2fe3aa5b3193dd3538a9740 by Andy Soffer <asoffer@google.com>: CMake support for Abseil Random This change touches almost build-related files for CMake almost exclusively. The one minor exception is random/internal/salted_seed_seq.h. The default warnings configuration for one of our CI builds requests not having named but unused parameters. The change in this file cleans up that warning. PiperOrigin-RevId: 261192369 GitOrigin-RevId: f8fe0f483378c7520d8f8bdfabe4b20de4d96c7e Change-Id: I05f662baacfe78750651535aa658f61c2327bc44
Diffstat (limited to 'absl/base')
-rw-r--r-- | absl/base/BUILD.bazel | 3 | ||||
-rw-r--r-- | absl/base/CMakeLists.txt | 2 | ||||
-rw-r--r-- | absl/base/internal/invoke.h | 37 | ||||
-rw-r--r-- | absl/base/invoke_test.cc | 21 |
4 files changed, 43 insertions, 20 deletions
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index e825de0c1c81..a512272adb94 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -155,6 +155,9 @@ cc_library( visibility = [ "//absl:__subpackages__", ], + deps = [ + "//absl/meta:type_traits", + ], ) cc_library( diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 9ff80738db5f..cc7960e3ae88 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -133,6 +133,8 @@ absl_cc_library( "internal/invoke.h" COPTS ${ABSL_DEFAULT_COPTS} + DEPS + absl::type_traits ) absl_cc_library( diff --git a/absl/base/internal/invoke.h b/absl/base/internal/invoke.h index 8da2869afbd7..44f13302f434 100644 --- a/absl/base/internal/invoke.h +++ b/absl/base/internal/invoke.h @@ -39,6 +39,8 @@ #include <type_traits> #include <utility> +#include "absl/meta/type_traits.h" + // The following code is internal implementation detail. See the comment at the // top of this file for the API documentation. @@ -67,15 +69,11 @@ struct MemFunAndRef : StrippedAccept<MemFunAndRef> { template <typename... Args> struct AcceptImpl : std::false_type {}; - template <typename R, typename C, typename... Params, typename Obj, - typename... Args> - struct AcceptImpl<R (C::*)(Params...), Obj, Args...> - : std::is_base_of<C, Obj> {}; - - template <typename R, typename C, typename... Params, typename Obj, - typename... Args> - struct AcceptImpl<R (C::*)(Params...) const, Obj, Args...> - : std::is_base_of<C, Obj> {}; + template <typename MemFunType, typename C, typename Obj, typename... Args> + struct AcceptImpl<MemFunType C::*, Obj, Args...> + : std::integral_constant<bool, std::is_base_of<C, Obj>::value && + absl::is_function<MemFunType>::value> { + }; template <typename MemFun, typename Obj, typename... Args> static decltype((std::declval<Obj>().* @@ -92,15 +90,11 @@ struct MemFunAndPtr : StrippedAccept<MemFunAndPtr> { template <typename... Args> struct AcceptImpl : std::false_type {}; - template <typename R, typename C, typename... Params, typename Ptr, - typename... Args> - struct AcceptImpl<R (C::*)(Params...), Ptr, Args...> - : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value> {}; - - template <typename R, typename C, typename... Params, typename Ptr, - typename... Args> - struct AcceptImpl<R (C::*)(Params...) const, Ptr, Args...> - : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value> {}; + template <typename MemFunType, typename C, typename Ptr, typename... Args> + struct AcceptImpl<MemFunType C::*, Ptr, Args...> + : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value && + absl::is_function<MemFunType>::value> { + }; template <typename MemFun, typename Ptr, typename... Args> static decltype(((*std::declval<Ptr>()).* @@ -119,7 +113,9 @@ struct DataMemAndRef : StrippedAccept<DataMemAndRef> { struct AcceptImpl : std::false_type {}; template <typename R, typename C, typename Obj> - struct AcceptImpl<R C::*, Obj> : std::is_base_of<C, Obj> {}; + struct AcceptImpl<R C::*, Obj> + : std::integral_constant<bool, std::is_base_of<C, Obj>::value && + !absl::is_function<R>::value> {}; template <typename DataMem, typename Ref> static decltype(std::declval<Ref>().*std::declval<DataMem>()) Invoke( @@ -136,7 +132,8 @@ struct DataMemAndPtr : StrippedAccept<DataMemAndPtr> { template <typename R, typename C, typename Ptr> struct AcceptImpl<R C::*, Ptr> - : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value> {}; + : std::integral_constant<bool, !std::is_base_of<C, Ptr>::value && + !absl::is_function<R>::value> {}; template <typename DataMem, typename Ptr> static decltype((*std::declval<Ptr>()).*std::declval<DataMem>()) Invoke( diff --git a/absl/base/invoke_test.cc b/absl/base/invoke_test.cc index 691f553791d3..9074443b3cbb 100644 --- a/absl/base/invoke_test.cc +++ b/absl/base/invoke_test.cc @@ -70,6 +70,10 @@ struct OverloadedFunctor { struct Class { int Method(int a, int b) { return a - b; } int ConstMethod(int a, int b) const { return a - b; } + int RefMethod(int a, int b) & { return a - b; } + int RefRefMethod(int a, int b) && { return a - b; } + int NoExceptMethod(int a, int b) noexcept { return a - b; } + int VolatileMethod(int a, int b) volatile { return a - b; } int member; }; @@ -151,8 +155,18 @@ TEST(InvokeTest, ReferenceWrapper) { TEST(InvokeTest, MemberFunction) { std::unique_ptr<Class> p(new Class); std::unique_ptr<const Class> cp(new Class); + std::unique_ptr<volatile Class> vp(new Class); + EXPECT_EQ(1, Invoke(&Class::Method, p, 3, 2)); EXPECT_EQ(1, Invoke(&Class::Method, p.get(), 3, 2)); + EXPECT_EQ(1, Invoke(&Class::Method, *p, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::RefMethod, p, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::RefMethod, p.get(), 3, 2)); + EXPECT_EQ(1, Invoke(&Class::RefMethod, *p, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::RefRefMethod, std::move(*p), 3, 2)); // NOLINT + EXPECT_EQ(1, Invoke(&Class::NoExceptMethod, p, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::NoExceptMethod, p.get(), 3, 2)); + EXPECT_EQ(1, Invoke(&Class::NoExceptMethod, *p, 3, 2)); EXPECT_EQ(1, Invoke(&Class::ConstMethod, p, 3, 2)); EXPECT_EQ(1, Invoke(&Class::ConstMethod, p.get(), 3, 2)); @@ -162,6 +176,13 @@ TEST(InvokeTest, MemberFunction) { EXPECT_EQ(1, Invoke(&Class::ConstMethod, cp.get(), 3, 2)); EXPECT_EQ(1, Invoke(&Class::ConstMethod, *cp, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::VolatileMethod, p, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::VolatileMethod, p.get(), 3, 2)); + EXPECT_EQ(1, Invoke(&Class::VolatileMethod, *p, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::VolatileMethod, vp, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::VolatileMethod, vp.get(), 3, 2)); + EXPECT_EQ(1, Invoke(&Class::VolatileMethod, *vp, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::Method, make_unique<Class>(), 3, 2)); EXPECT_EQ(1, Invoke(&Class::ConstMethod, make_unique<Class>(), 3, 2)); EXPECT_EQ(1, Invoke(&Class::ConstMethod, make_unique<const Class>(), 3, 2)); |