1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/template_util.h" 6 7 #include <string> 8 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 namespace base { 12 namespace { 13 14 enum SimpleEnum { SIMPLE_ENUM }; 15 enum EnumWithExplicitType : uint64_t { ENUM_WITH_EXPLICIT_TYPE }; 16 enum class ScopedEnum { SCOPED_ENUM }; 17 enum class ScopedEnumWithOperator { SCOPED_ENUM_WITH_OPERATOR }; 18 std::ostream& operator<<(std::ostream& os, ScopedEnumWithOperator v) { 19 return os; 20 } 21 struct SimpleStruct {}; 22 struct StructWithOperator {}; 23 std::ostream& operator<<(std::ostream& os, const StructWithOperator& v) { 24 return os; 25 } 26 27 // is_non_const_reference<Type> 28 static_assert(!is_non_const_reference<int>::value, "IsNonConstReference"); 29 static_assert(!is_non_const_reference<const int&>::value, 30 "IsNonConstReference"); 31 static_assert(is_non_const_reference<int&>::value, "IsNonConstReference"); 32 33 class AssignParent {}; 34 class AssignChild : AssignParent {}; 35 36 // is_assignable<Type1, Type2> 37 static_assert(!is_assignable<int, int>::value, "IsAssignable"); // 1 = 1; 38 static_assert(!is_assignable<int, double>::value, "IsAssignable"); 39 static_assert(is_assignable<int&, int>::value, "IsAssignable"); 40 static_assert(is_assignable<int&, double>::value, "IsAssignable"); 41 static_assert(is_assignable<int&, int&>::value, "IsAssignable"); 42 static_assert(is_assignable<int&, int const&>::value, "IsAssignable"); 43 static_assert(!is_assignable<int const&, int>::value, "IsAssignable"); 44 static_assert(!is_assignable<AssignParent&, AssignChild>::value, 45 "IsAssignable"); 46 static_assert(!is_assignable<AssignChild&, AssignParent>::value, 47 "IsAssignable"); 48 49 struct AssignCopy {}; 50 struct AssignNoCopy { 51 AssignNoCopy& operator=(AssignNoCopy&&) { return *this; } 52 AssignNoCopy& operator=(const AssignNoCopy&) = delete; 53 }; 54 struct AssignNoMove { 55 AssignNoMove& operator=(AssignNoMove&&) = delete; 56 AssignNoMove& operator=(const AssignNoMove&) = delete; 57 }; 58 59 static_assert(is_copy_assignable<AssignCopy>::value, "IsCopyAssignable"); 60 static_assert(!is_copy_assignable<AssignNoCopy>::value, "IsCopyAssignable"); 61 62 static_assert(is_move_assignable<AssignCopy>::value, "IsMoveAssignable"); 63 static_assert(is_move_assignable<AssignNoCopy>::value, "IsMoveAssignable"); 64 static_assert(!is_move_assignable<AssignNoMove>::value, "IsMoveAssignable"); 65 66 // A few standard types that definitely support printing. 67 static_assert(internal::SupportsOstreamOperator<int>::value, 68 "ints should be printable"); 69 static_assert(internal::SupportsOstreamOperator<const char*>::value, 70 "C strings should be printable"); 71 static_assert(internal::SupportsOstreamOperator<std::string>::value, 72 "std::string should be printable"); 73 74 // Various kinds of enums operator<< support. 75 static_assert(internal::SupportsOstreamOperator<SimpleEnum>::value, 76 "simple enum should be printable by value"); 77 static_assert(internal::SupportsOstreamOperator<const SimpleEnum&>::value, 78 "simple enum should be printable by const ref"); 79 static_assert(internal::SupportsOstreamOperator<EnumWithExplicitType>::value, 80 "enum with explicit type should be printable by value"); 81 static_assert( 82 internal::SupportsOstreamOperator<const EnumWithExplicitType&>::value, 83 "enum with explicit type should be printable by const ref"); 84 static_assert(!internal::SupportsOstreamOperator<ScopedEnum>::value, 85 "scoped enum should not be printable by value"); 86 static_assert(!internal::SupportsOstreamOperator<const ScopedEnum&>::value, 87 "simple enum should not be printable by const ref"); 88 static_assert(internal::SupportsOstreamOperator<ScopedEnumWithOperator>::value, 89 "scoped enum with operator<< should be printable by value"); 90 static_assert( 91 internal::SupportsOstreamOperator<const ScopedEnumWithOperator&>::value, 92 "scoped enum with operator<< should be printable by const ref"); 93 94 // operator<< support on structs. 95 static_assert(!internal::SupportsOstreamOperator<SimpleStruct>::value, 96 "simple struct should not be printable by value"); 97 static_assert(!internal::SupportsOstreamOperator<const SimpleStruct&>::value, 98 "simple struct should not be printable by const ref"); 99 static_assert(internal::SupportsOstreamOperator<StructWithOperator>::value, 100 "struct with operator<< should be printable by value"); 101 static_assert( 102 internal::SupportsOstreamOperator<const StructWithOperator&>::value, 103 "struct with operator<< should be printable by const ref"); 104 105 // underlying type of enums 106 static_assert(std::is_integral<underlying_type<SimpleEnum>::type>::value, 107 "simple enum must have some integral type"); 108 static_assert( 109 std::is_same<underlying_type<EnumWithExplicitType>::type, uint64_t>::value, 110 "explicit type must be detected"); 111 static_assert(std::is_same<underlying_type<ScopedEnum>::type, int>::value, 112 "scoped enum defaults to int"); 113 114 struct TriviallyDestructible { 115 int field; 116 }; 117 118 class NonTriviallyDestructible { 119 ~NonTriviallyDestructible() {} 120 }; 121 122 static_assert(is_trivially_destructible<int>::value, "IsTriviallyDestructible"); 123 static_assert(is_trivially_destructible<TriviallyDestructible>::value, 124 "IsTriviallyDestructible"); 125 static_assert(!is_trivially_destructible<NonTriviallyDestructible>::value, 126 "IsTriviallyDestructible"); 127 128 } // namespace 129 } // namespace base 130