abseil-cpp/absl/flags/flag_test.cc
Go to the documentation of this file.
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 
51 std::string TestHelpMsg() { return "dynamic help"; }
52 #if defined(_MSC_VER) && !defined(__clang__)
53 std::string TestLiteralHelpMsg() { return "literal help"; }
54 #endif
55 template <typename T>
56 void TestMakeDflt(void* dst) {
57  new (dst) T{};
58 }
59 void TestCallback() {}
60 
61 struct UDT {
62  UDT() = default;
63  UDT(const UDT&) = default;
64  UDT& operator=(const UDT&) = default;
65 };
66 bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; }
67 std::string AbslUnparseFlag(const UDT&) { return ""; }
68 
69 class FlagTest : public testing::Test {
70  protected:
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:
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 
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>
176 bool TestConstructionFor(const absl::Flag<T>& f1, absl::Flag<T>& f2) {
178  EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Help(), "literal help");
180 
182  .OnUpdate(TestCallback);
183 
185  EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Help(), "dynamic help");
187 
188  return true;
189 }
190 
191 #define TEST_CONSTRUCTED_FLAG(T) TestConstructionFor(f1##T, f2##T);
192 
193 TEST_F(FlagTest, TestConstruction) {
194  TEST_CONSTRUCTED_FLAG(bool);
201  TEST_CONSTRUCTED_FLAG(float);
202  TEST_CONSTRUCTED_FLAG(double);
203  TEST_CONSTRUCTED_FLAG(String);
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 
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
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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 
392 TEST_F(FlagTest, TestDefault) {
394  "true");
396  "1234");
398  "-34");
400  "189");
402  "10765");
404  "40000");
406  "-1234567");
408  "9876543");
410  "-9.876e-50");
412  "1.234e+12");
414  "");
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;
461  NonTriviallyCopyableAggregate(const NonTriviallyCopyableAggregate& rhs)
462  : value(rhs.value) {}
463  NonTriviallyCopyableAggregate& operator=(
464  const NonTriviallyCopyableAggregate& rhs) {
465  value = rhs.value;
466  return *this;
467  }
468 
469  int value;
470 };
471 bool AbslParseFlag(absl::string_view src, NonTriviallyCopyableAggregate* f,
472  std::string* e) {
473  return absl::ParseFlag(src, &f->value, e);
474 }
475 std::string AbslUnparseFlag(const NonTriviallyCopyableAggregate& ntc) {
476  return absl::StrCat(ntc.value);
477 }
478 
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 
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 
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 
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 
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  }
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 
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 
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
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
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 
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 
676 void TestFlagCB() { cb_test_value = absl::GetFlag(FLAGS_test_flag_with_cb); }
677 
678 // Tests side-effects of callback invocation.
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 {
694  CustomUDT() : a(1), b(1) {}
695  CustomUDT(int a_, int b_) : a(a_), b(b_) {}
696 
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 };
704 bool AbslParseFlag(absl::string_view in, CustomUDT* f, std::string*) {
705  std::vector<absl::string_view> parts =
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 }
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 
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 
740 TEST_F(FlagDeathTest, TestTypeMismatchValidations) {
741 #if !defined(NDEBUG)
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");
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 
753  absl::SetFlag(&FLAGS_mistyped_int_flag, 1),
754  "Flag 'mistyped_int_flag' is defined as one type and declared "
755  "as another");
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;
770  explicit ConversionTestVal(int a_in) : a(a_in) {}
771 
772  enum class ViaImplicitConv { kTen = 10, kEleven };
773  // NOLINTNEXTLINE
774  ConversionTestVal(ViaImplicitConv from) : a(static_cast<int>(from)) {}
775 
776  int a;
777 };
778 
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 }
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 
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
812  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.
816  explicit NonDfltConstructible(char c) : value(100 + static_cast<int>(c)) {}
817 
818  int value;
819 };
820 
821 bool AbslParseFlag(absl::string_view in, NonDfltConstructible* ndc_out,
822  std::string*) {
823  return absl::SimpleAtoi(in, &ndc_out->value);
824 }
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 
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 
859 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 
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 {
890  SmallAlignUDT() : c('A'), s(12) {}
891  char c;
892  int16_t s;
893  char bytes[14];
894 };
895 
896 bool AbslParseFlag(absl::string_view, SmallAlignUDT*, std::string*) {
897  return true;
898 }
899 std::string AbslUnparseFlag(const SmallAlignUDT&) { return ""; }
900 
901 // User-defined type with small size, but not trivially copyable.
902 struct NonTriviallyCopyableUDT {
903  NonTriviallyCopyableUDT() : c('A') {}
904  NonTriviallyCopyableUDT(const NonTriviallyCopyableUDT& rhs) : c(rhs.c) {}
905  NonTriviallyCopyableUDT& operator=(const NonTriviallyCopyableUDT& rhs) {
906  c = rhs.c;
907  return *this;
908  }
909 
910  char c;
911 };
912 
913 bool AbslParseFlag(absl::string_view, NonTriviallyCopyableUDT*, std::string*) {
914  return true;
915 }
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 
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 
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 {
957  EnumWrapper() : e(A) {}
958 
959  TestE e;
960 };
961 
962 bool AbslParseFlag(absl::string_view, EnumWrapper*, std::string*) {
963  return true;
964 }
965 std::string AbslUnparseFlag(const EnumWrapper&) { return ""; }
966 
967 } // namespace
968 
969 ABSL_FLAG(EnumWrapper, test_enum_wrapper_flag, {}, "help");
970 
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 
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
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 
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 
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 
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 
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 
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),
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 
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
absl::StrSplit
strings_internal::Splitter< typename strings_internal::SelectDelimiter< Delimiter >::type, AllowEmpty, absl::string_view > StrSplit(strings_internal::ConvertibleToStringView text, Delimiter d)
Definition: abseil-cpp/absl/strings/str_split.h:499
absl::GetFlagReflectionHandle
const CommandLineFlag & GetFlagReflectionHandle(const absl::Flag< T > &f)
Definition: abseil-cpp/absl/flags/flag.h:134
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
UDT::operator=
UDT & operator=(const UDT &)=default
dst
static const char dst[]
Definition: test-fs-copyfile.c:37
absl::SetFlag
void SetFlag(absl::Flag< T > *flag, const T &v)
Definition: abseil-cpp/absl/flags/flag.h:110
absl::ParseFlag
ABSL_NAMESPACE_BEGIN bool ParseFlag(absl::string_view input, T *dst, std::string *error)
Definition: abseil-cpp/absl/flags/marshalling.h:328
DEFINE_CONSTRUCTED_FLAG
#define DEFINE_CONSTRUCTED_FLAG(T, dflt, dflt_kind)
Definition: abseil-cpp/absl/flags/flag_test.cc:140
Filename
static std::string Filename(const protobuf::FileDescriptor *file)
Definition: upbc.cc:53
grpc_event_engine::experimental::slice_detail::operator==
bool operator==(const BaseSlice &a, const BaseSlice &b)
Definition: include/grpc/event_engine/slice.h:117
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
absl::ZeroDuration
constexpr Duration ZeroDuration()
Definition: third_party/abseil-cpp/absl/time/time.h:308
absl::Time
Definition: third_party/abseil-cpp/absl/time/time.h:642
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
C
#define C(x)
Definition: abseil-cpp/absl/hash/internal/city_test.cc:49
xds_manager.f1
f1
Definition: xds_manager.py:42
ABSL_ATTRIBUTE_UNUSED
#define ABSL_ATTRIBUTE_UNUSED
Definition: abseil-cpp/absl/base/attributes.h:550
absl::Nanoseconds
constexpr Duration Nanoseconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:407
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
testing::Test::SetUpTestSuite
static void SetUpTestSuite()
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:417
absl::flags_internal::FlagHelpArg
Definition: abseil-cpp/absl/flags/internal/flag.h:213
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
end_time
static int64_t end_time
Definition: benchmark-getaddrinfo.c:38
absl::FindCommandLineFlag
CommandLineFlag * FindCommandLineFlag(absl::string_view name)
Definition: abseil-cpp/absl/flags/reflection.cc:336
absl::FormatConversionChar::s
@ s
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
absl::FlagsUsageConfig::normalize_filename
std::function< std::string(absl::string_view)> normalize_filename
Definition: abseil-cpp/absl/flags/usage_config.h:106
ABSL_ARRAYSIZE
#define ABSL_ARRAYSIZE(array)
Definition: abseil-cpp/absl/base/macros.h:44
FLAG_NAME_MACRO
#define FLAG_NAME_MACRO(name)
Definition: abseil-cpp/absl/flags/flag_test.cc:983
T
#define T(upbtypeconst, upbtype, ctype, default_value)
threads
static uv_thread_t * threads
Definition: threadpool.c:38
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
ABSL_RETIRED_FLAG
ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old descr")
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
from
size_t from
Definition: abseil-cpp/absl/container/internal/layout_test.cc:1384
absl::SimpleAtoi
ABSL_NAMESPACE_BEGIN ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str, int_type *out)
Definition: abseil-cpp/absl/strings/numbers.h:271
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
absl::FormatConversionChar::e
@ e
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
int16_t
signed short int16_t
Definition: stdint-msvc2008.h:76
xds_interop_client.int
int
Definition: xds_interop_client.py:113
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
AbslUnparseFlag
std::string AbslUnparseFlag(const UDT &)
Definition: bloaty/third_party/abseil-cpp/absl/flags/internal/usage_test.cc:50
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
absl::SetFlagsUsageConfig
void SetFlagsUsageConfig(FlagsUsageConfig usage_config)
Definition: abseil-cpp/absl/flags/usage_config.cc:138
UDT::UDT
UDT()=default
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
absl::optional< bool >
absl::flags_internal::FlagHelpMsg
Definition: abseil-cpp/absl/flags/internal/flag.h:203
absl::Duration
Definition: third_party/abseil-cpp/absl/time/time.h:159
absl::flags_internal::FlagRegistrar
Definition: abseil-cpp/absl/flags/internal/flag.h:775
absl::GetFlag
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag< T > &flag)
Definition: abseil-cpp/absl/flags/flag.h:98
google::protobuf::compiler::cpp::DefaultValue
std::string DefaultValue(const FieldDescriptor *field)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc:622
a_
arena< N > & a_
Definition: cxa_demangle.cpp:4778
absl::FlagsUsageConfig
Definition: abseil-cpp/absl/flags/usage_config.h:68
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
EXPECT_DEATH_IF_SUPPORTED
#define EXPECT_DEATH_IF_SUPPORTED(statement, regex)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-death-test.h:335
stdint.h
absl::CommandLineFlag::Filename
virtual std::string Filename() const =0
absl::flags_internal::FlagRegistrar::OnUpdate
FlagRegistrar OnUpdate(FlagCallbackFunc cb) &&
Definition: abseil-cpp/absl/flags/internal/flag.h:782
value
const char * value
Definition: hpack_parser_table.cc:165
absl::Seconds
constexpr Duration Seconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:419
absl::flags_internal::Flag
Definition: abseil-cpp/absl/flags/declare.h:36
absl::Now
ABSL_NAMESPACE_BEGIN Time Now()
Definition: abseil-cpp/absl/time/clock.cc:39
absl::FlagSaver
Definition: abseil-cpp/absl/flags/reflection.h:73
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
absl::SkipWhitespace
Definition: abseil-cpp/absl/strings/str_split.h:365
kNumThreads
const int kNumThreads
Definition: thread_stress_test.cc:46
absl::str_format_internal::LengthMod::t
@ t
absl::Hours
constexpr Duration Hours(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:427
absl::flags_internal::StorageKind
static constexpr FlagValueStorageKind StorageKind()
Definition: abseil-cpp/absl/flags/internal/flag.h:333
AbslParseFlag
bool AbslParseFlag(absl::string_view, UDT *, std::string *)
Definition: bloaty/third_party/abseil-cpp/absl/flags/internal/usage_test.cc:49
A
Definition: miscompile_with_no_unique_address_test.cc:23
TEST_F
TEST_F(FlagTest, TesTypeWrappingEnum)
Definition: abseil-cpp/absl/flags/flag_test.cc:971
absl::Minutes
constexpr Duration Minutes(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:423
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
EXPECT_DOUBLE_EQ
#define EXPECT_DOUBLE_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:28
EXPECT_NEAR
#define EXPECT_NEAR(val1, val2, abs_error)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2143
stop
static const char stop[]
Definition: benchmark-async-pummel.c:35
b_
const char * b_
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/common_unittest.cc:194
handle
static csh handle
Definition: test_arm_regression.c:16
ABSL_FLAG_IMPL_FLAG_PTR
#define ABSL_FLAG_IMPL_FLAG_PTR(flag)
Definition: abseil-cpp/absl/flags/flag.h:200
ABSL_FLAG
ABSL_FLAG(bool, test_flag_01, true, "test flag 01")
xds_manager.f2
f2
Definition: xds_manager.py:85
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
TEST_CONSTRUCTED_FLAG
#define TEST_CONSTRUCTED_FLAG(T)
Definition: abseil-cpp/absl/flags/flag_test.cc:191
ABSL_DECLARE_FLAG
ABSL_DECLARE_FLAG(int64_t, mistyped_int_flag)
absl::EndsWith
bool EndsWith(absl::string_view text, absl::string_view suffix) noexcept
Definition: third_party/abseil-cpp/absl/strings/match.h:68
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:24