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