summaryrefslogtreecommitdiff
path: root/absl/flags
diff options
context:
space:
mode:
Diffstat (limited to 'absl/flags')
-rw-r--r--absl/flags/BUILD.bazel31
-rw-r--r--absl/flags/CMakeLists.txt33
-rw-r--r--absl/flags/commandlineflag_test.cc31
-rw-r--r--absl/flags/flag_test.cc43
-rw-r--r--absl/flags/internal/registry.h13
-rw-r--r--absl/flags/internal/type_erased.cc86
-rw-r--r--absl/flags/internal/type_erased.h80
-rw-r--r--absl/flags/internal/type_erased_test.cc156
-rw-r--r--absl/flags/internal/usage_test.cc12
-rw-r--r--absl/flags/parse.cc6
-rw-r--r--absl/flags/parse_test.cc2
-rw-r--r--absl/flags/reflection.cc (renamed from absl/flags/internal/registry.cc)218
-rw-r--r--absl/flags/reflection.h47
-rw-r--r--absl/flags/reflection_test.cc60
14 files changed, 278 insertions, 540 deletions
diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel
index 6ffd07ce..37c9a105 100644
--- a/absl/flags/BUILD.bazel
+++ b/absl/flags/BUILD.bazel
@@ -159,14 +159,13 @@ cc_library(
)
cc_library(
- name = "registry",
+ name = "reflection",
srcs = [
- "internal/registry.cc",
- "internal/type_erased.cc",
+ "reflection.cc",
],
hdrs = [
"internal/registry.h",
- "internal/type_erased.h",
+ "reflection.h",
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -180,7 +179,6 @@ cc_library(
":private_handle_accessor",
"//absl/base:config",
"//absl/base:core_headers",
- "//absl/base:raw_logging_internal",
"//absl/strings",
"//absl/synchronization",
],
@@ -202,7 +200,7 @@ cc_library(
":commandlineflag_internal",
":config",
":marshalling",
- ":registry",
+ ":reflection",
"//absl/base",
"//absl/base:config",
"//absl/base:core_headers",
@@ -228,7 +226,7 @@ cc_library(
deps = [
":config",
":flag_internal",
- ":registry",
+ ":reflection",
"//absl/base",
"//absl/base:config",
"//absl/base:core_headers",
@@ -257,7 +255,7 @@ cc_library(
":path_util",
":private_handle_accessor",
":program_name",
- ":registry",
+ ":reflection",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/strings",
@@ -300,7 +298,7 @@ cc_library(
":flag_internal",
":private_handle_accessor",
":program_name",
- ":registry",
+ ":reflection",
":usage",
":usage_internal",
"//absl/base:config",
@@ -327,7 +325,7 @@ cc_test(
":config",
":flag",
":private_handle_accessor",
- ":registry",
+ ":reflection",
"//absl/memory",
"//absl/strings",
"@com_google_googletest//:gtest_main",
@@ -362,7 +360,7 @@ cc_test(
":flag",
":flag_internal",
":marshalling",
- ":registry",
+ ":reflection",
"//absl/base:core_headers",
"//absl/base:malloc_internal",
"//absl/strings",
@@ -415,7 +413,7 @@ cc_test(
deps = [
":flag",
":parse",
- ":registry",
+ ":reflection",
"//absl/base:raw_logging_internal",
"//absl/base:scoped_set_env",
"//absl/strings",
@@ -454,17 +452,18 @@ cc_test(
)
cc_test(
- name = "type_erased_test",
+ name = "reflection_test",
size = "small",
srcs = [
- "internal/type_erased_test.cc",
+ "reflection_test.cc",
],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":commandlineflag_internal",
":flag",
- ":registry",
+ ":marshalling",
+ ":reflection",
"//absl/memory",
"@com_google_googletest//:gtest_main",
],
@@ -501,7 +500,7 @@ cc_test(
":parse",
":path_util",
":program_name",
- ":registry",
+ ":reflection",
":usage",
":usage_internal",
"//absl/strings",
diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt
index 2dc7cf45..ef75db8e 100644
--- a/absl/flags/CMakeLists.txt
+++ b/absl/flags/CMakeLists.txt
@@ -144,16 +144,14 @@ absl_cc_library(
absl::strings
)
-# Internal-only target, do not depend on directly.
absl_cc_library(
NAME
- flags_registry
+ flags_reflection
SRCS
- "internal/registry.cc"
- "internal/type_erased.cc"
+ "reflection.cc"
HDRS
+ "reflection.h"
"internal/registry.h"
- "internal/type_erased.h"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -161,10 +159,8 @@ absl_cc_library(
DEPS
absl::config
absl::flags_commandlineflag
- absl::flags_config
absl::flags_private_handle_accessor
- absl::core_headers
- absl::raw_logging_internal
+ absl::flags_config
absl::strings
absl::synchronization
)
@@ -187,7 +183,6 @@ absl_cc_library(
absl::flags_commandlineflag_internal
absl::flags_config
absl::flags_marshalling
- absl::flags_registry
absl::synchronization
absl::meta
absl::utility
@@ -211,7 +206,7 @@ absl_cc_library(
absl::flags_commandlineflag
absl::flags_config
absl::flags_internal
- absl::flags_registry
+ absl::flags_reflection
absl::base
absl::core_headers
absl::strings
@@ -238,7 +233,7 @@ absl_cc_library(
absl::flags_path_util
absl::flags_private_handle_accessor
absl::flags_program_name
- absl::flags_registry
+ absl::flags_reflection
absl::strings
absl::synchronization
)
@@ -284,7 +279,7 @@ absl_cc_library(
absl::flags_internal
absl::flags_private_handle_accessor
absl::flags_program_name
- absl::flags_registry
+ absl::flags_reflection
absl::flags_usage
absl::strings
absl::synchronization
@@ -306,7 +301,7 @@ absl_cc_test(
absl::flags_commandlineflag_internal
absl::flags_config
absl::flags_private_handle_accessor
- absl::flags_registry
+ absl::flags_reflection
absl::memory
absl::strings
gtest_main
@@ -338,7 +333,7 @@ absl_cc_test(
absl::flags_config
absl::flags_internal
absl::flags_marshalling
- absl::flags_registry
+ absl::flags_reflection
absl::strings
absl::time
gtest_main
@@ -366,7 +361,7 @@ absl_cc_test(
DEPS
absl::flags
absl::flags_parse
- absl::flags_registry
+ absl::flags_reflection
absl::raw_logging_internal
absl::scoped_set_env
absl::span
@@ -401,15 +396,15 @@ absl_cc_test(
absl_cc_test(
NAME
- flags_type_erased_test
+ flags_reflection_test
SRCS
- "internal/type_erased_test.cc"
+ "reflection_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::flags_commandlineflag_internal
absl::flags
- absl::flags_registry
+ absl::flags_reflection
absl::memory
absl::strings
gtest_main
@@ -443,7 +438,7 @@ absl_cc_test(
absl::flags_path_util
absl::flags_program_name
absl::flags_parse
- absl::flags_registry
+ absl::flags_reflection
absl::flags_usage
absl::strings
gtest
diff --git a/absl/flags/commandlineflag_test.cc b/absl/flags/commandlineflag_test.cc
index 570bbe2f..cc8eae91 100644
--- a/absl/flags/commandlineflag_test.cc
+++ b/absl/flags/commandlineflag_test.cc
@@ -22,7 +22,7 @@
#include "absl/flags/flag.h"
#include "absl/flags/internal/commandlineflag.h"
#include "absl/flags/internal/private_handle_accessor.h"
-#include "absl/flags/internal/registry.h"
+#include "absl/flags/reflection.h"
#include "absl/flags/usage_config.h"
#include "absl/memory/memory.h"
#include "absl/strings/match.h"
@@ -64,7 +64,7 @@ class CommandLineFlagTest : public testing::Test {
};
TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) {
- auto* flag_01 = flags::FindCommandLineFlag("int_flag");
+ auto* flag_01 = absl::FindCommandLineFlag("int_flag");
ASSERT_TRUE(flag_01);
EXPECT_EQ(flag_01->Name(), "int_flag");
@@ -77,7 +77,7 @@ TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) {
"absl/flags/commandlineflag_test.cc"))
<< flag_01->Filename();
- auto* flag_02 = flags::FindCommandLineFlag("string_flag");
+ auto* flag_02 = absl::FindCommandLineFlag("string_flag");
ASSERT_TRUE(flag_02);
EXPECT_EQ(flag_02->Name(), "string_flag");
@@ -89,31 +89,20 @@ TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) {
EXPECT_TRUE(absl::EndsWith(flag_02->Filename(),
"absl/flags/commandlineflag_test.cc"))
<< flag_02->Filename();
-
- auto* flag_03 = flags::FindRetiredFlag("bool_retired_flag");
-
- ASSERT_TRUE(flag_03);
- EXPECT_EQ(flag_03->Name(), "bool_retired_flag");
- EXPECT_EQ(flag_03->Help(), "");
- EXPECT_TRUE(flag_03->IsRetired());
- EXPECT_TRUE(flag_03->IsOfType<bool>());
- EXPECT_TRUE(!flag_03->IsOfType<int>());
- EXPECT_TRUE(!flag_03->IsOfType<std::string>());
- EXPECT_EQ(flag_03->Filename(), "RETIRED");
}
// --------------------------------------------------------------------
TEST_F(CommandLineFlagTest, TestValueAccessMethods) {
absl::SetFlag(&FLAGS_int_flag, 301);
- auto* flag_01 = flags::FindCommandLineFlag("int_flag");
+ auto* flag_01 = absl::FindCommandLineFlag("int_flag");
ASSERT_TRUE(flag_01);
EXPECT_EQ(flag_01->CurrentValue(), "301");
EXPECT_EQ(flag_01->DefaultValue(), "201");
absl::SetFlag(&FLAGS_string_flag, "new_str_value");
- auto* flag_02 = flags::FindCommandLineFlag("string_flag");
+ auto* flag_02 = absl::FindCommandLineFlag("string_flag");
ASSERT_TRUE(flag_02);
EXPECT_EQ(flag_02->CurrentValue(), "new_str_value");
@@ -125,7 +114,7 @@ TEST_F(CommandLineFlagTest, TestValueAccessMethods) {
TEST_F(CommandLineFlagTest, TestParseFromCurrentValue) {
std::string err;
- auto* flag_01 = flags::FindCommandLineFlag("int_flag");
+ auto* flag_01 = absl::FindCommandLineFlag("int_flag");
EXPECT_FALSE(
flags::PrivateHandleAccessor::IsSpecifiedOnCommandLine(*flag_01));
@@ -173,7 +162,7 @@ TEST_F(CommandLineFlagTest, TestParseFromCurrentValue) {
*flag_01, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, err));
EXPECT_EQ(err, "Illegal value '' specified for flag 'int_flag'");
- auto* flag_02 = flags::FindCommandLineFlag("string_flag");
+ auto* flag_02 = absl::FindCommandLineFlag("string_flag");
EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
*flag_02, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange,
err));
@@ -189,14 +178,14 @@ TEST_F(CommandLineFlagTest, TestParseFromCurrentValue) {
TEST_F(CommandLineFlagTest, TestParseFromDefaultValue) {
std::string err;
- auto* flag_01 = flags::FindCommandLineFlag("int_flag");
+ auto* flag_01 = absl::FindCommandLineFlag("int_flag");
EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
*flag_01, "111", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange,
err));
EXPECT_EQ(flag_01->DefaultValue(), "111");
- auto* flag_02 = flags::FindCommandLineFlag("string_flag");
+ auto* flag_02 = absl::FindCommandLineFlag("string_flag");
EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
*flag_02, "abc", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange,
@@ -209,7 +198,7 @@ TEST_F(CommandLineFlagTest, TestParseFromDefaultValue) {
TEST_F(CommandLineFlagTest, TestParseFromIfDefault) {
std::string err;
- auto* flag_01 = flags::FindCommandLineFlag("int_flag");
+ auto* flag_01 = absl::FindCommandLineFlag("int_flag");
EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom(
*flag_01, "22", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange,
diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc
index 71661d39..0c88e24a 100644
--- a/absl/flags/flag_test.cc
+++ b/absl/flags/flag_test.cc
@@ -29,8 +29,8 @@
#include "absl/flags/config.h"
#include "absl/flags/declare.h"
#include "absl/flags/internal/flag.h"
-#include "absl/flags/internal/registry.h"
#include "absl/flags/marshalling.h"
+#include "absl/flags/reflection.h"
#include "absl/flags/usage_config.h"
#include "absl/strings/match.h"
#include "absl/strings/numbers.h"
@@ -555,29 +555,29 @@ TEST_F(FlagTest, TestGetSet) {
// --------------------------------------------------------------------
TEST_F(FlagTest, TestGetViaReflection) {
- auto* handle = flags::FindCommandLineFlag("test_flag_01");
+ auto* handle = absl::FindCommandLineFlag("test_flag_01");
EXPECT_EQ(*handle->TryGet<bool>(), true);
- handle = flags::FindCommandLineFlag("test_flag_02");
+ handle = absl::FindCommandLineFlag("test_flag_02");
EXPECT_EQ(*handle->TryGet<int>(), 1234);
- handle = flags::FindCommandLineFlag("test_flag_03");
+ handle = absl::FindCommandLineFlag("test_flag_03");
EXPECT_EQ(*handle->TryGet<int16_t>(), -34);
- handle = flags::FindCommandLineFlag("test_flag_04");
+ handle = absl::FindCommandLineFlag("test_flag_04");
EXPECT_EQ(*handle->TryGet<uint16_t>(), 189);
- handle = flags::FindCommandLineFlag("test_flag_05");
+ handle = absl::FindCommandLineFlag("test_flag_05");
EXPECT_EQ(*handle->TryGet<int32_t>(), 10765);
- handle = flags::FindCommandLineFlag("test_flag_06");
+ handle = absl::FindCommandLineFlag("test_flag_06");
EXPECT_EQ(*handle->TryGet<uint32_t>(), 40000);
- handle = flags::FindCommandLineFlag("test_flag_07");
+ handle = absl::FindCommandLineFlag("test_flag_07");
EXPECT_EQ(*handle->TryGet<int64_t>(), -1234567);
- handle = flags::FindCommandLineFlag("test_flag_08");
+ handle = absl::FindCommandLineFlag("test_flag_08");
EXPECT_EQ(*handle->TryGet<uint64_t>(), 9876543);
- handle = flags::FindCommandLineFlag("test_flag_09");
+ handle = absl::FindCommandLineFlag("test_flag_09");
EXPECT_NEAR(*handle->TryGet<double>(), -9.876e-50, 1e-55);
- handle = flags::FindCommandLineFlag("test_flag_10");
+ handle = absl::FindCommandLineFlag("test_flag_10");
EXPECT_NEAR(*handle->TryGet<float>(), 1.234e12f, 1e5f);
- handle = flags::FindCommandLineFlag("test_flag_11");
+ handle = absl::FindCommandLineFlag("test_flag_11");
EXPECT_EQ(*handle->TryGet<std::string>(), "");
- handle = flags::FindCommandLineFlag("test_flag_12");
+ handle = absl::FindCommandLineFlag("test_flag_12");
EXPECT_EQ(*handle->TryGet<absl::Duration>(), absl::Minutes(10));
}
@@ -815,14 +815,15 @@ ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr"));
namespace {
TEST_F(FlagTest, TestRetiredFlagRegistration) {
- bool is_bool = false;
- EXPECT_TRUE(flags::IsRetiredFlag("old_bool_flag", &is_bool));
- EXPECT_TRUE(is_bool);
- EXPECT_TRUE(flags::IsRetiredFlag("old_int_flag", &is_bool));
- EXPECT_FALSE(is_bool);
- EXPECT_TRUE(flags::IsRetiredFlag("old_str_flag", &is_bool));
- EXPECT_FALSE(is_bool);
- EXPECT_FALSE(flags::IsRetiredFlag("some_other_flag", &is_bool));
+ auto* handle = absl::FindCommandLineFlag("old_bool_flag");
+ EXPECT_TRUE(handle->IsOfType<bool>());
+ EXPECT_TRUE(handle->IsRetired());
+ handle = absl::FindCommandLineFlag("old_int_flag");
+ EXPECT_TRUE(handle->IsOfType<int>());
+ EXPECT_TRUE(handle->IsRetired());
+ handle = absl::FindCommandLineFlag("old_str_flag");
+ EXPECT_TRUE(handle->IsOfType<std::string>());
+ EXPECT_TRUE(handle->IsRetired());
}
} // namespace
diff --git a/absl/flags/internal/registry.h b/absl/flags/internal/registry.h
index d207c225..1e655a3e 100644
--- a/absl/flags/internal/registry.h
+++ b/absl/flags/internal/registry.h
@@ -28,10 +28,14 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace flags_internal {
+// TODO(rogeeff): remove this declaration
CommandLineFlag* FindCommandLineFlag(absl::string_view name);
-CommandLineFlag* FindRetiredFlag(absl::string_view name);
+
+namespace flags_internal {
+
+// TODO(rogeeff): remove this alias
+using absl::FindCommandLineFlag;
// Executes specified visitor for each non-retired flag in the registry.
// Requires the caller hold the registry lock.
@@ -85,11 +89,6 @@ inline bool RetiredFlag(const char* flag_name) {
return flags_internal::Retire(flag_name, base_internal::FastTypeId<T>());
}
-// If the flag is retired, returns true and indicates in |*type_is_bool|
-// whether the type of the retired flag is a bool.
-// Only to be called by code that needs to explicitly ignore retired flags.
-bool IsRetiredFlag(absl::string_view name, bool* type_is_bool);
-
//-----------------------------------------------------------------------------
// Saves the states (value, default value, whether the user has set
// the flag, registered validators, etc) of all flags, and restores
diff --git a/absl/flags/internal/type_erased.cc b/absl/flags/internal/type_erased.cc
deleted file mode 100644
index b2523b24..00000000
--- a/absl/flags/internal/type_erased.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-//
-// Copyright 2019 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/flags/internal/type_erased.h"
-
-#include <assert.h>
-
-#include <string>
-
-#include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
-#include "absl/flags/commandlineflag.h"
-#include "absl/flags/internal/private_handle_accessor.h"
-#include "absl/flags/internal/registry.h"
-#include "absl/flags/usage_config.h"
-#include "absl/strings/string_view.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace flags_internal {
-
-bool GetCommandLineOption(absl::string_view name, std::string* value) {
- if (name.empty()) return false;
- assert(value);
-
- CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name);
- if (flag == nullptr || flag->IsRetired()) {
- return false;
- }
-
- *value = flag->CurrentValue();
- return true;
-}
-
-bool SetCommandLineOption(absl::string_view name, absl::string_view value) {
- return SetCommandLineOptionWithMode(name, value,
- flags_internal::SET_FLAGS_VALUE);
-}
-
-bool SetCommandLineOptionWithMode(absl::string_view name,
- absl::string_view value,
- FlagSettingMode set_mode) {
- CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name);
-
- if (!flag || flag->IsRetired()) return false;
-
- std::string error;
- if (!flags_internal::PrivateHandleAccessor::ParseFrom(
- *flag, value, set_mode, kProgrammaticChange, error)) {
- // Errors here are all of the form: the provided name was a recognized
- // flag, but the value was invalid (bad type, or validation failed).
- flags_internal::ReportUsageError(error, false);
- return false;
- }
-
- return true;
-}
-
-// --------------------------------------------------------------------
-
-bool IsValidFlagValue(absl::string_view name, absl::string_view value) {
- CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name);
-
- return flag != nullptr &&
- (flag->IsRetired() ||
- flags_internal::PrivateHandleAccessor::ValidateInputValue(*flag,
- value));
-}
-
-// --------------------------------------------------------------------
-
-} // namespace flags_internal
-ABSL_NAMESPACE_END
-} // namespace absl
diff --git a/absl/flags/internal/type_erased.h b/absl/flags/internal/type_erased.h
deleted file mode 100644
index 437a8c28..00000000
--- a/absl/flags/internal/type_erased.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//
-// Copyright 2019 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_
-#define ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_
-
-#include <string>
-
-#include "absl/base/config.h"
-#include "absl/flags/commandlineflag.h"
-#include "absl/flags/internal/commandlineflag.h"
-#include "absl/flags/internal/registry.h"
-#include "absl/strings/string_view.h"
-
-// --------------------------------------------------------------------
-// Registry interfaces operating on type erased handles.
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace flags_internal {
-
-// If a flag named "name" exists, store its current value in *OUTPUT
-// and return true. Else return false without changing *OUTPUT.
-// Thread-safe.
-bool GetCommandLineOption(absl::string_view name, std::string* value);
-
-// Set the value of the flag named "name" to value. If successful,
-// returns true. If not successful (e.g., the flag was not found or
-// the value is not a valid value), returns false.
-// Thread-safe.
-bool SetCommandLineOption(absl::string_view name, absl::string_view value);
-
-bool SetCommandLineOptionWithMode(absl::string_view name,
- absl::string_view value,
- FlagSettingMode set_mode);
-
-//-----------------------------------------------------------------------------
-
-// Returns true iff all of the following conditions are true:
-// (a) "name" names a registered flag
-// (b) "value" can be parsed succesfully according to the type of the flag
-// (c) parsed value passes any validator associated with the flag
-bool IsValidFlagValue(absl::string_view name, absl::string_view value);
-
-//-----------------------------------------------------------------------------
-
-// If a flag with specified "name" exists and has type T, store
-// its current value in *dst and return true. Else return false
-// without touching *dst. T must obey all of the requirements for
-// types passed to DEFINE_FLAG.
-template <typename T>
-inline bool GetByName(absl::string_view name, T* dst) {
- CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name);
- if (!flag) return false;
-
- if (auto val = flag->TryGet<T>()) {
- *dst = *val;
- return true;
- }
-
- return false;
-}
-
-} // namespace flags_internal
-ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_FLAGS_INTERNAL_TYPE_ERASED_H_
diff --git a/absl/flags/internal/type_erased_test.cc b/absl/flags/internal/type_erased_test.cc
deleted file mode 100644
index 42f374dc..00000000
--- a/absl/flags/internal/type_erased_test.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-//
-// Copyright 2019 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/flags/internal/type_erased.h"
-
-#include <memory>
-#include <string>
-
-#include "gtest/gtest.h"
-#include "absl/flags/flag.h"
-#include "absl/flags/internal/commandlineflag.h"
-#include "absl/flags/internal/registry.h"
-#include "absl/memory/memory.h"
-
-ABSL_FLAG(int, int_flag, 1, "int_flag help");
-ABSL_FLAG(std::string, string_flag, "dflt", "string_flag help");
-ABSL_RETIRED_FLAG(bool, bool_retired_flag, false, "bool_retired_flag help");
-
-namespace {
-
-namespace flags = absl::flags_internal;
-
-class TypeErasedTest : public testing::Test {
- protected:
- void SetUp() override { flag_saver_ = absl::make_unique<flags::FlagSaver>(); }
- void TearDown() override { flag_saver_.reset(); }
-
- private:
- std::unique_ptr<flags::FlagSaver> flag_saver_;
-};
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestGetCommandLineOption) {
- std::string value;
- EXPECT_TRUE(flags::GetCommandLineOption("int_flag", &value));
- EXPECT_EQ(value, "1");
-
- EXPECT_TRUE(flags::GetCommandLineOption("string_flag", &value));
- EXPECT_EQ(value, "dflt");
-
- EXPECT_FALSE(flags::GetCommandLineOption("bool_retired_flag", &value));
-
- EXPECT_FALSE(flags::GetCommandLineOption("unknown_flag", &value));
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestSetCommandLineOption) {
- EXPECT_TRUE(flags::SetCommandLineOption("int_flag", "101"));
- EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101);
-
- EXPECT_TRUE(flags::SetCommandLineOption("string_flag", "asdfgh"));
- EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh");
-
- EXPECT_FALSE(flags::SetCommandLineOption("bool_retired_flag", "true"));
-
- EXPECT_FALSE(flags::SetCommandLineOption("unknown_flag", "true"));
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAGS_VALUE) {
- EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101",
- flags::SET_FLAGS_VALUE));
- EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101);
-
- EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh",
- flags::SET_FLAGS_VALUE));
- EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh");
-
- EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true",
- flags::SET_FLAGS_VALUE));
-
- EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true",
- flags::SET_FLAGS_VALUE));
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAG_IF_DEFAULT) {
- EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101",
- flags::SET_FLAG_IF_DEFAULT));
- EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101);
-
- // This semantic is broken. We return true instead of false. Value is not
- // updated.
- EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "202",
- flags::SET_FLAG_IF_DEFAULT));
- EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 101);
-
- EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh",
- flags::SET_FLAG_IF_DEFAULT));
- EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh");
-
- EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true",
- flags::SET_FLAG_IF_DEFAULT));
-
- EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true",
- flags::SET_FLAG_IF_DEFAULT));
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestSetCommandLineOptionWithMode_SET_FLAGS_DEFAULT) {
- EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "101",
- flags::SET_FLAGS_DEFAULT));
-
- // Set it again to ensure that resetting logic is covered.
- EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "102",
- flags::SET_FLAGS_DEFAULT));
-
- EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "103",
- flags::SET_FLAGS_DEFAULT));
-
- EXPECT_TRUE(flags::SetCommandLineOptionWithMode("string_flag", "asdfgh",
- flags::SET_FLAGS_DEFAULT));
- EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "asdfgh");
-
- EXPECT_FALSE(flags::SetCommandLineOptionWithMode("bool_retired_flag", "true",
- flags::SET_FLAGS_DEFAULT));
-
- EXPECT_FALSE(flags::SetCommandLineOptionWithMode("unknown_flag", "true",
- flags::SET_FLAGS_DEFAULT));
-
- // This should be successfull, since flag is still is not set
- EXPECT_TRUE(flags::SetCommandLineOptionWithMode("int_flag", "202",
- flags::SET_FLAG_IF_DEFAULT));
- EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 202);
-}
-
-// --------------------------------------------------------------------
-
-TEST_F(TypeErasedTest, TestIsValidFlagValue) {
- EXPECT_TRUE(flags::IsValidFlagValue("int_flag", "57"));
- EXPECT_TRUE(flags::IsValidFlagValue("int_flag", "-101"));
- EXPECT_FALSE(flags::IsValidFlagValue("int_flag", "1.1"));
-
- EXPECT_TRUE(flags::IsValidFlagValue("string_flag", "#%^#%^$%DGHDG$W%adsf"));
-
- EXPECT_TRUE(flags::IsValidFlagValue("bool_retired_flag", "true"));
-}
-
-} // namespace
diff --git a/absl/flags/internal/usage_test.cc b/absl/flags/internal/usage_test.cc
index 53b4d983..46f85b55 100644
--- a/absl/flags/internal/usage_test.cc
+++ b/absl/flags/internal/usage_test.cc
@@ -25,7 +25,7 @@
#include "absl/flags/internal/parse.h"
#include "absl/flags/internal/path_util.h"
#include "absl/flags/internal/program_name.h"
-#include "absl/flags/internal/registry.h"
+#include "absl/flags/reflection.h"
#include "absl/flags/usage.h"
#include "absl/flags/usage_config.h"
#include "absl/strings/match.h"
@@ -110,7 +110,7 @@ TEST_F(UsageReportingDeathTest, TestSetProgramUsageMessage) {
// --------------------------------------------------------------------
TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_01) {
- const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_01");
+ const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_01");
std::stringstream test_buf;
flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
@@ -122,7 +122,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_01) {
}
TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_02) {
- const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_02");
+ const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_02");
std::stringstream test_buf;
flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
@@ -134,7 +134,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_02) {
}
TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_03) {
- const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_03");
+ const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_03");
std::stringstream test_buf;
flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
@@ -146,7 +146,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_03) {
}
TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_04) {
- const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_04");
+ const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_04");
std::stringstream test_buf;
flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
@@ -158,7 +158,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_04) {
}
TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_05) {
- const auto* flag = flags::FindCommandLineFlag("usage_reporting_test_flag_05");
+ const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_05");
std::stringstream test_buf;
flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable);
diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc
index f0a131f2..e2c88ff8 100644
--- a/absl/flags/parse.cc
+++ b/absl/flags/parse.cc
@@ -42,8 +42,8 @@
#include "absl/flags/internal/parse.h"
#include "absl/flags/internal/private_handle_accessor.h"
#include "absl/flags/internal/program_name.h"
-#include "absl/flags/internal/registry.h"
#include "absl/flags/internal/usage.h"
+#include "absl/flags/reflection.h"
#include "absl/flags/usage.h"
#include "absl/flags/usage_config.h"
#include "absl/strings/ascii.h"
@@ -290,11 +290,11 @@ std::tuple<absl::string_view, absl::string_view, bool> SplitNameAndValue(
// found flag or nullptr
// is negative in case of --nofoo
std::tuple<CommandLineFlag*, bool> LocateFlag(absl::string_view flag_name) {
- CommandLineFlag* flag = flags_internal::FindCommandLineFlag(flag_name);
+ CommandLineFlag* flag = absl::FindCommandLineFlag(flag_name);
bool is_negative = false;
if (!flag && absl::ConsumePrefix(&flag_name, "no")) {
- flag = flags_internal::FindCommandLineFlag(flag_name);
+ flag = absl::FindCommandLineFlag(flag_name);
is_negative = true;
}
diff --git a/absl/flags/parse_test.cc b/absl/flags/parse_test.cc
index aea068ee..1ab87690 100644
--- a/absl/flags/parse_test.cc
+++ b/absl/flags/parse_test.cc
@@ -28,7 +28,7 @@
#include "absl/flags/declare.h"
#include "absl/flags/flag.h"
#include "absl/flags/internal/parse.h"
-#include "absl/flags/internal/registry.h"
+#include "absl/flags/reflection.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
diff --git a/absl/flags/internal/registry.cc b/absl/flags/reflection.cc
index e582d79d..02bb6c2e 100644
--- a/absl/flags/internal/registry.cc
+++ b/absl/flags/reflection.cc
@@ -1,5 +1,5 @@
//
-// Copyright 2019 The Abseil Authors.
+// Copyright 2020 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -13,47 +13,34 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "absl/flags/internal/registry.h"
+#include "absl/flags/reflection.h"
#include <assert.h>
-#include <stdlib.h>
-#include <functional>
#include <map>
-#include <memory>
#include <string>
-#include <utility>
-#include <vector>
#include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
#include "absl/base/thread_annotations.h"
#include "absl/flags/commandlineflag.h"
-#include "absl/flags/internal/commandlineflag.h"
#include "absl/flags/internal/private_handle_accessor.h"
+#include "absl/flags/internal/registry.h"
#include "absl/flags/usage_config.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
-// --------------------------------------------------------------------
-// FlagRegistry implementation
-// A FlagRegistry holds all flag objects indexed
-// by their names so that if you know a flag's name you can access or
-// set it.
-
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace flags_internal {
// --------------------------------------------------------------------
// FlagRegistry
-// A FlagRegistry singleton object holds all flag objects indexed
-// by their names so that if you know a flag's name (as a C
-// string), you can access or set it. If the function is named
-// FooLocked(), you must own the registry lock before calling
-// the function; otherwise, you should *not* hold the lock, and
-// the function will acquire it itself if needed.
+// A FlagRegistry singleton object holds all flag objects indexed by their
+// names so that if you know a flag's name, you can access or set it. If the
+// function is named FooLocked(), you must own the registry lock before
+// calling the function; otherwise, you should *not* hold the lock, and the
+// function will acquire it itself if needed.
// --------------------------------------------------------------------
class FlagRegistry {
@@ -95,9 +82,27 @@ class FlagRegistry {
FlagRegistry& operator=(const FlagRegistry&);
};
-FlagRegistry& FlagRegistry::GlobalRegistry() {
- static FlagRegistry* global_registry = new FlagRegistry;
- return *global_registry;
+CommandLineFlag* FlagRegistry::FindFlagLocked(absl::string_view name) {
+ FlagConstIterator i = flags_.find(name);
+ if (i == flags_.end()) {
+ return nullptr;
+ }
+
+ if (i->second->IsRetired()) {
+ flags_internal::ReportUsageError(
+ absl::StrCat("Accessing retired flag '", name, "'"), false);
+ }
+
+ return i->second;
+}
+
+CommandLineFlag* FlagRegistry::FindRetiredFlagLocked(absl::string_view name) {
+ FlagConstIterator i = flags_.find(name);
+ if (i == flags_.end() || !i->second->IsRetired()) {
+ return nullptr;
+ }
+
+ return i->second;
}
namespace {
@@ -161,98 +166,9 @@ void FlagRegistry::RegisterFlag(CommandLineFlag& flag) {
}
}
-CommandLineFlag* FlagRegistry::FindFlagLocked(absl::string_view name) {
- FlagConstIterator i = flags_.find(name);
- if (i == flags_.end()) {
- return nullptr;
- }
-
- if (i->second->IsRetired()) {
- flags_internal::ReportUsageError(
- absl::StrCat("Accessing retired flag '", name, "'"), false);
- }
-
- return i->second;
-}
-
-CommandLineFlag* FlagRegistry::FindRetiredFlagLocked(absl::string_view name) {
- FlagConstIterator i = flags_.find(name);
- if (i == flags_.end() || !i->second->IsRetired()) {
- return nullptr;
- }
-
- return i->second;
-}
-
-// --------------------------------------------------------------------
-// FlagSaver
-// FlagSaverImpl
-// This class stores the states of all flags at construct time,
-// and restores all flags to that state at destruct time.
-// Its major implementation challenge is that it never modifies
-// pointers in the 'main' registry, so global FLAG_* vars always
-// point to the right place.
-// --------------------------------------------------------------------
-
-class FlagSaverImpl {
- public:
- FlagSaverImpl() = default;
- FlagSaverImpl(const FlagSaverImpl&) = delete;
- void operator=(const FlagSaverImpl&) = delete;
-
- // Saves the flag states from the flag registry into this object.
- // It's an error to call this more than once.
- void SaveFromRegistry() {
- assert(backup_registry_.empty()); // call only once!
- flags_internal::ForEachFlag([&](CommandLineFlag& flag) {
- if (auto flag_state =
- flags_internal::PrivateHandleAccessor::SaveState(flag)) {
- backup_registry_.emplace_back(std::move(flag_state));
- }
- });
- }
-
- // Restores the saved flag states into the flag registry.
- void RestoreToRegistry() {
- for (const auto& flag_state : backup_registry_) {
- flag_state->Restore();
- }
- }
-
- private:
- std::vector<std::unique_ptr<flags_internal::FlagStateInterface>>
- backup_registry_;
-};
-
-FlagSaver::FlagSaver() : impl_(new FlagSaverImpl) { impl_->SaveFromRegistry(); }
-
-void FlagSaver::Ignore() {
- delete impl_;
- impl_ = nullptr;
-}
-
-FlagSaver::~FlagSaver() {
- if (!impl_) return;
-
- impl_->RestoreToRegistry();
- delete impl_;
-}
-
-// --------------------------------------------------------------------
-
-CommandLineFlag* FindCommandLineFlag(absl::string_view name) {
- if (name.empty()) return nullptr;
- FlagRegistry& registry = FlagRegistry::GlobalRegistry();
- FlagRegistryLock frl(registry);
-
- return registry.FindFlagLocked(name);
-}
-
-CommandLineFlag* FindRetiredFlag(absl::string_view name) {
- FlagRegistry& registry = FlagRegistry::GlobalRegistry();
- FlagRegistryLock frl(registry);
-
- return registry.FindRetiredFlagLocked(name);
+FlagRegistry& FlagRegistry::GlobalRegistry() {
+ static FlagRegistry* global_registry = new FlagRegistry;
+ return *global_registry;
}
// --------------------------------------------------------------------
@@ -333,17 +249,71 @@ bool Retire(const char* name, FlagFastTypeId type_id) {
// --------------------------------------------------------------------
-bool IsRetiredFlag(absl::string_view name, bool* type_is_bool) {
- assert(!name.empty());
- CommandLineFlag* flag = flags_internal::FindRetiredFlag(name);
- if (flag == nullptr) {
- return false;
+// FlagSaver
+// FlagSaverImpl
+// This class stores the states of all flags at construct time,
+// and restores all flags to that state at destruct time.
+// Its major implementation challenge is that it never modifies
+// pointers in the 'main' registry, so global FLAG_* vars always
+// point to the right place.
+// --------------------------------------------------------------------
+
+class FlagSaverImpl {
+ public:
+ FlagSaverImpl() = default;
+ FlagSaverImpl(const FlagSaverImpl&) = delete;
+ void operator=(const FlagSaverImpl&) = delete;
+
+ // Saves the flag states from the flag registry into this object.
+ // It's an error to call this more than once.
+ void SaveFromRegistry() {
+ assert(backup_registry_.empty()); // call only once!
+ flags_internal::ForEachFlag([&](CommandLineFlag& flag) {
+ if (auto flag_state =
+ flags_internal::PrivateHandleAccessor::SaveState(flag)) {
+ backup_registry_.emplace_back(std::move(flag_state));
+ }
+ });
}
- assert(type_is_bool);
- *type_is_bool = flag->IsOfType<bool>();
- return true;
+
+ // Restores the saved flag states into the flag registry.
+ void RestoreToRegistry() {
+ for (const auto& flag_state : backup_registry_) {
+ flag_state->Restore();
+ }
+ }
+
+ private:
+ std::vector<std::unique_ptr<flags_internal::FlagStateInterface>>
+ backup_registry_;
+};
+
+FlagSaver::FlagSaver() : impl_(new FlagSaverImpl) { impl_->SaveFromRegistry(); }
+
+void FlagSaver::Ignore() {
+ delete impl_;
+ impl_ = nullptr;
+}
+
+FlagSaver::~FlagSaver() {
+ if (!impl_) return;
+
+ impl_->RestoreToRegistry();
+ delete impl_;
}
+// --------------------------------------------------------------------
+
} // namespace flags_internal
+
+CommandLineFlag* FindCommandLineFlag(absl::string_view name) {
+ if (name.empty()) return nullptr;
+ flags_internal::FlagRegistry& registry =
+ flags_internal::FlagRegistry::GlobalRegistry();
+ flags_internal::FlagRegistryLock frl(registry);
+
+ return registry.FindFlagLocked(name);
+}
+
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/absl/flags/reflection.h b/absl/flags/reflection.h
new file mode 100644
index 00000000..e8e24f68
--- /dev/null
+++ b/absl/flags/reflection.h
@@ -0,0 +1,47 @@
+//
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: reflection.h
+// -----------------------------------------------------------------------------
+//
+// This file defines the routines to access and operate on an Abseil Flag's
+// reflection handle.
+
+#ifndef ABSL_FLAGS_REFLECTION_H_
+#define ABSL_FLAGS_REFLECTION_H_
+
+#include <string>
+
+#include "absl/base/config.h"
+#include "absl/flags/commandlineflag.h"
+#include "absl/flags/internal/commandlineflag.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+// FindCommandLineFlag()
+//
+// Returns the reflection handle of an Abseil flag of the specified name, or
+// `nullptr` if not found. This function will emit a warning if the name of a
+// 'retired' flag is specified.
+CommandLineFlag* FindCommandLineFlag(absl::string_view name);
+
+//-----------------------------------------------------------------------------
+
+ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_FLAGS_REFLECTION_H_
diff --git a/absl/flags/reflection_test.cc b/absl/flags/reflection_test.cc
new file mode 100644
index 00000000..2a137bf7
--- /dev/null
+++ b/absl/flags/reflection_test.cc
@@ -0,0 +1,60 @@
+//
+// Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/flags/reflection.h"
+
+#include <memory>
+#include <string>
+
+#include "gtest/gtest.h"
+#include "absl/flags/flag.h"
+#include "absl/flags/internal/commandlineflag.h"
+#include "absl/flags/marshalling.h"
+#include "absl/memory/memory.h"
+
+ABSL_FLAG(int, int_flag, 1, "int_flag help");
+ABSL_FLAG(std::string, string_flag, "dflt", "string_flag help");
+ABSL_RETIRED_FLAG(bool, bool_retired_flag, false, "bool_retired_flag help");
+
+namespace {
+
+namespace flags = absl::flags_internal;
+
+class ReflectionTest : public testing::Test {
+ protected:
+ void SetUp() override { flag_saver_ = absl::make_unique<flags::FlagSaver>(); }
+ void TearDown() override { flag_saver_.reset(); }
+
+ private:
+ std::unique_ptr<flags::FlagSaver> flag_saver_;
+};
+
+// --------------------------------------------------------------------
+
+TEST_F(ReflectionTest, TestFindCommandLineFlag) {
+ auto* handle = absl::FindCommandLineFlag("some_flag");
+ EXPECT_EQ(handle, nullptr);
+
+ handle = absl::FindCommandLineFlag("int_flag");
+ EXPECT_NE(handle, nullptr);
+
+ handle = absl::FindCommandLineFlag("string_flag");
+ EXPECT_NE(handle, nullptr);
+
+ handle = absl::FindCommandLineFlag("bool_retired_flag");
+ EXPECT_NE(handle, nullptr);
+}
+
+} // namespace