xref: /aosp_15_r20/external/cronet/third_party/abseil-cpp/absl/flags/flag_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 //
2 //  Copyright 2019 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #include "absl/flags/flag.h"
17 
18 #include <stddef.h>
19 #include <stdint.h>
20 
21 #include <atomic>
22 #include <string>
23 #include <thread>  // NOLINT
24 #include <vector>
25 
26 #include "gtest/gtest.h"
27 #include "absl/base/attributes.h"
28 #include "absl/base/internal/raw_logging.h"
29 #include "absl/base/macros.h"
30 #include "absl/flags/config.h"
31 #include "absl/flags/declare.h"
32 #include "absl/flags/internal/flag.h"
33 #include "absl/flags/marshalling.h"
34 #include "absl/flags/reflection.h"
35 #include "absl/flags/usage_config.h"
36 #include "absl/numeric/int128.h"
37 #include "absl/strings/match.h"
38 #include "absl/strings/numbers.h"
39 #include "absl/strings/str_cat.h"
40 #include "absl/strings/str_split.h"
41 #include "absl/strings/string_view.h"
42 #include "absl/time/clock.h"
43 #include "absl/time/time.h"
44 #include "absl/types/optional.h"
45 
46 ABSL_DECLARE_FLAG(int64_t, mistyped_int_flag);
47 ABSL_DECLARE_FLAG(std::vector<std::string>, mistyped_string_flag);
48 
49 namespace {
50 
51 namespace flags = absl::flags_internal;
52 
TestHelpMsg()53 std::string TestHelpMsg() { return "dynamic help"; }
54 #if defined(_MSC_VER) && !defined(__clang__)
TestLiteralHelpMsg()55 std::string TestLiteralHelpMsg() { return "literal help"; }
56 #endif
57 template <typename T>
TestMakeDflt(void * dst)58 void TestMakeDflt(void* dst) {
59   new (dst) T{};
60 }
TestCallback()61 void TestCallback() {}
62 
63 struct UDT {
64   UDT() = default;
65   UDT(const UDT&) = default;
66   UDT& operator=(const UDT&) = default;
67 };
AbslParseFlag(absl::string_view,UDT *,std::string *)68 bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; }
AbslUnparseFlag(const UDT &)69 std::string AbslUnparseFlag(const UDT&) { return ""; }
70 
71 class FlagTest : public testing::Test {
72  protected:
SetUpTestSuite()73   static void SetUpTestSuite() {
74     // Install a function to normalize filenames before this test is run.
75     absl::FlagsUsageConfig default_config;
76     default_config.normalize_filename = &FlagTest::NormalizeFileName;
77     absl::SetFlagsUsageConfig(default_config);
78   }
79 
80  private:
NormalizeFileName(absl::string_view fname)81   static std::string NormalizeFileName(absl::string_view fname) {
82 #ifdef _WIN32
83     std::string normalized(fname);
84     std::replace(normalized.begin(), normalized.end(), '\\', '/');
85     fname = normalized;
86 #endif
87     return std::string(fname);
88   }
89   absl::FlagSaver flag_saver_;
90 };
91 
92 struct S1 {
93   S1() = default;
94   S1(const S1&) = default;
95   int32_t f1;
96   int64_t f2;
97 };
98 
99 struct S2 {
100   S2() = default;
101   S2(const S2&) = default;
102   int64_t f1;
103   double f2;
104 };
105 
TEST_F(FlagTest,Traits)106 TEST_F(FlagTest, Traits) {
107   EXPECT_EQ(flags::StorageKind<int>(),
108             flags::FlagValueStorageKind::kValueAndInitBit);
109   EXPECT_EQ(flags::StorageKind<bool>(),
110             flags::FlagValueStorageKind::kValueAndInitBit);
111   EXPECT_EQ(flags::StorageKind<double>(),
112             flags::FlagValueStorageKind::kOneWordAtomic);
113   EXPECT_EQ(flags::StorageKind<int64_t>(),
114             flags::FlagValueStorageKind::kOneWordAtomic);
115 
116   EXPECT_EQ(flags::StorageKind<S1>(),
117             flags::FlagValueStorageKind::kSequenceLocked);
118   EXPECT_EQ(flags::StorageKind<S2>(),
119             flags::FlagValueStorageKind::kSequenceLocked);
120 // Make sure absl::Duration uses the sequence-locked code path. MSVC 2015
121 // doesn't consider absl::Duration to be trivially-copyable so we just
122 // restrict this to clang as it seems to be a well-behaved compiler.
123 #ifdef __clang__
124   EXPECT_EQ(flags::StorageKind<absl::Duration>(),
125             flags::FlagValueStorageKind::kSequenceLocked);
126 #endif
127 
128   EXPECT_EQ(flags::StorageKind<std::string>(),
129             flags::FlagValueStorageKind::kAlignedBuffer);
130   EXPECT_EQ(flags::StorageKind<std::vector<std::string>>(),
131             flags::FlagValueStorageKind::kAlignedBuffer);
132 
133   EXPECT_EQ(flags::StorageKind<absl::int128>(),
134             flags::FlagValueStorageKind::kSequenceLocked);
135   EXPECT_EQ(flags::StorageKind<absl::uint128>(),
136             flags::FlagValueStorageKind::kSequenceLocked);
137 }
138 
139 // --------------------------------------------------------------------
140 
141 constexpr flags::FlagHelpArg help_arg{flags::FlagHelpMsg("literal help"),
142                                       flags::FlagHelpKind::kLiteral};
143 
144 using String = std::string;
145 using int128 = absl::int128;
146 using uint128 = absl::uint128;
147 
148 #define DEFINE_CONSTRUCTED_FLAG(T, dflt, dflt_kind)                        \
149   constexpr flags::FlagDefaultArg f1default##T{                            \
150       flags::FlagDefaultSrc{dflt}, flags::FlagDefaultKind::dflt_kind};     \
151   constexpr absl::Flag<T> f1##T{"f1", "file", help_arg, f1default##T};     \
152   ABSL_CONST_INIT absl::Flag<T> f2##T {                                    \
153     "f2", "file",                                                          \
154         {flags::FlagHelpMsg(&TestHelpMsg), flags::FlagHelpKind::kGenFunc}, \
155         flags::FlagDefaultArg {                                            \
156       flags::FlagDefaultSrc(&TestMakeDflt<T>),                             \
157           flags::FlagDefaultKind::kGenFunc                                 \
158     }                                                                      \
159   }
160 
161 DEFINE_CONSTRUCTED_FLAG(bool, true, kOneWord);
162 DEFINE_CONSTRUCTED_FLAG(int16_t, 1, kOneWord);
163 DEFINE_CONSTRUCTED_FLAG(uint16_t, 2, kOneWord);
164 DEFINE_CONSTRUCTED_FLAG(int32_t, 3, kOneWord);
165 DEFINE_CONSTRUCTED_FLAG(uint32_t, 4, kOneWord);
166 DEFINE_CONSTRUCTED_FLAG(int64_t, 5, kOneWord);
167 DEFINE_CONSTRUCTED_FLAG(uint64_t, 6, kOneWord);
168 DEFINE_CONSTRUCTED_FLAG(float, 7.8, kOneWord);
169 DEFINE_CONSTRUCTED_FLAG(double, 9.10, kOneWord);
170 DEFINE_CONSTRUCTED_FLAG(String, &TestMakeDflt<String>, kGenFunc);
171 DEFINE_CONSTRUCTED_FLAG(UDT, &TestMakeDflt<UDT>, kGenFunc);
172 DEFINE_CONSTRUCTED_FLAG(int128, 13, kGenFunc);
173 DEFINE_CONSTRUCTED_FLAG(uint128, 14, kGenFunc);
174 
175 template <typename T>
TestConstructionFor(const absl::Flag<T> & f1,absl::Flag<T> & f2)176 bool TestConstructionFor(const absl::Flag<T>& f1, absl::Flag<T>& f2) {
177   EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Name(), "f1");
178   EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Help(), "literal help");
179   EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Filename(), "file");
180 
181   flags::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(f2), nullptr)
182       .OnUpdate(TestCallback);
183 
184   EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Name(), "f2");
185   EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Help(), "dynamic help");
186   EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Filename(), "file");
187 
188   return true;
189 }
190 
191 #define TEST_CONSTRUCTED_FLAG(T) TestConstructionFor(f1##T, f2##T);
192 
TEST_F(FlagTest,TestConstruction)193 TEST_F(FlagTest, TestConstruction) {
194   TEST_CONSTRUCTED_FLAG(bool);
195   TEST_CONSTRUCTED_FLAG(int16_t);
196   TEST_CONSTRUCTED_FLAG(uint16_t);
197   TEST_CONSTRUCTED_FLAG(int32_t);
198   TEST_CONSTRUCTED_FLAG(uint32_t);
199   TEST_CONSTRUCTED_FLAG(int64_t);
200   TEST_CONSTRUCTED_FLAG(uint64_t);
201   TEST_CONSTRUCTED_FLAG(float);
202   TEST_CONSTRUCTED_FLAG(double);
203   TEST_CONSTRUCTED_FLAG(String);
204   TEST_CONSTRUCTED_FLAG(UDT);
205   TEST_CONSTRUCTED_FLAG(int128);
206   TEST_CONSTRUCTED_FLAG(uint128);
207 }
208 
209 // --------------------------------------------------------------------
210 
211 }  // namespace
212 
213 ABSL_DECLARE_FLAG(bool, test_flag_01);
214 ABSL_DECLARE_FLAG(int, test_flag_02);
215 ABSL_DECLARE_FLAG(int16_t, test_flag_03);
216 ABSL_DECLARE_FLAG(uint16_t, test_flag_04);
217 ABSL_DECLARE_FLAG(int32_t, test_flag_05);
218 ABSL_DECLARE_FLAG(uint32_t, test_flag_06);
219 ABSL_DECLARE_FLAG(int64_t, test_flag_07);
220 ABSL_DECLARE_FLAG(uint64_t, test_flag_08);
221 ABSL_DECLARE_FLAG(double, test_flag_09);
222 ABSL_DECLARE_FLAG(float, test_flag_10);
223 ABSL_DECLARE_FLAG(std::string, test_flag_11);
224 ABSL_DECLARE_FLAG(absl::Duration, test_flag_12);
225 ABSL_DECLARE_FLAG(absl::int128, test_flag_13);
226 ABSL_DECLARE_FLAG(absl::uint128, test_flag_14);
227 
228 namespace {
229 
TEST_F(FlagTest,TestFlagDeclaration)230 TEST_F(FlagTest, TestFlagDeclaration) {
231 #if ABSL_FLAGS_STRIP_NAMES
232   GTEST_SKIP() << "This test requires flag names to be present";
233 #endif
234   // test that we can access flag objects.
235   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Name(),
236             "test_flag_01");
237   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Name(),
238             "test_flag_02");
239   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Name(),
240             "test_flag_03");
241   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Name(),
242             "test_flag_04");
243   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Name(),
244             "test_flag_05");
245   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Name(),
246             "test_flag_06");
247   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Name(),
248             "test_flag_07");
249   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Name(),
250             "test_flag_08");
251   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Name(),
252             "test_flag_09");
253   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Name(),
254             "test_flag_10");
255   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Name(),
256             "test_flag_11");
257   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Name(),
258             "test_flag_12");
259   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_13).Name(),
260             "test_flag_13");
261   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_14).Name(),
262             "test_flag_14");
263 }
264 
265 }  // namespace
266 
267 #if ABSL_FLAGS_STRIP_NAMES
268 // The intent of this helper struct and an expression below is to make sure that
269 // in the configuration where ABSL_FLAGS_STRIP_NAMES=1 registrar construction
270 // (in cases of of no Tail calls like OnUpdate) is constexpr and thus can and
271 // should be completely optimized away, thus avoiding the cost/overhead of
272 // static initializers.
273 struct VerifyConsteval {
operator +(flags::FlagRegistrarEmpty,VerifyConsteval)274   friend consteval flags::FlagRegistrarEmpty operator+(
275       flags::FlagRegistrarEmpty, VerifyConsteval) {
276     return {};
277   }
278 };
279 
280 ABSL_FLAG(int, test_registrar_const_init, 0, "") + VerifyConsteval();
281 #endif
282 
283 // --------------------------------------------------------------------
284 
285 ABSL_FLAG(bool, test_flag_01, true, "test flag 01");
286 ABSL_FLAG(int, test_flag_02, 1234, "test flag 02");
287 ABSL_FLAG(int16_t, test_flag_03, -34, "test flag 03");
288 ABSL_FLAG(uint16_t, test_flag_04, 189, "test flag 04");
289 ABSL_FLAG(int32_t, test_flag_05, 10765, "test flag 05");
290 ABSL_FLAG(uint32_t, test_flag_06, 40000, "test flag 06");
291 ABSL_FLAG(int64_t, test_flag_07, -1234567, "test flag 07");
292 ABSL_FLAG(uint64_t, test_flag_08, 9876543, "test flag 08");
293 ABSL_FLAG(double, test_flag_09, -9.876e-50, "test flag 09");
294 ABSL_FLAG(float, test_flag_10, 1.234e12f, "test flag 10");
295 ABSL_FLAG(std::string, test_flag_11, "", "test flag 11");
296 ABSL_FLAG(absl::Duration, test_flag_12, absl::Minutes(10), "test flag 12");
297 ABSL_FLAG(absl::int128, test_flag_13, absl::MakeInt128(-1, 0), "test flag 13");
298 ABSL_FLAG(absl::uint128, test_flag_14, absl::MakeUint128(0, 0xFFFAAABBBCCCDDD),
299           "test flag 14");
300 
301 namespace {
302 
TEST_F(FlagTest,TestFlagDefinition)303 TEST_F(FlagTest, TestFlagDefinition) {
304 #if ABSL_FLAGS_STRIP_NAMES
305   GTEST_SKIP() << "This test requires flag names to be present";
306 #endif
307   absl::string_view expected_file_name = "absl/flags/flag_test.cc";
308 
309   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Name(),
310             "test_flag_01");
311   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Help(),
312             "test flag 01");
313   EXPECT_TRUE(absl::EndsWith(
314       absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Filename(),
315       expected_file_name))
316       << absl::GetFlagReflectionHandle(FLAGS_test_flag_01).Filename();
317 
318   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Name(),
319             "test_flag_02");
320   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Help(),
321             "test flag 02");
322   EXPECT_TRUE(absl::EndsWith(
323       absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Filename(),
324       expected_file_name))
325       << absl::GetFlagReflectionHandle(FLAGS_test_flag_02).Filename();
326 
327   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Name(),
328             "test_flag_03");
329   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Help(),
330             "test flag 03");
331   EXPECT_TRUE(absl::EndsWith(
332       absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Filename(),
333       expected_file_name))
334       << absl::GetFlagReflectionHandle(FLAGS_test_flag_03).Filename();
335 
336   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Name(),
337             "test_flag_04");
338   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Help(),
339             "test flag 04");
340   EXPECT_TRUE(absl::EndsWith(
341       absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Filename(),
342       expected_file_name))
343       << absl::GetFlagReflectionHandle(FLAGS_test_flag_04).Filename();
344 
345   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Name(),
346             "test_flag_05");
347   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Help(),
348             "test flag 05");
349   EXPECT_TRUE(absl::EndsWith(
350       absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Filename(),
351       expected_file_name))
352       << absl::GetFlagReflectionHandle(FLAGS_test_flag_05).Filename();
353 
354   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Name(),
355             "test_flag_06");
356   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Help(),
357             "test flag 06");
358   EXPECT_TRUE(absl::EndsWith(
359       absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Filename(),
360       expected_file_name))
361       << absl::GetFlagReflectionHandle(FLAGS_test_flag_06).Filename();
362 
363   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Name(),
364             "test_flag_07");
365   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Help(),
366             "test flag 07");
367   EXPECT_TRUE(absl::EndsWith(
368       absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Filename(),
369       expected_file_name))
370       << absl::GetFlagReflectionHandle(FLAGS_test_flag_07).Filename();
371 
372   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Name(),
373             "test_flag_08");
374   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Help(),
375             "test flag 08");
376   EXPECT_TRUE(absl::EndsWith(
377       absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Filename(),
378       expected_file_name))
379       << absl::GetFlagReflectionHandle(FLAGS_test_flag_08).Filename();
380 
381   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Name(),
382             "test_flag_09");
383   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Help(),
384             "test flag 09");
385   EXPECT_TRUE(absl::EndsWith(
386       absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Filename(),
387       expected_file_name))
388       << absl::GetFlagReflectionHandle(FLAGS_test_flag_09).Filename();
389 
390   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Name(),
391             "test_flag_10");
392   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Help(),
393             "test flag 10");
394   EXPECT_TRUE(absl::EndsWith(
395       absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Filename(),
396       expected_file_name))
397       << absl::GetFlagReflectionHandle(FLAGS_test_flag_10).Filename();
398 
399   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Name(),
400             "test_flag_11");
401   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Help(),
402             "test flag 11");
403   EXPECT_TRUE(absl::EndsWith(
404       absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Filename(),
405       expected_file_name))
406       << absl::GetFlagReflectionHandle(FLAGS_test_flag_11).Filename();
407 
408   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Name(),
409             "test_flag_12");
410   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Help(),
411             "test flag 12");
412   EXPECT_TRUE(absl::EndsWith(
413       absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Filename(),
414       expected_file_name))
415       << absl::GetFlagReflectionHandle(FLAGS_test_flag_12).Filename();
416 
417   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_13).Name(),
418             "test_flag_13");
419   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_13).Help(),
420             "test flag 13");
421   EXPECT_TRUE(absl::EndsWith(
422       absl::GetFlagReflectionHandle(FLAGS_test_flag_13).Filename(),
423       expected_file_name))
424       << absl::GetFlagReflectionHandle(FLAGS_test_flag_13).Filename();
425 
426   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_14).Name(),
427             "test_flag_14");
428   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_14).Help(),
429             "test flag 14");
430   EXPECT_TRUE(absl::EndsWith(
431       absl::GetFlagReflectionHandle(FLAGS_test_flag_14).Filename(),
432       expected_file_name))
433       << absl::GetFlagReflectionHandle(FLAGS_test_flag_14).Filename();
434 }
435 
436 // --------------------------------------------------------------------
437 
TEST_F(FlagTest,TestDefault)438 TEST_F(FlagTest, TestDefault) {
439   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).DefaultValue(),
440             "true");
441   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).DefaultValue(),
442             "1234");
443   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).DefaultValue(),
444             "-34");
445   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).DefaultValue(),
446             "189");
447   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).DefaultValue(),
448             "10765");
449   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).DefaultValue(),
450             "40000");
451   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).DefaultValue(),
452             "-1234567");
453   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).DefaultValue(),
454             "9876543");
455   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).DefaultValue(),
456             "-9.876e-50");
457   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).DefaultValue(),
458             "1.234e+12");
459   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).DefaultValue(),
460             "");
461   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).DefaultValue(),
462             "10m");
463   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_13).DefaultValue(),
464             "-18446744073709551616");
465   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_14).DefaultValue(),
466             "1152827684197027293");
467 
468   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_01).CurrentValue(),
469             "true");
470   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_02).CurrentValue(),
471             "1234");
472   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_03).CurrentValue(),
473             "-34");
474   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_04).CurrentValue(),
475             "189");
476   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_05).CurrentValue(),
477             "10765");
478   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_06).CurrentValue(),
479             "40000");
480   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_07).CurrentValue(),
481             "-1234567");
482   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_08).CurrentValue(),
483             "9876543");
484   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_09).CurrentValue(),
485             "-9.876e-50");
486   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_10).CurrentValue(),
487             "1.234e+12");
488   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_11).CurrentValue(),
489             "");
490   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_12).CurrentValue(),
491             "10m");
492   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_13).CurrentValue(),
493             "-18446744073709551616");
494   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_14).CurrentValue(),
495             "1152827684197027293");
496 
497   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), true);
498   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 1234);
499   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), -34);
500   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 189);
501   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), 10765);
502   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 40000);
503   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -1234567);
504   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 9876543);
505   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), -9.876e-50, 1e-55);
506   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), 1.234e12f, 1e5f);
507   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), "");
508   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), absl::Minutes(10));
509   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_13), absl::MakeInt128(-1, 0));
510   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_14),
511             absl::MakeUint128(0, 0xFFFAAABBBCCCDDD));
512 }
513 
514 // --------------------------------------------------------------------
515 
516 struct NonTriviallyCopyableAggregate {
517   NonTriviallyCopyableAggregate() = default;
NonTriviallyCopyableAggregate__anon1056e0630311::NonTriviallyCopyableAggregate518   NonTriviallyCopyableAggregate(const NonTriviallyCopyableAggregate& rhs)
519       : value(rhs.value) {}
operator =__anon1056e0630311::NonTriviallyCopyableAggregate520   NonTriviallyCopyableAggregate& operator=(
521       const NonTriviallyCopyableAggregate& rhs) {
522     value = rhs.value;
523     return *this;
524   }
525 
526   int value;
527 };
AbslParseFlag(absl::string_view src,NonTriviallyCopyableAggregate * f,std::string * e)528 bool AbslParseFlag(absl::string_view src, NonTriviallyCopyableAggregate* f,
529                    std::string* e) {
530   return absl::ParseFlag(src, &f->value, e);
531 }
AbslUnparseFlag(const NonTriviallyCopyableAggregate & ntc)532 std::string AbslUnparseFlag(const NonTriviallyCopyableAggregate& ntc) {
533   return absl::StrCat(ntc.value);
534 }
535 
operator ==(const NonTriviallyCopyableAggregate & ntc1,const NonTriviallyCopyableAggregate & ntc2)536 bool operator==(const NonTriviallyCopyableAggregate& ntc1,
537                 const NonTriviallyCopyableAggregate& ntc2) {
538   return ntc1.value == ntc2.value;
539 }
540 
541 }  // namespace
542 
543 ABSL_FLAG(bool, test_flag_eb_01, {}, "");
544 ABSL_FLAG(int32_t, test_flag_eb_02, {}, "");
545 ABSL_FLAG(int64_t, test_flag_eb_03, {}, "");
546 ABSL_FLAG(double, test_flag_eb_04, {}, "");
547 ABSL_FLAG(std::string, test_flag_eb_05, {}, "");
548 ABSL_FLAG(NonTriviallyCopyableAggregate, test_flag_eb_06, {}, "");
549 
550 namespace {
551 
TEST_F(FlagTest,TestEmptyBracesDefault)552 TEST_F(FlagTest, TestEmptyBracesDefault) {
553   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_01).DefaultValue(),
554             "false");
555   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_02).DefaultValue(),
556             "0");
557   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_03).DefaultValue(),
558             "0");
559   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_04).DefaultValue(),
560             "0");
561   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_05).DefaultValue(),
562             "");
563   EXPECT_EQ(absl::GetFlagReflectionHandle(FLAGS_test_flag_eb_06).DefaultValue(),
564             "0");
565 
566   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_01), false);
567   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_02), 0);
568   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_03), 0);
569   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_04), 0.0);
570   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_05), "");
571   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_06),
572             NonTriviallyCopyableAggregate{});
573 }
574 
575 // --------------------------------------------------------------------
576 
TEST_F(FlagTest,TestGetSet)577 TEST_F(FlagTest, TestGetSet) {
578   absl::SetFlag(&FLAGS_test_flag_01, false);
579   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), false);
580 
581   absl::SetFlag(&FLAGS_test_flag_02, 321);
582   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 321);
583 
584   absl::SetFlag(&FLAGS_test_flag_03, 67);
585   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), 67);
586 
587   absl::SetFlag(&FLAGS_test_flag_04, 1);
588   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_04), 1);
589 
590   absl::SetFlag(&FLAGS_test_flag_05, -908);
591   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_05), -908);
592 
593   absl::SetFlag(&FLAGS_test_flag_06, 4001);
594   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_06), 4001);
595 
596   absl::SetFlag(&FLAGS_test_flag_07, -23456);
597   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_07), -23456);
598 
599   absl::SetFlag(&FLAGS_test_flag_08, 975310);
600   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_08), 975310);
601 
602   absl::SetFlag(&FLAGS_test_flag_09, 1.00001);
603   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_09), 1.00001, 1e-10);
604 
605   absl::SetFlag(&FLAGS_test_flag_10, -3.54f);
606   EXPECT_NEAR(absl::GetFlag(FLAGS_test_flag_10), -3.54f, 1e-6f);
607 
608   absl::SetFlag(&FLAGS_test_flag_11, "asdf");
609   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_11), "asdf");
610 
611   absl::SetFlag(&FLAGS_test_flag_12, absl::Seconds(110));
612   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), absl::Seconds(110));
613 
614   absl::SetFlag(&FLAGS_test_flag_13, absl::MakeInt128(-1, 0));
615   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_13), absl::MakeInt128(-1, 0));
616 
617   absl::SetFlag(&FLAGS_test_flag_14, absl::MakeUint128(0, 0xFFFAAABBBCCCDDD));
618   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_14),
619             absl::MakeUint128(0, 0xFFFAAABBBCCCDDD));
620 }
621 
622 // --------------------------------------------------------------------
623 
TEST_F(FlagTest,TestGetViaReflection)624 TEST_F(FlagTest, TestGetViaReflection) {
625 #if ABSL_FLAGS_STRIP_NAMES
626   GTEST_SKIP() << "This test requires flag names to be present";
627 #endif
628   auto* handle = absl::FindCommandLineFlag("test_flag_01");
629   EXPECT_EQ(*handle->TryGet<bool>(), true);
630   handle = absl::FindCommandLineFlag("test_flag_02");
631   EXPECT_EQ(*handle->TryGet<int>(), 1234);
632   handle = absl::FindCommandLineFlag("test_flag_03");
633   EXPECT_EQ(*handle->TryGet<int16_t>(), -34);
634   handle = absl::FindCommandLineFlag("test_flag_04");
635   EXPECT_EQ(*handle->TryGet<uint16_t>(), 189);
636   handle = absl::FindCommandLineFlag("test_flag_05");
637   EXPECT_EQ(*handle->TryGet<int32_t>(), 10765);
638   handle = absl::FindCommandLineFlag("test_flag_06");
639   EXPECT_EQ(*handle->TryGet<uint32_t>(), 40000);
640   handle = absl::FindCommandLineFlag("test_flag_07");
641   EXPECT_EQ(*handle->TryGet<int64_t>(), -1234567);
642   handle = absl::FindCommandLineFlag("test_flag_08");
643   EXPECT_EQ(*handle->TryGet<uint64_t>(), 9876543);
644   handle = absl::FindCommandLineFlag("test_flag_09");
645   EXPECT_NEAR(*handle->TryGet<double>(), -9.876e-50, 1e-55);
646   handle = absl::FindCommandLineFlag("test_flag_10");
647   EXPECT_NEAR(*handle->TryGet<float>(), 1.234e12f, 1e5f);
648   handle = absl::FindCommandLineFlag("test_flag_11");
649   EXPECT_EQ(*handle->TryGet<std::string>(), "");
650   handle = absl::FindCommandLineFlag("test_flag_12");
651   EXPECT_EQ(*handle->TryGet<absl::Duration>(), absl::Minutes(10));
652   handle = absl::FindCommandLineFlag("test_flag_13");
653   EXPECT_EQ(*handle->TryGet<absl::int128>(), absl::MakeInt128(-1, 0));
654   handle = absl::FindCommandLineFlag("test_flag_14");
655   EXPECT_EQ(*handle->TryGet<absl::uint128>(),
656             absl::MakeUint128(0, 0xFFFAAABBBCCCDDD));
657 }
658 
659 // --------------------------------------------------------------------
660 
TEST_F(FlagTest,ConcurrentSetAndGet)661 TEST_F(FlagTest, ConcurrentSetAndGet) {
662 #if ABSL_FLAGS_STRIP_NAMES
663   GTEST_SKIP() << "This test requires flag names to be present";
664 #endif
665   static constexpr int kNumThreads = 8;
666   // Two arbitrary durations. One thread will concurrently flip the flag
667   // between these two values, while the other threads read it and verify
668   // that no other value is seen.
669   static const absl::Duration kValidDurations[] = {
670       absl::Seconds(int64_t{0x6cebf47a9b68c802}) + absl::Nanoseconds(229702057),
671       absl::Seconds(int64_t{0x23fec0307e4e9d3}) + absl::Nanoseconds(44555374)};
672   absl::SetFlag(&FLAGS_test_flag_12, kValidDurations[0]);
673 
674   std::atomic<bool> stop{false};
675   std::vector<std::thread> threads;
676   auto* handle = absl::FindCommandLineFlag("test_flag_12");
677   for (int i = 0; i < kNumThreads; i++) {
678     threads.emplace_back([&]() {
679       while (!stop.load(std::memory_order_relaxed)) {
680         // Try loading the flag both directly and via a reflection
681         // handle.
682         absl::Duration v = absl::GetFlag(FLAGS_test_flag_12);
683         EXPECT_TRUE(v == kValidDurations[0] || v == kValidDurations[1]);
684         v = *handle->TryGet<absl::Duration>();
685         EXPECT_TRUE(v == kValidDurations[0] || v == kValidDurations[1]);
686       }
687     });
688   }
689   absl::Time end_time = absl::Now() + absl::Seconds(1);
690   int i = 0;
691   while (absl::Now() < end_time) {
692     absl::SetFlag(&FLAGS_test_flag_12,
693                   kValidDurations[i++ % ABSL_ARRAYSIZE(kValidDurations)]);
694   }
695   stop.store(true, std::memory_order_relaxed);
696   for (auto& t : threads) t.join();
697 }
698 
699 // --------------------------------------------------------------------
700 
GetDflt1()701 int GetDflt1() { return 1; }
702 
703 }  // namespace
704 
705 ABSL_FLAG(int, test_int_flag_with_non_const_default, GetDflt1(),
706           "test int flag non const default");
707 ABSL_FLAG(std::string, test_string_flag_with_non_const_default,
708           absl::StrCat("AAA", "BBB"), "test string flag non const default");
709 
710 namespace {
711 
TEST_F(FlagTest,TestNonConstexprDefault)712 TEST_F(FlagTest, TestNonConstexprDefault) {
713   EXPECT_EQ(absl::GetFlag(FLAGS_test_int_flag_with_non_const_default), 1);
714   EXPECT_EQ(absl::GetFlag(FLAGS_test_string_flag_with_non_const_default),
715             "AAABBB");
716 }
717 
718 // --------------------------------------------------------------------
719 
720 }  // namespace
721 
722 ABSL_FLAG(bool, test_flag_with_non_const_help, true,
723           absl::StrCat("test ", "flag ", "non const help"));
724 
725 namespace {
726 
727 #if !ABSL_FLAGS_STRIP_HELP
TEST_F(FlagTest,TestNonConstexprHelp)728 TEST_F(FlagTest, TestNonConstexprHelp) {
729   EXPECT_EQ(
730       absl::GetFlagReflectionHandle(FLAGS_test_flag_with_non_const_help).Help(),
731       "test flag non const help");
732 }
733 #endif  //! ABSL_FLAGS_STRIP_HELP
734 
735 // --------------------------------------------------------------------
736 
737 int cb_test_value = -1;
738 void TestFlagCB();
739 
740 }  // namespace
741 
742 ABSL_FLAG(int, test_flag_with_cb, 100, "").OnUpdate(TestFlagCB);
743 
__anon1056e0630802() 744 ABSL_FLAG(int, test_flag_with_lambda_cb, 200, "").OnUpdate([]() {
745   cb_test_value = absl::GetFlag(FLAGS_test_flag_with_lambda_cb) +
746                   absl::GetFlag(FLAGS_test_flag_with_cb);
747 });
748 
749 namespace {
750 
TestFlagCB()751 void TestFlagCB() { cb_test_value = absl::GetFlag(FLAGS_test_flag_with_cb); }
752 
753 // Tests side-effects of callback invocation.
TEST_F(FlagTest,CallbackInvocation)754 TEST_F(FlagTest, CallbackInvocation) {
755   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_cb), 100);
756   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_lambda_cb), 200);
757   EXPECT_EQ(cb_test_value, 300);
758 
759   absl::SetFlag(&FLAGS_test_flag_with_cb, 1);
760   EXPECT_EQ(cb_test_value, 1);
761 
762   absl::SetFlag(&FLAGS_test_flag_with_lambda_cb, 3);
763   EXPECT_EQ(cb_test_value, 4);
764 }
765 
766 // --------------------------------------------------------------------
767 
768 struct CustomUDT {
CustomUDT__anon1056e0630911::CustomUDT769   CustomUDT() : a(1), b(1) {}
CustomUDT__anon1056e0630911::CustomUDT770   CustomUDT(int a_, int b_) : a(a_), b(b_) {}
771 
operator ==(const CustomUDT & f1,const CustomUDT & f2)772   friend bool operator==(const CustomUDT& f1, const CustomUDT& f2) {
773     return f1.a == f2.a && f1.b == f2.b;
774   }
775 
776   int a;
777   int b;
778 };
AbslParseFlag(absl::string_view in,CustomUDT * f,std::string *)779 bool AbslParseFlag(absl::string_view in, CustomUDT* f, std::string*) {
780   std::vector<absl::string_view> parts =
781       absl::StrSplit(in, ':', absl::SkipWhitespace());
782 
783   if (parts.size() != 2) return false;
784 
785   if (!absl::SimpleAtoi(parts[0], &f->a)) return false;
786 
787   if (!absl::SimpleAtoi(parts[1], &f->b)) return false;
788 
789   return true;
790 }
AbslUnparseFlag(const CustomUDT & f)791 std::string AbslUnparseFlag(const CustomUDT& f) {
792   return absl::StrCat(f.a, ":", f.b);
793 }
794 
795 }  // namespace
796 
797 ABSL_FLAG(CustomUDT, test_flag_custom_udt, CustomUDT(), "test flag custom UDT");
798 
799 namespace {
800 
TEST_F(FlagTest,TestCustomUDT)801 TEST_F(FlagTest, TestCustomUDT) {
802   EXPECT_EQ(flags::StorageKind<CustomUDT>(),
803             flags::FlagValueStorageKind::kOneWordAtomic);
804   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_custom_udt), CustomUDT(1, 1));
805   absl::SetFlag(&FLAGS_test_flag_custom_udt, CustomUDT(2, 3));
806   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_custom_udt), CustomUDT(2, 3));
807 }
808 
809 // MSVC produces link error on the type mismatch.
810 // Linux does not have build errors and validations work as expected.
811 #if !defined(_WIN32) && GTEST_HAS_DEATH_TEST
812 using FlagDeathTest = FlagTest;
813 
TEST_F(FlagDeathTest,TestTypeMismatchValidations)814 TEST_F(FlagDeathTest, TestTypeMismatchValidations) {
815 #if ABSL_FLAGS_STRIP_NAMES
816   GTEST_SKIP() << "This test requires flag names to be present";
817 #endif
818 #if !defined(NDEBUG)
819   EXPECT_DEATH_IF_SUPPORTED(
820       static_cast<void>(absl::GetFlag(FLAGS_mistyped_int_flag)),
821       "Flag 'mistyped_int_flag' is defined as one type and declared "
822       "as another");
823   EXPECT_DEATH_IF_SUPPORTED(
824       static_cast<void>(absl::GetFlag(FLAGS_mistyped_string_flag)),
825       "Flag 'mistyped_string_flag' is defined as one type and "
826       "declared as another");
827 #endif
828 
829   EXPECT_DEATH_IF_SUPPORTED(
830       absl::SetFlag(&FLAGS_mistyped_int_flag, 1),
831       "Flag 'mistyped_int_flag' is defined as one type and declared "
832       "as another");
833   EXPECT_DEATH_IF_SUPPORTED(
834       absl::SetFlag(&FLAGS_mistyped_string_flag, std::vector<std::string>{}),
835       "Flag 'mistyped_string_flag' is defined as one type and declared as "
836       "another");
837 }
838 
839 #endif
840 
841 // --------------------------------------------------------------------
842 
843 // A contrived type that offers implicit and explicit conversion from specific
844 // source types.
845 struct ConversionTestVal {
846   ConversionTestVal() = default;
ConversionTestVal__anon1056e0630a11::ConversionTestVal847   explicit ConversionTestVal(int a_in) : a(a_in) {}
848 
849   enum class ViaImplicitConv { kTen = 10, kEleven };
850   // NOLINTNEXTLINE
ConversionTestVal__anon1056e0630a11::ConversionTestVal851   ConversionTestVal(ViaImplicitConv from) : a(static_cast<int>(from)) {}
852 
853   int a;
854 };
855 
AbslParseFlag(absl::string_view in,ConversionTestVal * val_out,std::string *)856 bool AbslParseFlag(absl::string_view in, ConversionTestVal* val_out,
857                    std::string*) {
858   if (!absl::SimpleAtoi(in, &val_out->a)) {
859     return false;
860   }
861   return true;
862 }
AbslUnparseFlag(const ConversionTestVal & val)863 std::string AbslUnparseFlag(const ConversionTestVal& val) {
864   return absl::StrCat(val.a);
865 }
866 
867 }  // namespace
868 
869 // Flag default values can be specified with a value that converts to the flag
870 // value type implicitly.
871 ABSL_FLAG(ConversionTestVal, test_flag_implicit_conv,
872           ConversionTestVal::ViaImplicitConv::kTen,
873           "test flag init via implicit conversion");
874 
875 namespace {
876 
TEST_F(FlagTest,CanSetViaImplicitConversion)877 TEST_F(FlagTest, CanSetViaImplicitConversion) {
878   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_implicit_conv).a, 10);
879   absl::SetFlag(&FLAGS_test_flag_implicit_conv,
880                 ConversionTestVal::ViaImplicitConv::kEleven);
881   EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_implicit_conv).a, 11);
882 }
883 
884 // --------------------------------------------------------------------
885 
886 struct NonDfltConstructible {
887  public:
888   // This constructor tests that we can initialize the flag with int value
NonDfltConstructible__anon1056e0630b11::NonDfltConstructible889   NonDfltConstructible(int i) : value(i) {}  // NOLINT
890 
891   // This constructor tests that we can't initialize the flag with char value
892   // but can with explicitly constructed NonDfltConstructible.
NonDfltConstructible__anon1056e0630b11::NonDfltConstructible893   explicit NonDfltConstructible(char c) : value(100 + static_cast<int>(c)) {}
894 
895   int value;
896 };
897 
AbslParseFlag(absl::string_view in,NonDfltConstructible * ndc_out,std::string *)898 bool AbslParseFlag(absl::string_view in, NonDfltConstructible* ndc_out,
899                    std::string*) {
900   return absl::SimpleAtoi(in, &ndc_out->value);
901 }
AbslUnparseFlag(const NonDfltConstructible & ndc)902 std::string AbslUnparseFlag(const NonDfltConstructible& ndc) {
903   return absl::StrCat(ndc.value);
904 }
905 
906 }  // namespace
907 
908 ABSL_FLAG(NonDfltConstructible, ndc_flag1, NonDfltConstructible('1'),
909           "Flag with non default constructible type");
910 ABSL_FLAG(NonDfltConstructible, ndc_flag2, 0,
911           "Flag with non default constructible type");
912 
913 namespace {
914 
TEST_F(FlagTest,TestNonDefaultConstructibleType)915 TEST_F(FlagTest, TestNonDefaultConstructibleType) {
916   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, '1' + 100);
917   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 0);
918 
919   absl::SetFlag(&FLAGS_ndc_flag1, NonDfltConstructible('A'));
920   absl::SetFlag(&FLAGS_ndc_flag2, 25);
921 
922   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, 'A' + 100);
923   EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 25);
924 }
925 
926 }  // namespace
927 
928 // --------------------------------------------------------------------
929 
930 ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old descr");
931 ABSL_RETIRED_FLAG(int, old_int_flag, (int)std::sqrt(10), "old descr");
932 ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr"));
933 
934 namespace {
935 
__anon1056e0630e02null936 bool initialization_order_fiasco_test ABSL_ATTRIBUTE_UNUSED = [] {
937   // Iterate over all the flags during static initialization.
938   // This should not trigger ASan's initialization-order-fiasco.
939   auto* handle1 = absl::FindCommandLineFlag("flag_on_separate_file");
940   auto* handle2 = absl::FindCommandLineFlag("retired_flag_on_separate_file");
941   if (handle1 != nullptr && handle2 != nullptr) {
942     return handle1->Name() == handle2->Name();
943   }
944   return true;
945 }();
946 
TEST_F(FlagTest,TestRetiredFlagRegistration)947 TEST_F(FlagTest, TestRetiredFlagRegistration) {
948   auto* handle = absl::FindCommandLineFlag("old_bool_flag");
949   EXPECT_TRUE(handle->IsOfType<bool>());
950   EXPECT_TRUE(handle->IsRetired());
951   handle = absl::FindCommandLineFlag("old_int_flag");
952   EXPECT_TRUE(handle->IsOfType<int>());
953   EXPECT_TRUE(handle->IsRetired());
954   handle = absl::FindCommandLineFlag("old_str_flag");
955   EXPECT_TRUE(handle->IsOfType<std::string>());
956   EXPECT_TRUE(handle->IsRetired());
957 }
958 
959 }  // namespace
960 
961 // --------------------------------------------------------------------
962 
963 namespace {
964 
965 // User-defined type with small alignment, but size exceeding 16.
966 struct SmallAlignUDT {
SmallAlignUDT__anon1056e0630f11::SmallAlignUDT967   SmallAlignUDT() : c('A'), s(12) {}
968   char c;
969   int16_t s;
970   char bytes[14];
971 };
972 
AbslParseFlag(absl::string_view,SmallAlignUDT *,std::string *)973 bool AbslParseFlag(absl::string_view, SmallAlignUDT*, std::string*) {
974   return true;
975 }
AbslUnparseFlag(const SmallAlignUDT &)976 std::string AbslUnparseFlag(const SmallAlignUDT&) { return ""; }
977 
978 // User-defined type with small size, but not trivially copyable.
979 struct NonTriviallyCopyableUDT {
NonTriviallyCopyableUDT__anon1056e0630f11::NonTriviallyCopyableUDT980   NonTriviallyCopyableUDT() : c('A') {}
NonTriviallyCopyableUDT__anon1056e0630f11::NonTriviallyCopyableUDT981   NonTriviallyCopyableUDT(const NonTriviallyCopyableUDT& rhs) : c(rhs.c) {}
operator =__anon1056e0630f11::NonTriviallyCopyableUDT982   NonTriviallyCopyableUDT& operator=(const NonTriviallyCopyableUDT& rhs) {
983     c = rhs.c;
984     return *this;
985   }
986 
987   char c;
988 };
989 
AbslParseFlag(absl::string_view,NonTriviallyCopyableUDT *,std::string *)990 bool AbslParseFlag(absl::string_view, NonTriviallyCopyableUDT*, std::string*) {
991   return true;
992 }
AbslUnparseFlag(const NonTriviallyCopyableUDT &)993 std::string AbslUnparseFlag(const NonTriviallyCopyableUDT&) { return ""; }
994 
995 }  // namespace
996 
997 ABSL_FLAG(SmallAlignUDT, test_flag_sa_udt, {}, "help");
998 ABSL_FLAG(NonTriviallyCopyableUDT, test_flag_ntc_udt, {}, "help");
999 
1000 namespace {
1001 
TEST_F(FlagTest,TestSmallAlignUDT)1002 TEST_F(FlagTest, TestSmallAlignUDT) {
1003   SmallAlignUDT value = absl::GetFlag(FLAGS_test_flag_sa_udt);
1004   EXPECT_EQ(value.c, 'A');
1005   EXPECT_EQ(value.s, 12);
1006 
1007   value.c = 'B';
1008   value.s = 45;
1009   absl::SetFlag(&FLAGS_test_flag_sa_udt, value);
1010   value = absl::GetFlag(FLAGS_test_flag_sa_udt);
1011   EXPECT_EQ(value.c, 'B');
1012   EXPECT_EQ(value.s, 45);
1013 }
1014 
TEST_F(FlagTest,TestNonTriviallyCopyableUDT)1015 TEST_F(FlagTest, TestNonTriviallyCopyableUDT) {
1016   NonTriviallyCopyableUDT value = absl::GetFlag(FLAGS_test_flag_ntc_udt);
1017   EXPECT_EQ(value.c, 'A');
1018 
1019   value.c = 'B';
1020   absl::SetFlag(&FLAGS_test_flag_ntc_udt, value);
1021   value = absl::GetFlag(FLAGS_test_flag_ntc_udt);
1022   EXPECT_EQ(value.c, 'B');
1023 }
1024 
1025 }  // namespace
1026 
1027 // --------------------------------------------------------------------
1028 
1029 namespace {
1030 
1031 enum TestE { A = 1, B = 2, C = 3 };
1032 
1033 struct EnumWrapper {
EnumWrapper__anon1056e0631111::EnumWrapper1034   EnumWrapper() : e(A) {}
1035 
1036   TestE e;
1037 };
1038 
AbslParseFlag(absl::string_view,EnumWrapper *,std::string *)1039 bool AbslParseFlag(absl::string_view, EnumWrapper*, std::string*) {
1040   return true;
1041 }
AbslUnparseFlag(const EnumWrapper &)1042 std::string AbslUnparseFlag(const EnumWrapper&) { return ""; }
1043 
1044 }  // namespace
1045 
1046 ABSL_FLAG(EnumWrapper, test_enum_wrapper_flag, {}, "help");
1047 
TEST_F(FlagTest,TesTypeWrappingEnum)1048 TEST_F(FlagTest, TesTypeWrappingEnum) {
1049   EnumWrapper value = absl::GetFlag(FLAGS_test_enum_wrapper_flag);
1050   EXPECT_EQ(value.e, A);
1051 
1052   value.e = B;
1053   absl::SetFlag(&FLAGS_test_enum_wrapper_flag, value);
1054   value = absl::GetFlag(FLAGS_test_enum_wrapper_flag);
1055   EXPECT_EQ(value.e, B);
1056 }
1057 
1058 // This is a compile test to ensure macros are expanded within ABSL_FLAG and
1059 // ABSL_DECLARE_FLAG.
1060 #define FLAG_NAME_MACRO(name) prefix_##name
1061 ABSL_DECLARE_FLAG(int, FLAG_NAME_MACRO(test_macro_named_flag));
1062 ABSL_FLAG(int, FLAG_NAME_MACRO(test_macro_named_flag), 0,
1063           "Testing macro expansion within ABSL_FLAG");
1064 
TEST_F(FlagTest,MacroWithinAbslFlag)1065 TEST_F(FlagTest, MacroWithinAbslFlag) {
1066   EXPECT_EQ(absl::GetFlag(FLAGS_prefix_test_macro_named_flag), 0);
1067   absl::SetFlag(&FLAGS_prefix_test_macro_named_flag, 1);
1068   EXPECT_EQ(absl::GetFlag(FLAGS_prefix_test_macro_named_flag), 1);
1069 }
1070 
1071 // --------------------------------------------------------------------
1072 
1073 ABSL_FLAG(absl::optional<bool>, optional_bool, absl::nullopt, "help");
1074 ABSL_FLAG(absl::optional<int>, optional_int, {}, "help");
1075 ABSL_FLAG(absl::optional<double>, optional_double, 9.3, "help");
1076 ABSL_FLAG(absl::optional<std::string>, optional_string, absl::nullopt, "help");
1077 ABSL_FLAG(absl::optional<absl::Duration>, optional_duration, absl::nullopt,
1078           "help");
1079 ABSL_FLAG(absl::optional<absl::optional<int>>, optional_optional_int,
1080           absl::nullopt, "help");
1081 #if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL)
1082 ABSL_FLAG(std::optional<int64_t>, std_optional_int64, std::nullopt, "help");
1083 #endif
1084 
1085 namespace {
1086 
TEST_F(FlagTest,TestOptionalBool)1087 TEST_F(FlagTest, TestOptionalBool) {
1088   EXPECT_FALSE(absl::GetFlag(FLAGS_optional_bool).has_value());
1089   EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), absl::nullopt);
1090 
1091   absl::SetFlag(&FLAGS_optional_bool, false);
1092   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_bool).has_value());
1093   EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), false);
1094 
1095   absl::SetFlag(&FLAGS_optional_bool, true);
1096   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_bool).has_value());
1097   EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), true);
1098 
1099   absl::SetFlag(&FLAGS_optional_bool, absl::nullopt);
1100   EXPECT_FALSE(absl::GetFlag(FLAGS_optional_bool).has_value());
1101   EXPECT_EQ(absl::GetFlag(FLAGS_optional_bool), absl::nullopt);
1102 }
1103 
1104 // --------------------------------------------------------------------
1105 
TEST_F(FlagTest,TestOptionalInt)1106 TEST_F(FlagTest, TestOptionalInt) {
1107   EXPECT_FALSE(absl::GetFlag(FLAGS_optional_int).has_value());
1108   EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), absl::nullopt);
1109 
1110   absl::SetFlag(&FLAGS_optional_int, 0);
1111   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_int).has_value());
1112   EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), 0);
1113 
1114   absl::SetFlag(&FLAGS_optional_int, 10);
1115   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_int).has_value());
1116   EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), 10);
1117 
1118   absl::SetFlag(&FLAGS_optional_int, absl::nullopt);
1119   EXPECT_FALSE(absl::GetFlag(FLAGS_optional_int).has_value());
1120   EXPECT_EQ(absl::GetFlag(FLAGS_optional_int), absl::nullopt);
1121 }
1122 
1123 // --------------------------------------------------------------------
1124 
TEST_F(FlagTest,TestOptionalDouble)1125 TEST_F(FlagTest, TestOptionalDouble) {
1126   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_double).has_value());
1127   EXPECT_DOUBLE_EQ(*absl::GetFlag(FLAGS_optional_double), 9.3);
1128 
1129   absl::SetFlag(&FLAGS_optional_double, 0.0);
1130   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_double).has_value());
1131   EXPECT_EQ(absl::GetFlag(FLAGS_optional_double), 0.0);
1132 
1133   absl::SetFlag(&FLAGS_optional_double, 1.234);
1134   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_double).has_value());
1135   EXPECT_DOUBLE_EQ(*absl::GetFlag(FLAGS_optional_double), 1.234);
1136 
1137   absl::SetFlag(&FLAGS_optional_double, absl::nullopt);
1138   EXPECT_FALSE(absl::GetFlag(FLAGS_optional_double).has_value());
1139   EXPECT_EQ(absl::GetFlag(FLAGS_optional_double), absl::nullopt);
1140 }
1141 
1142 // --------------------------------------------------------------------
1143 
TEST_F(FlagTest,TestOptionalString)1144 TEST_F(FlagTest, TestOptionalString) {
1145   EXPECT_FALSE(absl::GetFlag(FLAGS_optional_string).has_value());
1146   EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), absl::nullopt);
1147 
1148   // Setting optional string to "" leads to undefined behavior.
1149 
1150   absl::SetFlag(&FLAGS_optional_string, " ");
1151   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_string).has_value());
1152   EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), " ");
1153 
1154   absl::SetFlag(&FLAGS_optional_string, "QWERTY");
1155   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_string).has_value());
1156   EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), "QWERTY");
1157 
1158   absl::SetFlag(&FLAGS_optional_string, absl::nullopt);
1159   EXPECT_FALSE(absl::GetFlag(FLAGS_optional_string).has_value());
1160   EXPECT_EQ(absl::GetFlag(FLAGS_optional_string), absl::nullopt);
1161 }
1162 
1163 // --------------------------------------------------------------------
1164 
TEST_F(FlagTest,TestOptionalDuration)1165 TEST_F(FlagTest, TestOptionalDuration) {
1166   EXPECT_FALSE(absl::GetFlag(FLAGS_optional_duration).has_value());
1167   EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::nullopt);
1168 
1169   absl::SetFlag(&FLAGS_optional_duration, absl::ZeroDuration());
1170   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_duration).has_value());
1171   EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::Seconds(0));
1172 
1173   absl::SetFlag(&FLAGS_optional_duration, absl::Hours(3));
1174   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_duration).has_value());
1175   EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::Hours(3));
1176 
1177   absl::SetFlag(&FLAGS_optional_duration, absl::nullopt);
1178   EXPECT_FALSE(absl::GetFlag(FLAGS_optional_duration).has_value());
1179   EXPECT_EQ(absl::GetFlag(FLAGS_optional_duration), absl::nullopt);
1180 }
1181 
1182 // --------------------------------------------------------------------
1183 
TEST_F(FlagTest,TestOptionalOptional)1184 TEST_F(FlagTest, TestOptionalOptional) {
1185   EXPECT_FALSE(absl::GetFlag(FLAGS_optional_optional_int).has_value());
1186   EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), absl::nullopt);
1187 
1188   absl::optional<int> nullint{absl::nullopt};
1189 
1190   absl::SetFlag(&FLAGS_optional_optional_int, nullint);
1191   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_optional_int).has_value());
1192   EXPECT_NE(absl::GetFlag(FLAGS_optional_optional_int), nullint);
1193   EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int),
1194             absl::optional<absl::optional<int>>{nullint});
1195 
1196   absl::SetFlag(&FLAGS_optional_optional_int, 0);
1197   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_optional_int).has_value());
1198   EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), 0);
1199 
1200   absl::SetFlag(&FLAGS_optional_optional_int, absl::optional<int>{0});
1201   EXPECT_TRUE(absl::GetFlag(FLAGS_optional_optional_int).has_value());
1202   EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), 0);
1203   EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), absl::optional<int>{0});
1204 
1205   absl::SetFlag(&FLAGS_optional_optional_int, absl::nullopt);
1206   EXPECT_FALSE(absl::GetFlag(FLAGS_optional_optional_int).has_value());
1207   EXPECT_EQ(absl::GetFlag(FLAGS_optional_optional_int), absl::nullopt);
1208 }
1209 
1210 // --------------------------------------------------------------------
1211 
1212 #if defined(ABSL_HAVE_STD_OPTIONAL) && !defined(ABSL_USES_STD_OPTIONAL)
1213 
TEST_F(FlagTest,TestStdOptional)1214 TEST_F(FlagTest, TestStdOptional) {
1215   EXPECT_FALSE(absl::GetFlag(FLAGS_std_optional_int64).has_value());
1216   EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), std::nullopt);
1217 
1218   absl::SetFlag(&FLAGS_std_optional_int64, 0);
1219   EXPECT_TRUE(absl::GetFlag(FLAGS_std_optional_int64).has_value());
1220   EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), 0);
1221 
1222   absl::SetFlag(&FLAGS_std_optional_int64, 0xFFFFFFFFFF16);
1223   EXPECT_TRUE(absl::GetFlag(FLAGS_std_optional_int64).has_value());
1224   EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), 0xFFFFFFFFFF16);
1225 
1226   absl::SetFlag(&FLAGS_std_optional_int64, std::nullopt);
1227   EXPECT_FALSE(absl::GetFlag(FLAGS_std_optional_int64).has_value());
1228   EXPECT_EQ(absl::GetFlag(FLAGS_std_optional_int64), std::nullopt);
1229 }
1230 
1231 // --------------------------------------------------------------------
1232 
1233 #endif
1234 
1235 }  // namespace
1236