diff options
Diffstat (limited to 'absl/flags/internal/commandlineflag.h')
-rw-r--r-- | absl/flags/internal/commandlineflag.h | 124 |
1 files changed, 17 insertions, 107 deletions
diff --git a/absl/flags/internal/commandlineflag.h b/absl/flags/internal/commandlineflag.h index 4ac50190c6c0..6363c6615b12 100644 --- a/absl/flags/internal/commandlineflag.h +++ b/absl/flags/internal/commandlineflag.h @@ -34,22 +34,23 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace flags_internal { -// Type-specific operations, eg., parsing, copying, etc. are provided -// by function specific to that type with a signature matching FlagOpFn. -enum FlagOp { - kDelete, - kClone, - kCopy, - kCopyConstruct, - kSizeof, - kParse, - kUnparse, +// An alias for flag static type id. Values of type identify the flag value type +// simialarly to typeid(T), but without relying on RTTI being available. In most +// cases this id is enough to uniquely identify the flag's value type. In a few +// cases we'll have to resort to using actual RTTI implementation if it is +// available. +using FlagStaticTypeId = void* (*)(); + +// Address of this function template is used in current implementation as a flag +// static type id. +template <typename T> +void* FlagStaticTypeIdGen() { #if defined(ABSL_FLAGS_INTERNAL_HAS_RTTI) - kRuntimeTypeId + return const_cast<std::type_info*>(&typeid(T)); +#else + return nullptr; #endif -}; -using FlagOpFn = void* (*)(FlagOp, const void*, void*); -using FlagMarshallingOpFn = void* (*)(FlagOp, const void*, void*, void*); +} // Options that control SetCommandLineOptionWithMode. enum FlagSettingMode { @@ -72,97 +73,6 @@ enum ValueSource { kProgrammaticChange, }; -// The per-type function -template <typename T> -void* FlagOps(FlagOp op, const void* v1, void* v2) { - switch (op) { - case kDelete: - delete static_cast<const T*>(v1); - return nullptr; - case kClone: - return new T(*static_cast<const T*>(v1)); - case kCopy: - *static_cast<T*>(v2) = *static_cast<const T*>(v1); - return nullptr; - case kCopyConstruct: - new (v2) T(*static_cast<const T*>(v1)); - return nullptr; - case kSizeof: - return reinterpret_cast<void*>(sizeof(T)); -#if defined(ABSL_FLAGS_INTERNAL_HAS_RTTI) - case kRuntimeTypeId: - return const_cast<std::type_info*>(&typeid(T)); - break; -#endif - default: - return nullptr; - } -} - -template <typename T> -void* FlagMarshallingOps(FlagOp op, const void* v1, void* v2, void* v3) { - switch (op) { - case kParse: { - // initialize the temporary instance of type T based on current value in - // destination (which is going to be flag's default value). - T temp(*static_cast<T*>(v2)); - if (!absl::ParseFlag<T>(*static_cast<const absl::string_view*>(v1), &temp, - static_cast<std::string*>(v3))) { - return nullptr; - } - *static_cast<T*>(v2) = std::move(temp); - return v2; - } - case kUnparse: - *static_cast<std::string*>(v2) = - absl::UnparseFlag<T>(*static_cast<const T*>(v1)); - return nullptr; - default: - return nullptr; - } -} - -// Functions that invoke flag-type-specific operations. -inline void Delete(FlagOpFn op, const void* obj) { - op(flags_internal::kDelete, obj, nullptr); -} - -inline void* Clone(FlagOpFn op, const void* obj) { - return op(flags_internal::kClone, obj, nullptr); -} - -inline void Copy(FlagOpFn op, const void* src, void* dst) { - op(flags_internal::kCopy, src, dst); -} - -inline void CopyConstruct(FlagOpFn op, const void* src, void* dst) { - op(flags_internal::kCopyConstruct, src, dst); -} - -inline bool Parse(FlagMarshallingOpFn op, absl::string_view text, void* dst, - std::string* error) { - return op(flags_internal::kParse, &text, dst, error) != nullptr; -} - -inline std::string Unparse(FlagMarshallingOpFn op, const void* val) { - std::string result; - op(flags_internal::kUnparse, val, &result, nullptr); - return result; -} - -inline size_t Sizeof(FlagOpFn op) { - // This sequence of casts reverses the sequence from base::internal::FlagOps() - return static_cast<size_t>(reinterpret_cast<intptr_t>( - op(flags_internal::kSizeof, nullptr, nullptr))); -} - -#if defined(ABSL_FLAGS_INTERNAL_HAS_RTTI) -inline const std::type_info& RuntimeTypeId(FlagOpFn op) { - return *static_cast<const std::type_info*>( - op(flags_internal::kRuntimeTypeId, nullptr, nullptr)); -} -#endif - // Handle to FlagState objects. Specific flag state objects will restore state // of a flag produced this flag state from method CommandLineFlag::SaveState(). class FlagStateInterface { @@ -187,7 +97,7 @@ class CommandLineFlag { // Return true iff flag has type T. template <typename T> inline bool IsOfType() const { - return TypeId() == &flags_internal::FlagOps<T>; + return TypeId() == &flags_internal::FlagStaticTypeIdGen<T>; } // Attempts to retrieve the flag value. Returns value on success, @@ -240,7 +150,7 @@ class CommandLineFlag { // Returns true iff this is a handle to an Abseil Flag. virtual bool IsAbseilFlag() const { return true; } // Returns id of the flag's value type. - virtual flags_internal::FlagOpFn TypeId() const = 0; + virtual FlagStaticTypeId TypeId() const = 0; virtual bool IsModified() const = 0; virtual bool IsSpecifiedOnCommandLine() const = 0; virtual std::string DefaultValue() const = 0; |