xref: /aosp_15_r20/external/abseil-cpp/absl/strings/str_cat_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker 
15*9356374aSAndroid Build Coastguard Worker // Unit tests for all str_cat.h functions
16*9356374aSAndroid Build Coastguard Worker 
17*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_cat.h"
18*9356374aSAndroid Build Coastguard Worker 
19*9356374aSAndroid Build Coastguard Worker #include <cstddef>
20*9356374aSAndroid Build Coastguard Worker #include <cstdint>
21*9356374aSAndroid Build Coastguard Worker #include <cstdlib>
22*9356374aSAndroid Build Coastguard Worker #include <limits>
23*9356374aSAndroid Build Coastguard Worker #include <string>
24*9356374aSAndroid Build Coastguard Worker #include <vector>
25*9356374aSAndroid Build Coastguard Worker 
26*9356374aSAndroid Build Coastguard Worker #include "gtest/gtest.h"
27*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_format.h"
28*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
29*9356374aSAndroid Build Coastguard Worker 
30*9356374aSAndroid Build Coastguard Worker #ifdef __ANDROID__
31*9356374aSAndroid Build Coastguard Worker // Android assert messages only go to system log, so death tests cannot inspect
32*9356374aSAndroid Build Coastguard Worker // the message for matching.
33*9356374aSAndroid Build Coastguard Worker #define ABSL_EXPECT_DEBUG_DEATH(statement, regex) \
34*9356374aSAndroid Build Coastguard Worker   EXPECT_DEBUG_DEATH(statement, ".*")
35*9356374aSAndroid Build Coastguard Worker #else
36*9356374aSAndroid Build Coastguard Worker #define ABSL_EXPECT_DEBUG_DEATH(statement, regex) \
37*9356374aSAndroid Build Coastguard Worker   EXPECT_DEBUG_DEATH(statement, regex)
38*9356374aSAndroid Build Coastguard Worker #endif
39*9356374aSAndroid Build Coastguard Worker 
40*9356374aSAndroid Build Coastguard Worker namespace {
41*9356374aSAndroid Build Coastguard Worker 
42*9356374aSAndroid Build Coastguard Worker // Test absl::StrCat of ints and longs of various sizes and signdedness.
TEST(StrCat,Ints)43*9356374aSAndroid Build Coastguard Worker TEST(StrCat, Ints) {
44*9356374aSAndroid Build Coastguard Worker   const short s = -1;  // NOLINT(runtime/int)
45*9356374aSAndroid Build Coastguard Worker   const uint16_t us = 2;
46*9356374aSAndroid Build Coastguard Worker   const int i = -3;
47*9356374aSAndroid Build Coastguard Worker   const unsigned int ui = 4;
48*9356374aSAndroid Build Coastguard Worker   const long l = -5;                 // NOLINT(runtime/int)
49*9356374aSAndroid Build Coastguard Worker   const unsigned long ul = 6;        // NOLINT(runtime/int)
50*9356374aSAndroid Build Coastguard Worker   const long long ll = -7;           // NOLINT(runtime/int)
51*9356374aSAndroid Build Coastguard Worker   const unsigned long long ull = 8;  // NOLINT(runtime/int)
52*9356374aSAndroid Build Coastguard Worker   const ptrdiff_t ptrdiff = -9;
53*9356374aSAndroid Build Coastguard Worker   const size_t size = 10;
54*9356374aSAndroid Build Coastguard Worker   const intptr_t intptr = -12;
55*9356374aSAndroid Build Coastguard Worker   const uintptr_t uintptr = 13;
56*9356374aSAndroid Build Coastguard Worker   std::string answer;
57*9356374aSAndroid Build Coastguard Worker   answer = absl::StrCat(s, us);
58*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(answer, "-12");
59*9356374aSAndroid Build Coastguard Worker   answer = absl::StrCat(i, ui);
60*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(answer, "-34");
61*9356374aSAndroid Build Coastguard Worker   answer = absl::StrCat(l, ul);
62*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(answer, "-56");
63*9356374aSAndroid Build Coastguard Worker   answer = absl::StrCat(ll, ull);
64*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(answer, "-78");
65*9356374aSAndroid Build Coastguard Worker   answer = absl::StrCat(ptrdiff, size);
66*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(answer, "-910");
67*9356374aSAndroid Build Coastguard Worker   answer = absl::StrCat(ptrdiff, intptr);
68*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(answer, "-9-12");
69*9356374aSAndroid Build Coastguard Worker   answer = absl::StrCat(uintptr, 0);
70*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(answer, "130");
71*9356374aSAndroid Build Coastguard Worker }
72*9356374aSAndroid Build Coastguard Worker 
TEST(StrCat,Enums)73*9356374aSAndroid Build Coastguard Worker TEST(StrCat, Enums) {
74*9356374aSAndroid Build Coastguard Worker   enum SmallNumbers { One = 1, Ten = 10 } e = Ten;
75*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("10", absl::StrCat(e));
76*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("-5", absl::StrCat(SmallNumbers(-5)));
77*9356374aSAndroid Build Coastguard Worker 
78*9356374aSAndroid Build Coastguard Worker   enum class Option { Boxers = 1, Briefs = -1 };
79*9356374aSAndroid Build Coastguard Worker 
80*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("-1", absl::StrCat(Option::Briefs));
81*9356374aSAndroid Build Coastguard Worker 
82*9356374aSAndroid Build Coastguard Worker   enum class Airplane : uint64_t {
83*9356374aSAndroid Build Coastguard Worker     Airbus = 1,
84*9356374aSAndroid Build Coastguard Worker     Boeing = 1000,
85*9356374aSAndroid Build Coastguard Worker     Canary = 10000000000  // too big for "int"
86*9356374aSAndroid Build Coastguard Worker   };
87*9356374aSAndroid Build Coastguard Worker 
88*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("10000000000", absl::StrCat(Airplane::Canary));
89*9356374aSAndroid Build Coastguard Worker 
90*9356374aSAndroid Build Coastguard Worker   enum class TwoGig : int32_t {
91*9356374aSAndroid Build Coastguard Worker     TwoToTheZero = 1,
92*9356374aSAndroid Build Coastguard Worker     TwoToTheSixteenth = 1 << 16,
93*9356374aSAndroid Build Coastguard Worker     TwoToTheThirtyFirst = INT32_MIN
94*9356374aSAndroid Build Coastguard Worker   };
95*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("65536", absl::StrCat(TwoGig::TwoToTheSixteenth));
96*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("-2147483648", absl::StrCat(TwoGig::TwoToTheThirtyFirst));
97*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("-1", absl::StrCat(static_cast<TwoGig>(-1)));
98*9356374aSAndroid Build Coastguard Worker 
99*9356374aSAndroid Build Coastguard Worker   enum class FourGig : uint32_t {
100*9356374aSAndroid Build Coastguard Worker     TwoToTheZero = 1,
101*9356374aSAndroid Build Coastguard Worker     TwoToTheSixteenth = 1 << 16,
102*9356374aSAndroid Build Coastguard Worker     TwoToTheThirtyFirst = 1U << 31  // too big for "int"
103*9356374aSAndroid Build Coastguard Worker   };
104*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("65536", absl::StrCat(FourGig::TwoToTheSixteenth));
105*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("2147483648", absl::StrCat(FourGig::TwoToTheThirtyFirst));
106*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("4294967295", absl::StrCat(static_cast<FourGig>(-1)));
107*9356374aSAndroid Build Coastguard Worker 
108*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("10000000000", absl::StrCat(Airplane::Canary));
109*9356374aSAndroid Build Coastguard Worker }
110*9356374aSAndroid Build Coastguard Worker 
TEST(StrCat,Basics)111*9356374aSAndroid Build Coastguard Worker TEST(StrCat, Basics) {
112*9356374aSAndroid Build Coastguard Worker   std::string result;
113*9356374aSAndroid Build Coastguard Worker 
114*9356374aSAndroid Build Coastguard Worker   std::string strs[] = {"Hello", "Cruel", "World"};
115*9356374aSAndroid Build Coastguard Worker 
116*9356374aSAndroid Build Coastguard Worker   std::string stdstrs[] = {
117*9356374aSAndroid Build Coastguard Worker     "std::Hello",
118*9356374aSAndroid Build Coastguard Worker     "std::Cruel",
119*9356374aSAndroid Build Coastguard Worker     "std::World"
120*9356374aSAndroid Build Coastguard Worker   };
121*9356374aSAndroid Build Coastguard Worker 
122*9356374aSAndroid Build Coastguard Worker   absl::string_view pieces[] = {"Hello", "Cruel", "World"};
123*9356374aSAndroid Build Coastguard Worker 
124*9356374aSAndroid Build Coastguard Worker   const char* c_strs[] = {
125*9356374aSAndroid Build Coastguard Worker     "Hello",
126*9356374aSAndroid Build Coastguard Worker     "Cruel",
127*9356374aSAndroid Build Coastguard Worker     "World"
128*9356374aSAndroid Build Coastguard Worker   };
129*9356374aSAndroid Build Coastguard Worker 
130*9356374aSAndroid Build Coastguard Worker   int32_t i32s[] = {'H', 'C', 'W'};
131*9356374aSAndroid Build Coastguard Worker   uint64_t ui64s[] = {12345678910LL, 10987654321LL};
132*9356374aSAndroid Build Coastguard Worker 
133*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::StrCat(), "");
134*9356374aSAndroid Build Coastguard Worker 
135*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(false, true, 2, 3);
136*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "0123");
137*9356374aSAndroid Build Coastguard Worker 
138*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(-1);
139*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "-1");
140*9356374aSAndroid Build Coastguard Worker 
141*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(absl::SixDigits(0.5));
142*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "0.5");
143*9356374aSAndroid Build Coastguard Worker 
144*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(strs[1], pieces[2]);
145*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "CruelWorld");
146*9356374aSAndroid Build Coastguard Worker 
147*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(stdstrs[1], " ", stdstrs[2]);
148*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "std::Cruel std::World");
149*9356374aSAndroid Build Coastguard Worker 
150*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(strs[0], ", ", pieces[2]);
151*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "Hello, World");
152*9356374aSAndroid Build Coastguard Worker 
153*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(strs[0], ", ", strs[1], " ", strs[2], "!");
154*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "Hello, Cruel World!");
155*9356374aSAndroid Build Coastguard Worker 
156*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(pieces[0], ", ", pieces[1], " ", pieces[2]);
157*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "Hello, Cruel World");
158*9356374aSAndroid Build Coastguard Worker 
159*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(c_strs[0], ", ", c_strs[1], " ", c_strs[2]);
160*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "Hello, Cruel World");
161*9356374aSAndroid Build Coastguard Worker 
162*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat("ASCII ", i32s[0], ", ", i32s[1], " ", i32s[2], "!");
163*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "ASCII 72, 67 87!");
164*9356374aSAndroid Build Coastguard Worker 
165*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(ui64s[0], ", ", ui64s[1], "!");
166*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "12345678910, 10987654321!");
167*9356374aSAndroid Build Coastguard Worker 
168*9356374aSAndroid Build Coastguard Worker   std::string one =
169*9356374aSAndroid Build Coastguard Worker       "1";  // Actually, it's the size of this string that we want; a
170*9356374aSAndroid Build Coastguard Worker             // 64-bit build distinguishes between size_t and uint64_t,
171*9356374aSAndroid Build Coastguard Worker             // even though they're both unsigned 64-bit values.
172*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat("And a ", one.size(), " and a ",
173*9356374aSAndroid Build Coastguard Worker                         &result[2] - &result[0], " and a ", one, " 2 3 4", "!");
174*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "And a 1 and a 2 and a 1 2 3 4!");
175*9356374aSAndroid Build Coastguard Worker 
176*9356374aSAndroid Build Coastguard Worker   // result = absl::StrCat("Single chars won't compile", '!');
177*9356374aSAndroid Build Coastguard Worker   // result = absl::StrCat("Neither will nullptrs", nullptr);
178*9356374aSAndroid Build Coastguard Worker   result =
179*9356374aSAndroid Build Coastguard Worker       absl::StrCat("To output a char by ASCII/numeric value, use +: ", '!' + 0);
180*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "To output a char by ASCII/numeric value, use +: 33");
181*9356374aSAndroid Build Coastguard Worker 
182*9356374aSAndroid Build Coastguard Worker   float f = 100000.5;
183*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat("A hundred K and a half is ", absl::SixDigits(f));
184*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "A hundred K and a half is 100000");
185*9356374aSAndroid Build Coastguard Worker 
186*9356374aSAndroid Build Coastguard Worker   f = 100001.5;
187*9356374aSAndroid Build Coastguard Worker   result =
188*9356374aSAndroid Build Coastguard Worker       absl::StrCat("A hundred K and one and a half is ", absl::SixDigits(f));
189*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "A hundred K and one and a half is 100002");
190*9356374aSAndroid Build Coastguard Worker 
191*9356374aSAndroid Build Coastguard Worker   double d = 100000.5;
192*9356374aSAndroid Build Coastguard Worker   d *= d;
193*9356374aSAndroid Build Coastguard Worker   result =
194*9356374aSAndroid Build Coastguard Worker       absl::StrCat("A hundred K and a half squared is ", absl::SixDigits(d));
195*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "A hundred K and a half squared is 1.00001e+10");
196*9356374aSAndroid Build Coastguard Worker 
197*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 333, 4444, 55555, 666666, 7777777, 88888888,
198*9356374aSAndroid Build Coastguard Worker                         999999999);
199*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "12333444455555666666777777788888888999999999");
200*9356374aSAndroid Build Coastguard Worker }
201*9356374aSAndroid Build Coastguard Worker 
TEST(StrCat,CornerCases)202*9356374aSAndroid Build Coastguard Worker TEST(StrCat, CornerCases) {
203*9356374aSAndroid Build Coastguard Worker   std::string result;
204*9356374aSAndroid Build Coastguard Worker 
205*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat("");  // NOLINT
206*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "");
207*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat("", "");
208*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "");
209*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat("", "", "");
210*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "");
211*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat("", "", "", "");
212*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "");
213*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat("", "", "", "", "");
214*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "");
215*9356374aSAndroid Build Coastguard Worker }
216*9356374aSAndroid Build Coastguard Worker 
TEST(StrCat,NullConstCharPtr)217*9356374aSAndroid Build Coastguard Worker TEST(StrCat, NullConstCharPtr) {
218*9356374aSAndroid Build Coastguard Worker   const char* null = nullptr;
219*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::StrCat("mon", null, "key"), "monkey");
220*9356374aSAndroid Build Coastguard Worker }
221*9356374aSAndroid Build Coastguard Worker 
222*9356374aSAndroid Build Coastguard Worker // A minimal allocator that uses malloc().
223*9356374aSAndroid Build Coastguard Worker template <typename T>
224*9356374aSAndroid Build Coastguard Worker struct Mallocator {
225*9356374aSAndroid Build Coastguard Worker   typedef T value_type;
226*9356374aSAndroid Build Coastguard Worker   typedef size_t size_type;
227*9356374aSAndroid Build Coastguard Worker   typedef ptrdiff_t difference_type;
228*9356374aSAndroid Build Coastguard Worker   typedef T* pointer;
229*9356374aSAndroid Build Coastguard Worker   typedef const T* const_pointer;
230*9356374aSAndroid Build Coastguard Worker   typedef T& reference;
231*9356374aSAndroid Build Coastguard Worker   typedef const T& const_reference;
232*9356374aSAndroid Build Coastguard Worker 
max_size__anona7fc5ba30111::Mallocator233*9356374aSAndroid Build Coastguard Worker   size_type max_size() const {
234*9356374aSAndroid Build Coastguard Worker     return size_t(std::numeric_limits<size_type>::max()) / sizeof(value_type);
235*9356374aSAndroid Build Coastguard Worker   }
236*9356374aSAndroid Build Coastguard Worker   template <typename U>
237*9356374aSAndroid Build Coastguard Worker   struct rebind {
238*9356374aSAndroid Build Coastguard Worker     typedef Mallocator<U> other;
239*9356374aSAndroid Build Coastguard Worker   };
240*9356374aSAndroid Build Coastguard Worker   Mallocator() = default;
241*9356374aSAndroid Build Coastguard Worker   template <class U>
Mallocator__anona7fc5ba30111::Mallocator242*9356374aSAndroid Build Coastguard Worker   Mallocator(const Mallocator<U>&) {}  // NOLINT(runtime/explicit)
243*9356374aSAndroid Build Coastguard Worker 
allocate__anona7fc5ba30111::Mallocator244*9356374aSAndroid Build Coastguard Worker   T* allocate(size_t n) { return static_cast<T*>(std::malloc(n * sizeof(T))); }
deallocate__anona7fc5ba30111::Mallocator245*9356374aSAndroid Build Coastguard Worker   void deallocate(T* p, size_t) { std::free(p); }
246*9356374aSAndroid Build Coastguard Worker };
247*9356374aSAndroid Build Coastguard Worker template <typename T, typename U>
operator ==(const Mallocator<T> &,const Mallocator<U> &)248*9356374aSAndroid Build Coastguard Worker bool operator==(const Mallocator<T>&, const Mallocator<U>&) {
249*9356374aSAndroid Build Coastguard Worker   return true;
250*9356374aSAndroid Build Coastguard Worker }
251*9356374aSAndroid Build Coastguard Worker template <typename T, typename U>
operator !=(const Mallocator<T> &,const Mallocator<U> &)252*9356374aSAndroid Build Coastguard Worker bool operator!=(const Mallocator<T>&, const Mallocator<U>&) {
253*9356374aSAndroid Build Coastguard Worker   return false;
254*9356374aSAndroid Build Coastguard Worker }
255*9356374aSAndroid Build Coastguard Worker 
TEST(StrCat,CustomAllocator)256*9356374aSAndroid Build Coastguard Worker TEST(StrCat, CustomAllocator) {
257*9356374aSAndroid Build Coastguard Worker   using mstring =
258*9356374aSAndroid Build Coastguard Worker       std::basic_string<char, std::char_traits<char>, Mallocator<char>>;
259*9356374aSAndroid Build Coastguard Worker   const mstring str1("PARACHUTE OFF A BLIMP INTO MOSCONE!!");
260*9356374aSAndroid Build Coastguard Worker 
261*9356374aSAndroid Build Coastguard Worker   const mstring str2("Read this book about coffee tables");
262*9356374aSAndroid Build Coastguard Worker 
263*9356374aSAndroid Build Coastguard Worker   std::string result = absl::StrCat(str1, str2);
264*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result,
265*9356374aSAndroid Build Coastguard Worker             "PARACHUTE OFF A BLIMP INTO MOSCONE!!"
266*9356374aSAndroid Build Coastguard Worker             "Read this book about coffee tables");
267*9356374aSAndroid Build Coastguard Worker }
268*9356374aSAndroid Build Coastguard Worker 
TEST(StrCat,MaxArgs)269*9356374aSAndroid Build Coastguard Worker TEST(StrCat, MaxArgs) {
270*9356374aSAndroid Build Coastguard Worker   std::string result;
271*9356374aSAndroid Build Coastguard Worker   // Test 10 up to 26 arguments, the old maximum
272*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a");
273*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789a");
274*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b");
275*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789ab");
276*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c");
277*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abc");
278*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d");
279*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcd");
280*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e");
281*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcde");
282*9356374aSAndroid Build Coastguard Worker   result =
283*9356374aSAndroid Build Coastguard Worker       absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f");
284*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdef");
285*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
286*9356374aSAndroid Build Coastguard Worker                         "g");
287*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdefg");
288*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
289*9356374aSAndroid Build Coastguard Worker                         "g", "h");
290*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdefgh");
291*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
292*9356374aSAndroid Build Coastguard Worker                         "g", "h", "i");
293*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdefghi");
294*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
295*9356374aSAndroid Build Coastguard Worker                         "g", "h", "i", "j");
296*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdefghij");
297*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
298*9356374aSAndroid Build Coastguard Worker                         "g", "h", "i", "j", "k");
299*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdefghijk");
300*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
301*9356374aSAndroid Build Coastguard Worker                         "g", "h", "i", "j", "k", "l");
302*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdefghijkl");
303*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
304*9356374aSAndroid Build Coastguard Worker                         "g", "h", "i", "j", "k", "l", "m");
305*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdefghijklm");
306*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
307*9356374aSAndroid Build Coastguard Worker                         "g", "h", "i", "j", "k", "l", "m", "n");
308*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdefghijklmn");
309*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
310*9356374aSAndroid Build Coastguard Worker                         "g", "h", "i", "j", "k", "l", "m", "n", "o");
311*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdefghijklmno");
312*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
313*9356374aSAndroid Build Coastguard Worker                         "g", "h", "i", "j", "k", "l", "m", "n", "o", "p");
314*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdefghijklmnop");
315*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f",
316*9356374aSAndroid Build Coastguard Worker                         "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q");
317*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "123456789abcdefghijklmnopq");
318*9356374aSAndroid Build Coastguard Worker   // No limit thanks to C++11's variadic templates
319*9356374aSAndroid Build Coastguard Worker   result = absl::StrCat(
320*9356374aSAndroid Build Coastguard Worker       1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "a", "b", "c", "d", "e", "f", "g", "h",
321*9356374aSAndroid Build Coastguard Worker       "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
322*9356374aSAndroid Build Coastguard Worker       "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
323*9356374aSAndroid Build Coastguard Worker       "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z");
324*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result,
325*9356374aSAndroid Build Coastguard Worker             "12345678910abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
326*9356374aSAndroid Build Coastguard Worker }
327*9356374aSAndroid Build Coastguard Worker 
TEST(StrAppend,Basics)328*9356374aSAndroid Build Coastguard Worker TEST(StrAppend, Basics) {
329*9356374aSAndroid Build Coastguard Worker   std::string result = "existing text";
330*9356374aSAndroid Build Coastguard Worker 
331*9356374aSAndroid Build Coastguard Worker   std::string strs[] = {"Hello", "Cruel", "World"};
332*9356374aSAndroid Build Coastguard Worker 
333*9356374aSAndroid Build Coastguard Worker   std::string stdstrs[] = {
334*9356374aSAndroid Build Coastguard Worker     "std::Hello",
335*9356374aSAndroid Build Coastguard Worker     "std::Cruel",
336*9356374aSAndroid Build Coastguard Worker     "std::World"
337*9356374aSAndroid Build Coastguard Worker   };
338*9356374aSAndroid Build Coastguard Worker 
339*9356374aSAndroid Build Coastguard Worker   absl::string_view pieces[] = {"Hello", "Cruel", "World"};
340*9356374aSAndroid Build Coastguard Worker 
341*9356374aSAndroid Build Coastguard Worker   const char* c_strs[] = {
342*9356374aSAndroid Build Coastguard Worker     "Hello",
343*9356374aSAndroid Build Coastguard Worker     "Cruel",
344*9356374aSAndroid Build Coastguard Worker     "World"
345*9356374aSAndroid Build Coastguard Worker   };
346*9356374aSAndroid Build Coastguard Worker 
347*9356374aSAndroid Build Coastguard Worker   int32_t i32s[] = {'H', 'C', 'W'};
348*9356374aSAndroid Build Coastguard Worker   uint64_t ui64s[] = {12345678910LL, 10987654321LL};
349*9356374aSAndroid Build Coastguard Worker 
350*9356374aSAndroid Build Coastguard Worker   std::string::size_type old_size = result.size();
351*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result);
352*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.size(), old_size);
353*9356374aSAndroid Build Coastguard Worker 
354*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
355*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, strs[0]);
356*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size), "Hello");
357*9356374aSAndroid Build Coastguard Worker 
358*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
359*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, strs[1], pieces[2]);
360*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size), "CruelWorld");
361*9356374aSAndroid Build Coastguard Worker 
362*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
363*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, stdstrs[0], ", ", pieces[2]);
364*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size), "std::Hello, World");
365*9356374aSAndroid Build Coastguard Worker 
366*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
367*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, strs[0], ", ", stdstrs[1], " ", strs[2], "!");
368*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size), "Hello, std::Cruel World!");
369*9356374aSAndroid Build Coastguard Worker 
370*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
371*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, pieces[0], ", ", pieces[1], " ", pieces[2]);
372*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size), "Hello, Cruel World");
373*9356374aSAndroid Build Coastguard Worker 
374*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
375*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, c_strs[0], ", ", c_strs[1], " ", c_strs[2]);
376*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size), "Hello, Cruel World");
377*9356374aSAndroid Build Coastguard Worker 
378*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
379*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, "ASCII ", i32s[0], ", ", i32s[1], " ", i32s[2], "!");
380*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size), "ASCII 72, 67 87!");
381*9356374aSAndroid Build Coastguard Worker 
382*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
383*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, ui64s[0], ", ", ui64s[1], "!");
384*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size), "12345678910, 10987654321!");
385*9356374aSAndroid Build Coastguard Worker 
386*9356374aSAndroid Build Coastguard Worker   std::string one =
387*9356374aSAndroid Build Coastguard Worker       "1";  // Actually, it's the size of this string that we want; a
388*9356374aSAndroid Build Coastguard Worker             // 64-bit build distinguishes between size_t and uint64_t,
389*9356374aSAndroid Build Coastguard Worker             // even though they're both unsigned 64-bit values.
390*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
391*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, "And a ", one.size(), " and a ",
392*9356374aSAndroid Build Coastguard Worker                   &result[2] - &result[0], " and a ", one, " 2 3 4", "!");
393*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size), "And a 1 and a 2 and a 1 2 3 4!");
394*9356374aSAndroid Build Coastguard Worker 
395*9356374aSAndroid Build Coastguard Worker   // result = absl::StrCat("Single chars won't compile", '!');
396*9356374aSAndroid Build Coastguard Worker   // result = absl::StrCat("Neither will nullptrs", nullptr);
397*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
398*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result,
399*9356374aSAndroid Build Coastguard Worker                   "To output a char by ASCII/numeric value, use +: ", '!' + 0);
400*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size),
401*9356374aSAndroid Build Coastguard Worker             "To output a char by ASCII/numeric value, use +: 33");
402*9356374aSAndroid Build Coastguard Worker 
403*9356374aSAndroid Build Coastguard Worker   // Test 9 arguments, the old maximum
404*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
405*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, 1, 22, 333, 4444, 55555, 666666, 7777777, 88888888,
406*9356374aSAndroid Build Coastguard Worker                   9);
407*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size), "1223334444555556666667777777888888889");
408*9356374aSAndroid Build Coastguard Worker 
409*9356374aSAndroid Build Coastguard Worker   // No limit thanks to C++11's variadic templates
410*9356374aSAndroid Build Coastguard Worker   old_size = result.size();
411*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(
412*9356374aSAndroid Build Coastguard Worker       &result, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,                           //
413*9356374aSAndroid Build Coastguard Worker       "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",  //
414*9356374aSAndroid Build Coastguard Worker       "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",  //
415*9356374aSAndroid Build Coastguard Worker       "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",  //
416*9356374aSAndroid Build Coastguard Worker       "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",  //
417*9356374aSAndroid Build Coastguard Worker       "No limit thanks to C++11's variadic templates");
418*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.substr(old_size),
419*9356374aSAndroid Build Coastguard Worker             "12345678910abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
420*9356374aSAndroid Build Coastguard Worker             "No limit thanks to C++11's variadic templates");
421*9356374aSAndroid Build Coastguard Worker }
422*9356374aSAndroid Build Coastguard Worker 
TEST(StrCat,VectorBoolReferenceTypes)423*9356374aSAndroid Build Coastguard Worker TEST(StrCat, VectorBoolReferenceTypes) {
424*9356374aSAndroid Build Coastguard Worker   std::vector<bool> v;
425*9356374aSAndroid Build Coastguard Worker   v.push_back(true);
426*9356374aSAndroid Build Coastguard Worker   v.push_back(false);
427*9356374aSAndroid Build Coastguard Worker   std::vector<bool> const& cv = v;
428*9356374aSAndroid Build Coastguard Worker   // Test that vector<bool>::reference and vector<bool>::const_reference
429*9356374aSAndroid Build Coastguard Worker   // are handled as if the were really bool types and not the proxy types
430*9356374aSAndroid Build Coastguard Worker   // they really are.
431*9356374aSAndroid Build Coastguard Worker   std::string result = absl::StrCat(v[0], v[1], cv[0], cv[1]); // NOLINT
432*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "1010");
433*9356374aSAndroid Build Coastguard Worker }
434*9356374aSAndroid Build Coastguard Worker 
435*9356374aSAndroid Build Coastguard Worker // Passing nullptr to memcpy is undefined behavior and this test
436*9356374aSAndroid Build Coastguard Worker // provides coverage of codepaths that handle empty strings with nullptrs.
TEST(StrCat,AvoidsMemcpyWithNullptr)437*9356374aSAndroid Build Coastguard Worker TEST(StrCat, AvoidsMemcpyWithNullptr) {
438*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::StrCat(42, absl::string_view{}), "42");
439*9356374aSAndroid Build Coastguard Worker 
440*9356374aSAndroid Build Coastguard Worker   // Cover CatPieces code.
441*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::StrCat(1, 2, 3, 4, 5, absl::string_view{}), "12345");
442*9356374aSAndroid Build Coastguard Worker 
443*9356374aSAndroid Build Coastguard Worker   // Cover AppendPieces.
444*9356374aSAndroid Build Coastguard Worker   std::string result;
445*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, 1, 2, 3, 4, 5, absl::string_view{});
446*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "12345");
447*9356374aSAndroid Build Coastguard Worker }
448*9356374aSAndroid Build Coastguard Worker 
449*9356374aSAndroid Build Coastguard Worker #if GTEST_HAS_DEATH_TEST
TEST(StrAppend,Death)450*9356374aSAndroid Build Coastguard Worker TEST(StrAppend, Death) {
451*9356374aSAndroid Build Coastguard Worker   std::string s = "self";
452*9356374aSAndroid Build Coastguard Worker   // on linux it's "assertion", on mac it's "Assertion",
453*9356374aSAndroid Build Coastguard Worker   // on chromiumos it's "Assertion ... failed".
454*9356374aSAndroid Build Coastguard Worker   ABSL_EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s.c_str() + 1),
455*9356374aSAndroid Build Coastguard Worker                           "ssertion.*failed");
456*9356374aSAndroid Build Coastguard Worker   ABSL_EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s), "ssertion.*failed");
457*9356374aSAndroid Build Coastguard Worker }
458*9356374aSAndroid Build Coastguard Worker #endif  // GTEST_HAS_DEATH_TEST
459*9356374aSAndroid Build Coastguard Worker 
TEST(StrAppend,CornerCases)460*9356374aSAndroid Build Coastguard Worker TEST(StrAppend, CornerCases) {
461*9356374aSAndroid Build Coastguard Worker   std::string result;
462*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, "");
463*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "");
464*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, "", "");
465*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "");
466*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, "", "", "");
467*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "");
468*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, "", "", "", "");
469*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "");
470*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&result, "", "", "", "", "");
471*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result, "");
472*9356374aSAndroid Build Coastguard Worker }
473*9356374aSAndroid Build Coastguard Worker 
TEST(StrAppend,CornerCasesNonEmptyAppend)474*9356374aSAndroid Build Coastguard Worker TEST(StrAppend, CornerCasesNonEmptyAppend) {
475*9356374aSAndroid Build Coastguard Worker   for (std::string result : {"hello", "a string too long to fit in the SSO"}) {
476*9356374aSAndroid Build Coastguard Worker     const std::string expected = result;
477*9356374aSAndroid Build Coastguard Worker     absl::StrAppend(&result, "");
478*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(result, expected);
479*9356374aSAndroid Build Coastguard Worker     absl::StrAppend(&result, "", "");
480*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(result, expected);
481*9356374aSAndroid Build Coastguard Worker     absl::StrAppend(&result, "", "", "");
482*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(result, expected);
483*9356374aSAndroid Build Coastguard Worker     absl::StrAppend(&result, "", "", "", "");
484*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(result, expected);
485*9356374aSAndroid Build Coastguard Worker     absl::StrAppend(&result, "", "", "", "", "");
486*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(result, expected);
487*9356374aSAndroid Build Coastguard Worker   }
488*9356374aSAndroid Build Coastguard Worker }
489*9356374aSAndroid Build Coastguard Worker 
490*9356374aSAndroid Build Coastguard Worker template <typename IntType>
CheckHex(IntType v,const char * nopad_format,const char * zeropad_format,const char * spacepad_format)491*9356374aSAndroid Build Coastguard Worker void CheckHex(IntType v, const char* nopad_format, const char* zeropad_format,
492*9356374aSAndroid Build Coastguard Worker               const char* spacepad_format) {
493*9356374aSAndroid Build Coastguard Worker   char expected[256];
494*9356374aSAndroid Build Coastguard Worker 
495*9356374aSAndroid Build Coastguard Worker   std::string actual = absl::StrCat(absl::Hex(v, absl::kNoPad));
496*9356374aSAndroid Build Coastguard Worker   snprintf(expected, sizeof(expected), nopad_format, v);
497*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(expected, actual) << " decimal value " << v;
498*9356374aSAndroid Build Coastguard Worker 
499*9356374aSAndroid Build Coastguard Worker   for (int spec = absl::kZeroPad2; spec <= absl::kZeroPad20; ++spec) {
500*9356374aSAndroid Build Coastguard Worker     std::string actual =
501*9356374aSAndroid Build Coastguard Worker         absl::StrCat(absl::Hex(v, static_cast<absl::PadSpec>(spec)));
502*9356374aSAndroid Build Coastguard Worker     snprintf(expected, sizeof(expected), zeropad_format,
503*9356374aSAndroid Build Coastguard Worker              spec - absl::kZeroPad2 + 2, v);
504*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(expected, actual) << " decimal value " << v;
505*9356374aSAndroid Build Coastguard Worker   }
506*9356374aSAndroid Build Coastguard Worker 
507*9356374aSAndroid Build Coastguard Worker   for (int spec = absl::kSpacePad2; spec <= absl::kSpacePad20; ++spec) {
508*9356374aSAndroid Build Coastguard Worker     std::string actual =
509*9356374aSAndroid Build Coastguard Worker         absl::StrCat(absl::Hex(v, static_cast<absl::PadSpec>(spec)));
510*9356374aSAndroid Build Coastguard Worker     snprintf(expected, sizeof(expected), spacepad_format,
511*9356374aSAndroid Build Coastguard Worker              spec - absl::kSpacePad2 + 2, v);
512*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(expected, actual) << " decimal value " << v;
513*9356374aSAndroid Build Coastguard Worker   }
514*9356374aSAndroid Build Coastguard Worker }
515*9356374aSAndroid Build Coastguard Worker 
516*9356374aSAndroid Build Coastguard Worker template <typename IntType>
CheckDec(IntType v,const char * nopad_format,const char * zeropad_format,const char * spacepad_format)517*9356374aSAndroid Build Coastguard Worker void CheckDec(IntType v, const char* nopad_format, const char* zeropad_format,
518*9356374aSAndroid Build Coastguard Worker               const char* spacepad_format) {
519*9356374aSAndroid Build Coastguard Worker   char expected[256];
520*9356374aSAndroid Build Coastguard Worker 
521*9356374aSAndroid Build Coastguard Worker   std::string actual = absl::StrCat(absl::Dec(v, absl::kNoPad));
522*9356374aSAndroid Build Coastguard Worker   snprintf(expected, sizeof(expected), nopad_format, v);
523*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(expected, actual) << " decimal value " << v;
524*9356374aSAndroid Build Coastguard Worker 
525*9356374aSAndroid Build Coastguard Worker   for (int spec = absl::kZeroPad2; spec <= absl::kZeroPad20; ++spec) {
526*9356374aSAndroid Build Coastguard Worker     std::string actual =
527*9356374aSAndroid Build Coastguard Worker         absl::StrCat(absl::Dec(v, static_cast<absl::PadSpec>(spec)));
528*9356374aSAndroid Build Coastguard Worker     snprintf(expected, sizeof(expected), zeropad_format,
529*9356374aSAndroid Build Coastguard Worker              spec - absl::kZeroPad2 + 2, v);
530*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(expected, actual)
531*9356374aSAndroid Build Coastguard Worker         << " decimal value " << v << " format '" << zeropad_format
532*9356374aSAndroid Build Coastguard Worker         << "' digits " << (spec - absl::kZeroPad2 + 2);
533*9356374aSAndroid Build Coastguard Worker   }
534*9356374aSAndroid Build Coastguard Worker 
535*9356374aSAndroid Build Coastguard Worker   for (int spec = absl::kSpacePad2; spec <= absl::kSpacePad20; ++spec) {
536*9356374aSAndroid Build Coastguard Worker     std::string actual =
537*9356374aSAndroid Build Coastguard Worker         absl::StrCat(absl::Dec(v, static_cast<absl::PadSpec>(spec)));
538*9356374aSAndroid Build Coastguard Worker     snprintf(expected, sizeof(expected), spacepad_format,
539*9356374aSAndroid Build Coastguard Worker              spec - absl::kSpacePad2 + 2, v);
540*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(expected, actual)
541*9356374aSAndroid Build Coastguard Worker         << " decimal value " << v << " format '" << spacepad_format
542*9356374aSAndroid Build Coastguard Worker         << "' digits " << (spec - absl::kSpacePad2 + 2);
543*9356374aSAndroid Build Coastguard Worker   }
544*9356374aSAndroid Build Coastguard Worker }
545*9356374aSAndroid Build Coastguard Worker 
CheckHexDec64(uint64_t v)546*9356374aSAndroid Build Coastguard Worker void CheckHexDec64(uint64_t v) {
547*9356374aSAndroid Build Coastguard Worker   unsigned long long ullv = v;  // NOLINT(runtime/int)
548*9356374aSAndroid Build Coastguard Worker 
549*9356374aSAndroid Build Coastguard Worker   CheckHex(ullv, "%llx", "%0*llx", "%*llx");
550*9356374aSAndroid Build Coastguard Worker   CheckDec(ullv, "%llu", "%0*llu", "%*llu");
551*9356374aSAndroid Build Coastguard Worker 
552*9356374aSAndroid Build Coastguard Worker   long long llv = static_cast<long long>(ullv);  // NOLINT(runtime/int)
553*9356374aSAndroid Build Coastguard Worker   CheckDec(llv, "%lld", "%0*lld", "%*lld");
554*9356374aSAndroid Build Coastguard Worker 
555*9356374aSAndroid Build Coastguard Worker   if (sizeof(v) == sizeof(&v)) {
556*9356374aSAndroid Build Coastguard Worker     auto uintptr = static_cast<uintptr_t>(v);
557*9356374aSAndroid Build Coastguard Worker     void* ptr = reinterpret_cast<void*>(uintptr);
558*9356374aSAndroid Build Coastguard Worker     CheckHex(ptr, "%llx", "%0*llx", "%*llx");
559*9356374aSAndroid Build Coastguard Worker   }
560*9356374aSAndroid Build Coastguard Worker }
561*9356374aSAndroid Build Coastguard Worker 
CheckHexDec32(uint32_t uv)562*9356374aSAndroid Build Coastguard Worker void CheckHexDec32(uint32_t uv) {
563*9356374aSAndroid Build Coastguard Worker   CheckHex(uv, "%x", "%0*x", "%*x");
564*9356374aSAndroid Build Coastguard Worker   CheckDec(uv, "%u", "%0*u", "%*u");
565*9356374aSAndroid Build Coastguard Worker   int32_t v = static_cast<int32_t>(uv);
566*9356374aSAndroid Build Coastguard Worker   CheckDec(v, "%d", "%0*d", "%*d");
567*9356374aSAndroid Build Coastguard Worker 
568*9356374aSAndroid Build Coastguard Worker   if (sizeof(v) == sizeof(&v)) {
569*9356374aSAndroid Build Coastguard Worker     auto uintptr = static_cast<uintptr_t>(v);
570*9356374aSAndroid Build Coastguard Worker     void* ptr = reinterpret_cast<void*>(uintptr);
571*9356374aSAndroid Build Coastguard Worker     CheckHex(ptr, "%x", "%0*x", "%*x");
572*9356374aSAndroid Build Coastguard Worker   }
573*9356374aSAndroid Build Coastguard Worker }
574*9356374aSAndroid Build Coastguard Worker 
CheckAll(uint64_t v)575*9356374aSAndroid Build Coastguard Worker void CheckAll(uint64_t v) {
576*9356374aSAndroid Build Coastguard Worker   CheckHexDec64(v);
577*9356374aSAndroid Build Coastguard Worker   CheckHexDec32(static_cast<uint32_t>(v));
578*9356374aSAndroid Build Coastguard Worker }
579*9356374aSAndroid Build Coastguard Worker 
TestFastPrints()580*9356374aSAndroid Build Coastguard Worker void TestFastPrints() {
581*9356374aSAndroid Build Coastguard Worker   // Test all small ints; there aren't many and they're common.
582*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 10000; i++) {
583*9356374aSAndroid Build Coastguard Worker     CheckAll(i);
584*9356374aSAndroid Build Coastguard Worker   }
585*9356374aSAndroid Build Coastguard Worker 
586*9356374aSAndroid Build Coastguard Worker   CheckAll(std::numeric_limits<uint64_t>::max());
587*9356374aSAndroid Build Coastguard Worker   CheckAll(std::numeric_limits<uint64_t>::max() - 1);
588*9356374aSAndroid Build Coastguard Worker   CheckAll(std::numeric_limits<int64_t>::min());
589*9356374aSAndroid Build Coastguard Worker   CheckAll(std::numeric_limits<int64_t>::min() + 1);
590*9356374aSAndroid Build Coastguard Worker   CheckAll(std::numeric_limits<uint32_t>::max());
591*9356374aSAndroid Build Coastguard Worker   CheckAll(std::numeric_limits<uint32_t>::max() - 1);
592*9356374aSAndroid Build Coastguard Worker   CheckAll(std::numeric_limits<int32_t>::min());
593*9356374aSAndroid Build Coastguard Worker   CheckAll(std::numeric_limits<int32_t>::min() + 1);
594*9356374aSAndroid Build Coastguard Worker   CheckAll(999999999);              // fits in 32 bits
595*9356374aSAndroid Build Coastguard Worker   CheckAll(1000000000);             // fits in 32 bits
596*9356374aSAndroid Build Coastguard Worker   CheckAll(9999999999);             // doesn't fit in 32 bits
597*9356374aSAndroid Build Coastguard Worker   CheckAll(10000000000);            // doesn't fit in 32 bits
598*9356374aSAndroid Build Coastguard Worker   CheckAll(999999999999999999);     // fits in signed 64-bit
599*9356374aSAndroid Build Coastguard Worker   CheckAll(9999999999999999999u);   // fits in unsigned 64-bit, but not signed.
600*9356374aSAndroid Build Coastguard Worker   CheckAll(1000000000000000000);    // fits in signed 64-bit
601*9356374aSAndroid Build Coastguard Worker   CheckAll(10000000000000000000u);  // fits in unsigned 64-bit, but not signed.
602*9356374aSAndroid Build Coastguard Worker 
603*9356374aSAndroid Build Coastguard Worker   CheckAll(999999999876543210);    // check all decimal digits, signed
604*9356374aSAndroid Build Coastguard Worker   CheckAll(9999999999876543210u);  // check all decimal digits, unsigned.
605*9356374aSAndroid Build Coastguard Worker   CheckAll(0x123456789abcdef0);    // check all hex digits
606*9356374aSAndroid Build Coastguard Worker   CheckAll(0x12345678);
607*9356374aSAndroid Build Coastguard Worker 
608*9356374aSAndroid Build Coastguard Worker   int8_t minus_one_8bit = -1;
609*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("ff", absl::StrCat(absl::Hex(minus_one_8bit)));
610*9356374aSAndroid Build Coastguard Worker 
611*9356374aSAndroid Build Coastguard Worker   int16_t minus_one_16bit = -1;
612*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("ffff", absl::StrCat(absl::Hex(minus_one_16bit)));
613*9356374aSAndroid Build Coastguard Worker }
614*9356374aSAndroid Build Coastguard Worker 
TEST(Numbers,TestFunctionsMovedOverFromNumbersMain)615*9356374aSAndroid Build Coastguard Worker TEST(Numbers, TestFunctionsMovedOverFromNumbersMain) {
616*9356374aSAndroid Build Coastguard Worker   TestFastPrints();
617*9356374aSAndroid Build Coastguard Worker }
618*9356374aSAndroid Build Coastguard Worker 
619*9356374aSAndroid Build Coastguard Worker struct PointStringify {
620*9356374aSAndroid Build Coastguard Worker   template <typename FormatSink>
AbslStringify(FormatSink & sink,const PointStringify & p)621*9356374aSAndroid Build Coastguard Worker   friend void AbslStringify(FormatSink& sink, const PointStringify& p) {
622*9356374aSAndroid Build Coastguard Worker     sink.Append("(");
623*9356374aSAndroid Build Coastguard Worker     sink.Append(absl::StrCat(p.x));
624*9356374aSAndroid Build Coastguard Worker     sink.Append(", ");
625*9356374aSAndroid Build Coastguard Worker     sink.Append(absl::StrCat(p.y));
626*9356374aSAndroid Build Coastguard Worker     sink.Append(")");
627*9356374aSAndroid Build Coastguard Worker   }
628*9356374aSAndroid Build Coastguard Worker 
629*9356374aSAndroid Build Coastguard Worker   double x = 10.0;
630*9356374aSAndroid Build Coastguard Worker   double y = 20.0;
631*9356374aSAndroid Build Coastguard Worker };
632*9356374aSAndroid Build Coastguard Worker 
TEST(StrCat,AbslStringifyExample)633*9356374aSAndroid Build Coastguard Worker TEST(StrCat, AbslStringifyExample) {
634*9356374aSAndroid Build Coastguard Worker   PointStringify p;
635*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::StrCat(p), "(10, 20)");
636*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::StrCat("a ", p, " z"), "a (10, 20) z");
637*9356374aSAndroid Build Coastguard Worker }
638*9356374aSAndroid Build Coastguard Worker 
639*9356374aSAndroid Build Coastguard Worker struct PointStringifyUsingFormat {
640*9356374aSAndroid Build Coastguard Worker   template <typename FormatSink>
AbslStringify(FormatSink & sink,const PointStringifyUsingFormat & p)641*9356374aSAndroid Build Coastguard Worker   friend void AbslStringify(FormatSink& sink,
642*9356374aSAndroid Build Coastguard Worker                             const PointStringifyUsingFormat& p) {
643*9356374aSAndroid Build Coastguard Worker     absl::Format(&sink, "(%g, %g)", p.x, p.y);
644*9356374aSAndroid Build Coastguard Worker   }
645*9356374aSAndroid Build Coastguard Worker 
646*9356374aSAndroid Build Coastguard Worker   double x = 10.0;
647*9356374aSAndroid Build Coastguard Worker   double y = 20.0;
648*9356374aSAndroid Build Coastguard Worker };
649*9356374aSAndroid Build Coastguard Worker 
TEST(StrCat,AbslStringifyExampleUsingFormat)650*9356374aSAndroid Build Coastguard Worker TEST(StrCat, AbslStringifyExampleUsingFormat) {
651*9356374aSAndroid Build Coastguard Worker   PointStringifyUsingFormat p;
652*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::StrCat(p), "(10, 20)");
653*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::StrCat("a ", p, " z"), "a (10, 20) z");
654*9356374aSAndroid Build Coastguard Worker }
655*9356374aSAndroid Build Coastguard Worker 
656*9356374aSAndroid Build Coastguard Worker enum class EnumWithStringify { Many = 0, Choices = 1 };
657*9356374aSAndroid Build Coastguard Worker 
658*9356374aSAndroid Build Coastguard Worker template <typename Sink>
AbslStringify(Sink & sink,EnumWithStringify e)659*9356374aSAndroid Build Coastguard Worker void AbslStringify(Sink& sink, EnumWithStringify e) {
660*9356374aSAndroid Build Coastguard Worker   absl::Format(&sink, "%s", e == EnumWithStringify::Many ? "Many" : "Choices");
661*9356374aSAndroid Build Coastguard Worker }
662*9356374aSAndroid Build Coastguard Worker 
TEST(StrCat,AbslStringifyWithEnum)663*9356374aSAndroid Build Coastguard Worker TEST(StrCat, AbslStringifyWithEnum) {
664*9356374aSAndroid Build Coastguard Worker   const auto e = EnumWithStringify::Choices;
665*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::StrCat(e), "Choices");
666*9356374aSAndroid Build Coastguard Worker }
667*9356374aSAndroid Build Coastguard Worker 
668*9356374aSAndroid Build Coastguard Worker template <typename Integer>
CheckSingleArgumentIntegerLimits()669*9356374aSAndroid Build Coastguard Worker void CheckSingleArgumentIntegerLimits() {
670*9356374aSAndroid Build Coastguard Worker   Integer max = std::numeric_limits<Integer>::max();
671*9356374aSAndroid Build Coastguard Worker   Integer min = std::numeric_limits<Integer>::min();
672*9356374aSAndroid Build Coastguard Worker 
673*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::StrCat(max), std::to_string(max));
674*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(absl::StrCat(min), std::to_string(min));
675*9356374aSAndroid Build Coastguard Worker }
676*9356374aSAndroid Build Coastguard Worker 
TEST(StrCat,SingleArgumentLimits)677*9356374aSAndroid Build Coastguard Worker TEST(StrCat, SingleArgumentLimits) {
678*9356374aSAndroid Build Coastguard Worker   CheckSingleArgumentIntegerLimits<int32_t>();
679*9356374aSAndroid Build Coastguard Worker   CheckSingleArgumentIntegerLimits<uint32_t>();
680*9356374aSAndroid Build Coastguard Worker   CheckSingleArgumentIntegerLimits<int64_t>();
681*9356374aSAndroid Build Coastguard Worker   CheckSingleArgumentIntegerLimits<uint64_t>();
682*9356374aSAndroid Build Coastguard Worker }
683*9356374aSAndroid Build Coastguard Worker 
684*9356374aSAndroid Build Coastguard Worker }  // namespace
685