about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2019-04-12T07·26-0700
committerShaindel Schwartz <shaindel@google.com>2019-04-12T19·05-0400
commita02f62f456f2c4a7ecf2be3104fe0c6e16fbad9a (patch)
treef272090343f4daae3a1d06de120db8ebc54cfc72
parent0b545b460141b882b244a1efcef7621d59278160 (diff)
Export of internal Abseil changes.
--
5755b40f6025f3ca126070fc68adb8fde9a7f01b by Abseil Team <absl-team@google.com>:

Fix -Wextra-semi error.

PiperOrigin-RevId: 243215850

--
3b6b6e18df9fbd233943cae460f0063f4efaa7c7 by Eric Fiselier <ericwf@google.com>:

Internal Change.

PiperOrigin-RevId: 243152671

--
82eef03f246009c806c25607c5682547cb4ad21e by Abseil Team <absl-team@google.com>:

Internal change.

PiperOrigin-RevId: 243151861

--
c14e6340fca7070634e0ecfdf97833d930dd0e5d by Samuel Benzaquen <sbenza@google.com>:

Internal change

PiperOrigin-RevId: 243123590

--
9abb7a6b22457c0aa72d72b3b9392efd226d302a by Andy Getzendanner <durandal@google.com>:

Implement operator<<(std::ostream &, absl::LogSeverity) so that absl::LogSeverity values can be streamed.

PiperOrigin-RevId: 243117646
GitOrigin-RevId: 5755b40f6025f3ca126070fc68adb8fde9a7f01b
Change-Id: I7ea607d8a4e803ad15a3090139271f58ad4173a3
-rw-r--r--absl/base/BUILD.bazel14
-rw-r--r--absl/base/CMakeLists.txt13
-rw-r--r--absl/base/casts.h22
-rw-r--r--absl/base/dynamic_annotations.h2
-rw-r--r--absl/base/log_severity.cc25
-rw-r--r--absl/base/log_severity.h5
-rw-r--r--absl/base/log_severity_test.cc43
-rw-r--r--absl/meta/BUILD.bazel1
-rw-r--r--absl/meta/CMakeLists.txt2
-rw-r--r--absl/meta/type_traits.h43
-rw-r--r--absl/meta/type_traits_test.cc135
-rw-r--r--absl/strings/BUILD.bazel2
12 files changed, 281 insertions, 26 deletions
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 8133a4627e1a..9fb1d8cdddb3 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -135,6 +135,7 @@ cc_library(
         "internal/sysinfo.cc",
         "internal/thread_identity.cc",
         "internal/unscaledcycleclock.cc",
+        "log_severity.cc",
     ],
     hdrs = [
         "call_once.h",
@@ -162,6 +163,7 @@ cc_library(
         ":core_headers",
         ":dynamic_annotations",
         ":spinlock_wait",
+        "//absl/meta:type_traits",
     ],
 )
 
@@ -523,3 +525,15 @@ cc_test(
         "@com_google_googletest//:gtest_main",
     ],
 )
