diff options
Diffstat (limited to 'absl/flags')
-rw-r--r-- | absl/flags/flag.h | 12 | ||||
-rw-r--r-- | absl/flags/flag_test.cc | 23 | ||||
-rw-r--r-- | absl/flags/internal/flag.h | 14 |
3 files changed, 47 insertions, 2 deletions
diff --git a/absl/flags/flag.h b/absl/flags/flag.h index b6fbd116ed2f..f18e9f56a5cc 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -384,11 +384,19 @@ ABSL_NAMESPACE_END // // `default_value` is only used as a double check on the type. `explanation` is // unused. +// +// ABSL_RETIRED_FLAG support omitting the default value for default +// constructible value type, so that users can delete the code generatring this +// value. +// // TODO(rogeeff): Return an anonymous struct instead of bool, and place it into // the unnamed namespace. #define ABSL_RETIRED_FLAG(type, flagname, default_value, explanation) \ - ABSL_ATTRIBUTE_UNUSED static const bool ignored_##flagname = \ - ([] { return type(default_value); }, \ + ABSL_ATTRIBUTE_UNUSED static const bool ignored_##flagname = \ + ([] { \ + return absl::flags_internal::MakeFromDefaultValueOrEmpty<type>( \ + default_value); \ + }, \ absl::flags_internal::RetiredFlag<type>(#flagname)) #endif // ABSL_FLAGS_FLAG_H_ diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc index 4e08da8589a5..465f018c5e4f 100644 --- a/absl/flags/flag_test.cc +++ b/absl/flags/flag_test.cc @@ -486,11 +486,30 @@ TEST_F(FlagTest, TestNonDefaultConstructibleType) { // -------------------------------------------------------------------- +struct Wrapper { + Wrapper() {} + + // NOLINTNEXTLINE(runtime/explicit) + Wrapper(const std::string& val) : val(val) {} + + // NOLINTNEXTLINE(runtime/explicit) + template <typename T> + Wrapper(T&& t) : val(std::forward<T>(t)) {} + + // NOLINTNEXTLINE(runtime/explicit) + operator std::string() const& { return val; } + + std::string val; +}; + } // namespace ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old descr"); ABSL_RETIRED_FLAG(int, old_int_flag, (int)std::sqrt(10), "old descr"); ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr")); +ABSL_RETIRED_FLAG(Wrapper, old_wrapper_flag, {}, "old wrapper"); +ABSL_RETIRED_FLAG(Wrapper, old_wrapper_no_default_flag, , + "old wrapper no default"); namespace { @@ -502,6 +521,10 @@ TEST_F(FlagTest, TestRetiredFlagRegistration) { EXPECT_FALSE(is_bool); EXPECT_TRUE(flags::IsRetiredFlag("old_str_flag", &is_bool)); EXPECT_FALSE(is_bool); + EXPECT_TRUE(flags::IsRetiredFlag("old_wrapper_flag", &is_bool)); + EXPECT_FALSE(is_bool); + EXPECT_TRUE(flags::IsRetiredFlag("old_wrapper_no_default_flag", &is_bool)); + EXPECT_FALSE(is_bool); EXPECT_FALSE(flags::IsRetiredFlag("some_other_flag", &is_bool)); } diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index 20de406f4615..21a10c7f85f8 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -416,6 +416,20 @@ T* MakeFromDefaultValue(EmptyBraces) { return new T; } +// MakeFromDefaultValueOrEmpty is basically the same as MakeFromDefaultValue. It +// also allows for empty macro parameter (hence no argument), which was somehow +// widely used for ABSL_RETIRED_FLAG(). + +template <typename T> +T* MakeFromDefaultValueOrEmpty(T t) { + return MakeFromDefaultValue(std::move(t)); +} + +template <typename T> +T* MakeFromDefaultValueOrEmpty() { + return MakeFromDefaultValue<T>(EmptyBraces()); +} + } // namespace flags_internal ABSL_NAMESPACE_END } // namespace absl |