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
This commit is contained in:
		
							parent
							
								
									14550beb3b
								
							
						
					
					
						commit
						c5c4db4f51
					
				
					 12 changed files with 1145 additions and 26 deletions
				
			
		| 
						 | 
					@ -25,6 +25,7 @@ add_subdirectory(hash)
 | 
				
			||||||
add_subdirectory(memory)
 | 
					add_subdirectory(memory)
 | 
				
			||||||
add_subdirectory(meta)
 | 
					add_subdirectory(meta)
 | 
				
			||||||
add_subdirectory(numeric)
 | 
					add_subdirectory(numeric)
 | 
				
			||||||
 | 
					add_subdirectory(random)
 | 
				
			||||||
add_subdirectory(strings)
 | 
					add_subdirectory(strings)
 | 
				
			||||||
add_subdirectory(synchronization)
 | 
					add_subdirectory(synchronization)
 | 
				
			||||||
add_subdirectory(time)
 | 
					add_subdirectory(time)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,6 +155,9 @@ cc_library(
 | 
				
			||||||
    visibility = [
 | 
					    visibility = [
 | 
				
			||||||
        "//absl:__subpackages__",
 | 
					        "//absl:__subpackages__",
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    deps = [
 | 
				
			||||||
 | 
					        "//absl/meta:type_traits",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cc_library(
 | 
					cc_library(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,6 +133,8 @@ absl_cc_library(
 | 
				
			||||||
    "internal/invoke.h"
 | 
					    "internal/invoke.h"
 | 
				
			||||||
  COPTS
 | 
					  COPTS
 | 
				
			||||||
    ${ABSL_DEFAULT_COPTS}
 | 
					    ${ABSL_DEFAULT_COPTS}
 | 
				
			||||||
 | 
					  DEPS
 | 
				
			||||||
 | 
					    absl::type_traits
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
absl_cc_library(
 | 
					absl_cc_library(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,8 @@
 | 
				
			||||||
#include <type_traits>
 | 
					#include <type_traits>
 | 
				
			||||||
#include <utility>
 | 
					#include <utility>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "absl/meta/type_traits.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The following code is internal implementation detail.  See the comment at the
 | 
					// The following code is internal implementation detail.  See the comment at the
 | 
				
			||||||
// top of this file for the API documentation.
 | 
					// top of this file for the API documentation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,15 +69,11 @@ struct MemFunAndRef : StrippedAccept<MemFunAndRef> {
 | 
				
			||||||
  template <typename... Args>
 | 
					  template <typename... Args>
 | 
				
			||||||
  struct AcceptImpl : std::false_type {};
 | 
					  struct AcceptImpl : std::false_type {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename R, typename C, typename... Params, typename Obj,
 | 
					  template <typename MemFunType, typename C, typename Obj, typename... Args>
 | 
				
			||||||
            typename... Args>
 | 
					  struct AcceptImpl<MemFunType C::*, Obj, Args...>
 | 
				
			||||||
  struct AcceptImpl<R (C::*)(Params...), Obj, Args...>
 | 
					      : std::integral_constant<bool, std::is_base_of<C, Obj>::value &&
 | 
				
			||||||
      : std::is_base_of<C, Obj> {};
 | 
					                                         absl::is_function<MemFunType>::value> {
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
  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 MemFun, typename Obj, typename... Args>
 | 
					  template <typename MemFun, typename Obj, typename... Args>
 | 
				
			||||||
  static decltype((std::declval<Obj>().*
 | 
					  static decltype((std::declval<Obj>().*
 | 
				
			||||||
| 
						 | 
					@ -92,15 +90,11 @@ struct MemFunAndPtr : StrippedAccept<MemFunAndPtr> {
 | 
				
			||||||
  template <typename... Args>
 | 
					  template <typename... Args>
 | 
				
			||||||
  struct AcceptImpl : std::false_type {};
 | 
					  struct AcceptImpl : std::false_type {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename R, typename C, typename... Params, typename Ptr,
 | 
					  template <typename MemFunType, typename C, typename Ptr, typename... Args>
 | 
				
			||||||
            typename... Args>
 | 
					  struct AcceptImpl<MemFunType C::*, Ptr, Args...>
 | 
				
			||||||
  struct AcceptImpl<R (C::*)(Params...), Ptr, Args...>
 | 
					      : 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<MemFunType>::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 MemFun, typename Ptr, typename... Args>
 | 
					  template <typename MemFun, typename Ptr, typename... Args>
 | 
				
			||||||
  static decltype(((*std::declval<Ptr>()).*
 | 
					  static decltype(((*std::declval<Ptr>()).*
 | 
				
			||||||
| 
						 | 
					@ -119,7 +113,9 @@ struct DataMemAndRef : StrippedAccept<DataMemAndRef> {
 | 
				
			||||||
  struct AcceptImpl : std::false_type {};
 | 
					  struct AcceptImpl : std::false_type {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename R, typename C, typename Obj>
 | 
					  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>
 | 
					  template <typename DataMem, typename Ref>
 | 
				
			||||||
  static decltype(std::declval<Ref>().*std::declval<DataMem>()) Invoke(
 | 
					  static decltype(std::declval<Ref>().*std::declval<DataMem>()) Invoke(
 | 
				
			||||||
| 
						 | 
					@ -136,7 +132,8 @@ struct DataMemAndPtr : StrippedAccept<DataMemAndPtr> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename R, typename C, typename Ptr>
 | 
					  template <typename R, typename C, typename Ptr>
 | 
				
			||||||
  struct AcceptImpl<R C::*, 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>
 | 
					  template <typename DataMem, typename Ptr>
 | 
				
			||||||
  static decltype((*std::declval<Ptr>()).*std::declval<DataMem>()) Invoke(
 | 
					  static decltype((*std::declval<Ptr>()).*std::declval<DataMem>()) Invoke(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,6 +70,10 @@ struct OverloadedFunctor {
 | 
				
			||||||
struct Class {
 | 
					struct Class {
 | 
				
			||||||
  int Method(int a, int b) { return a - b; }
 | 
					  int Method(int a, int b) { return a - b; }
 | 
				
			||||||
  int ConstMethod(int a, int b) const { 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;
 | 
					  int member;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -151,8 +155,18 @@ TEST(InvokeTest, ReferenceWrapper) {
 | 
				
			||||||
TEST(InvokeTest, MemberFunction) {
 | 
					TEST(InvokeTest, MemberFunction) {
 | 
				
			||||||
  std::unique_ptr<Class> p(new Class);
 | 
					  std::unique_ptr<Class> p(new Class);
 | 
				
			||||||
  std::unique_ptr<const Class> cp(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, 3, 2));
 | 
				
			||||||
  EXPECT_EQ(1, Invoke(&Class::Method, p.get(), 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, 3, 2));
 | 
				
			||||||
  EXPECT_EQ(1, Invoke(&Class::ConstMethod, p.get(), 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.get(), 3, 2));
 | 
				
			||||||
  EXPECT_EQ(1, Invoke(&Class::ConstMethod, *cp, 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::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<Class>(), 3, 2));
 | 
				
			||||||
  EXPECT_EQ(1, Invoke(&Class::ConstMethod, make_unique<const Class>(), 3, 2));
 | 
					  EXPECT_EQ(1, Invoke(&Class::ConstMethod, make_unique<const Class>(), 3, 2));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
 | 
				
			||||||
  set(ABSL_DEFAULT_COPTS "${ABSL_GCC_FLAGS}")
 | 
					  set(ABSL_DEFAULT_COPTS "${ABSL_GCC_FLAGS}")
 | 
				
			||||||
  set(ABSL_TEST_COPTS "${ABSL_GCC_FLAGS};${ABSL_GCC_TEST_FLAGS}")
 | 
					  set(ABSL_TEST_COPTS "${ABSL_GCC_FLAGS};${ABSL_GCC_TEST_FLAGS}")
 | 
				
			||||||
  set(ABSL_EXCEPTIONS_FLAG "${ABSL_GCC_EXCEPTIONS_FLAGS}")
 | 
					  set(ABSL_EXCEPTIONS_FLAG "${ABSL_GCC_EXCEPTIONS_FLAGS}")
 | 
				
			||||||
 | 
					  set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_X64_FLAGS}")
 | 
				
			||||||
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
 | 
					elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
 | 
				
			||||||
  # MATCHES so we get both Clang and AppleClang
 | 
					  # MATCHES so we get both Clang and AppleClang
 | 
				
			||||||
  if(MSVC)
 | 
					  if(MSVC)
 | 
				
			||||||
| 
						 | 
					@ -17,10 +18,12 @@ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
 | 
				
			||||||
    set(ABSL_TEST_COPTS "${ABSL_CLANG_CL_FLAGS};${ABSL_CLANG_CL_TEST_FLAGS}")
 | 
					    set(ABSL_TEST_COPTS "${ABSL_CLANG_CL_FLAGS};${ABSL_CLANG_CL_TEST_FLAGS}")
 | 
				
			||||||
    set(ABSL_EXCEPTIONS_FLAG "${ABSL_CLANG_CL_EXCEPTIONS_FLAGS}")
 | 
					    set(ABSL_EXCEPTIONS_FLAG "${ABSL_CLANG_CL_EXCEPTIONS_FLAGS}")
 | 
				
			||||||
    set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}")
 | 
					    set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}")
 | 
				
			||||||
 | 
					    set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}")
 | 
				
			||||||
  else()
 | 
					  else()
 | 
				
			||||||
    set(ABSL_DEFAULT_COPTS "${ABSL_LLVM_FLAGS}")
 | 
					    set(ABSL_DEFAULT_COPTS "${ABSL_LLVM_FLAGS}")
 | 
				
			||||||
    set(ABSL_TEST_COPTS "${ABSL_LLVM_FLAGS};${ABSL_LLVM_TEST_FLAGS}")
 | 
					    set(ABSL_TEST_COPTS "${ABSL_LLVM_FLAGS};${ABSL_LLVM_TEST_FLAGS}")
 | 
				
			||||||
    set(ABSL_EXCEPTIONS_FLAG "${ABSL_LLVM_EXCEPTIONS_FLAGS}")
 | 
					    set(ABSL_EXCEPTIONS_FLAG "${ABSL_LLVM_EXCEPTIONS_FLAGS}")
 | 
				
			||||||
 | 
					    set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_X64_FLAGS}")
 | 
				
			||||||
    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
 | 
					    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
 | 
				
			||||||
      # AppleClang doesn't have lsan
 | 
					      # AppleClang doesn't have lsan
 | 
				
			||||||
      # https://developer.apple.com/documentation/code_diagnostics
 | 
					      # https://developer.apple.com/documentation/code_diagnostics
 | 
				
			||||||
| 
						 | 
					@ -35,11 +38,13 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
 | 
				
			||||||
  set(ABSL_TEST_COPTS "${ABSL_MSVC_FLAGS};${ABSL_MSVC_TEST_FLAGS}")
 | 
					  set(ABSL_TEST_COPTS "${ABSL_MSVC_FLAGS};${ABSL_MSVC_TEST_FLAGS}")
 | 
				
			||||||
  set(ABSL_EXCEPTIONS_FLAG "${ABSL_MSVC_EXCEPTIONS_FLAGS}")
 | 
					  set(ABSL_EXCEPTIONS_FLAG "${ABSL_MSVC_EXCEPTIONS_FLAGS}")
 | 
				
			||||||
  set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}")
 | 
					  set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}")
 | 
				
			||||||
 | 
					  set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}")
 | 
				
			||||||
else()
 | 
					else()
 | 
				
			||||||
  message(WARNING "Unknown compiler: ${CMAKE_CXX_COMPILER}.  Building with no default flags")
 | 
					  message(WARNING "Unknown compiler: ${CMAKE_CXX_COMPILER}.  Building with no default flags")
 | 
				
			||||||
  set(ABSL_DEFAULT_COPTS "")
 | 
					  set(ABSL_DEFAULT_COPTS "")
 | 
				
			||||||
  set(ABSL_TEST_COPTS "")
 | 
					  set(ABSL_TEST_COPTS "")
 | 
				
			||||||
  set(ABSL_EXCEPTIONS_FLAG "")
 | 
					  set(ABSL_EXCEPTIONS_FLAG "")
 | 
				
			||||||
 | 
					  set(ABSL_RANDOM_RANDEN_COPTS "")
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# This flag is used internally for Bazel builds and is kept here for consistency
 | 
					# This flag is used internally for Bazel builds and is kept here for consistency
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -224,6 +224,23 @@ struct disjunction<> : std::false_type {};
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
struct negation : std::integral_constant<bool, !T::value> {};
 | 
					struct negation : std::integral_constant<bool, !T::value> {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// is_function()
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Determines whether the passed type `T` is a function type.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This metafunction is designed to be a drop-in replacement for the C++11
 | 
				
			||||||
 | 
					// `std::is_function()` metafunction for platforms that have incomplete C++11
 | 
				
			||||||
 | 
					// support (such as libstdc++ 4.x).
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This metafunction works because appending `const` to a type does nothing to
 | 
				
			||||||
 | 
					// function types and reference types (and forms a const-qualified type
 | 
				
			||||||
 | 
					// otherwise).
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					struct is_function
 | 
				
			||||||
 | 
					    : std::integral_constant<
 | 
				
			||||||
 | 
					          bool, !(std::is_reference<T>::value ||
 | 
				
			||||||
 | 
					                  std::is_const<typename std::add_const<T>::type>::value)> {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// is_trivially_destructible()
 | 
					// is_trivially_destructible()
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Determines whether the passed type `T` is trivially destructable.
 | 
					// Determines whether the passed type `T` is trivially destructable.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -385,6 +385,22 @@ class Base {
 | 
				
			||||||
#define ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL 1
 | 
					#define ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL 1
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(TypeTraitsTest, TestIsFunction) {
 | 
				
			||||||
 | 
					  struct Callable {
 | 
				
			||||||
 | 
					    void operator()() {}
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_function<void()>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_function<void()&>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_function<void() const>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_function<void() noexcept>::value);
 | 
				
			||||||
 | 
					  EXPECT_TRUE(absl::is_function<void(...) noexcept>::value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_function<void(*)()>::value);
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_function<void(&)()>::value);
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_function<int>::value);
 | 
				
			||||||
 | 
					  EXPECT_FALSE(absl::is_function<Callable>::value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(TypeTraitsTest, TestTrivialDestructor) {
 | 
					TEST(TypeTraitsTest, TestTrivialDestructor) {
 | 
				
			||||||
  // Verify that arithmetic types and pointers have trivial destructors.
 | 
					  // Verify that arithmetic types and pointers have trivial destructors.
 | 
				
			||||||
  EXPECT_TRUE(absl::is_trivially_destructible<bool>::value);
 | 
					  EXPECT_TRUE(absl::is_trivially_destructible<bool>::value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1034
									
								
								absl/random/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1034
									
								
								absl/random/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -56,11 +56,11 @@ class SaltedSeedSeq {
 | 
				
			||||||
  SaltedSeedSeq(std::initializer_list<T> il)
 | 
					  SaltedSeedSeq(std::initializer_list<T> il)
 | 
				
			||||||
      : SaltedSeedSeq(il.begin(), il.end()) {}
 | 
					      : SaltedSeedSeq(il.begin(), il.end()) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SaltedSeedSeq(const SaltedSeedSeq& other) = delete;
 | 
					  SaltedSeedSeq(const SaltedSeedSeq&) = delete;
 | 
				
			||||||
  SaltedSeedSeq& operator=(const SaltedSeedSeq& other) = delete;
 | 
					  SaltedSeedSeq& operator=(const SaltedSeedSeq&) = delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SaltedSeedSeq(SaltedSeedSeq&& other) = default;
 | 
					  SaltedSeedSeq(SaltedSeedSeq&&) = default;
 | 
				
			||||||
  SaltedSeedSeq& operator=(SaltedSeedSeq&& other) = default;
 | 
					  SaltedSeedSeq& operator=(SaltedSeedSeq&&) = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename RandomAccessIterator>
 | 
					  template <typename RandomAccessIterator>
 | 
				
			||||||
  void generate(RandomAccessIterator begin, RandomAccessIterator end) {
 | 
					  void generate(RandomAccessIterator begin, RandomAccessIterator end) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,29 @@ void BM_Split2StringView(benchmark::State& state) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK_RANGE(BM_Split2StringView, 0, 1 << 20);
 | 
					BENCHMARK_RANGE(BM_Split2StringView, 0, 1 << 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const absl::string_view kDelimiters = ";:,.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string MakeMultiDelimiterTestString(int desired_length) {
 | 
				
			||||||
 | 
					  static const int kAverageValueLen = 25;
 | 
				
			||||||
 | 
					  std::string test(desired_length * kAverageValueLen, 'x');
 | 
				
			||||||
 | 
					  for (int i = 0; i * kAverageValueLen < test.size(); ++i) {
 | 
				
			||||||
 | 
					    // Cycle through a variety of delimiters.
 | 
				
			||||||
 | 
					    test[i * kAverageValueLen] = kDelimiters[i % kDelimiters.size()];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return test;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Measure StrSplit with ByAnyChar with four delimiters to choose from.
 | 
				
			||||||
 | 
					void BM_Split2StringViewByAnyChar(benchmark::State& state) {
 | 
				
			||||||
 | 
					  std::string test = MakeMultiDelimiterTestString(state.range(0));
 | 
				
			||||||
 | 
					  for (auto _ : state) {
 | 
				
			||||||
 | 
					    std::vector<absl::string_view> result =
 | 
				
			||||||
 | 
					        absl::StrSplit(test, absl::ByAnyChar(kDelimiters));
 | 
				
			||||||
 | 
					    benchmark::DoNotOptimize(result);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					BENCHMARK_RANGE(BM_Split2StringViewByAnyChar, 0, 1 << 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void BM_Split2StringViewLifted(benchmark::State& state) {
 | 
					void BM_Split2StringViewLifted(benchmark::State& state) {
 | 
				
			||||||
  std::string test = MakeTestString(state.range(0));
 | 
					  std::string test = MakeTestString(state.range(0));
 | 
				
			||||||
  std::vector<absl::string_view> result;
 | 
					  std::vector<absl::string_view> result;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -499,7 +499,7 @@ class optional : private optional_internal::optional_data<T>,
 | 
				
			||||||
  template <typename U>
 | 
					  template <typename U>
 | 
				
			||||||
  constexpr T value_or(U&& v) const& {
 | 
					  constexpr T value_or(U&& v) const& {
 | 
				
			||||||
    static_assert(std::is_copy_constructible<value_type>::value,
 | 
					    static_assert(std::is_copy_constructible<value_type>::value,
 | 
				
			||||||
                  "optional<T>::value_or: T must by copy constructible");
 | 
					                  "optional<T>::value_or: T must be copy constructible");
 | 
				
			||||||
    static_assert(std::is_convertible<U&&, value_type>::value,
 | 
					    static_assert(std::is_convertible<U&&, value_type>::value,
 | 
				
			||||||
                  "optional<T>::value_or: U must be convertible to T");
 | 
					                  "optional<T>::value_or: U must be convertible to T");
 | 
				
			||||||
    return static_cast<bool>(*this)
 | 
					    return static_cast<bool>(*this)
 | 
				
			||||||
| 
						 | 
					@ -509,7 +509,7 @@ class optional : private optional_internal::optional_data<T>,
 | 
				
			||||||
  template <typename U>
 | 
					  template <typename U>
 | 
				
			||||||
  T value_or(U&& v) && {  // NOLINT(build/c++11)
 | 
					  T value_or(U&& v) && {  // NOLINT(build/c++11)
 | 
				
			||||||
    static_assert(std::is_move_constructible<value_type>::value,
 | 
					    static_assert(std::is_move_constructible<value_type>::value,
 | 
				
			||||||
                  "optional<T>::value_or: T must by move constructible");
 | 
					                  "optional<T>::value_or: T must be move constructible");
 | 
				
			||||||
    static_assert(std::is_convertible<U&&, value_type>::value,
 | 
					    static_assert(std::is_convertible<U&&, value_type>::value,
 | 
				
			||||||
                  "optional<T>::value_or: U must be convertible to T");
 | 
					                  "optional<T>::value_or: U must be convertible to T");
 | 
				
			||||||
    return static_cast<bool>(*this) ? std::move(**this)
 | 
					    return static_cast<bool>(*this) ? std::move(**this)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue