|
||||
File indexing completed on 2025-01-18 09:27:16
0001 // 0002 // Copyright 2020 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: commandlineflag.h 0018 // ----------------------------------------------------------------------------- 0019 // 0020 // This header file defines the `CommandLineFlag`, which acts as a type-erased 0021 // handle for accessing metadata about the Abseil Flag in question. 0022 // 0023 // Because an actual Abseil flag is of an unspecified type, you should not 0024 // manipulate or interact directly with objects of that type. Instead, use the 0025 // CommandLineFlag type as an intermediary. 0026 #ifndef ABSL_FLAGS_COMMANDLINEFLAG_H_ 0027 #define ABSL_FLAGS_COMMANDLINEFLAG_H_ 0028 0029 #include <memory> 0030 #include <string> 0031 0032 #include "absl/base/config.h" 0033 #include "absl/base/internal/fast_type_id.h" 0034 #include "absl/flags/internal/commandlineflag.h" 0035 #include "absl/strings/string_view.h" 0036 #include "absl/types/optional.h" 0037 0038 namespace absl { 0039 ABSL_NAMESPACE_BEGIN 0040 namespace flags_internal { 0041 class PrivateHandleAccessor; 0042 } // namespace flags_internal 0043 0044 // CommandLineFlag 0045 // 0046 // This type acts as a type-erased handle for an instance of an Abseil Flag and 0047 // holds reflection information pertaining to that flag. Use CommandLineFlag to 0048 // access a flag's name, location, help string etc. 0049 // 0050 // To obtain an absl::CommandLineFlag, invoke `absl::FindCommandLineFlag()` 0051 // passing it the flag name string. 0052 // 0053 // Example: 0054 // 0055 // // Obtain reflection handle for a flag named "flagname". 0056 // const absl::CommandLineFlag* my_flag_data = 0057 // absl::FindCommandLineFlag("flagname"); 0058 // 0059 // // Now you can get flag info from that reflection handle. 0060 // std::string flag_location = my_flag_data->Filename(); 0061 // ... 0062 0063 // These are only used as constexpr global objects. 0064 // They do not use a virtual destructor to simplify their implementation. 0065 // They are not destroyed except at program exit, so leaks do not matter. 0066 #if defined(__GNUC__) && !defined(__clang__) 0067 #pragma GCC diagnostic push 0068 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 0069 #endif 0070 class CommandLineFlag { 0071 public: 0072 constexpr CommandLineFlag() = default; 0073 0074 // Not copyable/assignable. 0075 CommandLineFlag(const CommandLineFlag&) = delete; 0076 CommandLineFlag& operator=(const CommandLineFlag&) = delete; 0077 0078 // absl::CommandLineFlag::IsOfType() 0079 // 0080 // Return true iff flag has type T. 0081 template <typename T> 0082 inline bool IsOfType() const { 0083 return TypeId() == base_internal::FastTypeId<T>(); 0084 } 0085 0086 // absl::CommandLineFlag::TryGet() 0087 // 0088 // Attempts to retrieve the flag value. Returns value on success, 0089 // absl::nullopt otherwise. 0090 template <typename T> 0091 absl::optional<T> TryGet() const { 0092 if (IsRetired() || !IsOfType<T>()) { 0093 return absl::nullopt; 0094 } 0095 0096 // Implementation notes: 0097 // 0098 // We are wrapping a union around the value of `T` to serve three purposes: 0099 // 0100 // 1. `U.value` has correct size and alignment for a value of type `T` 0101 // 2. The `U.value` constructor is not invoked since U's constructor does 0102 // not do it explicitly. 0103 // 3. The `U.value` destructor is invoked since U's destructor does it 0104 // explicitly. This makes `U` a kind of RAII wrapper around non default 0105 // constructible value of T, which is destructed when we leave the 0106 // scope. We do need to destroy U.value, which is constructed by 0107 // CommandLineFlag::Read even though we left it in a moved-from state 0108 // after std::move. 0109 // 0110 // All of this serves to avoid requiring `T` being default constructible. 0111 union U { 0112 T value; 0113 U() {} 0114 ~U() { value.~T(); } 0115 }; 0116 U u; 0117 0118 Read(&u.value); 0119 // allow retired flags to be "read", so we can report invalid access. 0120 if (IsRetired()) { 0121 return absl::nullopt; 0122 } 0123 return std::move(u.value); 0124 } 0125 0126 // absl::CommandLineFlag::Name() 0127 // 0128 // Returns name of this flag. 0129 virtual absl::string_view Name() const = 0; 0130 0131 // absl::CommandLineFlag::Filename() 0132 // 0133 // Returns name of the file where this flag is defined. 0134 virtual std::string Filename() const = 0; 0135 0136 // absl::CommandLineFlag::Help() 0137 // 0138 // Returns help message associated with this flag. 0139 virtual std::string Help() const = 0; 0140 0141 // absl::CommandLineFlag::IsRetired() 0142 // 0143 // Returns true iff this object corresponds to retired flag. 0144 virtual bool IsRetired() const; 0145 0146 // absl::CommandLineFlag::DefaultValue() 0147 // 0148 // Returns the default value for this flag. 0149 virtual std::string DefaultValue() const = 0; 0150 0151 // absl::CommandLineFlag::CurrentValue() 0152 // 0153 // Returns the current value for this flag. 0154 virtual std::string CurrentValue() const = 0; 0155 0156 // absl::CommandLineFlag::ParseFrom() 0157 // 0158 // Sets the value of the flag based on specified string `value`. If the flag 0159 // was successfully set to new value, it returns true. Otherwise, sets `error` 0160 // to indicate the error, leaves the flag unchanged, and returns false. 0161 bool ParseFrom(absl::string_view value, std::string* error); 0162 0163 protected: 0164 ~CommandLineFlag() = default; 0165 0166 private: 0167 friend class flags_internal::PrivateHandleAccessor; 0168 0169 // Sets the value of the flag based on specified string `value`. If the flag 0170 // was successfully set to new value, it returns true. Otherwise, sets `error` 0171 // to indicate the error, leaves the flag unchanged, and returns false. There 0172 // are three ways to set the flag's value: 0173 // * Update the current flag value 0174 // * Update the flag's default value 0175 // * Update the current flag value if it was never set before 0176 // The mode is selected based on `set_mode` parameter. 0177 virtual bool ParseFrom(absl::string_view value, 0178 flags_internal::FlagSettingMode set_mode, 0179 flags_internal::ValueSource source, 0180 std::string& error) = 0; 0181 0182 // Returns id of the flag's value type. 0183 virtual flags_internal::FlagFastTypeId TypeId() const = 0; 0184 0185 // Interface to save flag to some persistent state. Returns current flag state 0186 // or nullptr if flag does not support saving and restoring a state. 0187 virtual std::unique_ptr<flags_internal::FlagStateInterface> SaveState() = 0; 0188 0189 // Copy-construct a new value of the flag's type in a memory referenced by 0190 // the dst based on the current flag's value. 0191 virtual void Read(void* dst) const = 0; 0192 0193 // To be deleted. Used to return true if flag's current value originated from 0194 // command line. 0195 virtual bool IsSpecifiedOnCommandLine() const = 0; 0196 0197 // Validates supplied value using validator or parseflag routine 0198 virtual bool ValidateInputValue(absl::string_view value) const = 0; 0199 0200 // Checks that flags default value can be converted to string and back to the 0201 // flag's value type. 0202 virtual void CheckDefaultValueParsingRoundtrip() const = 0; 0203 }; 0204 #if defined(__GNUC__) && !defined(__clang__) 0205 #pragma GCC diagnostic pop 0206 #endif 0207 0208 ABSL_NAMESPACE_END 0209 } // namespace absl 0210 0211 #endif // ABSL_FLAGS_COMMANDLINEFLAG_H_
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |