Back to home page

EIC code displayed by LXR

 
 

    


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_