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