registry.h
Go to the documentation of this file.
00001 //
00002 // Copyright 2019 The Abseil Authors.
00003 //
00004 // Licensed under the Apache License, Version 2.0 (the "License");
00005 // you may not use this file except in compliance with the License.
00006 // You may obtain a copy of the License at
00007 //
00008 //      https://www.apache.org/licenses/LICENSE-2.0
00009 //
00010 // Unless required by applicable law or agreed to in writing, software
00011 // distributed under the License is distributed on an "AS IS" BASIS,
00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 // See the License for the specific language governing permissions and
00014 // limitations under the License.
00015 
00016 #ifndef ABSL_FLAGS_INTERNAL_REGISTRY_H_
00017 #define ABSL_FLAGS_INTERNAL_REGISTRY_H_
00018 
00019 #include <functional>
00020 #include <map>
00021 #include <string>
00022 
00023 #include "absl/base/macros.h"
00024 #include "absl/flags/internal/commandlineflag.h"
00025 
00026 // --------------------------------------------------------------------
00027 // Global flags registry API.
00028 
00029 namespace absl {
00030 namespace flags_internal {
00031 
00032 // CommandLineFlagInfo holds all information for a flag.
00033 struct CommandLineFlagInfo {
00034   std::string name;           // the name of the flag
00035   std::string type;           // DO NOT use. Use flag->IsOfType<T>() instead.
00036   std::string description;    // the "help text" associated with the flag
00037   std::string current_value;  // the current value, as a std::string
00038   std::string default_value;  // the default value, as a std::string
00039   std::string filename;       // 'cleaned' version of filename holding the flag
00040   bool has_validator_fn;  // true if RegisterFlagValidator called on this flag
00041 
00042   bool is_default;  // true if the flag has the default value and
00043                     // has not been set explicitly from the cmdline
00044                     // or via SetCommandLineOption.
00045 
00046   // nullptr for ABSL_FLAG.  A pointer to the flag's current value
00047   // otherwise.  E.g., for DEFINE_int32(foo, ...), flag_ptr will be
00048   // &FLAGS_foo.
00049   const void* flag_ptr;
00050 };
00051 
00052 //-----------------------------------------------------------------------------
00053 
00054 void FillCommandLineFlagInfo(CommandLineFlag* flag,
00055                              CommandLineFlagInfo* result);
00056 
00057 //-----------------------------------------------------------------------------
00058 
00059 CommandLineFlag* FindCommandLineFlag(absl::string_view name);
00060 CommandLineFlag* FindCommandLineV1Flag(const void* flag_ptr);
00061 CommandLineFlag* FindRetiredFlag(absl::string_view name);
00062 
00063 // Executes specified visitor for each non-retired flag in the registry.
00064 // Requires the caller hold the registry lock.
00065 void ForEachFlagUnlocked(std::function<void(CommandLineFlag*)> visitor);
00066 // Executes specified visitor for each non-retired flag in the registry. While
00067 // callback are executed, the registry is locked and can't be changed.
00068 void ForEachFlag(std::function<void(CommandLineFlag*)> visitor);
00069 
00070 //-----------------------------------------------------------------------------
00071 
00072 // Store the list of all flags in *OUTPUT, sorted by file.
00073 void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
00074 
00075 //-----------------------------------------------------------------------------
00076 
00077 bool RegisterCommandLineFlag(CommandLineFlag*, const void* ptr = nullptr);
00078 
00079 //-----------------------------------------------------------------------------
00080 // Retired registrations:
00081 //
00082 // Retired flag registrations are treated specially. A 'retired' flag is
00083 // provided only for compatibility with automated invocations that still
00084 // name it.  A 'retired' flag:
00085 //   - is not bound to a C++ FLAGS_ reference.
00086 //   - has a type and a value, but that value is intentionally inaccessible.
00087 //   - does not appear in --help messages.
00088 //   - is fully supported by _all_ flag parsing routines.
00089 //   - consumes args normally, and complains about type mismatches in its
00090 //     argument.
00091 //   - emits a complaint but does not die (e.g. LOG(ERROR)) if it is
00092 //     accessed by name through the flags API for parsing or otherwise.
00093 //
00094 // The registrations for a flag happen in an unspecified order as the
00095 // initializers for the namespace-scope objects of a program are run.
00096 // Any number of weak registrations for a flag can weakly define the flag.
00097 // One non-weak registration will upgrade the flag from weak to non-weak.
00098 // Further weak registrations of a non-weak flag are ignored.
00099 //
00100 // This mechanism is designed to support moving dead flags into a
00101 // 'graveyard' library.  An example migration:
00102 //
00103 //   0: Remove references to this FLAGS_flagname in the C++ codebase.
00104 //   1: Register as 'retired' in old_lib.
00105 //   2: Make old_lib depend on graveyard.
00106 //   3: Add a redundant 'retired' registration to graveyard.
00107 //   4: Remove the old_lib 'retired' registration.
00108 //   5: Eventually delete the graveyard registration entirely.
00109 //
00110 // Returns bool to enable use in namespace-scope initializers.
00111 // For example:
00112 //
00113 //   static const bool dummy = base::RetiredFlag<int32_t>("myflag");
00114 //
00115 // Or to declare several at once:
00116 //
00117 //   static bool dummies[] = {
00118 //       base::RetiredFlag<std::string>("some_string_flag"),
00119 //       base::RetiredFlag<double>("some_double_flag"),
00120 //       base::RetiredFlag<int32_t>("some_int32_flag")
00121 //   };
00122 
00123 // Retire flag with name "name" and type indicated by ops.
00124 bool Retire(FlagOpFn ops, FlagMarshallingOpFn marshalling_ops,
00125             const char* name);
00126 
00127 // Registered a retired flag with name 'flag_name' and type 'T'.
00128 template <typename T>
00129 inline bool RetiredFlag(const char* flag_name) {
00130   return flags_internal::Retire(flags_internal::FlagOps<T>,
00131                                 flags_internal::FlagMarshallingOps<T>,
00132                                 flag_name);
00133 }
00134 
00135 // If the flag is retired, returns true and indicates in |*type_is_bool|
00136 // whether the type of the retired flag is a bool.
00137 // Only to be called by code that needs to explicitly ignore retired flags.
00138 bool IsRetiredFlag(absl::string_view name, bool* type_is_bool);
00139 
00140 //-----------------------------------------------------------------------------
00141 // Saves the states (value, default value, whether the user has set
00142 // the flag, registered validators, etc) of all flags, and restores
00143 // them when the FlagSaver is destroyed.
00144 //
00145 // This class is thread-safe.  However, its destructor writes to
00146 // exactly the set of flags that have changed value during its
00147 // lifetime, so concurrent _direct_ access to those flags
00148 // (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
00149 
00150 class FlagSaver {
00151  public:
00152   FlagSaver();
00153   ~FlagSaver();
00154 
00155   FlagSaver(const FlagSaver&) = delete;
00156   void operator=(const FlagSaver&) = delete;
00157 
00158   // Prevents saver from restoring the saved state of flags.
00159   void Ignore();
00160 
00161  private:
00162   class FlagSaverImpl* impl_;  // we use pimpl here to keep API steady
00163 };
00164 
00165 }  // namespace flags_internal
00166 }  // namespace absl
00167 
00168 #endif  // ABSL_FLAGS_INTERNAL_REGISTRY_H_


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:15