// 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 // // http://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; struct Dummy {}; 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_; }; class TrivialDefaultCtor { public: TrivialDefaultCtor() = default; explicit TrivialDefaultCtor(int n) : n_(n) {} 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 TrivialCopyAssign { public: explicit TrivialCopyAssign(int n) : n_(n) {} TrivialCopyAssign(const TrivialCopyAssign& t) : n_(t.n_) {} TrivialCopyAssign& operator=(const TrivialCopyAssign& t) = default; ~TrivialCopyAssign() {} // can have non trivial destructor private: int n_; }; struct NonTrivialDestructor { ~NonTrivialDestructor() {} }; struct TrivialDestructor { ~TrivialDestructor() = default; }; struct NonCopyable { NonCopyable() = default; NonCopyable(const NonCopyable&) = delete; NonCopyable& operator=(const NonCopyable&) = delete; }; class Base { public: virtual ~Base() {} }; // In GCC/Clang, std::is_trivially_constructible requires that the destructor is // trivial. However, MSVC doesn't require that. This results in different // behavior when checking is_trivially_constructible on any type with nontrivial // destructor. Since absl::is_trivially_default_constructible and // absl::is_trivially_copy_constructible both follows Clang/GCC's interpretation // and check is_trivially_destructible, it results in inconsistency with // std::is_trivially_xxx_constructible on MSVC. This macro is used to work // around this issue in test. In practice, a trivially constructible type // should also be trivially destructible. // 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. #ifdef _MSC_VER #define ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE #endif 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); // types with compiler generated default ctors EXPECT_TRUE(absl::is_trivially_default_constructible::value); EXPECT_TRUE( absl::is_trivially_default_constructible::value); #ifndef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE // types with non trivial destructor are non trivial EXPECT_FALSE( absl::is_trivially_default_constructible::value); #endif // types with vtables EXPECT_FALSE(absl::is_trivially_default_constructible::value); // Verify that arrays of such types are trivially default constructible typedef int int10[10]; EXPECT_TRUE(absl::is_trivially_default_constructible::value); typedef Trivial Trivial10[10]; EXPECT_TRUE(absl::is_trivially_default_constructible::value); typedef Trivial TrivialDefaultCtor10[10]; EXPECT_TRUE( absl::is_trivially_default_constructible::value); // Verify that std::pair has non-trivial constructors. EXPECT_FALSE( (absl::is_trivially_default_constructible>::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); } 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); // types with compiler generated copy ctors EXPECT_TRUE(absl::is_trivially_copy_constructible::value); EXPECT_TRUE(absl::is_trivially_copy_constructible::value); #ifndef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE // type with non-trivial destructor are non-trivial copy construbtible EXPECT_FALSE( absl::is_trivially_copy_constructible::value); #endif // types with vtables EXPECT_FALSE(absl::is_trivially_copy_constructible::value); // Verify that std 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< std::pair>::value)); // Verify that arrays are not typedef int int10[10]; EXPECT_FALSE(absl::is_trivially_copy_constructible::value); // Verify that pairs of types without trivial copy constructors // are not marked as trivial. EXPECT_FALSE((absl::is_trivially_copy_constructible< std::pair>::value)); EXPECT_FALSE((absl::is_trivially_copy_constructible< std::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); // types with deleted copy constructors are not copy constructible EXPECT_FALSE(absl::is_trivially_copy_constructible::value); } TEST(TypeTraitsTest, TestTrivialCopyAssign) { // Verify that arithmetic types and pointers have trivial copy // constructors. 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); // types with vtables EXPECT_FALSE(absl::is_trivially_copy_assignable::value); // Verify that arrays are not trivially copy assignable typedef int int10[10]; EXPECT_FALSE(absl::is_trivially_copy_assignable::value); // Verify that std::pair is not trivially assignable EXPECT_FALSE( (absl::is_trivially_copy_assignable>::value)); // Verify that types without trivial copy constructors are // correctly marked as such. EXPECT_FALSE(absl::is_trivially_copy_assignable::value); EXPECT_FALSE(absl::is_trivially_copy_assignable>::value); // types with deleted copy assignment are not copy assignable EXPECT_FALSE(absl::is_trivially_copy_assignable::value); } TEST(TypeTraitsTest, TestTrivialDestructor) { // Verify that arithmetic types and pointers have trivial copy // constructors. 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); EXPECT_FALSE(absl::is_trivially_destructible::value); // std::pair of such types is trivial EXPECT_TRUE((absl::is_trivially_destructible>::value)); EXPECT_TRUE((absl::is_trivially_destructible< std::pair>::value)); // array of such types is trivial typedef int int10[10]; EXPECT_TRUE(absl::is_trivially_destructible::value); typedef TrivialDestructor TrivialDestructor10[10]; EXPECT_TRUE(absl::is_trivially_destructible::value); typedef NonTrivialDestructor NonTrivialDestructor10[10]; EXPECT_FALSE(absl::is_trivially_destructible::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)); ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(char, ...)); } 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())); } } // namespace