|
|
|||
File indexing completed on 2025-12-16 09:40:51
0001 // 0002 // Copyright 2019 The Abseil Authors. 0003 // 0004 // Licensed under the Apache License, Version 2.0 (the "License"); 0005 // you may not use this file except in compliance with the License. 0006 // You may obtain a copy of the License at 0007 // 0008 // https://www.apache.org/licenses/LICENSE-2.0 0009 // 0010 // Unless required by applicable law or agreed to in writing, software 0011 // distributed under the License is distributed on an "AS IS" BASIS, 0012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0013 // See the License for the specific language governing permissions and 0014 // limitations under the License. 0015 // 0016 // ----------------------------------------------------------------------------- 0017 // File: flag.h 0018 // ----------------------------------------------------------------------------- 0019 // 0020 // This header file defines the `absl::Flag<T>` type for holding command-line 0021 // flag data, and abstractions to create, get and set such flag data. 0022 // 0023 // It is important to note that this type is **unspecified** (an implementation 0024 // detail) and you do not construct or manipulate actual `absl::Flag<T>` 0025 // instances. Instead, you define and declare flags using the 0026 // `ABSL_FLAG()` and `ABSL_DECLARE_FLAG()` macros, and get and set flag values 0027 // using the `absl::GetFlag()` and `absl::SetFlag()` functions. 0028 0029 #ifndef ABSL_FLAGS_FLAG_H_ 0030 #define ABSL_FLAGS_FLAG_H_ 0031 0032 #include <cstdint> 0033 #include <string> 0034 #include <type_traits> 0035 0036 #include "absl/base/attributes.h" 0037 #include "absl/base/config.h" 0038 #include "absl/base/optimization.h" 0039 #include "absl/flags/commandlineflag.h" 0040 #include "absl/flags/config.h" 0041 #include "absl/flags/internal/flag.h" 0042 #include "absl/flags/internal/registry.h" 0043 #include "absl/strings/string_view.h" 0044 0045 namespace absl { 0046 ABSL_NAMESPACE_BEGIN 0047 0048 // Flag 0049 // 0050 // An `absl::Flag` holds a command-line flag value, providing a runtime 0051 // parameter to a binary. Such flags should be defined in the global namespace 0052 // and (preferably) in the module containing the binary's `main()` function. 0053 // 0054 // You should not construct and cannot use the `absl::Flag` type directly; 0055 // instead, you should declare flags using the `ABSL_DECLARE_FLAG()` macro 0056 // within a header file, and define your flag using `ABSL_FLAG()` within your 0057 // header's associated `.cc` file. Such flags will be named `FLAGS_name`. 0058 // 0059 // Example: 0060 // 0061 // .h file 0062 // 0063 // // Declares usage of a flag named "FLAGS_count" 0064 // ABSL_DECLARE_FLAG(int, count); 0065 // 0066 // .cc file 0067 // 0068 // // Defines a flag named "FLAGS_count" with a default `int` value of 0. 0069 // ABSL_FLAG(int, count, 0, "Count of items to process"); 0070 // 0071 // No public methods of `absl::Flag<T>` are part of the Abseil Flags API. 0072 // 0073 // For type support of Abseil Flags, see the marshalling.h header file, which 0074 // discusses supported standard types, optional flags, and additional Abseil 0075 // type support. 0076 0077 template <typename T> 0078 using Flag = flags_internal::Flag<T>; 0079 0080 // GetFlag() 0081 // 0082 // Returns the value (of type `T`) of an `absl::Flag<T>` instance, by value. Do 0083 // not construct an `absl::Flag<T>` directly and call `absl::GetFlag()`; 0084 // instead, refer to flag's constructed variable name (e.g. `FLAGS_name`). 0085 // Because this function returns by value and not by reference, it is 0086 // thread-safe, but note that the operation may be expensive; as a result, avoid 0087 // `absl::GetFlag()` within any tight loops. 0088 // 0089 // Example: 0090 // 0091 // // FLAGS_count is a Flag of type `int` 0092 // int my_count = absl::GetFlag(FLAGS_count); 0093 // 0094 // // FLAGS_firstname is a Flag of type `std::string` 0095 // std::string first_name = absl::GetFlag(FLAGS_firstname); 0096 template <typename T> 0097 ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) { 0098 return flags_internal::FlagImplPeer::InvokeGet<T>(flag); 0099 } 0100 0101 // SetFlag() 0102 // 0103 // Sets the value of an `absl::Flag` to the value `v`. Do not construct an 0104 // `absl::Flag<T>` directly and call `absl::SetFlag()`; instead, use the 0105 // flag's variable name (e.g. `FLAGS_name`). This function is 0106 // thread-safe, but is potentially expensive. Avoid setting flags in general, 0107 // but especially within performance-critical code. 0108 template <typename T> 0109 void SetFlag(absl::Flag<T>* flag, const T& v) { 0110 flags_internal::FlagImplPeer::InvokeSet(*flag, v); 0111 } 0112 0113 // Overload of `SetFlag()` to allow callers to pass in a value that is 0114 // convertible to `T`. E.g., use this overload to pass a "const char*" when `T` 0115 // is `std::string`. 0116 template <typename T, typename V> 0117 void SetFlag(absl::Flag<T>* flag, const V& v) { 0118 T value(v); 0119 flags_internal::FlagImplPeer::InvokeSet(*flag, value); 0120 } 0121 0122 // GetFlagReflectionHandle() 0123 // 0124 // Returns the reflection handle corresponding to specified Abseil Flag 0125 // instance. Use this handle to access flag's reflection information, like name, 0126 // location, default value etc. 0127 // 0128 // Example: 0129 // 0130 // std::string = absl::GetFlagReflectionHandle(FLAGS_count).DefaultValue(); 0131 0132 template <typename T> 0133 const CommandLineFlag& GetFlagReflectionHandle(const absl::Flag<T>& f) { 0134 return flags_internal::FlagImplPeer::InvokeReflect(f); 0135 } 0136 0137 ABSL_NAMESPACE_END 0138 } // namespace absl 0139 0140 0141 // ABSL_FLAG() 0142 // 0143 // This macro defines an `absl::Flag<T>` instance of a specified type `T`: 0144 // 0145 // ABSL_FLAG(T, name, default_value, help); 0146 // 0147 // where: 0148 // 0149 // * `T` is a supported flag type (see the list of types in `marshalling.h`), 0150 // * `name` designates the name of the flag (as a global variable 0151 // `FLAGS_name`), 0152 // * `default_value` is an expression holding the default value for this flag 0153 // (which must be implicitly convertible to `T`), 0154 // * `help` is the help text, which can also be an expression. 0155 // 0156 // This macro expands to a flag named 'FLAGS_name' of type 'T': 0157 // 0158 // absl::Flag<T> FLAGS_name = ...; 0159 // 0160 // Note that all such instances are created as global variables. 0161 // 0162 // For `ABSL_FLAG()` values that you wish to expose to other translation units, 0163 // it is recommended to define those flags within the `.cc` file associated with 0164 // the header where the flag is declared. 0165 // 0166 // Note: do not construct objects of type `absl::Flag<T>` directly. Only use the 0167 // `ABSL_FLAG()` macro for such construction. 0168 #define ABSL_FLAG(Type, name, default_value, help) \ 0169 ABSL_FLAG_IMPL(Type, name, default_value, help) 0170 0171 // ABSL_FLAG().OnUpdate() 0172 // 0173 // Defines a flag of type `T` with a callback attached: 0174 // 0175 // ABSL_FLAG(T, name, default_value, help).OnUpdate(callback); 0176 // 0177 // `callback` should be convertible to `void (*)()`. 0178 // 0179 // After any setting of the flag value, the callback will be called at least 0180 // once. A rapid sequence of changes may be merged together into the same 0181 // callback. No concurrent calls to the callback will be made for the same 0182 // flag. Callbacks are allowed to read the current value of the flag but must 0183 // not mutate that flag. 0184 // 0185 // The update mechanism guarantees "eventual consistency"; if the callback 0186 // derives an auxiliary data structure from the flag value, it is guaranteed 0187 // that eventually the flag value and the derived data structure will be 0188 // consistent. 0189 // 0190 // Note: ABSL_FLAG.OnUpdate() does not have a public definition. Hence, this 0191 // comment serves as its API documentation. 0192 0193 // ----------------------------------------------------------------------------- 0194 // Implementation details below this section 0195 // ----------------------------------------------------------------------------- 0196 0197 // ABSL_FLAG_IMPL macro definition conditional on ABSL_FLAGS_STRIP_NAMES 0198 #define ABSL_FLAG_IMPL_FLAG_PTR(flag) flag 0199 #define ABSL_FLAG_IMPL_HELP_ARG(name) \ 0200 absl::flags_internal::HelpArg<AbslFlagHelpGenFor##name>( \ 0201 FLAGS_help_storage_##name) 0202 #define ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name) \ 0203 absl::flags_internal::DefaultArg<Type, AbslFlagDefaultGenFor##name>(0) 0204 0205 #if ABSL_FLAGS_STRIP_NAMES 0206 #define ABSL_FLAG_IMPL_FLAGNAME(txt) "" 0207 #define ABSL_FLAG_IMPL_FILENAME() "" 0208 #define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \ 0209 absl::flags_internal::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(flag), \ 0210 nullptr) 0211 #else 0212 #define ABSL_FLAG_IMPL_FLAGNAME(txt) txt 0213 #define ABSL_FLAG_IMPL_FILENAME() __FILE__ 0214 #define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \ 0215 absl::flags_internal::FlagRegistrar<T, true>(ABSL_FLAG_IMPL_FLAG_PTR(flag), \ 0216 __FILE__) 0217 #endif 0218 0219 // ABSL_FLAG_IMPL macro definition conditional on ABSL_FLAGS_STRIP_HELP 0220 0221 #if ABSL_FLAGS_STRIP_HELP 0222 #define ABSL_FLAG_IMPL_FLAGHELP(txt) absl::flags_internal::kStrippedFlagHelp 0223 #else 0224 #define ABSL_FLAG_IMPL_FLAGHELP(txt) txt 0225 #endif 0226 0227 // AbslFlagHelpGenFor##name is used to encapsulate both immediate (method Const) 0228 // and lazy (method NonConst) evaluation of help message expression. We choose 0229 // between the two via the call to HelpArg in absl::Flag instantiation below. 0230 // If help message expression is constexpr evaluable compiler will optimize 0231 // away this whole struct. 0232 // TODO(rogeeff): place these generated structs into local namespace and apply 0233 // ABSL_INTERNAL_UNIQUE_SHORT_NAME. 0234 // TODO(rogeeff): Apply __attribute__((nodebug)) to FLAGS_help_storage_##name 0235 #define ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, txt) \ 0236 struct AbslFlagHelpGenFor##name { \ 0237 /* The expression is run in the caller as part of the */ \ 0238 /* default value argument. That keeps temporaries alive */ \ 0239 /* long enough for NonConst to work correctly. */ \ 0240 static constexpr absl::string_view Value( \ 0241 absl::string_view absl_flag_help = ABSL_FLAG_IMPL_FLAGHELP(txt)) { \ 0242 return absl_flag_help; \ 0243 } \ 0244 static std::string NonConst() { return std::string(Value()); } \ 0245 }; \ 0246 constexpr auto FLAGS_help_storage_##name ABSL_INTERNAL_UNIQUE_SMALL_NAME() \ 0247 ABSL_ATTRIBUTE_SECTION_VARIABLE(flags_help_cold) = \ 0248 absl::flags_internal::HelpStringAsArray<AbslFlagHelpGenFor##name>( \ 0249 0); 0250 0251 #define ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ 0252 struct AbslFlagDefaultGenFor##name { \ 0253 Type value = absl::flags_internal::InitDefaultValue<Type>(default_value); \ 0254 static void Gen(void* absl_flag_default_loc) { \ 0255 new (absl_flag_default_loc) Type(AbslFlagDefaultGenFor##name{}.value); \ 0256 } \ 0257 }; 0258 0259 // ABSL_FLAG_IMPL 0260 // 0261 // Note: Name of registrar object is not arbitrary. It is used to "grab" 0262 // global name for FLAGS_no<flag_name> symbol, thus preventing the possibility 0263 // of defining two flags with names foo and nofoo. 0264 #define ABSL_FLAG_IMPL(Type, name, default_value, help) \ 0265 extern ::absl::Flag<Type> FLAGS_##name; \ 0266 namespace absl /* block flags in namespaces */ {} \ 0267 ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ 0268 ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help) \ 0269 ABSL_CONST_INIT absl::Flag<Type> FLAGS_##name{ \ 0270 ABSL_FLAG_IMPL_FLAGNAME(#name), ABSL_FLAG_IMPL_FILENAME(), \ 0271 ABSL_FLAG_IMPL_HELP_ARG(name), ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name)}; \ 0272 extern absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name; \ 0273 absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name = \ 0274 ABSL_FLAG_IMPL_REGISTRAR(Type, FLAGS_##name) 0275 0276 // ABSL_RETIRED_FLAG 0277 // 0278 // Designates the flag (which is usually pre-existing) as "retired." A retired 0279 // flag is a flag that is now unused by the program, but may still be passed on 0280 // the command line, usually by production scripts. A retired flag is ignored 0281 // and code can't access it at runtime. 0282 // 0283 // This macro registers a retired flag with given name and type, with a name 0284 // identical to the name of the original flag you are retiring. The retired 0285 // flag's type can change over time, so that you can retire code to support a 0286 // custom flag type. 0287 // 0288 // This macro has the same signature as `ABSL_FLAG`. To retire a flag, simply 0289 // replace an `ABSL_FLAG` definition with `ABSL_RETIRED_FLAG`, leaving the 0290 // arguments unchanged (unless of course you actually want to retire the flag 0291 // type at this time as well). 0292 // 0293 // `default_value` is only used as a double check on the type. `explanation` is 0294 // unused. 0295 // TODO(rogeeff): replace RETIRED_FLAGS with FLAGS once forward declarations of 0296 // retired flags are cleaned up. 0297 #define ABSL_RETIRED_FLAG(type, name, default_value, explanation) \ 0298 static absl::flags_internal::RetiredFlag<type> RETIRED_FLAGS_##name; \ 0299 ABSL_ATTRIBUTE_UNUSED static const auto RETIRED_FLAGS_REG_##name = \ 0300 (RETIRED_FLAGS_##name.Retire(#name), \ 0301 ::absl::flags_internal::FlagRegistrarEmpty{}) 0302 0303 #endif // ABSL_FLAGS_FLAG_H_
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|