+
+cc_test(
+    name = "log_severity_test",
+    size = "small",
+    srcs = ["log_severity_test.cc"],
+    copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    deps = [
+        ":base",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index cd1ec4128539..5042f1567043 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -127,6 +127,7 @@ absl_cc_library(
     "internal/sysinfo.cc"
     "internal/thread_identity.cc"
     "internal/unscaledcycleclock.cc"
+    "log_severity.cc"
   COPTS
     ${ABSL_DEFAULT_COPTS}
   DEPS
@@ -135,6 +136,7 @@ absl_cc_library(
     absl::core_headers
     absl::dynamic_annotations
     absl::spinlock_wait
+    absl::type_traits
     Threads::Threads
   PUBLIC
 )
@@ -449,3 +451,14 @@ absl_cc_test(
   DEPS
     absl::base
 )
+
+absl_cc_test(
+  NAME
+    log_severity_test
+  SRCS
+    "log_severity_test.cc"
+  DEPS
+    absl::base
+    gmock
+    gtest_main
+)
diff --git a/absl/base/casts.h b/absl/base/casts.h
index 00196d20ae77..a381c4276441 100644
--- a/absl/base/casts.h
+++ b/absl/base/casts.h
@@ -30,28 +30,20 @@
 
 #include "absl/base/internal/identity.h"
 #include "absl/base/macros.h"
+#include "absl/meta/type_traits.h"
 
 namespace absl {
 
 namespace internal_casts {
 
-// NOTE: Not a fully compliant implementation of `std::is_trivially_copyable`.
-// TODO(calabrese) Branch on implementations that directly provide
-// `std::is_trivially_copyable`, create a more rigorous workaround, and publicly
-// expose in meta/type_traits.
-template <class T>
-struct is_trivially_copyable
-    : std::integral_constant<
-          bool, std::is_destructible<T>::value&& __has_trivial_destructor(T) &&
-                    __has_trivial_copy(T) && __has_trivial_assign(T)> {};
-
 template <class Dest, class Source>
 struct is_bitcastable
-    : std::integral_constant<bool,
-                             sizeof(Dest) == sizeof(Source) &&
-                                 is_trivially_copyable<Source>::value &&
-                                 is_trivially_copyable<Dest>::value &&
-                                 std::is_default_constructible<Dest>::value> {};
+    : std::integral_constant<
+          bool,
+          sizeof(Dest) == sizeof(Source) &&
+              type_traits_internal::is_trivially_copyable<Source>::value &&
+              type_traits_internal::is_trivially_copyable<Dest>::value &&
+              std::is_default_constructible<Dest>::value> {};
 
 }  // namespace internal_casts
 
diff --git a/absl/base/dynamic_annotations.h b/absl/base/dynamic_annotations.h
index ac33df9e575a..65a54b447f80 100644
--- a/absl/base/dynamic_annotations.h
+++ b/absl/base/dynamic_annotations.h
@@ -377,7 +377,7 @@ inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { /* NOLINT */
   struct { char x[8] __attribute__ ((aligned (8))); } name
 #else
 #define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid)
-#define ADDRESS_SANITIZER_REDZONE(name)
+#define ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "")
 #endif  // ADDRESS_SANITIZER
 
 /* Undefine the macros intended only in this file. */
diff --git a/absl/base/log_severity.cc b/absl/base/log_severity.cc
new file mode 100644
index 000000000000..02a2a4852a57
--- /dev/null
+++ b/absl/base/log_severity.cc
@@ -0,0 +1,25 @@
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/base/log_severity.h"
+
+#include <ostream>
+
+namespace absl {
+
+std::ostream& operator<<(std::ostream& os, absl::LogSeverity s) {
+  if (s == absl::NormalizeLogSeverity(s)) return os << absl::LogSeverityName(s);
+  return os << "absl::LogSeverity(" << static_cast<int>(s) << ")";
+}
+}  // namespace absl
diff --git a/absl/base/log_severity.h b/absl/base/log_severity.h
index b19a7ffab820..5a1d5576ce7b 100644
--- a/absl/base/log_severity.h
+++ b/absl/base/log_severity.h
@@ -16,6 +16,7 @@
 #define ABSL_BASE_INTERNAL_LOG_SEVERITY_H_
 
 #include <array>
+#include <ostream>
 
 #include "absl/base/attributes.h"
 
@@ -61,6 +62,10 @@ constexpr absl::LogSeverity NormalizeLogSeverity(int s) {
   return NormalizeLogSeverity(static_cast<absl::LogSeverity>(s));
 }
 
+// The exact representation of a streamed `absl::LogSeverity` is deliberately
+// unspecified; do not rely on it.
+std::ostream& operator<<(std::ostream& os, absl::LogSeverity s);
+
 }  // namespace absl
 
 #endif  // ABSL_BASE_INTERNAL_LOG_SEVERITY_H_
diff --git a/absl/base/log_severity_test.cc b/absl/base/log_severity_test.cc
new file mode 100644
index 000000000000..1de2d101bfa8
--- /dev/null
+++ b/absl/base/log_severity_test.cc
@@ -0,0 +1,43 @@
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/base/log_severity.h"
+
+#include <sstream>
+#include <string>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace {
+using testing::Eq;
+
+std::string StreamHelper(absl::LogSeverity value) {
+  std::ostringstream stream;
+  stream << value;
+  return stream.str();
+}
+
+TEST(StreamTest, Works) {
+  EXPECT_THAT(StreamHelper(static_cast<absl::LogSeverity>(-100)),
+              Eq("absl::LogSeverity(-100)"));
+  EXPECT_THAT(StreamHelper(absl::LogSeverity::kInfo), Eq("INFO"));
+  EXPECT_THAT(StreamHelper(absl::LogSeverity::kWarning), Eq("WARNING"));
+  EXPECT_THAT(StreamHelper(absl::LogSeverity::kError), Eq("ERROR"));
+  EXPECT_THAT(StreamHelper(absl::LogSeverity::kFatal), Eq("FATAL"));
+  EXPECT_THAT(StreamHelper(static_cast<absl::LogSeverity>(4)),
+              Eq("absl::LogSeverity(4)"));
+}
+
+}  // namespace
diff --git a/absl/meta/BUILD.bazel b/absl/meta/BUILD.bazel
index c2435f4f6333..e004b509f27e 100644
--- a/absl/meta/BUILD.bazel
+++ b/absl/meta/BUILD.bazel
@@ -26,7 +26,6 @@ cc_test(
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":type_traits",
-        "//absl/base:core_headers",
         "@com_google_googletest//:gtest_main",
     ],
 )
diff --git a/absl/meta/CMakeLists.txt b/absl/meta/CMakeLists.txt
index 74d4a5430b82..f866e54e9271 100644
--- a/absl/meta/CMakeLists.txt
+++ b/absl/meta/CMakeLists.txt
@@ -35,8 +35,6 @@ absl_cc_test(
     ${ABSL_TEST_COPTS}
   DEPS
     absl::type_traits
-    absl::base
-    absl::core_headers
     gmock_main
 )
 
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index fbdc921f7816..a8068e315ed3 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -341,6 +341,49 @@ struct is_trivially_copy_assignable
 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
 };
 
+namespace type_traits_internal {
+// is_trivially_copyable()
+//
+// Determines whether the passed type `T` is trivially copyable.
+//
+// This metafunction is designed to be a drop-in replacement for the C++11
+// `std::is_trivially_copyable()` metafunction for platforms that have
+// incomplete C++11 support (such as libstdc++ 4.x). We use the C++17 definition
+// of TriviallyCopyable.
+//
+// NOTE: `is_trivially_copyable<T>::value` is `true` if all of T's copy/move
+// constructors/assignment operators are trivial or deleted, T has at least
+// one non-deleted copy/move constructor/assignment operator, and T is trivially
+// destructible. Arrays of trivially copyable types are trivially copyable.
+//
+// We expose this metafunction only for internal use within absl.
+template <typename T>
+class is_trivially_copyable_impl {
+  using ExtentsRemoved = typename std::remove_all_extents<T>::type;
+  static constexpr bool kIsCopyOrMoveConstructible =
+      std::is_copy_constructible<ExtentsRemoved>::value ||
+      std::is_move_constructible<ExtentsRemoved>::value;
+  static constexpr bool kIsCopyOrMoveAssignable =
+      absl::is_copy_assignable<ExtentsRemoved>::value ||
+      absl::is_move_assignable<ExtentsRemoved>::value;
+
+ public:
+  static constexpr bool kValue =
+      (__has_trivial_copy(ExtentsRemoved) || !kIsCopyOrMoveConstructible) &&
+      (__has_trivial_assign(ExtentsRemoved) || !kIsCopyOrMoveAssignable) &&
+      (kIsCopyOrMoveConstructible || kIsCopyOrMoveAssignable) &&
+      is_trivially_destructible<ExtentsRemoved>::value &&
+      // We need to check for this explicitly because otherwise we'll say
+      // references are trivial copyable when compiled by MSVC.
+      !std::is_reference<ExtentsRemoved>::value;
+};
+
+template <typename T>
+struct is_trivially_copyable
+    : std::integral_constant<
+          bool, type_traits_internal::is_trivially_copyable_impl<T>::kValue> {};
+}  // namespace type_traits_internal
+
 // -----------------------------------------------------------------------------
 // C++14 "_t" trait aliases
 // -----------------------------------------------------------------------------
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc
index 912336e99165..d3ead6d05158 100644
--- a/absl/meta/type_traits_test.cc
+++ b/absl/meta/type_traits_test.cc
@@ -280,10 +280,20 @@ class DeletedCopyAssign {
   int n_;
 };
 
-struct NonCopyable {
-  NonCopyable() = default;
-  NonCopyable(const NonCopyable&) = delete;
-  NonCopyable& operator=(const NonCopyable&) = delete;
+struct MovableNonCopyable {
+  MovableNonCopyable() = default;
+  MovableNonCopyable(const MovableNonCopyable&) = delete;
+  MovableNonCopyable(MovableNonCopyable&&) = default;
+  MovableNonCopyable& operator=(const MovableNonCopyable&) = delete;
+  MovableNonCopyable& operator=(MovableNonCopyable&&) = default;
+};
+
+struct NonCopyableOrMovable {
+  NonCopyableOrMovable() = default;
+  NonCopyableOrMovable(const NonCopyableOrMovable&) = delete;
+  NonCopyableOrMovable(NonCopyableOrMovable&&) = delete;
+  NonCopyableOrMovable& operator=(const NonCopyableOrMovable&) = delete;
+  NonCopyableOrMovable& operator=(NonCopyableOrMovable&&) = delete;
 };
 
 class Base {
@@ -507,7 +517,9 @@ TEST(TypeTraitsTest, TestTrivialCopyCtor) {
       absl::is_trivially_copy_constructible<NontrivialCopyCtor>::value);
   EXPECT_FALSE(absl::is_trivially_copy_constructible<DeletedCopyCtor>::value);
   EXPECT_FALSE(
-      absl::is_trivially_copy_constructible<NonCopyable>::value);
+      absl::is_trivially_copy_constructible<MovableNonCopyable>::value);
+  EXPECT_FALSE(
+      absl::is_trivially_copy_constructible<NonCopyableOrMovable>::value);
 
 #ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
   // type with nontrivial destructor are nontrivial copy construbtible
@@ -577,7 +589,8 @@ TEST(TypeTraitsTest, TestTrivialCopyAssign) {
   // Verify that types without them (i.e. nontrivial or deleted) are not.
   EXPECT_FALSE(absl::is_trivially_copy_assignable<NontrivialCopyAssign>::value);
   EXPECT_FALSE(absl::is_trivially_copy_assignable<DeletedCopyAssign>::value);
-  EXPECT_FALSE(absl::is_trivially_copy_assignable<NonCopyable>::value);
+  EXPECT_FALSE(absl::is_trivially_copy_assignable<MovableNonCopyable>::value);
+  EXPECT_FALSE(absl::is_trivially_copy_assignable<NonCopyableOrMovable>::value);
 
   // types with vtables
   EXPECT_FALSE(absl::is_trivially_copy_assignable<Base>::value);
@@ -611,6 +624,116 @@ TEST(TypeTraitsTest, TestTrivialCopyAssign) {
   EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial&>::value);
 }
 
+TEST(TypeTraitsTest, TestTriviallyCopyable) {
+  // Verify that arithmetic types and pointers are trivially copyable.
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<bool>::value);
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<char>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<unsigned char>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<signed char>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<wchar_t>::value);
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<int>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<unsigned int>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<int16_t>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<uint16_t>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<int64_t>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<uint64_t>::value);
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<float>::value);
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<double>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<long double>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<std::string*>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<Trivial*>::value);
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<
+              const std::string*>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<const Trivial*>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<std::string**>::value);
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<Trivial**>::value);
+
+  // const qualified types are not assignable but are constructible
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<const int>::value);
+
+  // Trivial copy constructor/assignment and destructor.
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<Trivial>::value);
+  // Trivial copy assignment, but non-trivial copy constructor/destructor.
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               TrivialCopyAssign>::value);
+  // Trivial copy constructor, but non-trivial assignment.
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               TrivialCopyCtor>::value);
+
+  // Types with a non-trivial copy constructor/assignment
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               NontrivialCopyCtor>::value);
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               NontrivialCopyAssign>::value);
+
+  // Types without copy constructor/assignment, but with move
+  // MSVC disagrees with other compilers about this:
+  // EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<
+  //             MovableNonCopyable>::value);
+
+  // Types without copy/move constructor/assignment
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               NonCopyableOrMovable>::value);
+
+  // No copy assign, but has trivial copy constructor.
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<
+              DeletedCopyAssign>::value);
+
+  // types with vtables
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<Base>::value);
+
+  // Verify that simple_pair is trivially copyable if members are
+  EXPECT_TRUE((absl::type_traits_internal::is_trivially_copyable<
+               simple_pair<int, char*>>::value));
+  EXPECT_TRUE((absl::type_traits_internal::is_trivially_copyable<
+               simple_pair<int, Trivial>>::value));
+
+  // Verify that types not trivially copyable are
+  // correctly marked as such.
+  EXPECT_FALSE(
+      absl::type_traits_internal::is_trivially_copyable<std::string>::value);
+  EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable<
+               std::vector<int>>::value);
+
+  // Verify that simple_pairs of types not trivially copyable
+  // are not marked as trivial.
+  EXPECT_FALSE((absl::type_traits_internal::is_trivially_copyable<
+                simple_pair<int, std::string>>::value));
+  EXPECT_FALSE((absl::type_traits_internal::is_trivially_copyable<
+                simple_pair<std::string, int>>::value));
+  EXPECT_FALSE((absl::type_traits_internal::is_trivially_copyable<
+                simple_pair<int, TrivialCopyAssign>>::value));
+
+  // Verify that arrays of trivially copyable types are trivially copyable
+  using int10 = int[10];
+  EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable<int10>::value);
+  using int10x10 = int[10][10];
+  EXPECT_TRUE(
+      absl::type_traits_internal::is_trivially_copyable<int10x10>::value);
+
+  // Verify that references are handled correctly
+  EXPECT_FALSE(
+      absl::type_traits_internal::is_trivially_copyable<Trivial&&>::value);
+  EXPECT_FALSE(
+      absl::type_traits_internal::is_trivially_copyable<Trivial&>::value);
+}
+
 #define ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(trait_name, ...)          \
   EXPECT_TRUE((std::is_same<typename std::trait_name<__VA_ARGS__>::type, \
                             absl::trait_name##_t<__VA_ARGS__>>::value))
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index 9640ff4627cb..2b1947371a70 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -16,9 +16,9 @@
 load(
     "//absl:copts/configure_copts.bzl",
     "ABSL_DEFAULT_COPTS",
-    "ABSL_TEST_COPTS",
     "ABSL_EXCEPTIONS_FLAG",
     "ABSL_EXCEPTIONS_FLAG_LINKOPTS",
+    "ABSL_TEST_COPTS",
 )
 
 package(