29 #ifndef ABSL_FLAGS_FLAG_H_
30 #define ABSL_FLAGS_FLAG_H_
33 #include <type_traits>
35 #include "absl/base/attributes.h"
36 #include "absl/base/config.h"
37 #include "absl/base/optimization.h"
38 #include "absl/flags/config.h"
39 #include "absl/flags/internal/flag.h"
40 #include "absl/flags/internal/registry.h"
41 #include "absl/strings/string_view.h"
70 #if !defined(_MSC_VER) || defined(__clang__)
72 using Flag = flags_internal::Flag<T>;
89 namespace flags_internal {
106 default_value_gen_(default_value_gen),
111 flags_internal::Flag<T>& GetImpl()
const {
112 if (!inited_.load(std::memory_order_acquire)) {
115 if (inited_.load(std::memory_order_acquire)) {
119 impl_ =
new flags_internal::Flag<T>(
121 {flags_internal::FlagHelpMsg(help_gen_),
123 {flags_internal::FlagDefaultSrc(default_value_gen_),
125 inited_.store(
true, std::memory_order_release);
133 bool IsRetired()
const {
return GetImpl().
IsRetired(); }
136 bool IsModified()
const {
return GetImpl().IsModified(); }
138 return GetImpl().IsSpecifiedOnCommandLine();
143 template <
typename U>
144 inline bool IsOfType()
const {
145 return GetImpl().template IsOfType<U>();
148 return flags_internal::FlagImplPeer::InvokeGet<T>(GetImpl());
150 void Set(
const T&
v) {
153 void InvokeCallback() { GetImpl().InvokeCallback(); }
155 const CommandLineFlag&
Reflect()
const {
162 const char* filename_;
166 mutable std::atomic<bool> inited_;
167 mutable flags_internal::Flag<T>*
impl_;
187 template <
typename T>
189 return flags_internal::FlagImplPeer::InvokeGet<T>(
flag);
199 template <
typename T>
207 template <
typename T,
typename V>
223 template <
typename T>
259 #define ABSL_FLAG(Type, name, default_value, help) \
260 ABSL_FLAG_IMPL(Type, name, default_value, help)
288 #if !defined(_MSC_VER) || defined(__clang__)
289 #define ABSL_FLAG_IMPL_FLAG_PTR(flag) flag
290 #define ABSL_FLAG_IMPL_HELP_ARG(name) \
291 absl::flags_internal::HelpArg<AbslFlagHelpGenFor##name>( \
292 FLAGS_help_storage_##name)
293 #define ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name) \
294 absl::flags_internal::DefaultArg<Type, AbslFlagDefaultGenFor##name>(0)
296 #define ABSL_FLAG_IMPL_FLAG_PTR(flag) flag.GetImpl()
297 #define ABSL_FLAG_IMPL_HELP_ARG(name) &AbslFlagHelpGenFor##name::NonConst
298 #define ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name) &AbslFlagDefaultGenFor##name::Gen
301 #if ABSL_FLAGS_STRIP_NAMES
302 #define ABSL_FLAG_IMPL_FLAGNAME(txt) ""
303 #define ABSL_FLAG_IMPL_FILENAME() ""
304 #define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
305 absl::flags_internal::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(flag), \
308 #define ABSL_FLAG_IMPL_FLAGNAME(txt) txt
309 #define ABSL_FLAG_IMPL_FILENAME() __FILE__
310 #define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
311 absl::flags_internal::FlagRegistrar<T, true>(ABSL_FLAG_IMPL_FLAG_PTR(flag), \
317 #if ABSL_FLAGS_STRIP_HELP
318 #define ABSL_FLAG_IMPL_FLAGHELP(txt) absl::flags_internal::kStrippedFlagHelp
320 #define ABSL_FLAG_IMPL_FLAGHELP(txt) txt
331 #define ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, txt) \
332 struct AbslFlagHelpGenFor##name { \
336 static constexpr absl::string_view Value( \
337 absl::string_view v = ABSL_FLAG_IMPL_FLAGHELP(txt)) { \
340 static std::string NonConst() { return std::string(Value()); } \
342 constexpr auto FLAGS_help_storage_##name ABSL_INTERNAL_UNIQUE_SMALL_NAME() \
343 ABSL_ATTRIBUTE_SECTION_VARIABLE(flags_help_cold) = \
344 absl::flags_internal::HelpStringAsArray<AbslFlagHelpGenFor##name>( \
347 #define ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \
348 struct AbslFlagDefaultGenFor##name { \
349 Type value = absl::flags_internal::InitDefaultValue<Type>(default_value); \
350 static void Gen(void* p) { \
351 new (p) Type(AbslFlagDefaultGenFor##name{}.value); \
360 #define ABSL_FLAG_IMPL(Type, name, default_value, help) \
362 ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \
363 ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help) \
364 ABSL_CONST_INIT absl::Flag<Type> FLAGS_##name{ \
365 ABSL_FLAG_IMPL_FLAGNAME(#name), ABSL_FLAG_IMPL_FILENAME(), \
366 ABSL_FLAG_IMPL_HELP_ARG(name), ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name)}; \
367 extern absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name; \
368 absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name = \
369 ABSL_FLAG_IMPL_REGISTRAR(Type, FLAGS_##name)
392 #define ABSL_RETIRED_FLAG(type, name, default_value, explanation) \
393 static absl::flags_internal::RetiredFlag<type> RETIRED_FLAGS_##name; \
394 ABSL_ATTRIBUTE_UNUSED static const auto RETIRED_FLAGS_REG_##name = \
395 (RETIRED_FLAGS_##name.Retire(#name), \
396 ::absl::flags_internal::FlagRegistrarEmpty{})
398 #endif // ABSL_FLAGS_FLAG_H_