char_formatting_test.cc (5178B)
1 // Copyright 2023 The Abseil Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <cstddef> 16 17 #include "gtest/gtest.h" 18 #include "absl/strings/str_cat.h" 19 #include "absl/strings/str_format.h" 20 #include "absl/strings/substitute.h" 21 22 namespace { 23 24 TEST(CharFormatting, Char) { 25 const char v = 'A'; 26 27 // Desired behavior: does not compile: 28 // EXPECT_EQ(absl::StrCat(v, "B"), "AB"); 29 // EXPECT_EQ(absl::StrFormat("%vB", v), "AB"); 30 31 // Legacy behavior: format as char: 32 EXPECT_EQ(absl::Substitute("$0B", v), "AB"); 33 } 34 35 enum CharEnum : char {}; 36 TEST(CharFormatting, CharEnum) { 37 auto v = static_cast<CharEnum>('A'); 38 39 // Desired behavior: format as decimal 40 EXPECT_EQ(absl::StrFormat("%vB", v), "65B"); 41 EXPECT_EQ(absl::StrCat(v, "B"), "65B"); 42 43 // Legacy behavior: format as character: 44 45 // Some older versions of gcc behave differently in this one case 46 #if !defined(__GNUC__) || defined(__clang__) 47 EXPECT_EQ(absl::Substitute("$0B", v), "AB"); 48 #endif 49 } 50 51 enum class CharEnumClass: char {}; 52 TEST(CharFormatting, CharEnumClass) { 53 auto v = static_cast<CharEnumClass>('A'); 54 55 // Desired behavior: format as decimal: 56 EXPECT_EQ(absl::StrFormat("%vB", v), "65B"); 57 EXPECT_EQ(absl::StrCat(v, "B"), "65B"); 58 59 // Legacy behavior: format as character: 60 EXPECT_EQ(absl::Substitute("$0B", v), "AB"); 61 } 62 63 TEST(CharFormatting, UnsignedChar) { 64 const unsigned char v = 'A'; 65 66 // Desired behavior: format as decimal: 67 EXPECT_EQ(absl::StrCat(v, "B"), "65B"); 68 EXPECT_EQ(absl::Substitute("$0B", v), "65B"); 69 EXPECT_EQ(absl::StrFormat("%vB", v), "65B"); 70 71 // Signedness check 72 const unsigned char w = 255; 73 EXPECT_EQ(absl::StrCat(w, "B"), "255B"); 74 EXPECT_EQ(absl::Substitute("$0B", w), "255B"); 75 // EXPECT_EQ(absl::StrFormat("%vB", v), "255B"); 76 } 77 78 TEST(CharFormatting, SignedChar) { 79 const signed char v = 'A'; 80 81 // Desired behavior: format as decimal: 82 EXPECT_EQ(absl::StrCat(v, "B"), "65B"); 83 EXPECT_EQ(absl::Substitute("$0B", v), "65B"); 84 EXPECT_EQ(absl::StrFormat("%vB", v), "65B"); 85 86 // Signedness check 87 const signed char w = -128; 88 EXPECT_EQ(absl::StrCat(w, "B"), "-128B"); 89 EXPECT_EQ(absl::Substitute("$0B", w), "-128B"); 90 } 91 92 enum UnsignedCharEnum : unsigned char {}; 93 TEST(CharFormatting, UnsignedCharEnum) { 94 auto v = static_cast<UnsignedCharEnum>('A'); 95 96 // Desired behavior: format as decimal: 97 EXPECT_EQ(absl::StrCat(v, "B"), "65B"); 98 EXPECT_EQ(absl::Substitute("$0B", v), "65B"); 99 EXPECT_EQ(absl::StrFormat("%vB", v), "65B"); 100 101 // Signedness check 102 auto w = static_cast<UnsignedCharEnum>(255); 103 EXPECT_EQ(absl::StrCat(w, "B"), "255B"); 104 EXPECT_EQ(absl::Substitute("$0B", w), "255B"); 105 EXPECT_EQ(absl::StrFormat("%vB", w), "255B"); 106 } 107 108 enum SignedCharEnum : signed char {}; 109 TEST(CharFormatting, SignedCharEnum) { 110 auto v = static_cast<SignedCharEnum>('A'); 111 112 // Desired behavior: format as decimal: 113 EXPECT_EQ(absl::StrCat(v, "B"), "65B"); 114 EXPECT_EQ(absl::Substitute("$0B", v), "65B"); 115 EXPECT_EQ(absl::StrFormat("%vB", v), "65B"); 116 117 // Signedness check 118 auto w = static_cast<SignedCharEnum>(-128); 119 EXPECT_EQ(absl::StrCat(w, "B"), "-128B"); 120 EXPECT_EQ(absl::Substitute("$0B", w), "-128B"); 121 EXPECT_EQ(absl::StrFormat("%vB", w), "-128B"); 122 } 123 124 enum class UnsignedCharEnumClass : unsigned char {}; 125 TEST(CharFormatting, UnsignedCharEnumClass) { 126 auto v = static_cast<UnsignedCharEnumClass>('A'); 127 128 // Desired behavior: format as decimal: 129 EXPECT_EQ(absl::StrCat(v, "B"), "65B"); 130 EXPECT_EQ(absl::Substitute("$0B", v), "65B"); 131 EXPECT_EQ(absl::StrFormat("%vB", v), "65B"); 132 133 // Signedness check 134 auto w = static_cast<UnsignedCharEnumClass>(255); 135 EXPECT_EQ(absl::StrCat(w, "B"), "255B"); 136 EXPECT_EQ(absl::Substitute("$0B", w), "255B"); 137 EXPECT_EQ(absl::StrFormat("%vB", w), "255B"); 138 } 139 140 enum SignedCharEnumClass : signed char {}; 141 TEST(CharFormatting, SignedCharEnumClass) { 142 auto v = static_cast<SignedCharEnumClass>('A'); 143 144 // Desired behavior: format as decimal: 145 EXPECT_EQ(absl::StrCat(v, "B"), "65B"); 146 EXPECT_EQ(absl::Substitute("$0B", v), "65B"); 147 EXPECT_EQ(absl::StrFormat("%vB", v), "65B"); 148 149 // Signedness check 150 auto w = static_cast<SignedCharEnumClass>(-128); 151 EXPECT_EQ(absl::StrCat(w, "B"), "-128B"); 152 EXPECT_EQ(absl::Substitute("$0B", w), "-128B"); 153 EXPECT_EQ(absl::StrFormat("%vB", w), "-128B"); 154 } 155 156 #ifdef __cpp_lib_byte 157 TEST(CharFormatting, StdByte) { 158 auto v = static_cast<std::byte>('A'); 159 // Desired behavior: format as 0xff 160 // (No APIs do this today.) 161 162 // Legacy behavior: format as decimal: 163 EXPECT_EQ(absl::StrCat(v, "B"), "65B"); 164 EXPECT_EQ(absl::Substitute("$0B", v), "65B"); 165 EXPECT_EQ(absl::StrFormat("%vB", v), "65B"); 166 } 167 #endif // _cpp_lib_byte 168 169 } // namespace