// 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 #include #include #include #include #include "gtest/gtest.h" namespace { using ::testing::StaticAssertTypeEq; template 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 ::value, int> = 0> ReturnType bar(T&&, const StructB&, StructC&&) &&; // NOLINT }; struct TypeWithBarFunctionAndConvertibleReturnType { template ::value, int> = 0> ConvertibleToReturnType bar(T&&, const StructB&, StructC&&) &&; // NOLINT }; template using BarIsCallableImpl = decltype(std::declval().bar(std::declval()...)); template using BarIsCallable = absl::type_traits_internal::is_detected; template 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::value)); EXPECT_TRUE( (BarIsCallable::value)); EXPECT_TRUE( (BarIsCallable::value)); EXPECT_FALSE((BarIsCallable::value)); EXPECT_FALSE((BarIsCallable::value)); EXPECT_FALSE((BarIsCallable::value)); } // NOTE: Test of detail type_traits_internal::is_detected_convertible. TEST(IsDetectedConvertibleTest, BasicUsage) { EXPECT_TRUE((BarIsCallableConv::value)); EXPECT_TRUE((BarIsCallableConv::value)); EXPECT_TRUE((BarIsCallableConv::value)); EXPECT_TRUE((BarIsCallableConv::value)); EXPECT_TRUE((BarIsCallableConv::value)); EXPECT_TRUE((BarIsCallableConv::value)); EXPECT_FALSE( (BarIsCallableConv::value)); EXPECT_FALSE((BarIsCallableConv::value)); EXPECT_FALSE((BarIsCallableConv::value)); EXPECT_FALSE((BarIsCallableConv::value)); EXPECT_FALSE((BarIsCallableConv::value)); } TEST(VoidTTest, BasicUsage) { StaticAssertTypeEq>(); StaticAssertTypeEq>(); } TEST(ConjunctionTest, BasicBooleanLogic) { EXPECT_TRUE(absl::conjunction<>::value); EXPECT_TRUE(absl::conjunction::value); EXPECT_TRUE((absl::conjunction::value)); EXPECT_FALSE((absl::conjunction::value)); EXPECT_FALSE((absl::conjunction::value)); EXPECT_FALSE((absl::conjunction::value)); } struct MyTrueType { static constexpr bool value = true; }; struct MyFalseType { static constexpr bool value = false; }; TEST(ConjunctionTest, ShortCircuiting) { EXPECT_FALSE( (absl::conjunction::value)); EXPECT_TRUE((std::is_base_of>::value)); EXPECT_TRUE( (std::is_base_of>::value)); } TEST(DisjunctionTest, BasicBooleanLogic) { EXPECT_FALSE(absl::disjunction<>::value); EXPECT_FALSE(absl::disjunction::value); EXPECT_TRUE((absl::disjunction::value)); EXPECT_TRUE((absl::disjunction::value)); EXPECT_TRUE((absl::disjunction::value)); EXPECT_FALSE((absl::disjunction::value)); } TEST(DisjunctionTest, ShortCircuiting) { EXPECT_TRUE( (absl::disjunction::value)); EXPECT_TRUE(( std::is_base_of>::value)); EXPECT_TRUE(( std::is_base_of>::value)); } TEST(NegationTest, BasicBooleanLogic) { EXPECT_FALSE(absl::negation::value); EXPECT_FALSE(absl::negation::value); EXPECT_TRUE(absl::negation::value); EXPECT_TRUE(absl::negation::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, 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 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::value); EXPECT_TRUE(absl::is_function::value); EXPECT_TRUE(absl::is_function::value); EXPECT_TRUE(absl::is_function::value); EXPECT_TRUE(absl::is_function::value); EXPECT_FALSE(absl::is_function::value); EXPECT_FALSE(absl::is_function::value); EXPECT_FALSE(absl::is_function::value); EXPECT_FALSE(absl::is_function::value); } TEST(TypeTraitsTest, TestTrivialDestructor) { // Verify that arithmetic types and pointers have trivial destructors. EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); // classes with destructors EXPECT_TRUE(absl::is_trivially_destructible::value); EXPECT_TRUE(absl::is_trivially_destructible::value); // Verify that types with a nontrivial or deleted destructor // are marked as such. EXPECT_FALSE(absl::is_trivially_destructible::value); #ifdef ABSL_TRIVIALLY_DESTRUCTIBLE_CONSIDER_DELETED_DESTRUCTOR_NOT_TRIVIAL EXPECT_FALSE(absl::is_trivially_destructible::value); #endif // simple_pair of such types is trivial EXPECT_TRUE((absl::is_trivially_destructible>::value)); EXPECT_TRUE((absl::is_trivially_destructible< simple_pair>::value)); // Verify that types without trivial destructors are correctly marked as such. EXPECT_FALSE(absl::is_trivially_destructible::value); EXPECT_FALSE(absl::is_trivially_destructible>::value); // Verify that simple_pairs of types without trivial destructors // are not marked as trivial. EXPECT_FALSE((absl::is_trivially_destructible< simple_pair>::value)); EXPECT_FALSE((absl::is_trivially_destructible< simple_pair>::value)); // array of such types is trivial using int10 = int[10]; EXPECT_TRUE(absl::is_trivially_destructible::value); using Trivial10 = Trivial[10]; EXPECT_TRUE(absl::is_trivially_destructible::value); using TrivialDestructor10 = TrivialDestructor[10]; EXPECT_TRUE(absl::is_trivially_destructible::value); // Conversely, the opposite also holds. using NontrivialDestructor10 = NontrivialDestructor[10]; EXPECT_FALSE(absl::is_trivially_destructible::value); } TEST(TypeTraitsTest, TestTrivialDefaultCtor) { // arithmetic types and pointers have trivial default constructors. EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE( absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE(absl::is_trivially_default_constructible::value); // types with compiler generated default ctors EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE( absl::is_trivially_default_constructible::value); // Verify that types without them are not. EXPECT_FALSE( absl::is_trivially_default_constructible::value); EXPECT_FALSE( absl::is_trivially_default_constructible::value); // types with nontrivial destructor are nontrivial EXPECT_FALSE( absl::is_trivially_default_constructible::value); // types with vtables EXPECT_FALSE(absl::is_trivially_default_constructible::value); // Verify that simple_pair has trivial constructors where applicable. EXPECT_TRUE((absl::is_trivially_default_constructible< simple_pair>::value)); EXPECT_TRUE((absl::is_trivially_default_constructible< simple_pair>::value)); EXPECT_TRUE((absl::is_trivially_default_constructible< simple_pair>::value)); // Verify that types without trivial constructors are // correctly marked as such. EXPECT_FALSE(absl::is_trivially_default_constructible::value); EXPECT_FALSE( absl::is_trivially_default_constructible>::value); // Verify that simple_pairs of types without trivial constructors // are not marked as trivial. EXPECT_FALSE((absl::is_trivially_default_constructible< simple_pair>::value)); EXPECT_FALSE((absl::is_trivially_default_constructible< simple_pair>::value)); // Verify that arrays of such types are trivially default constructible using int10 = int[10]; EXPECT_TRUE(absl::is_trivially_default_constructible::value); using Trivial10 = Trivial[10]; EXPECT_TRUE(absl::is_trivially_default_constructible::value); using TrivialDefaultCtor10 = TrivialDefaultCtor[10]; EXPECT_TRUE( absl::is_trivially_default_constructible::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::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 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; EXPECT_FALSE(absl::is_trivially_default_constructible::value); EXPECT_FALSE(absl::is_trivially_move_constructible::value); EXPECT_FALSE(absl::is_trivially_copy_constructible::value); } TEST(TypeTraitsTest, TestTrivialMoveCtor) { // Verify that arithmetic types and pointers have trivial move // constructors. EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); // Reference types EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); // types with compiler generated move ctors EXPECT_TRUE(absl::is_trivially_move_constructible::value); EXPECT_TRUE(absl::is_trivially_move_constructible::value); // Verify that types without them (i.e. nontrivial or deleted) are not. EXPECT_FALSE( absl::is_trivially_move_constructible::value); EXPECT_FALSE(absl::is_trivially_move_constructible::value); EXPECT_FALSE( absl::is_trivially_move_constructible::value); // type with nontrivial destructor are nontrivial move construbtible EXPECT_FALSE( absl::is_trivially_move_constructible::value); // types with vtables EXPECT_FALSE(absl::is_trivially_move_constructible::value); // Verify that simple_pair of such types is trivially move constructible EXPECT_TRUE( (absl::is_trivially_move_constructible>::value)); EXPECT_TRUE(( absl::is_trivially_move_constructible>::value)); EXPECT_TRUE((absl::is_trivially_move_constructible< simple_pair>::value)); // Verify that types without trivial move constructors are // correctly marked as such. EXPECT_FALSE(absl::is_trivially_move_constructible::value); EXPECT_FALSE(absl::is_trivially_move_constructible>::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>::value)); EXPECT_FALSE((absl::is_trivially_move_constructible< simple_pair>::value)); // Verify that arrays are not using int10 = int[10]; EXPECT_FALSE(absl::is_trivially_move_constructible::value); } TEST(TypeTraitsTest, TestTrivialCopyCtor) { // Verify that arithmetic types and pointers have trivial copy // constructors. EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); // Reference types EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_FALSE(absl::is_trivially_copy_constructible::value); // types with compiler generated copy ctors EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); // Verify that types without them (i.e. nontrivial or deleted) are not. EXPECT_FALSE( absl::is_trivially_copy_constructible::value); EXPECT_FALSE(absl::is_trivially_copy_constructible::value); EXPECT_FALSE( absl::is_trivially_copy_constructible::value); EXPECT_FALSE( absl::is_trivially_copy_constructible::value); // type with nontrivial destructor are nontrivial copy construbtible EXPECT_FALSE( absl::is_trivially_copy_constructible::value); // types with vtables EXPECT_FALSE(absl::is_trivially_copy_constructible::value); // Verify that simple_pair of such types is trivially copy constructible EXPECT_TRUE( (absl::is_trivially_copy_constructible>::value)); EXPECT_TRUE(( absl::is_trivially_copy_constructible>::value)); EXPECT_TRUE((absl::is_trivially_copy_constructible< simple_pair>::value)); // Verify that types without trivial copy constructors are // correctly marked as such. EXPECT_FALSE(absl::is_trivially_copy_constructible::value); EXPECT_FALSE(absl::is_trivially_copy_constructible>::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>::value)); EXPECT_FALSE((absl::is_trivially_copy_constructible< simple_pair>::value)); // Verify that arrays are not using int10 = int[10]; EXPECT_FALSE(absl::is_trivially_copy_constructible::value); } TEST(TypeTraitsTest, TestTrivialMoveAssign) { // Verify that arithmetic types and pointers have trivial move // assignment operators. EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); // const qualified types are not assignable EXPECT_FALSE(absl::is_trivially_move_assignable::value); // types with compiler generated move assignment EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); // Verify that types without them (i.e. nontrivial or deleted) are not. EXPECT_FALSE(absl::is_trivially_move_assignable::value); EXPECT_FALSE(absl::is_trivially_move_assignable::value); EXPECT_FALSE(absl::is_trivially_move_assignable::value); // types with vtables EXPECT_FALSE(absl::is_trivially_move_assignable::value); // Verify that simple_pair is trivially assignable EXPECT_TRUE( (absl::is_trivially_move_assignable>::value)); EXPECT_TRUE( (absl::is_trivially_move_assignable>::value)); EXPECT_TRUE((absl::is_trivially_move_assignable< simple_pair>::value)); // Verify that types not trivially move assignable are // correctly marked as such. EXPECT_FALSE(absl::is_trivially_move_assignable::value); EXPECT_FALSE(absl::is_trivially_move_assignable>::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>::value)); EXPECT_FALSE((absl::is_trivially_move_assignable< simple_pair>::value)); // Verify that arrays are not trivially move assignable using int10 = int[10]; EXPECT_FALSE(absl::is_trivially_move_assignable::value); // Verify that references are handled correctly EXPECT_TRUE(absl::is_trivially_move_assignable::value); EXPECT_TRUE(absl::is_trivially_move_assignable::value); } TEST(TypeTraitsTest, TestTrivialCopyAssign) { // Verify that arithmetic types and pointers have trivial copy // assignment operators. EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); // const qualified types are not assignable EXPECT_FALSE(absl::is_trivially_copy_assignable::value); // types with compiler generated copy assignment EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); // Verify that types without them (i.e. nontrivial or deleted) are not. EXPECT_FALSE(absl::is_trivially_copy_assignable::value); EXPECT_FALSE(absl::is_trivially_copy_assignable::value); EXPECT_FALSE(absl::is_trivially_copy_assignable::value); EXPECT_FALSE(absl::is_trivially_copy_assignable::value); // types with vtables EXPECT_FALSE(absl::is_trivially_copy_assignable::value); // Verify that simple_pair is trivially assignable EXPECT_TRUE( (absl::is_trivially_copy_assignable>::value)); EXPECT_TRUE( (absl::is_trivially_copy_assignable>::value)); EXPECT_TRUE((absl::is_trivially_copy_assignable< simple_pair>::value)); // Verify that types not trivially copy assignable are // correctly marked as such. EXPECT_FALSE(absl::is_trivially_copy_assignable::value); EXPECT_FALSE(absl::is_trivially_copy_assignable>::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>::value)); EXPECT_FALSE((absl::is_trivially_copy_assignable< simple_pair>::value)); // Verify that arrays are not trivially copy assignable using int10 = int[10]; EXPECT_FALSE(absl::is_trivially_copy_assignable::value); // Verify that references are handled correctly EXPECT_TRUE(absl::is_trivially_copy_assignable::value); EXPECT_TRUE(absl::is_trivially_copy_assignable::value); } TEST(TypeTraitsTest, TestTriviallyCopyable) { // Verify that arithmetic types and pointers are trivially copyable. EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable< const std::string*>::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); // const qualified types are not assignable but are constructible EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); // Trivial copy constructor/assignment and destructor. EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::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::value); // Verify that simple_pair is trivially copyable if members are EXPECT_TRUE((absl::type_traits_internal::is_trivially_copyable< simple_pair>::value)); EXPECT_TRUE((absl::type_traits_internal::is_trivially_copyable< simple_pair>::value)); // Verify that types not trivially copyable are // correctly marked as such. EXPECT_FALSE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_FALSE(absl::type_traits_internal::is_trivially_copyable< std::vector>::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>::value)); EXPECT_FALSE((absl::type_traits_internal::is_trivially_copyable< simple_pair>::value)); EXPECT_FALSE((absl::type_traits_internal::is_trivially_copyable< simple_pair>::value)); // Verify that arrays of trivially copyable types are trivially copyable using int10 = int[10]; EXPECT_TRUE(absl::type_traits_internal::is_trivially_copyable::value); using int10x10 = int[10][10]; EXPECT_TRUE( absl::type_traits_internal::is_trivially_copyable::value); // Verify that references are handled correctly EXPECT_FALSE( absl::type_traits_internal::is_trivially_copyable::value); EXPECT_FALSE( absl::type_traits_internal::is_trivially_copyable::value); } #define ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(trait_name, ...) \ EXPECT_TRUE((std::is_same::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 struct Wrap {}; enum class TypeEnum { A, B, C, D }; struct GetTypeT { template ::value, int> = 0> TypeEnum operator()(Wrap) const { return TypeEnum::A; } template ::value, int> = 0> TypeEnum operator()(Wrap) const { return TypeEnum::B; } template ::value, int> = 0> TypeEnum operator()(Wrap) const { return TypeEnum::C; } // NOTE: TypeD is intentionally not handled } constexpr GetType = {}; TEST(TypeTraitsTest, TestEnableIf) { EXPECT_EQ(TypeEnum::A, GetType(Wrap())); EXPECT_EQ(TypeEnum::B, GetType(Wrap())); EXPECT_EQ(TypeEnum::C, GetType(Wrap())); } 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 absl::result_of_t operator()(T&& arg) const { return GetType(std::forward(arg)); } TypeEnum operator()(Wrap) const { return TypeEnum::D; } } constexpr GetTypeExt = {}; TEST(TypeTraitsTest, TestResultOf) { EXPECT_EQ(TypeEnum::A, GetTypeExt(Wrap())); EXPECT_EQ(TypeEnum::B, GetTypeExt(Wrap())); EXPECT_EQ(TypeEnum::C, GetTypeExt(Wrap())); EXPECT_EQ(TypeEnum::D, GetTypeExt(Wrap())); } template bool TestCopyAssign() { return absl::is_copy_assignable::value == std::is_copy_assignable::value; } TEST(TypeTraitsTest, IsCopyAssignable) { EXPECT_TRUE(TestCopyAssign()); EXPECT_TRUE(TestCopyAssign()); EXPECT_TRUE(TestCopyAssign()); struct S {}; EXPECT_TRUE(TestCopyAssign()); EXPECT_TRUE(TestCopyAssign()); EXPECT_TRUE(TestCopyAssign()); class C { public: explicit C(C* c) : c_(c) {} ~C() { delete c_; } private: C* c_; }; EXPECT_TRUE(TestCopyAssign()); EXPECT_TRUE(TestCopyAssign()); EXPECT_TRUE(TestCopyAssign()); // Reason for ifndef: add_lvalue_reference in libc++ breaks for these cases #ifndef _LIBCPP_VERSION EXPECT_TRUE(TestCopyAssign()); EXPECT_TRUE(TestCopyAssign()); EXPECT_TRUE(TestCopyAssign()); EXPECT_TRUE(TestCopyAssign()); #endif // _LIBCPP_VERSION } template bool TestMoveAssign() { return absl::is_move_assignable::value == std::is_move_assignable::value; } TEST(TypeTraitsTest, IsMoveAssignable) { EXPECT_TRUE(TestMoveAssign()); EXPECT_TRUE(TestMoveAssign()); EXPECT_TRUE(TestMoveAssign()); struct S {}; EXPECT_TRUE(TestMoveAssign()); EXPECT_TRUE(TestMoveAssign()); EXPECT_TRUE(TestMoveAssign()); 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()); EXPECT_TRUE(TestMoveAssign()); EXPECT_TRUE(TestMoveAssign()); // Reason for ifndef: add_lvalue_reference in libc++ breaks for these cases #ifndef _LIBCPP_VERSION EXPECT_TRUE(TestMoveAssign()); EXPECT_TRUE(TestMoveAssign()); EXPECT_TRUE(TestMoveAssign()); EXPECT_TRUE(TestMoveAssign()); #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::value); struct S {}; EXPECT_TRUE(IsSwappable::value); struct NoConstruct { NoConstruct(NoConstruct&&) = delete; NoConstruct& operator=(NoConstruct&&) { return *this; } ~NoConstruct() = default; }; EXPECT_EQ(IsSwappable::value, StdSwapIsUnconstrained::value); struct NoAssign { NoAssign(NoAssign&&) {} NoAssign& operator=(NoAssign&&) = delete; ~NoAssign() = default; }; EXPECT_EQ(IsSwappable::value, StdSwapIsUnconstrained::value); EXPECT_FALSE(IsSwappable::value); EXPECT_TRUE(IsSwappable::value); } TEST(TypeTraitsTest, IsNothrowSwappable) { using absl::type_traits_internal::IsNothrowSwappable; using absl::type_traits_internal::StdSwapIsUnconstrained; EXPECT_TRUE(IsNothrowSwappable::value); struct NonNoexceptMoves { NonNoexceptMoves(NonNoexceptMoves&&) {} NonNoexceptMoves& operator=(NonNoexceptMoves&&) { return *this; } ~NonNoexceptMoves() = default; }; EXPECT_FALSE(IsNothrowSwappable::value); struct NoConstruct { NoConstruct(NoConstruct&&) = delete; NoConstruct& operator=(NoConstruct&&) { return *this; } ~NoConstruct() = default; }; EXPECT_FALSE(IsNothrowSwappable::value); struct NoAssign { NoAssign(NoAssign&&) {} NoAssign& operator=(NoAssign&&) = delete; ~NoAssign() = default; }; EXPECT_FALSE(IsNothrowSwappable::value); EXPECT_FALSE(IsNothrowSwappable::value); EXPECT_TRUE(IsNothrowSwappable::value); } } // namespace