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