diff options
Diffstat (limited to 'third_party/abseil_cpp/absl/meta')
-rw-r--r-- | third_party/abseil_cpp/absl/meta/BUILD.bazel | 48 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/meta/CMakeLists.txt | 50 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/meta/type_traits.h | 767 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/meta/type_traits_test.cc | 1368 |
4 files changed, 0 insertions, 2233 deletions
diff --git a/third_party/abseil_cpp/absl/meta/BUILD.bazel b/third_party/abseil_cpp/absl/meta/BUILD.bazel deleted file mode 100644 index 5585fcca794a..000000000000 --- a/third_party/abseil_cpp/absl/meta/BUILD.bazel +++ /dev/null @@ -1,48 +0,0 @@ -# -# Copyright 2019 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. -# - -load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") -load( - "//absl:copts/configure_copts.bzl", - "ABSL_DEFAULT_COPTS", - "ABSL_DEFAULT_LINKOPTS", - "ABSL_TEST_COPTS", -) - -package(default_visibility = ["//visibility:public"]) - -licenses(["notice"]) - -cc_library( - name = "type_traits", - hdrs = ["type_traits.h"], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - "//absl/base:config", - ], -) - -cc_test( - name = "type_traits_test", - srcs = ["type_traits_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":type_traits", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/third_party/abseil_cpp/absl/meta/CMakeLists.txt b/third_party/abseil_cpp/absl/meta/CMakeLists.txt deleted file mode 100644 index 672ead2fd0a5..000000000000 --- a/third_party/abseil_cpp/absl/meta/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -# -# 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. -# - -absl_cc_library( - NAME - type_traits - HDRS - "type_traits.h" - COPTS - ${ABSL_DEFAULT_COPTS} - DEPS - absl::config - PUBLIC -) - -absl_cc_test( - NAME - type_traits_test - SRCS - "type_traits_test.cc" - COPTS - ${ABSL_TEST_COPTS} - DEPS - absl::type_traits - gmock_main -) - -# component target -absl_cc_library( - NAME - meta - COPTS - ${ABSL_DEFAULT_COPTS} - DEPS - absl::type_traits - PUBLIC -) diff --git a/third_party/abseil_cpp/absl/meta/type_traits.h b/third_party/abseil_cpp/absl/meta/type_traits.h deleted file mode 100644 index d5cb5f3be39d..000000000000 --- a/third_party/abseil_cpp/absl/meta/type_traits.h +++ /dev/null @@ -1,767 +0,0 @@ -// -// 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. -// -// ----------------------------------------------------------------------------- -// type_traits.h -// ----------------------------------------------------------------------------- -// -// This file contains C++11-compatible versions of standard <type_traits> API -// functions for determining the characteristics of types. Such traits can -// support type inference, classification, and transformation, as well as -// make it easier to write templates based on generic type behavior. -// -// See https://en.cppreference.com/w/cpp/header/type_traits -// -// WARNING: use of many of the constructs in this header will count as "complex -// template metaprogramming", so before proceeding, please carefully consider -// https://google.github.io/styleguide/cppguide.html#Template_metaprogramming -// -// WARNING: using template metaprogramming to detect or depend on API -// features is brittle and not guaranteed. Neither the standard library nor -// Abseil provides any guarantee that APIs are stable in the face of template -// metaprogramming. Use with caution. -#ifndef ABSL_META_TYPE_TRAITS_H_ -#define ABSL_META_TYPE_TRAITS_H_ - -#include <stddef.h> -#include <functional> -#include <type_traits> - -#include "absl/base/config.h" - -// MSVC constructibility traits do not detect destructor properties and so our -// implementations should not use them as a source-of-truth. -#if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) -#define ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1 -#endif - -namespace absl { -ABSL_NAMESPACE_BEGIN - -// Defined and documented later on in this file. -template <typename T> -struct is_trivially_destructible; - -// Defined and documented later on in this file. -template <typename T> -struct is_trivially_move_assignable; - -namespace type_traits_internal { - -// Silence MSVC warnings about the destructor being defined as deleted. -#if defined(_MSC_VER) && !defined(__GNUC__) -#pragma warning(push) -#pragma warning(disable : 4624) -#endif // defined(_MSC_VER) && !defined(__GNUC__) - -template <class T> -union SingleMemberUnion { - T t; -}; - -// Restore the state of the destructor warning that was silenced above. -#if defined(_MSC_VER) && !defined(__GNUC__) -#pragma warning(pop) -#endif // defined(_MSC_VER) && !defined(__GNUC__) - -template <class T> -struct IsTriviallyMoveConstructibleObject - : std::integral_constant< - bool, std::is_move_constructible< - type_traits_internal::SingleMemberUnion<T>>::value && - absl::is_trivially_destructible<T>::value> {}; - -template <class T> -struct IsTriviallyCopyConstructibleObject - : std::integral_constant< - bool, std::is_copy_constructible< - type_traits_internal::SingleMemberUnion<T>>::value && - absl::is_trivially_destructible<T>::value> {}; - -template <class T> -struct IsTriviallyMoveAssignableReference : std::false_type {}; - -template <class T> -struct IsTriviallyMoveAssignableReference<T&> - : absl::is_trivially_move_assignable<T>::type {}; - -template <class T> -struct IsTriviallyMoveAssignableReference<T&&> - : absl::is_trivially_move_assignable<T>::type {}; - -template <typename... Ts> -struct VoidTImpl { - using type = void; -}; - -// This trick to retrieve a default alignment is necessary for our -// implementation of aligned_storage_t to be consistent with any implementation -// of std::aligned_storage. -template <size_t Len, typename T = std::aligned_storage<Len>> -struct default_alignment_of_aligned_storage; - -template <size_t Len, size_t Align> -struct default_alignment_of_aligned_storage<Len, - std::aligned_storage<Len, Align>> { - static constexpr size_t value = Align; -}; - -//////////////////////////////// -// Library Fundamentals V2 TS // -//////////////////////////////// - -// NOTE: The `is_detected` family of templates here differ from the library -// fundamentals specification in that for library fundamentals, `Op<Args...>` is -// evaluated as soon as the type `is_detected<Op, Args...>` undergoes -// substitution, regardless of whether or not the `::value` is accessed. That -// is inconsistent with all other standard traits and prevents lazy evaluation -// in larger contexts (such as if the `is_detected` check is a trailing argument -// of a `conjunction`. This implementation opts to instead be lazy in the same -// way that the standard traits are (this "defect" of the detection idiom -// specifications has been reported). - -template <class Enabler, template <class...> class Op, class... Args> -struct is_detected_impl { - using type = std::false_type; -}; - -template <template <class...> class Op, class... Args> -struct is_detected_impl<typename VoidTImpl<Op<Args...>>::type, Op, Args...> { - using type = std::true_type; -}; - -template <template <class...> class Op, class... Args> -struct is_detected : is_detected_impl<void, Op, Args...>::type {}; - -template <class Enabler, class To, template <class...> class Op, class... Args> -struct is_detected_convertible_impl { - using type = std::false_type; -}; - -template <class To, template <class...> class Op, class... Args> -struct is_detected_convertible_impl< - typename std::enable_if<std::is_convertible<Op<Args...>, To>::value>::type, - To, Op, Args...> { - using type = std::true_type; -}; - -template <class To, template <class...> class Op, class... Args> -struct is_detected_convertible - : is_detected_convertible_impl<void, To, Op, Args...>::type {}; - -template <typename T> -using IsCopyAssignableImpl = - decltype(std::declval<T&>() = std::declval<const T&>()); - -template <typename T> -using IsMoveAssignableImpl = decltype(std::declval<T&>() = std::declval<T&&>()); - -} // namespace type_traits_internal - -// MSVC 19.20 has a regression that causes our workarounds to fail, but their -// std forms now appear to be compliant. -#if defined(_MSC_VER) && !defined(__clang__) && (_MSC_VER >= 1920) - -template <typename T> -using is_copy_assignable = std::is_copy_assignable<T>; - -template <typename T> -using is_move_assignable = std::is_move_assignable<T>; - -#else - -template <typename T> -struct is_copy_assignable : type_traits_internal::is_detected< - type_traits_internal::IsCopyAssignableImpl, T> { -}; - -template <typename T> -struct is_move_assignable : type_traits_internal::is_detected< - type_traits_internal::IsMoveAssignableImpl, T> { -}; - -#endif - -// void_t() -// -// Ignores the type of any its arguments and returns `void`. In general, this -// metafunction allows you to create a general case that maps to `void` while -// allowing specializations that map to specific types. -// -// This metafunction is designed to be a drop-in replacement for the C++17 -// `std::void_t` metafunction. -// -// NOTE: `absl::void_t` does not use the standard-specified implementation so -// that it can remain compatible with gcc < 5.1. This can introduce slightly -// different behavior, such as when ordering partial specializations. -template <typename... Ts> -using void_t = typename type_traits_internal::VoidTImpl<Ts...>::type; - -// conjunction -// -// Performs a compile-time logical AND operation on the passed types (which -// must have `::value` members convertible to `bool`. Short-circuits if it -// encounters any `false` members (and does not compare the `::value` members -// of any remaining arguments). -// -// This metafunction is designed to be a drop-in replacement for the C++17 -// `std::conjunction` metafunction. -template <typename... Ts> -struct conjunction : std::true_type {}; - -template <typename T, typename... Ts> -struct conjunction<T, Ts...> - : std::conditional<T::value, conjunction<Ts...>, T>::type {}; - -template <typename T> -struct conjunction<T> : T {}; - -// disjunction -// -// Performs a compile-time logical OR operation on the passed types (which -// must have `::value` members convertible to `bool`. Short-circuits if it -// encounters any `true` members (and does not compare the `::value` members -// of any remaining arguments). -// -// This metafunction is designed to be a drop-in replacement for the C++17 -// `std::disjunction` metafunction. -template <typename... Ts> -struct disjunction : std::false_type {}; - -template <typename T, typename... Ts> -struct disjunction<T, Ts...> : - std::conditional<T::value, T, disjunction<Ts...>>::type {}; - -template <typename T> -struct disjunction<T> : T {}; - -// negation -// -// Performs a compile-time logical NOT operation on the passed type (which -// must have `::value` members convertible to `bool`. -// -// This metafunction is designed to be a drop-in replacement for the C++17 -// `std::negation` metafunction. -template <typename T> -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() -// -// Determines whether the passed type `T` is trivially destructible. -// -// This metafunction is designed to be a drop-in replacement for the C++11 -// `std::is_trivially_destructible()` metafunction for platforms that have -// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do -// fully support C++11, we check whether this yields the same result as the std -// implementation. -// -// NOTE: the extensions (__has_trivial_xxx) are implemented in gcc (version >= -// 4.3) and clang. Since we are supporting libstdc++ > 4.7, they should always -// be present. These extensions are documented at -// https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html#Type-Traits. -template <typename T> -struct is_trivially_destructible - : std::integral_constant<bool, __has_trivial_destructor(T) && - std::is_destructible<T>::value> { -#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE - private: - static constexpr bool compliant = std::is_trivially_destructible<T>::value == - is_trivially_destructible::value; - static_assert(compliant || std::is_trivially_destructible<T>::value, - "Not compliant with std::is_trivially_destructible; " - "Standard: false, Implementation: true"); - static_assert(compliant || !std::is_trivially_destructible<T>::value, - "Not compliant with std::is_trivially_destructible; " - "Standard: true, Implementation: false"); -#endif // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE -}; - -// is_trivially_default_constructible() -// -// Determines whether the passed type `T` is trivially default constructible. -// -// This metafunction is designed to be a drop-in replacement for the C++11 -// `std::is_trivially_default_constructible()` metafunction for platforms that -// have incomplete C++11 support (such as libstdc++ 4.x). On any platforms that -// do fully support C++11, we check whether this yields the same result as the -// std implementation. -// -// NOTE: according to the C++ standard, Section: 20.15.4.3 [meta.unary.prop] -// "The predicate condition for a template specialization is_constructible<T, -// Args...> shall be satisfied if and only if the following variable -// definition would be well-formed for some invented variable t: -// -// T t(declval<Args>()...); -// -// is_trivially_constructible<T, Args...> additionally requires that the -// variable definition does not call any operation that is not trivial. -// For the purposes of this check, the call to std::declval is considered -// trivial." -// -// Notes from https://en.cppreference.com/w/cpp/types/is_constructible: -// In many implementations, is_nothrow_constructible also checks if the -// destructor throws because it is effectively noexcept(T(arg)). Same -// applies to is_trivially_constructible, which, in these implementations, also -// requires that the destructor is trivial. -// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 -// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116. -// -// "T obj();" need to be well-formed and not call any nontrivial operation. -// Nontrivially destructible types will cause the expression to be nontrivial. -template <typename T> -struct is_trivially_default_constructible - : std::integral_constant<bool, __has_trivial_constructor(T) && - std::is_default_constructible<T>::value && - is_trivially_destructible<T>::value> { -#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ - !defined( \ - ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) - private: - static constexpr bool compliant = - std::is_trivially_default_constructible<T>::value == - is_trivially_default_constructible::value; - static_assert(compliant || std::is_trivially_default_constructible<T>::value, - "Not compliant with std::is_trivially_default_constructible; " - "Standard: false, Implementation: true"); - static_assert(compliant || !std::is_trivially_default_constructible<T>::value, - "Not compliant with std::is_trivially_default_constructible; " - "Standard: true, Implementation: false"); -#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE -}; - -// is_trivially_move_constructible() -// -// Determines whether the passed type `T` is trivially move constructible. -// -// This metafunction is designed to be a drop-in replacement for the C++11 -// `std::is_trivially_move_constructible()` metafunction for platforms that have -// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do -// fully support C++11, we check whether this yields the same result as the std -// implementation. -// -// NOTE: `T obj(declval<T>());` needs to be well-formed and not call any -// nontrivial operation. Nontrivially destructible types will cause the -// expression to be nontrivial. -template <typename T> -struct is_trivially_move_constructible - : std::conditional< - std::is_object<T>::value && !std::is_array<T>::value, - type_traits_internal::IsTriviallyMoveConstructibleObject<T>, - std::is_reference<T>>::type::type { -#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ - !defined( \ - ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) - private: - static constexpr bool compliant = - std::is_trivially_move_constructible<T>::value == - is_trivially_move_constructible::value; - static_assert(compliant || std::is_trivially_move_constructible<T>::value, - "Not compliant with std::is_trivially_move_constructible; " - "Standard: false, Implementation: true"); - static_assert(compliant || !std::is_trivially_move_constructible<T>::value, - "Not compliant with std::is_trivially_move_constructible; " - "Standard: true, Implementation: false"); -#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE -}; - -// is_trivially_copy_constructible() -// -// Determines whether the passed type `T` is trivially copy constructible. -// -// This metafunction is designed to be a drop-in replacement for the C++11 -// `std::is_trivially_copy_constructible()` metafunction for platforms that have -// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do -// fully support C++11, we check whether this yields the same result as the std -// implementation. -// -// NOTE: `T obj(declval<const T&>());` needs to be well-formed and not call any -// nontrivial operation. Nontrivially destructible types will cause the -// expression to be nontrivial. -template <typename T> -struct is_trivially_copy_constructible - : std::conditional< - std::is_object<T>::value && !std::is_array<T>::value, - type_traits_internal::IsTriviallyCopyConstructibleObject<T>, - std::is_lvalue_reference<T>>::type::type { -#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ - !defined( \ - ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) - private: - static constexpr bool compliant = - std::is_trivially_copy_constructible<T>::value == - is_trivially_copy_constructible::value; - static_assert(compliant || std::is_trivially_copy_constructible<T>::value, - "Not compliant with std::is_trivially_copy_constructible; " - "Standard: false, Implementation: true"); - static_assert(compliant || !std::is_trivially_copy_constructible<T>::value, - "Not compliant with std::is_trivially_copy_constructible; " - "Standard: true, Implementation: false"); -#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE -}; - -// is_trivially_move_assignable() -// -// Determines whether the passed type `T` is trivially move assignable. -// -// This metafunction is designed to be a drop-in replacement for the C++11 -// `std::is_trivially_move_assignable()` metafunction for platforms that have -// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do -// fully support C++11, we check whether this yields the same result as the std -// implementation. -// -// NOTE: `is_assignable<T, U>::value` is `true` if the expression -// `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated -// operand. `is_trivially_assignable<T, U>` requires the assignment to call no -// operation that is not trivial. `is_trivially_copy_assignable<T>` is simply -// `is_trivially_assignable<T&, T>`. -template <typename T> -struct is_trivially_move_assignable - : std::conditional< - std::is_object<T>::value && !std::is_array<T>::value && - std::is_move_assignable<T>::value, - std::is_move_assignable<type_traits_internal::SingleMemberUnion<T>>, - type_traits_internal::IsTriviallyMoveAssignableReference<T>>::type:: - type { -#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE - private: - static constexpr bool compliant = - std::is_trivially_move_assignable<T>::value == - is_trivially_move_assignable::value; - static_assert(compliant || std::is_trivially_move_assignable<T>::value, - "Not compliant with std::is_trivially_move_assignable; " - "Standard: false, Implementation: true"); - static_assert(compliant || !std::is_trivially_move_assignable<T>::value, - "Not compliant with std::is_trivially_move_assignable; " - "Standard: true, Implementation: false"); -#endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE -}; - -// is_trivially_copy_assignable() -// -// Determines whether the passed type `T` is trivially copy assignable. -// -// This metafunction is designed to be a drop-in replacement for the C++11 -// `std::is_trivially_copy_assignable()` metafunction for platforms that have -// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do -// fully support C++11, we check whether this yields the same result as the std -// implementation. -// -// NOTE: `is_assignable<T, U>::value` is `true` if the expression -// `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated -// operand. `is_trivially_assignable<T, U>` requires the assignment to call no -// operation that is not trivial. `is_trivially_copy_assignable<T>` is simply -// `is_trivially_assignable<T&, const T&>`. -template <typename T> -struct is_trivially_copy_assignable - : std::integral_constant< - bool, __has_trivial_assign(typename std::remove_reference<T>::type) && - absl::is_copy_assignable<T>::value> { -#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE - private: - static constexpr bool compliant = - std::is_trivially_copy_assignable<T>::value == - is_trivially_copy_assignable::value; - static_assert(compliant || std::is_trivially_copy_assignable<T>::value, - "Not compliant with std::is_trivially_copy_assignable; " - "Standard: false, Implementation: true"); - static_assert(compliant || !std::is_trivially_copy_assignable<T>::value, - "Not compliant with std::is_trivially_copy_assignable; " - "Standard: true, Implementation: false"); -#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 -// ----------------------------------------------------------------------------- - -template <typename T> -using remove_cv_t = typename std::remove_cv<T>::type; - -template <typename T> -using remove_const_t = typename std::remove_const<T>::type; - -template <typename T> -using remove_volatile_t = typename std::remove_volatile<T>::type; - -template <typename T> -using add_cv_t = typename std::add_cv<T>::type; - -template <typename T> -using add_const_t = typename std::add_const<T>::type; - -template <typename T> -using add_volatile_t = typename std::add_volatile<T>::type; - -template <typename T> -using remove_reference_t = typename std::remove_reference<T>::type; - -template <typename T> -using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type; - -template <typename T> -using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type; - -template <typename T> -using remove_pointer_t = typename std::remove_pointer<T>::type; - -template <typename T> -using add_pointer_t = typename std::add_pointer<T>::type; - -template <typename T> -using make_signed_t = typename std::make_signed<T>::type; - -template <typename T> -using make_unsigned_t = typename std::make_unsigned<T>::type; - -template <typename T> -using remove_extent_t = typename std::remove_extent<T>::type; - -template <typename T> -using remove_all_extents_t = typename std::remove_all_extents<T>::type; - -template <size_t Len, size_t Align = type_traits_internal:: - default_alignment_of_aligned_storage<Len>::value> -using aligned_storage_t = typename std::aligned_storage<Len, Align>::type; - -template <typename T> -using decay_t = typename std::decay<T>::type; - -template <bool B, typename T = void> -using enable_if_t = typename std::enable_if<B, T>::type; - -template <bool B, typename T, typename F> -using conditional_t = typename std::conditional<B, T, F>::type; - -template <typename... T> -using common_type_t = typename std::common_type<T...>::type; - -template <typename T> -using underlying_type_t = typename std::underlying_type<T>::type; - - -namespace type_traits_internal { - -#if __cplusplus >= 201703L -// std::result_of is deprecated (C++17) or removed (C++20) -template<typename> struct result_of; -template<typename F, typename... Args> -struct result_of<F(Args...)> : std::invoke_result<F, Args...> {}; -#else -template<typename F> using result_of = std::result_of<F>; -#endif - -} // namespace type_traits_internal - -template<typename F> -using result_of_t = typename type_traits_internal::result_of<F>::type; - -namespace type_traits_internal { -// In MSVC we can't probe std::hash or stdext::hash because it triggers a -// static_assert instead of failing substitution. Libc++ prior to 4.0 -// also used a static_assert. -// -#if defined(_MSC_VER) || (defined(_LIBCPP_VERSION) && \ - _LIBCPP_VERSION < 4000 && _LIBCPP_STD_VER > 11) -#define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 0 -#else -#define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 1 -#endif - -#if !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ -template <typename Key, typename = size_t> -struct IsHashable : std::true_type {}; -#else // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ -template <typename Key, typename = void> -struct IsHashable : std::false_type {}; - -template <typename Key> -struct IsHashable< - Key, - absl::enable_if_t<std::is_convertible< - decltype(std::declval<std::hash<Key>&>()(std::declval<Key const&>())), - std::size_t>::value>> : std::true_type {}; -#endif // !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ - -struct AssertHashEnabledHelper { - private: - static void Sink(...) {} - struct NAT {}; - - template <class Key> - static auto GetReturnType(int) - -> decltype(std::declval<std::hash<Key>>()(std::declval<Key const&>())); - template <class Key> - static NAT GetReturnType(...); - - template <class Key> - static std::nullptr_t DoIt() { - static_assert(IsHashable<Key>::value, - "std::hash<Key> does not provide a call operator"); - static_assert( - std::is_default_constructible<std::hash<Key>>::value, - "std::hash<Key> must be default constructible when it is enabled"); - static_assert( - std::is_copy_constructible<std::hash<Key>>::value, - "std::hash<Key> must be copy constructible when it is enabled"); - static_assert(absl::is_copy_assignable<std::hash<Key>>::value, - "std::hash<Key> must be copy assignable when it is enabled"); - // is_destructible is unchecked as it's implied by each of the - // is_constructible checks. - using ReturnType = decltype(GetReturnType<Key>(0)); - static_assert(std::is_same<ReturnType, NAT>::value || - std::is_same<ReturnType, size_t>::value, - "std::hash<Key> must return size_t"); - return nullptr; - } - - template <class... Ts> - friend void AssertHashEnabled(); -}; - -template <class... Ts> -inline void AssertHashEnabled() { - using Helper = AssertHashEnabledHelper; - Helper::Sink(Helper::DoIt<Ts>()...); -} - -} // namespace type_traits_internal - -// An internal namespace that is required to implement the C++17 swap traits. -// It is not further nested in type_traits_internal to avoid long symbol names. -namespace swap_internal { - -// Necessary for the traits. -using std::swap; - -// This declaration prevents global `swap` and `absl::swap` overloads from being -// considered unless ADL picks them up. -void swap(); - -template <class T> -using IsSwappableImpl = decltype(swap(std::declval<T&>(), std::declval<T&>())); - -// NOTE: This dance with the default template parameter is for MSVC. -template <class T, - class IsNoexcept = std::integral_constant< - bool, noexcept(swap(std::declval<T&>(), std::declval<T&>()))>> -using IsNothrowSwappableImpl = typename std::enable_if<IsNoexcept::value>::type; - -// IsSwappable -// -// Determines whether the standard swap idiom is a valid expression for -// arguments of type `T`. -template <class T> -struct IsSwappable - : absl::type_traits_internal::is_detected<IsSwappableImpl, T> {}; - -// IsNothrowSwappable -// -// Determines whether the standard swap idiom is a valid expression for -// arguments of type `T` and is noexcept. -template <class T> -struct IsNothrowSwappable - : absl::type_traits_internal::is_detected<IsNothrowSwappableImpl, T> {}; - -// Swap() -// -// Performs the swap idiom from a namespace where valid candidates may only be -// found in `std` or via ADL. -template <class T, absl::enable_if_t<IsSwappable<T>::value, int> = 0> -void Swap(T& lhs, T& rhs) noexcept(IsNothrowSwappable<T>::value) { - swap(lhs, rhs); -} - -// StdSwapIsUnconstrained -// -// Some standard library implementations are broken in that they do not -// constrain `std::swap`. This will effectively tell us if we are dealing with -// one of those implementations. -using StdSwapIsUnconstrained = IsSwappable<void()>; - -} // namespace swap_internal - -namespace type_traits_internal { - -// Make the swap-related traits/function accessible from this namespace. -using swap_internal::IsNothrowSwappable; -using swap_internal::IsSwappable; -using swap_internal::Swap; -using swap_internal::StdSwapIsUnconstrained; - -} // namespace type_traits_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_META_TYPE_TRAITS_H_ diff --git a/third_party/abseil_cpp/absl/meta/type_traits_test.cc b/third_party/abseil_cpp/absl/meta/type_traits_test.cc deleted file mode 100644 index 1aafd0d49a83..000000000000 --- a/third_party/abseil_cpp/absl/meta/type_traits_test.cc +++ /dev/null @@ -1,1368 +0,0 @@ -// 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/meta/type_traits.h" - -#include <cstdint> -#include <string> -#include <type_traits> -#include <utility> -#include <vector> - -#include "gtest/gtest.h" - -namespace { - -using ::testing::StaticAssertTypeEq; - -template <class T, class U> -struct simple_pair { - T first; - U second; -}; - -struct Dummy {}; - -struct ReturnType {}; -struct ConvertibleToReturnType { - operator ReturnType() const; // NOLINT -}; - -// Unique types used as parameter types for testing the detection idiom. -struct StructA {}; -struct StructB {}; -struct StructC {}; - -struct TypeWithBarFunction { - template <class T, - absl::enable_if_t<std::is_same<T&&, StructA&>::value, int> = 0> - ReturnType bar(T&&, const StructB&, StructC&&) &&; // NOLINT -}; - -struct TypeWithBarFunctionAndConvertibleReturnType { - template <class T, - absl::enable_if_t<std::is_same<T&&, StructA&>::value, int> = 0> - ConvertibleToReturnType bar(T&&, const StructB&, StructC&&) &&; // NOLINT -}; - -template <class Class, class... Ts> -using BarIsCallableImpl = - decltype(std::declval<Class>().bar(std::declval<Ts>()...)); - -template <class Class, class... T> -using BarIsCallable = - absl::type_traits_internal::is_detected<BarIsCallableImpl, Class, T...>; - -template <class Class, class... T> -using BarIsCallableConv = absl::type_traits_internal::is_detected_convertible< - ReturnType, BarIsCallableImpl, Class, T...>; - -// NOTE: Test of detail type_traits_internal::is_detected. -TEST(IsDetectedTest, BasicUsage) { - EXPECT_TRUE((BarIsCallable<TypeWithBarFunction, StructA&, const StructB&, - StructC>::value)); - EXPECT_TRUE( - (BarIsCallable<TypeWithBarFunction, StructA&, StructB&, StructC>::value)); - EXPECT_TRUE( - (BarIsCallable<TypeWithBarFunction, StructA&, StructB, StructC>::value)); - - EXPECT_FALSE((BarIsCallable<int, StructA&, const StructB&, StructC>::value)); - EXPECT_FALSE((BarIsCallable<TypeWithBarFunction&, StructA&, const StructB&, - StructC>::value)); - EXPECT_FALSE((BarIsCallable<TypeWithBarFunction, StructA, const StructB&, - StructC>::value)); -} - -// NOTE: Test of detail type_traits_internal::is_detected_convertible. -TEST(IsDetectedConvertibleTest, BasicUsage) { - EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunction, StructA&, const StructB&, - StructC>::value)); - EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunction, StructA&, StructB&, - StructC>::value)); - EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunction, StructA&, StructB, - StructC>::value)); - EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType, - StructA&, const StructB&, StructC>::value)); - EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType, - StructA&, StructB&, StructC>::value)); - EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType, - StructA&, StructB, StructC>::value)); - - EXPECT_FALSE( - (BarIsCallableConv<int, StructA&, const StructB&, StructC>::value)); - EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunction&, StructA&, - const StructB&, StructC>::value)); - EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunction, StructA, const StructB&, - StructC>::value)); - EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType&, - StructA&, const StructB&, StructC>::value)); - EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType, - StructA, const StructB&, StructC>::value)); -} - -TEST(VoidTTest, BasicUsage) { - StaticAssertTypeEq<void, absl::void_t<Dummy>>(); - StaticAssertTypeEq<void, absl::void_t<Dummy, Dummy, Dummy>>(); -} - -TEST(ConjunctionTest, BasicBooleanLogic) { - EXPECT_TRUE(absl::conjunction<>::value); - EXPECT_TRUE(absl::conjunction<std::true_type>::value); - EXPECT_TRUE((absl::conjunction<std::true_type, std::true_type>::value)); - EXPECT_FALSE((absl::conjunction<std::true_type, std::false_type>::value)); - EXPECT_FALSE((absl::conjunction<std::false_type, std::true_type>::value)); - EXPECT_FALSE((absl::conjunction<std::false_type, std::false_type>::value)); -} - -struct MyTrueType { - static constexpr bool value = true; -}; - -struct MyFalseType { - static constexpr bool value = false; -}; - -TEST(ConjunctionTest, ShortCircuiting) { - EXPECT_FALSE( - (absl::conjunction<std::true_type, std::false_type, Dummy>::value)); - EXPECT_TRUE((std::is_base_of<MyFalseType, - absl::conjunction<std::true_type, MyFalseType, - std::false_type>>::value)); - EXPECT_TRUE( - (std::is_base_of<MyTrueType, - absl::conjunction<std::true_type, MyTrueType>>::value)); -} - -TEST(DisjunctionTest, BasicBooleanLogic) { - EXPECT_FALSE(absl::disjunction<>::value); - EXPECT_FALSE(absl::disjunction<std::false_type>::value); - EXPECT_TRUE((absl::disjunction<std::true_type, std::true_type>::value)); - EXPECT_TRUE((absl::disjunction<std::true_type, std::false_type>::value)); - EXPECT_TRUE((absl::disjunction<std::false_type, std::true_type>::value)); - EXPECT_FALSE((absl::disjunction<std::false_type, std::false_type>::value)); -} - -TEST(DisjunctionTest, ShortCircuiting) { - EXPECT_TRUE( - (absl::disjunction<std::false_type, std::true_type, Dummy>::value)); - EXPECT_TRUE(( - std::is_base_of<MyTrueType, absl::disjunction<std::false_type, MyTrueType, - std::true_type>>::value)); - EXPECT_TRUE(( - std::is_base_of<MyFalseType, - absl::disjunction<std::false_type, MyFalseType>>::value)); -} - -TEST(NegationTest, BasicBooleanLogic) { - EXPECT_FALSE(absl::negation<std::true_type>::value); - EXPECT_FALSE(absl::negation<MyTrueType>::value); - EXPECT_TRUE(absl::negation<std::false_type>::value); - EXPECT_TRUE(absl::negation<MyFalseType>::value); -} - -// all member functions are trivial -class Trivial { - int n_; -}; - -struct TrivialDestructor { - ~TrivialDestructor() = default; -}; - -struct NontrivialDestructor { - ~NontrivialDestructor() {} -}; - -struct DeletedDestructor { - ~DeletedDestructor() = delete; -}; - -class TrivialDefaultCtor { - public: - TrivialDefaultCtor() = default; - explicit TrivialDefaultCtor(int n) : n_(n) {} - - private: - int n_; -}; - -class NontrivialDefaultCtor { - public: - NontrivialDefaultCtor() : n_(1) {} - - private: - int n_; -}; - -class DeletedDefaultCtor { - public: - DeletedDefaultCtor() = delete; - explicit DeletedDefaultCtor(int n) : n_(n) {} - - private: - int n_; -}; - -class TrivialMoveCtor { - public: - explicit TrivialMoveCtor(int n) : n_(n) {} - TrivialMoveCtor(TrivialMoveCtor&&) = default; - TrivialMoveCtor& operator=(const TrivialMoveCtor& t) { - n_ = t.n_; - return *this; - } - - private: - int n_; -}; - -class NontrivialMoveCtor { - public: - explicit NontrivialMoveCtor(int n) : n_(n) {} - NontrivialMoveCtor(NontrivialMoveCtor&& t) noexcept : n_(t.n_) {} - NontrivialMoveCtor& operator=(const NontrivialMoveCtor&) = default; - - private: - int n_; -}; - -class TrivialCopyCtor { - public: - explicit TrivialCopyCtor(int n) : n_(n) {} - TrivialCopyCtor(const TrivialCopyCtor&) = default; - TrivialCopyCtor& operator=(const TrivialCopyCtor& t) { - n_ = t.n_; - return *this; - } - - private: - int n_; -}; - -class NontrivialCopyCtor { - public: - explicit NontrivialCopyCtor(int n) : n_(n) {} - NontrivialCopyCtor(const NontrivialCopyCtor& t) : n_(t.n_) {} - NontrivialCopyCtor& operator=(const NontrivialCopyCtor&) = default; - - private: - int n_; -}; - -class DeletedCopyCtor { - public: - explicit DeletedCopyCtor(int n) : n_(n) {} - DeletedCopyCtor(const DeletedCopyCtor&) = delete; - DeletedCopyCtor& operator=(const DeletedCopyCtor&) = default; - - private: - int n_; -}; - -class TrivialMoveAssign { - public: - explicit TrivialMoveAssign(int n) : n_(n) {} - TrivialMoveAssign(const TrivialMoveAssign& t) : n_(t.n_) {} - TrivialMoveAssign& operator=(TrivialMoveAssign&&) = default; - ~TrivialMoveAssign() {} // can have nontrivial destructor - private: - int n_; -}; - -class NontrivialMoveAssign { - public: - explicit NontrivialMoveAssign(int n) : n_(n) {} - NontrivialMoveAssign(const NontrivialMoveAssign&) = default; - NontrivialMoveAssign& operator=(NontrivialMoveAssign&& t) noexcept { - n_ = t.n_; - return *this; - } - - private: - int n_; -}; - -class TrivialCopyAssign { - public: - explicit TrivialCopyAssign(int n) : n_(n) {} - TrivialCopyAssign(const TrivialCopyAssign& t) : n_(t.n_) {} - TrivialCopyAssign& operator=(const TrivialCopyAssign& t) = default; - ~TrivialCopyAssign() {} // can have nontrivial destructor - private: - int n_; -}; - -class NontrivialCopyAssign { - public: - explicit NontrivialCopyAssign(int n) : n_(n) {} - NontrivialCopyAssign(const NontrivialCopyAssign&) = default; - NontrivialCopyAssign& operator=(const NontrivialCopyAssign& t) { - n_ = t.n_; - return *this; - } - - private: - int n_; -}; - -class DeletedCopyAssign { - public: - explicit DeletedCopyAssign(int n) : n_(n) {} - DeletedCopyAssign(const DeletedCopyAssign&) = default; - DeletedCopyAssign& operator=(const DeletedCopyAssign&) = delete; - - private: - int n_; -}; - -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 { - public: - virtual ~Base() {} -}; - -// Old versions of libc++, around Clang 3.5 to 3.6, consider deleted destructors -// as also being trivial. With the resolution of CWG 1928 and CWG 1734, this -// is no longer considered true and has thus been amended. -// Compiler Explorer: https://godbolt.org/g/zT59ZL -// CWG issue 1734: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1734 -// CWG issue 1928: http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1928 -#if !defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 3700 -#define ABSL_TRIVIALLY_DESTRUCTIBLE_CONSIDER_DELETED_DESTRUCTOR_NOT_TRIVIAL 1 -#endif - -// As of the moment, GCC versions >5.1 have a problem compiling for -// std::is_trivially_default_constructible<NontrivialDestructor[10]>, where -// NontrivialDestructor is a struct with a custom nontrivial destructor. Note -// that this problem only occurs for arrays of a known size, so something like -// std::is_trivially_default_constructible<NontrivialDestructor[]> does not -// have any problems. -// Compiler Explorer: https://godbolt.org/g/dXRbdK -// GCC bug 83689: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83689 -#if defined(__clang__) || defined(_MSC_VER) || \ - (defined(__GNUC__) && __GNUC__ < 5) -#define ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL 1 -#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) { - // Verify that arithmetic types and pointers have trivial destructors. - EXPECT_TRUE(absl::is_trivially_destructible<bool>::value); - EXPECT_TRUE(absl::is_trivially_destructible<char>::value); - EXPECT_TRUE(absl::is_trivially_destructible<unsigned char>::value); - EXPECT_TRUE(absl::is_trivially_destructible<signed char>::value); - EXPECT_TRUE(absl::is_trivially_destructible<wchar_t>::value); - EXPECT_TRUE(absl::is_trivially_destructible<int>::value); - EXPECT_TRUE(absl::is_trivially_destructible<unsigned int>::value); - EXPECT_TRUE(absl::is_trivially_destructible<int16_t>::value); - EXPECT_TRUE(absl::is_trivially_destructible<uint16_t>::value); - EXPECT_TRUE(absl::is_trivially_destructible<int64_t>::value); - EXPECT_TRUE(absl::is_trivially_destructible<uint64_t>::value); - EXPECT_TRUE(absl::is_trivially_destructible<float>::value); - EXPECT_TRUE(absl::is_trivially_destructible<double>::value); - EXPECT_TRUE(absl::is_trivially_destructible<long double>::value); - EXPECT_TRUE(absl::is_trivially_destructible<std::string*>::value); - EXPECT_TRUE(absl::is_trivially_destructible<Trivial*>::value); - EXPECT_TRUE(absl::is_trivially_destructible<const std::string*>::value); - EXPECT_TRUE(absl::is_trivially_destructible<const Trivial*>::value); - EXPECT_TRUE(absl::is_trivially_destructible<std::string**>::value); - EXPECT_TRUE(absl::is_trivially_destructible<Trivial**>::value); - - // classes with destructors - EXPECT_TRUE(absl::is_trivially_destructible<Trivial>::value); - EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor>::value); - - // Verify that types with a nontrivial or deleted destructor - // are marked as such. - EXPECT_FALSE(absl::is_trivially_destructible<NontrivialDestructor>::value); -#ifdef ABSL_TRIVIALLY_DESTRUCTIBLE_CONSIDER_DELETED_DESTRUCTOR_NOT_TRIVIAL - EXPECT_FALSE(absl::is_trivially_destructible<DeletedDestructor>::value); -#endif - - // simple_pair of such types is trivial - EXPECT_TRUE((absl::is_trivially_destructible<simple_pair<int, int>>::value)); - EXPECT_TRUE((absl::is_trivially_destructible< - simple_pair<Trivial, TrivialDestructor>>::value)); - - // Verify that types without trivial destructors are correctly marked as such. - EXPECT_FALSE(absl::is_trivially_destructible<std::string>::value); - EXPECT_FALSE(absl::is_trivially_destructible<std::vector<int>>::value); - - // Verify that simple_pairs of types without trivial destructors - // are not marked as trivial. - EXPECT_FALSE((absl::is_trivially_destructible< - simple_pair<int, std::string>>::value)); - EXPECT_FALSE((absl::is_trivially_destructible< - simple_pair<std::string, int>>::value)); - - // array of such types is trivial - using int10 = int[10]; - EXPECT_TRUE(absl::is_trivially_destructible<int10>::value); - using Trivial10 = Trivial[10]; - EXPECT_TRUE(absl::is_trivially_destructible<Trivial10>::value); - using TrivialDestructor10 = TrivialDestructor[10]; - EXPECT_TRUE(absl::is_trivially_destructible<TrivialDestructor10>::value); - - // Conversely, the opposite also holds. - using NontrivialDestructor10 = NontrivialDestructor[10]; - EXPECT_FALSE(absl::is_trivially_destructible<NontrivialDestructor10>::value); -} - -TEST(TypeTraitsTest, TestTrivialDefaultCtor) { - // arithmetic types and pointers have trivial default constructors. - EXPECT_TRUE(absl::is_trivially_default_constructible<bool>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<char>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<unsigned char>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<signed char>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<wchar_t>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<int>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<unsigned int>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<int16_t>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<uint16_t>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<int64_t>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<uint64_t>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<float>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<double>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<long double>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<std::string*>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial*>::value); - EXPECT_TRUE( - absl::is_trivially_default_constructible<const std::string*>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<const Trivial*>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<std::string**>::value); - EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial**>::value); - - // types with compiler generated default ctors - EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial>::value); - EXPECT_TRUE( - absl::is_trivially_default_constructible<TrivialDefaultCtor>::value); - - // Verify that types without them are not. - EXPECT_FALSE( - absl::is_trivially_default_constructible<NontrivialDefaultCtor>::value); - EXPECT_FALSE( - absl::is_trivially_default_constructible<DeletedDefaultCtor>::value); - - // types with nontrivial destructor are nontrivial - EXPECT_FALSE( - absl::is_trivially_default_constructible<NontrivialDestructor>::value); - - // types with vtables - EXPECT_FALSE(absl::is_trivially_default_constructible<Base>::value); - - // Verify that simple_pair has trivial constructors where applicable. - EXPECT_TRUE((absl::is_trivially_default_constructible< - simple_pair<int, char*>>::value)); - EXPECT_TRUE((absl::is_trivially_default_constructible< - simple_pair<int, Trivial>>::value)); - EXPECT_TRUE((absl::is_trivially_default_constructible< - simple_pair<int, TrivialDefaultCtor>>::value)); - - // Verify that types without trivial constructors are - // correctly marked as such. - EXPECT_FALSE(absl::is_trivially_default_constructible<std::string>::value); - EXPECT_FALSE( - absl::is_trivially_default_constructible<std::vector<int>>::value); - - // Verify that simple_pairs of types without trivial constructors - // are not marked as trivial. - EXPECT_FALSE((absl::is_trivially_default_constructible< - simple_pair<int, std::string>>::value)); - EXPECT_FALSE((absl::is_trivially_default_constructible< - simple_pair<std::string, int>>::value)); - - // Verify that arrays of such types are trivially default constructible - using int10 = int[10]; - EXPECT_TRUE(absl::is_trivially_default_constructible<int10>::value); - using Trivial10 = Trivial[10]; - EXPECT_TRUE(absl::is_trivially_default_constructible<Trivial10>::value); - using TrivialDefaultCtor10 = TrivialDefaultCtor[10]; - EXPECT_TRUE( - absl::is_trivially_default_constructible<TrivialDefaultCtor10>::value); - - // Conversely, the opposite also holds. -#ifdef ABSL_GCC_BUG_TRIVIALLY_CONSTRUCTIBLE_ON_ARRAY_OF_NONTRIVIAL - using NontrivialDefaultCtor10 = NontrivialDefaultCtor[10]; - EXPECT_FALSE( - absl::is_trivially_default_constructible<NontrivialDefaultCtor10>::value); -#endif -} - -// GCC prior to 7.4 had a bug in its trivially-constructible traits -// (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80654). -// This test makes sure that we do not depend on the trait in these cases when -// implementing absl triviality traits. - -template <class T> -struct BadConstructors { - BadConstructors() { static_assert(T::value, ""); } - - BadConstructors(BadConstructors&&) { static_assert(T::value, ""); } - - BadConstructors(const BadConstructors&) { static_assert(T::value, ""); } -}; - -TEST(TypeTraitsTest, TestTrivialityBadConstructors) { - using BadType = BadConstructors<int>; - - EXPECT_FALSE(absl::is_trivially_default_constructible<BadType>::value); - EXPECT_FALSE(absl::is_trivially_move_constructible<BadType>::value); - EXPECT_FALSE(absl::is_trivially_copy_constructible<BadType>::value); -} - -TEST(TypeTraitsTest, TestTrivialMoveCtor) { - // Verify that arithmetic types and pointers have trivial move - // constructors. - EXPECT_TRUE(absl::is_trivially_move_constructible<bool>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<char>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<unsigned char>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<signed char>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<wchar_t>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<int>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<unsigned int>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<int16_t>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<uint16_t>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<int64_t>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<uint64_t>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<float>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<double>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<long double>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<std::string*>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial*>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<const std::string*>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<const Trivial*>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<std::string**>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial**>::value); - - // Reference types - EXPECT_TRUE(absl::is_trivially_move_constructible<int&>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<int&&>::value); - - // types with compiler generated move ctors - EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial>::value); - EXPECT_TRUE(absl::is_trivially_move_constructible<TrivialMoveCtor>::value); - - // Verify that types without them (i.e. nontrivial or deleted) are not. - EXPECT_FALSE( - absl::is_trivially_move_constructible<NontrivialCopyCtor>::value); - EXPECT_FALSE(absl::is_trivially_move_constructible<DeletedCopyCtor>::value); - EXPECT_FALSE( - absl::is_trivially_move_constructible<NonCopyableOrMovable>::value); - - // type with nontrivial destructor are nontrivial move construbtible - EXPECT_FALSE( - absl::is_trivially_move_constructible<NontrivialDestructor>::value); - - // types with vtables - EXPECT_FALSE(absl::is_trivially_move_constructible<Base>::value); - - // Verify that simple_pair of such types is trivially move constructible - EXPECT_TRUE( - (absl::is_trivially_move_constructible<simple_pair<int, char*>>::value)); - EXPECT_TRUE(( - absl::is_trivially_move_constructible<simple_pair<int, Trivial>>::value)); - EXPECT_TRUE((absl::is_trivially_move_constructible< - simple_pair<int, TrivialMoveCtor>>::value)); - - // Verify that types without trivial move constructors are - // correctly marked as such. - EXPECT_FALSE(absl::is_trivially_move_constructible<std::string>::value); - EXPECT_FALSE(absl::is_trivially_move_constructible<std::vector<int>>::value); - - // Verify that simple_pairs of types without trivial move constructors - // are not marked as trivial. - EXPECT_FALSE((absl::is_trivially_move_constructible< - simple_pair<int, std::string>>::value)); - EXPECT_FALSE((absl::is_trivially_move_constructible< - simple_pair<std::string, int>>::value)); - - // Verify that arrays are not - using int10 = int[10]; - EXPECT_FALSE(absl::is_trivially_move_constructible<int10>::value); -} - -TEST(TypeTraitsTest, TestTrivialCopyCtor) { - // Verify that arithmetic types and pointers have trivial copy - // constructors. - EXPECT_TRUE(absl::is_trivially_copy_constructible<bool>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<char>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<unsigned char>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<signed char>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<wchar_t>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<int>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<unsigned int>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<int16_t>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<uint16_t>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<int64_t>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<uint64_t>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<float>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<double>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<long double>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string*>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial*>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<const std::string*>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<const Trivial*>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string**>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial**>::value); - - // Reference types - EXPECT_TRUE(absl::is_trivially_copy_constructible<int&>::value); - EXPECT_FALSE(absl::is_trivially_copy_constructible<int&&>::value); - - // types with compiler generated copy ctors - EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial>::value); - EXPECT_TRUE(absl::is_trivially_copy_constructible<TrivialCopyCtor>::value); - - // Verify that types without them (i.e. nontrivial or deleted) are not. - EXPECT_FALSE( - absl::is_trivially_copy_constructible<NontrivialCopyCtor>::value); - EXPECT_FALSE(absl::is_trivially_copy_constructible<DeletedCopyCtor>::value); - EXPECT_FALSE( - absl::is_trivially_copy_constructible<MovableNonCopyable>::value); - EXPECT_FALSE( - absl::is_trivially_copy_constructible<NonCopyableOrMovable>::value); - - // type with nontrivial destructor are nontrivial copy construbtible - EXPECT_FALSE( - absl::is_trivially_copy_constructible<NontrivialDestructor>::value); - - // types with vtables - EXPECT_FALSE(absl::is_trivially_copy_constructible<Base>::value); - - // Verify that simple_pair of such types is trivially copy constructible - EXPECT_TRUE( - (absl::is_trivially_copy_constructible<simple_pair<int, char*>>::value)); - EXPECT_TRUE(( - absl::is_trivially_copy_constructible<simple_pair<int, Trivial>>::value)); - EXPECT_TRUE((absl::is_trivially_copy_constructible< - simple_pair<int, TrivialCopyCtor>>::value)); - - // Verify that types without trivial copy constructors are - // correctly marked as such. - EXPECT_FALSE(absl::is_trivially_copy_constructible<std::string>::value); - EXPECT_FALSE(absl::is_trivially_copy_constructible<std::vector<int>>::value); - - // Verify that simple_pairs of types without trivial copy constructors - // are not marked as trivial. - EXPECT_FALSE((absl::is_trivially_copy_constructible< - simple_pair<int, std::string>>::value)); - EXPECT_FALSE((absl::is_trivially_copy_constructible< - simple_pair<std::string, int>>::value)); - - // Verify that arrays are not - using int10 = int[10]; - EXPECT_FALSE(absl::is_trivially_copy_constructible<int10>::value); -} - -TEST(TypeTraitsTest, TestTrivialMoveAssign) { - // Verify that arithmetic types and pointers have trivial move - // assignment operators. - EXPECT_TRUE(absl::is_trivially_move_assignable<bool>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<char>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<unsigned char>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<signed char>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<wchar_t>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<int>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<unsigned int>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<int16_t>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<uint16_t>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<int64_t>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<uint64_t>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<float>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<double>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<long double>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<std::string*>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial*>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<const std::string*>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<const Trivial*>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<std::string**>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial**>::value); - - // const qualified types are not assignable - EXPECT_FALSE(absl::is_trivially_move_assignable<const int>::value); - - // types with compiler generated move assignment - EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<TrivialMoveAssign>::value); - - // Verify that types without them (i.e. nontrivial or deleted) are not. - EXPECT_FALSE(absl::is_trivially_move_assignable<NontrivialCopyAssign>::value); - EXPECT_FALSE(absl::is_trivially_move_assignable<DeletedCopyAssign>::value); - EXPECT_FALSE(absl::is_trivially_move_assignable<NonCopyableOrMovable>::value); - - // types with vtables - EXPECT_FALSE(absl::is_trivially_move_assignable<Base>::value); - - // Verify that simple_pair is trivially assignable - EXPECT_TRUE( - (absl::is_trivially_move_assignable<simple_pair<int, char*>>::value)); - EXPECT_TRUE( - (absl::is_trivially_move_assignable<simple_pair<int, Trivial>>::value)); - EXPECT_TRUE((absl::is_trivially_move_assignable< - simple_pair<int, TrivialMoveAssign>>::value)); - - // Verify that types not trivially move assignable are - // correctly marked as such. - EXPECT_FALSE(absl::is_trivially_move_assignable<std::string>::value); - EXPECT_FALSE(absl::is_trivially_move_assignable<std::vector<int>>::value); - - // Verify that simple_pairs of types not trivially move assignable - // are not marked as trivial. - EXPECT_FALSE((absl::is_trivially_move_assignable< - simple_pair<int, std::string>>::value)); - EXPECT_FALSE((absl::is_trivially_move_assignable< - simple_pair<std::string, int>>::value)); - - // Verify that arrays are not trivially move assignable - using int10 = int[10]; - EXPECT_FALSE(absl::is_trivially_move_assignable<int10>::value); - - // Verify that references are handled correctly - EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial&&>::value); - EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial&>::value); -} - -TEST(TypeTraitsTest, TestTrivialCopyAssign) { - // Verify that arithmetic types and pointers have trivial copy - // assignment operators. - EXPECT_TRUE(absl::is_trivially_copy_assignable<bool>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<char>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<unsigned char>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<signed char>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<wchar_t>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<int>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<unsigned int>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<int16_t>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<uint16_t>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<int64_t>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<uint64_t>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<float>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<double>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<long double>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<std::string*>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial*>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<const std::string*>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<const Trivial*>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<std::string**>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial**>::value); - - // const qualified types are not assignable - EXPECT_FALSE(absl::is_trivially_copy_assignable<const int>::value); - - // types with compiler generated copy assignment - EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value); - EXPECT_TRUE(absl::is_trivially_copy_assignable<TrivialCopyAssign>::value); - - // 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<MovableNonCopyable>::value); - EXPECT_FALSE(absl::is_trivially_copy_assignable<NonCopyableOrMovable>::value); - - // types with vtables - EXPECT_FALSE(absl::is_trivially_copy_assignable<Base>::value); - - // Verify that simple_pair is trivially assignable - EXPECT_TRUE( - (absl::is_trivially_copy_assignable<simple_pair<int, char*>>::value)); - EXPECT_TRUE( - (absl::is_trivially_copy_assignable<simple_pair<int, Trivial>>::value)); - EXPECT_TRUE((absl::is_trivially_copy_assignable< - simple_pair<int, TrivialCopyAssign>>::value)); - - // Verify that types not trivially copy assignable are - // correctly marked as such. - EXPECT_FALSE(absl::is_trivially_copy_assignable<std::string>::value); - EXPECT_FALSE(absl::is_trivially_copy_assignable<std::vector<int>>::value); - - // Verify that simple_pairs of types not trivially copy assignable - // are not marked as trivial. - EXPECT_FALSE((absl::is_trivially_copy_assignable< - simple_pair<int, std::string>>::value)); - EXPECT_FALSE((absl::is_trivially_copy_assignable< - simple_pair<std::string, int>>::value)); - - // Verify that arrays are not trivially copy assignable - using int10 = int[10]; - EXPECT_FALSE(absl::is_trivially_copy_assignable<int10>::value); - - // Verify that references are handled correctly - EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial&&>::value); - 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)) - -TEST(TypeTraitsTest, TestRemoveCVAliases) { - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, const int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_cv, const volatile int); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, const int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_const, const volatile int); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, const int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_volatile, const volatile int); -} - -TEST(TypeTraitsTest, TestAddCVAliases) { - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, const int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_cv, const volatile int); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, const int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_const, const volatile int); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, const int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_volatile, const volatile int); -} - -TEST(TypeTraitsTest, TestReferenceAliases) { - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, int&&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_reference, volatile int&&); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, int&&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_lvalue_reference, volatile int&&); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, int&&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_rvalue_reference, volatile int&&); -} - -TEST(TypeTraitsTest, TestPointerAliases) { - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_pointer, int*); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_pointer, volatile int*); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_pointer, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(add_pointer, volatile int); -} - -TEST(TypeTraitsTest, TestSignednessAliases) { - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, unsigned); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_signed, volatile unsigned); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, unsigned); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(make_unsigned, volatile unsigned); -} - -TEST(TypeTraitsTest, TestExtentAliases) { - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[]); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[1]); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[1][1]); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_extent, int[][1]); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[]); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[1]); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[1][1]); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(remove_all_extents, int[][1]); -} - -TEST(TypeTraitsTest, TestAlignedStorageAlias) { - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 1); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 2); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 3); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 4); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 5); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 6); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 7); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 8); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 9); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 10); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 11); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 12); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 13); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 14); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 15); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 16); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 17); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 18); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 19); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 20); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 21); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 22); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 23); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 24); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 25); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 26); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 27); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 28); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 29); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 30); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 31); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 32); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 33); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 1, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 2, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 3, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 4, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 5, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 6, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 7, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 8, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 9, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 10, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 11, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 12, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 13, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 14, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 15, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 16, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 17, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 18, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 19, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 20, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 21, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 22, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 23, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 24, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 25, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 26, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 27, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 28, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 29, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 30, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 31, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 32, 128); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(aligned_storage, 33, 128); -} - -TEST(TypeTraitsTest, TestDecay) { - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int&); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, volatile int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, const volatile int&); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[1]); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[1][1]); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[][1]); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int()); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(float)); // NOLINT - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(char, ...)); // NOLINT -} - -struct TypeA {}; -struct TypeB {}; -struct TypeC {}; -struct TypeD {}; - -template <typename T> -struct Wrap {}; - -enum class TypeEnum { A, B, C, D }; - -struct GetTypeT { - template <typename T, - absl::enable_if_t<std::is_same<T, TypeA>::value, int> = 0> - TypeEnum operator()(Wrap<T>) const { - return TypeEnum::A; - } - - template <typename T, - absl::enable_if_t<std::is_same<T, TypeB>::value, int> = 0> - TypeEnum operator()(Wrap<T>) const { - return TypeEnum::B; - } - - template <typename T, - absl::enable_if_t<std::is_same<T, TypeC>::value, int> = 0> - TypeEnum operator()(Wrap<T>) const { - return TypeEnum::C; - } - - // NOTE: TypeD is intentionally not handled -} constexpr GetType = {}; - -TEST(TypeTraitsTest, TestEnableIf) { - EXPECT_EQ(TypeEnum::A, GetType(Wrap<TypeA>())); - EXPECT_EQ(TypeEnum::B, GetType(Wrap<TypeB>())); - EXPECT_EQ(TypeEnum::C, GetType(Wrap<TypeC>())); -} - -TEST(TypeTraitsTest, TestConditional) { - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(conditional, true, int, char); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(conditional, false, int, char); -} - -// TODO(calabrese) Check with specialized std::common_type -TEST(TypeTraitsTest, TestCommonType) { - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char, int); - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char&); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(common_type, int, char, int&); -} - -TEST(TypeTraitsTest, TestUnderlyingType) { - enum class enum_char : char {}; - enum class enum_long_long : long long {}; // NOLINT(runtime/int) - - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(underlying_type, enum_char); - ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(underlying_type, enum_long_long); -} - -struct GetTypeExtT { - template <typename T> - absl::result_of_t<const GetTypeT&(T)> operator()(T&& arg) const { - return GetType(std::forward<T>(arg)); - } - - TypeEnum operator()(Wrap<TypeD>) const { return TypeEnum::D; } -} constexpr GetTypeExt = {}; - -TEST(TypeTraitsTest, TestResultOf) { - EXPECT_EQ(TypeEnum::A, GetTypeExt(Wrap<TypeA>())); - EXPECT_EQ(TypeEnum::B, GetTypeExt(Wrap<TypeB>())); - EXPECT_EQ(TypeEnum::C, GetTypeExt(Wrap<TypeC>())); - EXPECT_EQ(TypeEnum::D, GetTypeExt(Wrap<TypeD>())); -} - -template <typename T> -bool TestCopyAssign() { - return absl::is_copy_assignable<T>::value == - std::is_copy_assignable<T>::value; -} - -TEST(TypeTraitsTest, IsCopyAssignable) { - EXPECT_TRUE(TestCopyAssign<int>()); - EXPECT_TRUE(TestCopyAssign<int&>()); - EXPECT_TRUE(TestCopyAssign<int&&>()); - - struct S {}; - EXPECT_TRUE(TestCopyAssign<S>()); - EXPECT_TRUE(TestCopyAssign<S&>()); - EXPECT_TRUE(TestCopyAssign<S&&>()); - - class C { - public: - explicit C(C* c) : c_(c) {} - ~C() { delete c_; } - - private: - C* c_; - }; - EXPECT_TRUE(TestCopyAssign<C>()); - EXPECT_TRUE(TestCopyAssign<C&>()); - EXPECT_TRUE(TestCopyAssign<C&&>()); - - // Reason for ifndef: add_lvalue_reference<T> in libc++ breaks for these cases -#ifndef _LIBCPP_VERSION - EXPECT_TRUE(TestCopyAssign<int()>()); - EXPECT_TRUE(TestCopyAssign<int(int) const>()); - EXPECT_TRUE(TestCopyAssign<int(...) volatile&>()); - EXPECT_TRUE(TestCopyAssign<int(int, ...) const volatile&&>()); -#endif // _LIBCPP_VERSION -} - -template <typename T> -bool TestMoveAssign() { - return absl::is_move_assignable<T>::value == - std::is_move_assignable<T>::value; -} - -TEST(TypeTraitsTest, IsMoveAssignable) { - EXPECT_TRUE(TestMoveAssign<int>()); - EXPECT_TRUE(TestMoveAssign<int&>()); - EXPECT_TRUE(TestMoveAssign<int&&>()); - - struct S {}; - EXPECT_TRUE(TestMoveAssign<S>()); - EXPECT_TRUE(TestMoveAssign<S&>()); - EXPECT_TRUE(TestMoveAssign<S&&>()); - - class C { - public: - explicit C(C* c) : c_(c) {} - ~C() { delete c_; } - void operator=(const C&) = delete; - void operator=(C&&) = delete; - - private: - C* c_; - }; - EXPECT_TRUE(TestMoveAssign<C>()); - EXPECT_TRUE(TestMoveAssign<C&>()); - EXPECT_TRUE(TestMoveAssign<C&&>()); - - // Reason for ifndef: add_lvalue_reference<T> in libc++ breaks for these cases -#ifndef _LIBCPP_VERSION - EXPECT_TRUE(TestMoveAssign<int()>()); - EXPECT_TRUE(TestMoveAssign<int(int) const>()); - EXPECT_TRUE(TestMoveAssign<int(...) volatile&>()); - EXPECT_TRUE(TestMoveAssign<int(int, ...) const volatile&&>()); -#endif // _LIBCPP_VERSION -} - -namespace adl_namespace { - -struct DeletedSwap { -}; - -void swap(DeletedSwap&, DeletedSwap&) = delete; - -struct SpecialNoexceptSwap { - SpecialNoexceptSwap(SpecialNoexceptSwap&&) {} - SpecialNoexceptSwap& operator=(SpecialNoexceptSwap&&) { return *this; } - ~SpecialNoexceptSwap() = default; -}; - -void swap(SpecialNoexceptSwap&, SpecialNoexceptSwap&) noexcept {} - -} // namespace adl_namespace - -TEST(TypeTraitsTest, IsSwappable) { - using absl::type_traits_internal::IsSwappable; - using absl::type_traits_internal::StdSwapIsUnconstrained; - - EXPECT_TRUE(IsSwappable<int>::value); - - struct S {}; - EXPECT_TRUE(IsSwappable<S>::value); - - struct NoConstruct { - NoConstruct(NoConstruct&&) = delete; - NoConstruct& operator=(NoConstruct&&) { return *this; } - ~NoConstruct() = default; - }; - - EXPECT_EQ(IsSwappable<NoConstruct>::value, StdSwapIsUnconstrained::value); - struct NoAssign { - NoAssign(NoAssign&&) {} - NoAssign& operator=(NoAssign&&) = delete; - ~NoAssign() = default; - }; - - EXPECT_EQ(IsSwappable<NoAssign>::value, StdSwapIsUnconstrained::value); - - EXPECT_FALSE(IsSwappable<adl_namespace::DeletedSwap>::value); - - EXPECT_TRUE(IsSwappable<adl_namespace::SpecialNoexceptSwap>::value); -} - -TEST(TypeTraitsTest, IsNothrowSwappable) { - using absl::type_traits_internal::IsNothrowSwappable; - using absl::type_traits_internal::StdSwapIsUnconstrained; - - EXPECT_TRUE(IsNothrowSwappable<int>::value); - - struct NonNoexceptMoves { - NonNoexceptMoves(NonNoexceptMoves&&) {} - NonNoexceptMoves& operator=(NonNoexceptMoves&&) { return *this; } - ~NonNoexceptMoves() = default; - }; - - EXPECT_FALSE(IsNothrowSwappable<NonNoexceptMoves>::value); - - struct NoConstruct { - NoConstruct(NoConstruct&&) = delete; - NoConstruct& operator=(NoConstruct&&) { return *this; } - ~NoConstruct() = default; - }; - - EXPECT_FALSE(IsNothrowSwappable<NoConstruct>::value); - - struct NoAssign { - NoAssign(NoAssign&&) {} - NoAssign& operator=(NoAssign&&) = delete; - ~NoAssign() = default; - }; - - EXPECT_FALSE(IsNothrowSwappable<NoAssign>::value); - - EXPECT_FALSE(IsNothrowSwappable<adl_namespace::DeletedSwap>::value); - - EXPECT_TRUE(IsNothrowSwappable<adl_namespace::SpecialNoexceptSwap>::value); -} - -} // namespace |